Compare commits

..

98 Commits

Author SHA1 Message Date
Lukas Wöhrl
999bd723d8 fix margin auto lead to negativ positioning 2020-06-09 13:01:50 +02:00
Steven Koeber
ede65bbce4 Buckification of Yoga build script
Reviewed By: liorisraeli87, k21

Differential Revision: D21429174

fbshipit-source-id: f12c8349cc59398553773df7bc15f0f83bd571b4
2020-06-04 06:54:18 -07:00
Jon Janzen
4135420cba Fix GitHub Actions secrets access (#1005)
Summary:
Ref: [Secrets documentation](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#using-encrypted-secrets-in-a-workflow)

In combination with setting the secrets in the GitHub settings, this should fully migrate yoga to GH actions.

Pull Request resolved: https://github.com/facebook/yoga/pull/1005

Test Plan: GitHub Actions CI on the PR attached to this diff

Reviewed By: SidharthGuglani

Differential Revision: D21574995

Pulled By: bigfootjon

fbshipit-source-id: e9ee6d7cf1ae131afdc3aa3778667f1e9b9de833
2020-05-14 12:21:28 -07:00
Sidharth Guglani
07c0d539bd throw std::logic_error instead of aborting the process and convert to java exception
Summary: Changelog: [Internal][Yoga] throw std::logic_error instead of aborting the process and convert to java exception for jni layer

Reviewed By: pasqualeanatriello

Differential Revision: D21301235

fbshipit-source-id: 148b27920e62990a271e1d0df8c85a2cc42f4fd4
2020-05-14 06:39:25 -07:00
Jon Janzen
ac7c85c0a6 Migrate CI from TravisCI to GitHub Actions (#1004)
Summary:
Migrate from TravisCI to GitHub Actions. Facebook employees can read about this migration [here](https://fburl.com/rfp033ou).

CC: wittgenst
Pull Request resolved: https://github.com/facebook/yoga/pull/1004

Test Plan: GitHub Actions CI on my personal GitHub: https://github.com/bigfootjon/yoga/runs/653755729

Reviewed By: passy

Differential Revision: D21431309

Pulled By: bigfootjon

fbshipit-source-id: 490a8679bc0cfec26b13c8c584a928f03c6e26e7
2020-05-12 12:01:53 -07:00
Sidharth Guglani
83b27417ae Fix rounding error using double instead of float
Summary: Changelog: [Internal] [Yoga] Use double instead of float during rounding process to prevent loss of precision.

Reviewed By: mdvacca

Differential Revision: D21227565

fbshipit-source-id: 380b57535a356624cda8dc2017871a4ef3c882d1
2020-04-27 14:48:15 -07:00
Valentin Shergin
884f147742 Fixed incorrect owner assignment in YGNode move constructor
Summary:
Assigning self as an owner makes a cycle which is obviously a bug.

Changelog: [Internal] Small change in Yoga (should not affect RN).

Reviewed By: SidharthGuglani

Differential Revision: D21111423

fbshipit-source-id: 1835561c055ac827f5ce98a044f25aed0d1845a5
2020-04-20 12:05:55 -07:00
Gavin Weng
a96a36ef59 Link yogacore statically into yoga
Summary: A revert of D20879886.

Reviewed By: iliagore

Differential Revision: D20979490

fbshipit-source-id: cb37f931654450c408e72578abcc549f35727b07
2020-04-17 17:34:17 -07:00
acton393
1bd4123df1 fix typo as there is no file called YGJNI.cpp (#990)
Summary:
fix typo in `YogaJNIBase.java` as there is no such file called `YGJNI.cpp`
Pull Request resolved: https://github.com/facebook/yoga/pull/990

Reviewed By: pasqualeanatriello

Differential Revision: D20735102

Pulled By: SidharthGuglani

fbshipit-source-id: 3f9f4d78ba390feae3451330f997a221ab4ec70e
2020-04-17 05:45:41 -07:00
Sidharth Guglani
92b76447b7 use default value of enums YGDirection and YGMeasureMode instead of -1
Summary:
Changelog:
[Internal][Yoga] YGDirection variable was initialized incorrectly by casting -1 to YGDirection. Changing it to default value of direction

Same for YGMeasureMode.

Reviewed By: pasqualeanatriello

Differential Revision: D20869042

fbshipit-source-id: 7bfe490193321baae875ef6fb49a938851950c9f
2020-04-17 05:32:05 -07:00
Sidharth Guglani
e637cf2d72 Add Yoga also as a dependency of testutil-jni
Summary:
`scripts/deploy_jcenter.sh` was failing

{F234018047}

Added `yoga` also as a dependency of `testutil-jni`

Reviewed By: gavinweng

Differential Revision: D21017796

fbshipit-source-id: 0c34e7fc2373906441bd7805f5687b2c5dab6242
2020-04-15 00:49:53 -07:00
empyrical
9b96a5362a Yoga Podspec: Export YGNode and YGStyle headers (#997)
Summary:
This pull request adds `YGNode.h` and `YGStyle.h` to the headers exported by Yoga's podspec. They are required by the new Fabric architecture of React Native.

The modulemap and its umbrella header automatically generated by Cocoapods adds all exported headers to the `modulemap`. Having YGNode and YGStyle exported through here has problems, because they are only available in environments that have C++ available, and will produce errors otherwise.

This pull request fences off the contents of those headers in an `#ifdef __cplusplus` block, so they will not cause errors when imported into environments where C++ isn't available.

I had considered adding a custom modulemap to the podspec as part of this pull request, but this way seems the least "invasive", and this way you are able to add and remove exported headers in the podspec without needing to worry about updating the umbrella header at the same time.

Changelog:

[Internal] - Yoga Podspec: Export YGNore and YGStyle headers

Pull Request resolved: https://github.com/facebook/yoga/pull/997

Reviewed By: hramos

Differential Revision: D20966075

Pulled By: mdvacca

fbshipit-source-id: 5f5caa6b639d11e660b968d681da9a4de6c0eb8e
2020-04-14 16:42:27 -07:00
Sidharth Guglani
e5743e851b Set width/height also to Undefined when we change the measure mode to Undefined
Summary:
Make sure width/height is always passed as Undefined when measure mode is changed to Undefined.

Changelog: [Internal][Yoga] Set width and height as Undefined when we change measure mode to Undefined

Reviewed By: alickbass

Differential Revision: D20029838

fbshipit-source-id: b9931f6ddb13ffd1565889535ade5bbffbe0c304
2020-04-14 02:09:29 -07:00
George Zahariev
f7bc0ad248 Upgrade Prettier in Xplat to version 1.19.1: format files
Summary:
Part two of D20879147 where we update the versions of Prettier used in Xplat. I will stack land the diffs.
Here, we format all the files, and use the drop conflicts flag. After this lands, I will go and format the files which had conflicts again.

Changelog: [Internal]

drop-conflicts
bypass-lint
allow-large-files

Reviewed By: gkz

Differential Revision: D20929844

fbshipit-source-id: 2c1df8966a48b5db4f890e2cc494cb1c69422b7d
2020-04-09 11:06:06 -07:00
George Zahariev
8c53c2dcca Upgrade Prettier in Xplat to version 1.19.1
Summary:
Upgrades Prettier in Xplat to 1.19.1
Ignores upgrading packages on already on versions greater than 1.19.1

Changelog: [Internal]

allow-large-files
bypass-lint

(Note: this ignores all push blocking failures!)

Reviewed By: gkz, cpojer

Differential Revision: D20879147

fbshipit-source-id: 0deee7ac941e91e1c3c3a1e7d3d3ed20de1d657d
2020-04-09 11:06:04 -07:00
Gavin Weng
be51bc44a4 Revert Name Change for FBLite
Summary: To unblock

Reviewed By: Arieg419

Differential Revision: D20879886

fbshipit-source-id: 428f9147e540b94dec7f72a7f844949722165a07
2020-04-06 19:53:50 -07:00
Gavin Weng
5eba2d42bd Enhance build process (#994)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/994

After building yoga aar, we found several issues:
1. More dynamic so files. This is bad as lower-end Android devices cannot load that many sos.
2. Size increase.
3. (Minor) The libs are stored in asset folder rather than "libs/".

We apply the following optimizations:
1. Remove dependency on memalign16 (this is brought in by a pure header dependency jni-hack);
2. Enable native relinker to remove unused symbols in the so files.
3. Link yogacore statically to reduce size churn.

Reviewed By: SidharthGuglani

Differential Revision: D20808623

fbshipit-source-id: 6c6bbd4f71b6bf6ad272ec05dd56696ddb14a8e0
2020-04-06 11:51:16 -07:00
Sidharth Guglani
2049c85a6c Unit tests for flexshrink min width cases
Reviewed By: pasqualeanatriello

Differential Revision: D20219428

fbshipit-source-id: 8cbd028627095d9f7b393489ddba1f31c3207b67
2020-04-01 14:56:49 -07:00
Sidharth Guglani
ecd7790dd8 Fix Yoga flexshrink with min-width sizing issue
Summary:
While resolving the flexible items we calculate totalFlexShrinkScaledFactors which uses the flexBasis or initial width of node (Not min-width).

At a later stage during distribution of space we are subtracting value from this which also takes care of min-width.

For example
If node has flexShrink 1 and width 100 and min-width 301  then totalFlexShrinkScaledFactors will become -1*100 = -100
but later we are subtracting -1 * 301 (min-width) = -301 which is ambiguous and causing layout inconsistencies with how web behaves.

Fixed this by only using the flexBasis or width for these calculations.

Changelog:
[Internal][Yoga] Fix layout issue when flexShrink and min-width are used together

Reviewed By: pasqualeanatriello

Differential Revision: D20219419

fbshipit-source-id: 948fbc06ca541d4ad307c88c8a2df65d157778b1
2020-04-01 14:56:45 -07:00
Michael Bolin
0f08aa53da Back out "Upgrade Prettier from 1.17 to 2.0.2."
Differential Revision: D20639755

fbshipit-source-id: 5028563f9cf0527a30b4259daac50cdc03934bfd
2020-03-24 21:41:08 -07:00
Michael Bolin
5bf93e81ba Upgrade Prettier from 1.17 to 2.0.2.
Summary:
This gets us on the latest Prettier 2.x:
https://prettier.io/blog/2020/03/21/2.0.0.html

Notably, this adds support for TypeScript 3.8,
which introduces new syntax, such as `import type`.

Reviewed By: zertosh

Differential Revision: D20636268

fbshipit-source-id: fca5833d003804333a05ba16325bbbe0e06d6c8a
2020-03-24 20:26:19 -07:00
Lior Israeli
4f1231f411 Fix typo in buck targets
Summary: Proguard is spelled wrong

Reviewed By: SidharthGuglani

Differential Revision: D20619173

fbshipit-source-id: 463788454ad7e72337121ed63ab79129db45113e
2020-03-24 05:37:47 -07:00
Adam Ernst
b280a19b0a Run 'arc lint-deps'
Reviewed By: d16r

Differential Revision: D20362505

fbshipit-source-id: f3b7e62f7665d20a32788042772b731d6ed53f36
2020-03-10 10:58:46 -07:00
Nate Stedman
63a463d011 Mark YogaKit as modular
Differential Revision: D20364340

fbshipit-source-id: ce4bc1f474177ffc9c77eb2f10bdb7cb549dd6d8
2020-03-10 09:38:56 -07:00
Jesse Katsumata
adb87e347f chore: fix typo in comments (#28269)
Summary:
Fixed some typos in the comment.

## Changelog

[Internal] [Fixed] - Fixed typo in the comments
Pull Request resolved: https://github.com/facebook/react-native/pull/28269

Test Plan: Changes are only made in the comments, so test is not necessary.

Reviewed By: cpojer

Differential Revision: D20342637

Pulled By: shergin

fbshipit-source-id: f6e7dd538ee54c43e1570c35e1f8c4502054e328
2020-03-09 16:03:44 -07:00
Sidharth Guglani
2d52b5a873 fix layout tab height issue in playground on home page
Summary: Fixed layout tab height issue properly

Reviewed By: danielbuechele

Differential Revision: D20003594

fbshipit-source-id: 6d9ce89a5d82a83937e5cb0f989bb028e07d576f
2020-02-25 07:34:37 -08:00
Sidharth Guglani
6c61cd5f05 Fix layout tab scrolling in playground
Summary: Add a scroll bar to layout tab in playground to fix the UI issue where margin, border were not accessible.

Reviewed By: danielbuechele

Differential Revision: D19906128

fbshipit-source-id: 2c2d7695f731b2d312b78eab31c66d737915eaae
2020-02-19 11:12:41 -08:00
Sidharth Guglani
bfc3b2f86f fix lint errors
Summary:
Changelog: [Internal][Yoga] Fixed lint errors

```arc lint --apply-patches --take CLANGFORMAT --paths-cmd 'hg files xplat/yoga'
```
Added .clang-tidy file

Reviewed By: zertosh

Differential Revision: D19948702

fbshipit-source-id: f77a16d6f2c532267597a84a9caded0aae68c3aa
2020-02-18 08:24:46 -08:00
Christoph Purrer
a1278cee05 Make YGValue.h compile with Clang on Windows
Summary:
- We use a fork of Microsoft's react-native-windows which uses a fork of Facebook's react-native
- YGValue.h does not compile with Clang on Windows
- This change should fix that
- I want to put the change here so that it bubbles back to our fork > https://our.intern.facebook.com/intern/diff/D19656093/

#Changelog:
[General][Fixed] Make YGValue.h compile with Clang on Windows

Reviewed By: SidharthGuglani

Differential Revision: D19717489

fbshipit-source-id: ad867ecaf910bb64a777a06c656a1867bb15484b
2020-02-05 13:44:21 -08:00
Pasquale Anatriello
e983c4a5ef Swap child Yoga
Summary:
Changelog: [Internal]

Expose the replaceChild Yoga call to Java

Reviewed By: SidharthGuglani

Differential Revision: D19497193

fbshipit-source-id: 153243cc1d8c23dcaf2c772ca794bd59a230f652
2020-01-30 04:32:20 -08:00
Amir Shalem
7f97e8b232 Allow redex to optimize more of yoga by removing unneeded @DoNotStrip marks
Summary:
There are multiple `DoNotStrip` in Yoga java binding, they aren't needed.

##Changelog:
[Internal][Yoga] Allow redex to optimize more of yoga by removing unneeded DoNotStrip marks

Reviewed By: SidharthGuglani

Differential Revision: D17519844

fbshipit-source-id: 8b26800d720f34cae87754d85460abf88acbe713
2019-12-04 01:34:54 -08:00
Sidharth Guglani
089095f532 create global ref properly in YogaJNIException
Summary:
##Changelog:
[Internal][Yoga] create global ref properly in YogaJNIException

Reviewed By: astreet

Differential Revision: D18775982

fbshipit-source-id: ee529d6178d40b5f887fa1327fe156fa466f154f
2019-12-03 16:02:13 -08:00
Sidharth Guglani
ac8eb111a9 Add defensive check for result returned after JNI function calls
Summary:
Added method which checks if value(methodId, fieldId, class ...) returned by JNI functions (getMethod, getField, getClass ...) is valid or not and throw exception if they are not valid

##Changelog:
[Internal][Yoga] Add defensive check for result returned after JNI calls

Reviewed By: astreet

Differential Revision: D18745718

fbshipit-source-id: 2af26eda15fbe7834e1c9b274deeed4f106274ab
2019-12-02 05:24:54 -08:00
Sidharth Guglani
073f49d0d0 Use YogaJniException in jni call exception handling
Summary:
##Changelog:
[Internal][Yoga] Use YogaJniException in jni call exception handling

Reviewed By: astreet

Differential Revision: D18745615

fbshipit-source-id: 5fcf4c31f04fade94ef98a5349782ed3d43805b0
2019-12-02 05:24:54 -08:00
Sidharth Guglani
67915b5905 Add YogaJniException class
Summary:
## Changelog:
[Internal][Yoga] Add YogaJniException class to be used later for jni exceptions

Reviewed By: astreet

Differential Revision: D18745609

fbshipit-source-id: 53503b54dbc59e9fe47f599dee6be9cb68134cb2
2019-12-02 05:24:53 -08:00
Sidharth Guglani
015df9c512 Remove bitfield.h
Summary:
##Changelog:

[Internal][Yoga] Remove Bitfield.h

Reviewed By: astreet

Differential Revision: D18519647

fbshipit-source-id: b46fe585d3ef5f1da7d2726b2d9f759a649be121
2019-11-27 14:19:47 -08:00
Sidharth Guglani
f7f134274c Remove bitfield from YGNode.h
Summary:
##Changelog:

[Internal][Yoga] remove Bitfield from YGNode.h

Reviewed By: astreet

Differential Revision: D18519633

fbshipit-source-id: b5a7d8d5ee960c5618df382900c4ded3da0587a6
2019-11-27 14:19:46 -08:00
Sergey Ryabov
aeb9549af7 Fix javadocs
Summary: Changelog: [Internal]

Reviewed By: muraziz

Differential Revision: D15538725

fbshipit-source-id: 5cf60f47b07ce355e40d5b064add1df980beed89
2019-11-22 10:25:41 -08:00
Sidharth Guglani
f3498a2959 Remove BItfield from YGLayout.h
Summary:
##Changelog:

[Internal][Yoga] Remove Bitfield from YGLayout

Reviewed By: astreet

Differential Revision: D18519623

fbshipit-source-id: 950b8cb1ca2cd0424b8d8748c4b71336b40fc15f
2019-11-22 04:51:14 -08:00
Sidharth Guglani
9d2ca758fa Remove Bitfield from YGStyle
Summary:
##Changelog:

[Internal][Yoga] Remove Bitfield from YGStyle

Reviewed By: astreet

Differential Revision: D18519614

fbshipit-source-id: 70f18bc679b62712d40d76bd793cf85906b067a1
2019-11-22 04:51:13 -08:00
Sidharth Guglani
9650c1903d converts BitfieldTests to BitUtilsTest
Summary: Use BitUtils for testing bit operations

Reviewed By: astreet

Differential Revision: D18596312

fbshipit-source-id: 83f93cd7f1f056b3f64070debbc452877b44ac7a
2019-11-22 04:51:13 -08:00
Sidharth Guglani
f4840a0148 Added BitUtils
Summary:
Adds BitUtils to be used later instead of Bitfield.h

##Changelog:
[Internal][Yoga] : Adds BitUtils to be used later instead of Bitfield.h

Reviewed By: astreet

Differential Revision: D18519609

fbshipit-source-id: 8353929543505a7d80d66281adb801d34372beed
2019-11-22 04:51:12 -08:00
Sidharth Guglani
198e99d30c Back out "not using templates for updating styles which are used via bitfield"
Reviewed By: astreet

Differential Revision: D18628090

fbshipit-source-id: 9d006534111f10ec25a0d56214792aeb96fbdef9
2019-11-22 04:51:11 -08:00
Sidharth Guglani
cd0191c247 not using templates for updating styles which are used via bitfield
Summary:
We want completely remove usages of Bitfield as it uses templates which bloats binary size
This stack will reduce 2.2 Kb in binary size bringing it down to 61.3KB on armv7

In this diff we are removing usage of template while updating styles.

## Changelog:
[Internal][Yoga] : Not using templates for updating styles

Reviewed By: astreet

Differential Revision: D18519570

fbshipit-source-id: 2324088b8c63154f818b1da1edf24c0533e10082
2019-11-15 06:39:29 -08:00
Sidharth Guglani
7ec0ef8470 add test for margin and padding percent applied on leaf nodes with measure function
Summary: Add tests for using margin and padding percent on nodes with measure function set on them

Reviewed By: alickbass

Differential Revision: D17130693

fbshipit-source-id: 9a5c963671f7649dead459969b008335f15e45ce
2019-11-15 05:13:35 -08:00
Sidharth Guglani
b88cf7ff67 use owner's width for resolving the margin and padding for node
Summary:
The margin and padding are resolved incorrectly for leaf nodes (nodes with measure function set) if margin and padding are used in percentages.
Here we were using node's width instead of container width to calculate the margin and padding.

Fixed this to use container's width.

## Changelog:

[General][Yoga] : Fixed an issue where margin and padding were resolved incorrectly for leaf nodes (nodes with measure function set) if margin and padding are used in percentages.

Reviewed By: alickbass

Differential Revision: D17130520

fbshipit-source-id: ac904d432f121973e7739debd9136909b5ca1427
2019-11-15 05:13:34 -08:00
Sidharth Guglani
20fe53b254 Add --version-script
Summary: Adds version script to exclude all exported symbols and export only JNI_onLoad

Reviewed By: Andrey-Mishanin

Differential Revision: D18076602

fbshipit-source-id: cac4ef9c800de6a3b2081a1f847fa918687896fe
2019-11-13 16:46:09 -08:00
Sidharth Guglani
f99da09716 Remove useVanillaJNI flag and usage of fbjni in yoga build
Summary:
## Changelog:

[General] [Yoga] - Use vanilla jni instead of fbjni for all the jni communication

Reviewed By: astreet

Differential Revision: D17808005

fbshipit-source-id: 5e9a1ed73978f519c71c248774a28e5a294e7c7f
2019-11-13 15:16:37 -08:00
Sidharth Guglani
5960dd888d Add test for margin top not calculated correctly if defined in percentage
Summary:
Unit tests for margin percent scenario where height was being used instead of width

## Changelog:

[Internal] [Yoga] - Added unit tests for margin percent

Reviewed By: alickbass

Differential Revision: D18448365

fbshipit-source-id: f4404b0c493938fc04dc685e97effa08bfd553b0
2019-11-13 07:25:59 -08:00
Sidharth Guglani
b0a0007d6e using width for calculating margin top percent
Summary:
In Yoga, margin is not calculated correctly when defined in terms of percentage at one place.
According to CSS docs , margin percentage should be calculated according to width of container's block in case of horizontal writing mode. (https://fburl.com/5imus0it)
We were using height of container causing some issues in both android and iOS.

## Changelog:

[Yoga] [Fixed] - margin if defined in percentage should use container's width in horizontal writing mode

Reviewed By: alickbass

Differential Revision: D18395285

fbshipit-source-id: 87ebd013e3cba36da45f6548e4dff1bce69cce9b
2019-11-13 05:29:36 -08:00
Pritesh Nandgaonkar
73a4a6d29f Fixes the Yogakit compilation bug for xcode11
Summary:
This fixes the yogakit compilation bug for xcode 11, where it fails to find swift core frameworks for pure objc project.

https://github.com/Carthage/Carthage/issues/2825
https://twitter.com/krzyzanowskim/status/1151549874653081601?s=21

Also published this podspec on cocoapods and deleted .swift-version file as it was not required, because swift version is mentioned in podspec

Reviewed By: SidharthGuglani

Differential Revision: D18420963

fbshipit-source-id: d617bf643ac6481d6add86e6a4bfadd6e0d0c229
2019-11-11 10:18:52 -08:00
Pritesh Nandgaonkar
0be0e9fc01 Solve lib lint failure
Summary:
This diff solves `pod lib lint` failure.

We want to make a new yoga release, as I landed some changes in its podspec which solves the broken flipper build for xcode 11.

{F221612119}

Reviewed By: passy

Differential Revision: D18382588

fbshipit-source-id: efddfa3e93ca59b79b887d04f83407b004d9a199
2019-11-08 04:03:00 -08:00
Pritesh Nandgaonkar
ddf748a99d Add Swift extension as a separate pod
Summary:
Adds swift extension file as a separate subspec, as it is not required for the objc projects.

Also this fixes the current issue where the flipper sample app fails to build on xcode 11, as it fails to link the Swift specific literals.

Fixes this too https://github.com/facebook/yoga/issues/565

Reviewed By: SidharthGuglani

Differential Revision: D18373993

fbshipit-source-id: 0c058886a837c7ceafcd0167f878b3e0f7763aa1
2019-11-07 10:51:42 -08:00
Sidharth Guglani
4d16ee4ed4 Use double for YGRoundValueToPixelGrid calculations
Summary:
Use double for YGRoundValueToPixelGrid calculations as we were losing some precision in float operations

#Changelog:
[Internal][Yoga] Use double for YGRoundValueToPixelGrid calculations

Reviewed By: astreet

Differential Revision: D18225999

fbshipit-source-id: 69c05f56a0e0f3433bf0bd958aa07d26dd83fe02
2019-11-05 17:26:00 -08:00
Dmytro Kasianchuk
b72efaaaca Added missing YOGA_EXPORT
Summary:
Added missing YOGA_EXPORT

#Changelog:
[Internal] [Fixed] - Added missing YOGA_EXPORT

Reviewed By: SidharthGuglani

Differential Revision: D18289071

fbshipit-source-id: a2e16a59427aa33b34b3d1fab9d1088904ee62f5
2019-11-02 20:43:17 -07:00
Sidharth Guglani
6327893b9b Use compiler flags -ffunction-sections, -fdata-sections and gc sections in both jni and core
Summary: Use compiler flags -ffunction-sections, -fdata-sections and  -Wl,--gc-sections  in both jni and yoga core

Reviewed By: amir-shalem

Differential Revision: D18029671

fbshipit-source-id: 5192fb6d682248b16781dead0d7b0a0377861fb6
2019-11-01 11:54:45 -07:00
Sidharth Guglani
8c3ee81d6e Use compiler flag -fvisibility=hidden
Summary:
Using compiler flag -fvisibility=hidden and explicitly setting visibility to default to public methods

#Changelog:
[Internal] [Yoga] Use compiler flag -fvisibility=hidden for reducing yoga binary size

Reviewed By: astreet

Differential Revision: D18029030

fbshipit-source-id: 545e73f9c25f3108fc9d9bb7f08c157dbc8da005
2019-11-01 11:54:45 -07:00
Scott Wolchok
fb07dcff40 Fix data race with gCurrentGenerationCount
Summary:
Yoga layout can be invoked on multiple threads, and gCurrentGenerationCount is a shared global without synchronization.

Changelog: [General] [Fixed] - Fix an internal thread safety issue in Yoga

Reviewed By: SidharthGuglani

Differential Revision: D18092734

fbshipit-source-id: 85753d139549b4e5507f97a56d589fb6854557fa
2019-10-28 12:54:52 -07:00
Sidharth Guglani
27f42c90db Remove setStyleInputs API
Summary:
setStyleInputs batching API was added to reduce the number of jni calls and although it improved performance in yoga world but was not impactful in litho and is not used anywhere.

Removing this saves around 500 bytes per architecture

#Changelog:
[Internal][Yoga] Removed unused code setStyleInputs batching API form Yoga

Reviewed By: amir-shalem

Differential Revision: D18036536

fbshipit-source-id: 7436b55dcd464dd9f9cc46406d4fd78d12babe55
2019-10-23 02:38:03 -07:00
Sidharth Guglani
688bd4ef72 Add exception handling in vanilla jni
Summary:
Exception handling in vanilla jni

## Changelog:
[Internal] [Added] Added exception handling for vanilla jni implementation in yoga

Reviewed By: amir-shalem

Differential Revision: D18036134

fbshipit-source-id: 965eaa2fddbc00b9ac0120b79678608e280d03db
2019-10-22 11:01:00 -07:00
Andres Suarez
42bba10894 Tidy up license headers
Summary: Changelog: Tidy up license headers

Reviewed By: SidharthGuglani

Differential Revision: D17919414

fbshipit-source-id: 0501b495dc0a42256ca6ba3284a873da1ab175c0
2019-10-15 10:36:38 -07:00
Sidharth Guglani
495d8da596 useVanilla flag for measure and baseline methods as well
Summary: UseVanillaJNI flag was missing for measure and baseline functions

Reviewed By: amir-shalem

Differential Revision: D17868201

fbshipit-source-id: 95d6843d643e90157a51550d6efbf059f0ca2c39
2019-10-11 02:04:02 -07:00
Sidharth Guglani
869a33eb13 no need to pass env to ref method , we can directly use getCurrentEnv()
Summary: We can use getCurrentEnv() instead of passing environment variable around

Reviewed By: amir-shalem

Differential Revision: D17842042

fbshipit-source-id: 185b174ae7c08e746bc76c0600c2e326b15c4993
2019-10-10 05:33:20 -07:00
Sidharth Guglani
050893f15a rename PtrJNodeMap to PtrJNodeMapVanilla in yoga vanilla jni files
Summary: Rename PtrJNodeMap in vanilla files top PtrJNodeMapVanilla , otherwise they conflict

Reviewed By: amir-shalem

Differential Revision: D17842001

fbshipit-source-id: eb164076ee2a68d79dc376826508a4143056ea31
2019-10-10 05:33:19 -07:00
Sidharth Guglani
8aa67abdb2 Fix YGNodeJobject method
Summary: We can use getCurrentEnv() , no need to pass env around methods

Reviewed By: amir-shalem

Differential Revision: D17841281

fbshipit-source-id: a4a58292e70ac05b0f0b9eb962a82a8501ad0226
2019-10-10 05:33:19 -07:00
Sidharth Guglani
2e321fc69f Move JNI_OnLoad to separate file which registers both fbjni and jni methods
Summary: Move JNI_ONLoad to a separate file so that both fbjni native methods and vanillla jni native methods can be initialized correctly

Reviewed By: amir-shalem

Differential Revision: D17840166

fbshipit-source-id: 045df0df7a95bc331cbbefb3a118a349f3029465
2019-10-10 05:33:18 -07:00
Amir Shalem
aa2610c2dd Set missing useVanillaJNI in constructor for YogaNode
Summary: set missing useVanillaJNI, it was causing part of the unit-tests to run in fbjni instead of vanillajni.

Reviewed By: SidharthGuglani

Differential Revision: D17852635

fbshipit-source-id: 5bc187d90fbdc430015be55a015a7d1e0ba0ebc6
2019-10-10 02:45:00 -07:00
Sidharth Guglani
293b657aef Use TestParametrization for testing both fbjni and vanillaJNI version
Summary: Use TestParametrization to test both fbjni and vanilla jni versions

Reviewed By: amir-shalem

Differential Revision: D17788718

fbshipit-source-id: 0f3317b7403cadca7b7ccd9140f1933d746bf433
2019-10-09 09:28:41 -07:00
Sidharth Guglani
d6591439d1 move YGSetLogger and YGConfigFree with global ref to vanilla jni
Summary: Move YGSetLogger and YGConfigFree methods to vanilla JNI

Reviewed By: amir-shalem

Differential Revision: D17754999

fbshipit-source-id: 8dfcf1a54e4d54ebf91e38c6513e6a703a40ae92
2019-10-09 09:28:41 -07:00
Sidharth Guglani
2ef674edd3 move measure and baseline methods
Summary: Measure and baseline callbacks moved to vanilla JNI

Reviewed By: amir-shalem

Differential Revision: D17714334

fbshipit-source-id: dafbde36984aba948a6345a21d3808a6ef4013e8
2019-10-08 17:51:35 -07:00
Sidharth Guglani
22a60e82b0 move yg node new and ygnode new with config
Summary: YGNode creation methods to vanilla JNI

Reviewed By: amir-shalem

Differential Revision: D17714230

fbshipit-source-id: 74e14e876ab7efc67771d92091c2a78f09072b83
2019-10-08 17:51:34 -07:00
Sidharth Guglani
34739ec652 Move calculate layout method to vanilla JNI
Summary: Using vanilla JNI for calculate layout

Reviewed By: amir-shalem

Differential Revision: D17714219

fbshipit-source-id: bb05de4a0112eefc2b731997a4c1ecef5c0c7361
2019-10-08 17:51:34 -07:00
Sidharth Guglani
b9b0217a07 Add Scoped Local and Global Ref
Summary: Add ScopedLocalRef, ScopedGlobalRef and some common methods to be used later.

Reviewed By: amir-shalem

Differential Revision: D17711284

fbshipit-source-id: be43d5e246bc2406765057783be11854877c41f1
2019-10-08 17:51:33 -07:00
Sidharth Guglani
7c2683fe52 move setStyleInputs to vanilla jni (YogaStyleProperties Part 5)
Summary: Move Yoga style properties to vanilla JNI under a flag.

Reviewed By: amir-shalem

Differential Revision: D17686117

fbshipit-source-id: e79bee1188c24e301b23416486b10f613434eebc
2019-10-08 14:37:27 -07:00
Sidharth Guglani
ee73f556b4 move config jni methods to vanilla jni
Summary: Move yoga node config related jni methods to vanilla jni

Reviewed By: amir-shalem

Differential Revision: D17684821

fbshipit-source-id: 31a667b3ad67501aaef83a132971e4e0826cacd4
2019-10-08 14:37:26 -07:00
Sidharth Guglani
34b68cf1d2 move YGNode related methods to vanilla jni
Summary: This diff moves methods related to actions on YGNode like free node, reset node etc. to vanilla JNI

Reviewed By: amir-shalem

Differential Revision: D17668008

fbshipit-source-id: 03bfc51ec1fcf06569713400f984d551827e22fe
2019-10-08 14:37:26 -07:00
Sidharth Guglani
8975019269 move edge style properties to vanilla jni (YogaStyleProperties Part 4)
Summary: Move Yoga style properties to vanilla JNI under a flag.

Reviewed By: amir-shalem

Differential Revision: D17667201

fbshipit-source-id: 448134d6d7d0dd0c6ff2734b3eb39e65d1cb403f
2019-10-08 14:37:25 -07:00
Sidharth Guglani
6e6b1369ac move percent auto style properties to vanilla jni (YogaStyleProperties Part 3)
Summary: Move Yoga style properties to vanilla JNI under a flag.

Reviewed By: amir-shalem

Differential Revision: D17666674

fbshipit-source-id: 08490bf7c214c856a93214088a27dd4e6df9e0fd
2019-10-08 14:37:25 -07:00
Sidharth Guglani
25b8c94788 move common code to YGJNI.h header class
Summary: Moving common code to YGJNI.h header class so that same can be used in fbjni and vanilla jni implementations

Reviewed By: amir-shalem

Differential Revision: D17666457

fbshipit-source-id: 1e6cd2506fb773b8a17ebef277a2c7ef9728e66b
2019-10-08 14:37:24 -07:00
Sidharth Guglani
3fce27c48c Migrate YGNodeStyleGetFlex method to vanilla jni (YogaStyleProperties Part 2)
Summary: Move Yoga style properties to vanilla JNI under a flag.

Reviewed By: amir-shalem

Differential Revision: D17666090

fbshipit-source-id: 121b939c310799c79f2fce0ea293f88b2940c4fc
2019-10-08 14:37:24 -07:00
Sidharth Guglani
32a973ebd1 Move style properties which accept one parameter to vanilla JNI (YogaStyleProperties Part 1)
Summary: Move Yoga style properties to vanilla JNI under a flag.

Reviewed By: amir-shalem

Differential Revision: D17666048

fbshipit-source-id: 6565acd35ab04ef0c3a2544447a25dc6edc3e7a5
2019-10-08 14:37:24 -07:00
Andres Suarez
c37f5956e4 Fix license headers
Reviewed By: scottrice

Differential Revision: D17673223

fbshipit-source-id: 42a3a25934ef63b24ebf9f5f1909cb562d0d4172
2019-09-30 15:09:48 -07:00
Sidharth Guglani
0875b6b542 Add boolean flag to decide whether to use fbjni or jni
Summary:
Adds a flag useVanillaJNI in YogaConfig to determine whether to use FbJNI or JNI.
Currently default is set to false.

We will experiment based on this flag once all code have been migrated.

Reviewed By: Andrey-Mishanin

Differential Revision: D17601703

fbshipit-source-id: 377a5bd2a6f8a7584e84932e87fa7044d8165efd
2019-09-26 17:34:18 -07:00
Sidharth Guglani
b29e144649 Add separate classes to implement JNI methods suing vanilla JNI
Summary:
This diffs adds a separate file YGJNIVanilla.cpp to add jni methods which uses vanilla JNI instead of FBJNI.
In this diff only one method has been added to setup the experiment boolean setup.

At the end of this diff stack , we will be able to experiment between fbjni and vanilla jni in yoga and finally get rid of fbjni which saves us around 300Kb per architecture in yoga binary size.

Reviewed By: Andrey-Mishanin

Differential Revision: D17601591

fbshipit-source-id: a88520c625bd8b5d9ffcf8ab5f02fc71dc800081
2019-09-26 17:34:17 -07:00
Uts Sikder
f00116c3a6 BREAKING: rm YogaNode parameter from YogaLogger#log
Summary:
In D17439957, I noted that YogaLogger#log throws a NoMethodFoundException when called from C++ b/c C++ and Java's signatures of that method don't match. C++ uses YogaNodeJNIBase for the first param, Java uses YogaNode. Both my attempts to fix this failed.

Attempt #1 - Make Java use YogaNodeJNIBase. This doesn't work because the :java-interface target includes YogaLogger but not YogaNodeJNIBase. Moving YogaLogger to the impl target doesn't work either b/c other files in :java-interface reference YogaLogger.

Attempt #2 - Make C++ use YogaNode. This doesn't work b/c we try to call the log method with objects of fbjni type YogaNodeJNIBase. This would be fine in Java since YogaNodeJNIBase extends YogaNode. But fbjni's typing isn't advanced enough to know this, so the Yoga C++ fails to compile.

At this point, I was wondering what the value of having this param in the log function at all was. None of the implementations in our codebase use it today. It might be easier to just remove it all together. This also removes a bug with YGNodePrint where we pass a null layout context that eventually causes a SIG_ABRT when we use it to try to find a YogaNode to pass to this function. (https://fburl.com/diffusion/ssw9h8lv).

Reviewed By: amir-shalem

Differential Revision: D17470379

fbshipit-source-id: 8fc2d95505971a52af2399a9fbb60b63f27f0ec2
2019-09-25 09:15:45 -07:00
Amir Shalem
f1baf8336b Use direct access to YogaConfig mNativePointer parameter
Summary:
Use direct access to YogaConfig mNativePointer parameter

Results:
```
The following primary metrics showed statistically significant changes at the 95% confidence level:
javaFullLifecycleAllocateCalculateReadLayout	-1.25%
javaLayoutReading	0.44%
javaYogaNodeAllocateAndSetProps	-1.92%
javaYogaNodeAllocation	-2.11%
javaYogaNodeStylePropAssignment	-0.89%
```

Differential Revision: D17519542

fbshipit-source-id: c39bfe1b0ecae9149dc6da2a0a7e936df215ec5b
2019-09-22 13:53:06 -07:00
Uts Sikder
36eae205e1 fix type mismatches in YogaLogger#log function
Summary: This diff fixes two issues with the JNI integration of YogaLogger#log. (1) The YogaLogger class descriptor was missing a semicolon. This causes a ClassNotFoundException whenever you try to call the log method from C++. (2) The C++ signature for the class was using YogaNodeJNIBase as an arg but the Java signature was using YogaNode. This causes a MethodNotFoundException whenever you try to call the method after fixing problem 1.

Reviewed By: astreet

Differential Revision: D17439957

fbshipit-source-id: be3c16512558050265565b3688fb09a7da31b9b2
2019-09-18 21:32:09 -07:00
Amir Shalem
ad5b3410f0 Remove dead code of mYogaNodeCloneFunction
Summary: Code cleanup, remove mYogaNodeCloneFunction completely and its `YogaNodeCloneFunction`

Reviewed By: SidharthGuglani

Differential Revision: D17284191

fbshipit-source-id: 36dae0c0548cfdd3e85182a8e3c6ff9a2d3a5011
2019-09-18 05:52:56 -07:00
Amir Shalem
e2dbff0ca6 Split interface and jni java target
Summary:
Split the yoga buck targets from interface to actual implementation.

This is currently done without moving any files folder, since only we will make the distinction between interface<-->implementation only this buck target (and not in the litho/reactnative yoga copies).

Buck does insures that the `java-interface` is pure since it doesn't depend on any fbjni code.

Reviewed By: SidharthGuglani

Differential Revision: D17266406

fbshipit-source-id: 46aa469b74c2c3114f1d3d762c41d32cfe269f57
2019-09-18 00:40:28 -07:00
Amir Shalem
96eb94afd0 Remove YogaNode.create() from the abstract class
Summary:
Remove YogaNode.create() from the abstract class after we made sure nothing uses it anymore
This is the final stage to make `YogaNode` a pure class without JNI references

Reviewed By: SidharthGuglani

Differential Revision: D17280571

fbshipit-source-id: bd0eb138f7a6a9de8988fc0a7b90badbf635dac5
2019-09-18 00:40:27 -07:00
Amir Shalem
9100019c0a Split YogaConfig into interface and actual implementation
Summary:
Split YogaConfig into the same way YogaNode is split today.

Into an abstract class defining the interface, and actual JNI implementation

Reviewed By: SidharthGuglani

Differential Revision: D17266404

fbshipit-source-id: 3d5d6aa65c55cfa61d47c662d140cdce6dcb0ea1
2019-09-18 00:40:27 -07:00
Sidharth Guglani
21f814b2a6 remove infer-annotations dependency (#922)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/922

We are not using this dependency anywhere in yoga. Removed in this diff.

Reviewed By: passy

Differential Revision: D17131081

fbshipit-source-id: 5544b892f4ef5ca0207d9e21a5b97a2940ac6d53
2019-09-17 12:08:19 -07:00
Amir Shalem
499d28d021 Expose native pointer thru an interface function for YogaConfig
Summary:
Expose native pointer thru an interface function for YogaConfig (its package private to `com.facebook.yoga` namespace),
This way we can make later on YogaConfig a pure abstract class.

Plus, it makes sure external users don't modify the pointer

Reviewed By: SidharthGuglani

Differential Revision: D17266401

fbshipit-source-id: f39b488cea0b73bc3578bb3aa90ab00139bf9271
2019-09-17 07:15:24 -07:00
Amir Shalem
d697bbe0a5 Switch to YogaConfigFactory.create
Summary: Switch to `YogaNodeFactory.create()` instead of using `YogaNode.create()`

Reviewed By: SidharthGuglani

Differential Revision: D17266408

fbshipit-source-id: 69e1e59c7345d16eb174af97c2e231666a02354b
2019-09-17 07:15:23 -07:00
Amir Shalem
67a3841164 Switch to YogaNodeFactory.create
Summary: Switch to `YogaNodeFactory.create()` instead of using `YogaNode.create()`

Reviewed By: SidharthGuglani

Differential Revision: D17258195

fbshipit-source-id: 5f31540724a16e401fcd0fbdf19a4baa354b2d72
2019-09-17 07:15:23 -07:00
Sidharth Guglani
6ac38d188c use implementation instead of compile for yoga dependencies
Summary: Use implementation instead of compile in build.gradle

Reviewed By: passy

Differential Revision: D17343602

fbshipit-source-id: a2ec21a46ebbf3feb5dcc0d9ae2684f8efb096e3
2019-09-16 09:14:28 -07:00
Sidharth Guglani
8216c54b05 update build tools versions
Summary:
Update build tools version to 28.0.3 to fix the below warning

WARNING: The specified Android SDK Build Tools version (26.0.2) is ignored, as it is below the minimum supported version (27.0.3) for Android Gradle Plugin 3.1.0.
Android SDK Build Tools 27.0.3 will be used.

Reviewed By: passy

Differential Revision: D17343575

fbshipit-source-id: aa12bf2b55666aacb18f09b1cca22eab05f38220
2019-09-16 09:14:28 -07:00
Sidharth Guglani
968c075e39 bump version to 1.16.0-SNAPSHOT
Summary: Bump version to 1.16.0-SNAPSHOT for new yoga release

Reviewed By: amir-shalem

Differential Revision: D17396540

fbshipit-source-id: ddd01454752d88548ae7490cfd9fccfb8c591ec9
2019-09-16 08:25:31 -07:00
277 changed files with 5465 additions and 4044 deletions

56
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,56 @@
name: CI
on: [push, pull_request]
jobs:
website:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 8.x
- name: Install dependencies
run: yarn install --frozen-lockfile --ignore-scripts
working-directory: website
- name: Build
run: yarn build
working-directory: website
- name: Deploy
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_branch: gh-pages
publish_dir: website/public
cname: yogalayout.com
keep_files: true
user_name: 'Yoga-bot'
user_email: 'yogabot@fb.com'
android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
if [[ -n "${{ secrets.encrypted_d27e803291ff_iv }}" ]]; then
openssl aes-256-cbc -K ${{ secrets.encrypted_d27e803291ff_key }} -iv {{ secrets.encrypted_d27e803291ff_iv }} -in scripts/setup-keys.enc -d >> gradle.properties;
fi
sudo apt-get update
sudo apt-get install -y ninja-build
pushd $HOME
git clone --depth 1 https://github.com/facebook/buck.git
cd buck
ant
popd
echo "::set-env name=PATH::$PATH:$HOME/buck/bin/"
export PATH=$PATH:$HOME/buck/bin/
buck --version
export TERMINAL=dumb
source scripts/android-setup.sh && installAndroidSDK
echo "::set-env name=ANDROID_SDK::$ANDROID_HOME"
echo "::set-env name=ANDROID_NDK_REPOSITORY::$HOME/android-ndk"
echo "::set-env name=ANDROID_NDK_HOME::$ANDROID_NDK_REPOSITORY/android-ndk-r15c"
- name: Build
run: ./gradlew testDebugUnit && scripts/publish-snapshot.sh

View File

@@ -1 +0,0 @@
4.0

View File

@@ -1,77 +0,0 @@
language: java
os: linux
dist: trusty
addons:
apt:
sources:
- llvm-toolchain-trusty-6.0
- ubuntu-toolchain-r-test
packages:
- clang-6.0
env:
- TARGET: website
- TARGET: android
install:
- cd website
- yarn --ignore-scripts
- cd ..
cache:
directories:
- $HOME/buck
- $HOME/.gradle
before_install:
- |
if [[ -n "$encrypted_d27e803291ff_iv" ]]; then
openssl aes-256-cbc -K $encrypted_d27e803291ff_key -iv $encrypted_d27e803291ff_iv -in scripts/setup-keys.enc -d >> gradle.properties;
fi
# Android
- |
if [[ $TARGET = "android" ]]; then
pushd $HOME
git clone --depth 1 https://github.com/facebook/buck.git
cd buck
ant
popd
export PATH=$PATH:$HOME/buck/bin/
buck --version
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
# Website
- |
if [[ $TARGET = "website" ]]; then
nvm install 8
nvm use 8
fi
script:
- |
if [[ $TARGET = "android" ]]; then
./gradlew testDebugUnit && scripts/publish-snapshot.sh
fi
- |
if [[ $TARGET = "website" ]]; then
pushd website
yarn build
popd
fi
deploy:
provider: pages
skip-cleanup: true
github-token: $GITHUB_TOKEN
fqdn: yogalayout.com
local-dir: website/public
email: yogabot@fb.com
name: Yoga-bot
keep-history: true
on:
branch: master
condition: $TARGET = website

31
BUCK
View File

@@ -2,7 +2,7 @@
# #
# This source code is licensed under the MIT license found in the # This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree. # LICENSE file in the root directory of this source tree.
load("//tools/build_defs/oss:yoga_defs.bzl", "BASE_COMPILER_FLAGS", "GTEST_TARGET", "LIBRARY_COMPILER_FLAGS", "subdir_glob", "yoga_cxx_library", "yoga_cxx_test", "yoga_dep") load("//tools/build_defs/oss:yoga_defs.bzl", "BASE_COMPILER_FLAGS", "GTEST_TARGET", "LIBRARY_COMPILER_FLAGS", "YOGA_ROOTS", "subdir_glob", "yoga_cxx_library", "yoga_cxx_test", "yoga_dep", "yoga_prebuilt_cxx_library")
GMOCK_OVERRIDE_FLAGS = [ GMOCK_OVERRIDE_FLAGS = [
# gmock does not mark mocked methods as override, ignore the warnings in tests # gmock does not mark mocked methods as override, ignore the warnings in tests
@@ -14,6 +14,18 @@ TEST_COMPILER_FLAGS = BASE_COMPILER_FLAGS + GMOCK_OVERRIDE_FLAGS + [
"-DYG_ENABLE_EVENTS", "-DYG_ENABLE_EVENTS",
] ]
yoga_prebuilt_cxx_library(
name = "ndklog",
exported_platform_linker_flags = [
(
"^android.*",
["-llog"],
),
],
header_only = True,
visibility = YOGA_ROOTS,
)
yoga_cxx_library( yoga_cxx_library(
name = "yoga", name = "yoga",
srcs = glob(["yoga/**/*.cpp"]), srcs = glob(["yoga/**/*.cpp"]),
@@ -24,7 +36,21 @@ yoga_cxx_library(
tests = [":YogaTests"], tests = [":YogaTests"],
visibility = ["PUBLIC"], visibility = ["PUBLIC"],
deps = [ deps = [
yoga_dep("lib/fb:ndklog"), ":ndklog",
],
)
yoga_cxx_library(
name = "yoga-static",
srcs = glob(["yoga/**/*.cpp"]),
compiler_flags = LIBRARY_COMPILER_FLAGS,
preferred_linkage = "static",
public_include_directories = ["."],
raw_headers = glob(["yoga/**/*.h"]),
tests = [":YogaTests"],
visibility = ["PUBLIC"],
deps = [
":ndklog",
], ],
) )
@@ -39,7 +65,6 @@ yoga_cxx_library(
visibility = ["PUBLIC"], visibility = ["PUBLIC"],
deps = [ deps = [
":yoga", ":yoga",
yoga_dep("lib/fb:ndklog"),
], ],
) )

View File

@@ -1,14 +1,21 @@
#
# Copyright (c) Facebook, Inc. and its affiliates. # Copyright (c) Facebook, Inc. and its affiliates.
# #
# This source code is licensed under the MIT license found in the # This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree. # LICENSE file in the root directory of this source tree.
#
cmake_minimum_required(VERSION 3.4.1) cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_VERBOSE_MAKEFILE on) set(CMAKE_VERBOSE_MAKEFILE on)
add_compile_options(
-fno-omit-frame-pointer
-fexceptions
-fvisibility=hidden
-ffunction-sections
-fdata-sections
-Wall
-std=c++11)
file(GLOB_RECURSE yogacore_SRC yoga/*.cpp) file(GLOB_RECURSE yogacore_SRC yoga/*.cpp)
add_library(yogacore STATIC ${yogacore_SRC}) add_library(yogacore STATIC ${yogacore_SRC})

View File

@@ -1,9 +1,8 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# #
# Copyright (c) Facebook, Inc. and its affiliates. # This source code is licensed under the MIT license found in the
# # LICENSE file in the root directory of this source tree.
# This source code is licensed under the MIT license found in the LICENSE
# file in the root directory of this source tree.
#
Pod::Spec.new do |spec| Pod::Spec.new do |spec|
spec.name = 'Yoga' spec.name = 'Yoga'
spec.version = '1.14.0' spec.version = '1.14.0'
@@ -34,6 +33,6 @@ Pod::Spec.new do |spec|
'-fPIC' '-fPIC'
] ]
spec.source_files = 'yoga/**/*.{c,h,cpp}' spec.source_files = 'yoga/**/*.{c,h,cpp}'
spec.public_header_files = 'yoga/{Yoga,YGEnums,YGMacros,YGValue}.h' spec.public_header_files = 'yoga/{Yoga,YGEnums,YGMacros,YGNode,YGStyle,YGValue}.h'
end end

View File

@@ -1,12 +1,11 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# #
# Copyright (c) Facebook, Inc. and its affiliates. # This source code is licensed under the MIT license found in the
# # LICENSE file in the root directory of this source tree.
# This source code is licensed under the MIT license found in the LICENSE
# file in the root directory of this source tree.
#
podspec = Pod::Spec.new do |spec| podspec = Pod::Spec.new do |spec|
spec.name = 'YogaKit' spec.name = 'YogaKit'
spec.version = '1.14.0' spec.version = '1.18.1'
spec.license = { :type => 'MIT', :file => "LICENSE" } spec.license = { :type => 'MIT', :file => "LICENSE" }
spec.homepage = 'https://facebook.github.io/yoga/' spec.homepage = 'https://facebook.github.io/yoga/'
spec.documentation_url = 'https://facebook.github.io/yoga/docs/' spec.documentation_url = 'https://facebook.github.io/yoga/docs/'
@@ -17,17 +16,22 @@ podspec = Pod::Spec.new do |spec|
spec.authors = 'Facebook' spec.authors = 'Facebook'
spec.source = { spec.source = {
:git => 'https://github.com/facebook/yoga.git', :git => 'https://github.com/facebook/yoga.git',
:tag => spec.version.to_s, :tag => "1.18.0",
} }
spec.platform = :ios spec.platform = :ios
spec.ios.deployment_target = '8.0' spec.ios.deployment_target = '8.0'
spec.ios.frameworks = 'UIKit' spec.ios.frameworks = 'UIKit'
spec.module_name = 'YogaKit'
spec.dependency 'Yoga', '~> 1.14' spec.dependency 'Yoga', '~> 1.14'
# Fixes the bug related the xcode 11 not able to find swift related frameworks.
# https://github.com/Carthage/Carthage/issues/2825
# https://twitter.com/krzyzanowskim/status/1151549874653081601?s=21
spec.pod_target_xcconfig = {"LD_VERIFY_BITCODE": "NO"}
spec.source_files = 'YogaKit/Source/*.{h,m,swift}' spec.source_files = 'YogaKit/Source/*.{h,m,swift}'
spec.public_header_files = 'YogaKit/Source/{YGLayout,UIView+Yoga}.h' spec.public_header_files = 'YogaKit/Source/{YGLayout,UIView+Yoga}.h'
spec.private_header_files = 'YogaKit/Source/YGLayout+Private.h' spec.private_header_files = 'YogaKit/Source/YGLayout+Private.h'
spec.swift_version = '4.0' spec.swift_version = '5.1'
end end
# See https://github.com/facebook/yoga/pull/366 # See https://github.com/facebook/yoga/pull/366

View File

@@ -37,11 +37,14 @@ yoga_apple_library(
), ),
compiler_flags = COMPILER_FLAGS, compiler_flags = COMPILER_FLAGS,
frameworks = [ frameworks = [
"$SDKROOT/System/Library/Frameworks/CoreGraphics.framework",
"$SDKROOT/System/Library/Frameworks/Foundation.framework", "$SDKROOT/System/Library/Frameworks/Foundation.framework",
"$SDKROOT/System/Library/Frameworks/UIKit.framework", "$SDKROOT/System/Library/Frameworks/UIKit.framework",
], ],
header_path_prefix = "", header_path_prefix = "",
link_whole = True, link_whole = True,
modular = True,
module_name = "YogaKit",
visibility = ["PUBLIC"], visibility = ["PUBLIC"],
deps = [ deps = [
yoga_dep(":yoga"), yoga_dep(":yoga"),

View File

@@ -1,31 +1,33 @@
/* /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#import "YGLayout.h"
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "YGLayout.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
typedef void (^YGLayoutConfigurationBlock)(YGLayout *layout); typedef void (^YGLayoutConfigurationBlock)(YGLayout* layout);
@interface UIView (Yoga) @interface UIView (Yoga)
/** /**
The YGLayout that is attached to this view. It is lazily created. The YGLayout that is attached to this view. It is lazily created.
*/ */
@property (nonatomic, readonly, strong) YGLayout *yoga; @property(nonatomic, readonly, strong) YGLayout* yoga;
/** /**
Indicates whether or not Yoga is enabled Indicates whether or not Yoga is enabled
*/ */
@property (nonatomic, readonly, assign) BOOL isYogaEnabled; @property(nonatomic, readonly, assign) BOOL isYogaEnabled;
/** /**
In ObjC land, every time you access `view.yoga.*` you are adding another `objc_msgSend` In ObjC land, every time you access `view.yoga.*` you are adding another
to your code. If you plan on making multiple changes to YGLayout, it's more performant `objc_msgSend` to your code. If you plan on making multiple changes to
to use this method, which uses a single objc_msgSend call. YGLayout, it's more performant to use this method, which uses a single
objc_msgSend call.
*/ */
- (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block - (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block
NS_SWIFT_NAME(configureLayout(block:)); NS_SWIFT_NAME(configureLayout(block:));

View File

@@ -1,36 +1,34 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#import <objc/runtime.h>
#import "UIView+Yoga.h" #import "UIView+Yoga.h"
#import "YGLayout+Private.h" #import "YGLayout+Private.h"
#import <objc/runtime.h>
static const void *kYGYogaAssociatedKey = &kYGYogaAssociatedKey; static const void* kYGYogaAssociatedKey = &kYGYogaAssociatedKey;
@implementation UIView (YogaKit) @implementation UIView (YogaKit)
- (YGLayout *)yoga - (YGLayout*)yoga {
{ YGLayout* yoga = objc_getAssociatedObject(self, kYGYogaAssociatedKey);
YGLayout *yoga = objc_getAssociatedObject(self, kYGYogaAssociatedKey);
if (!yoga) { if (!yoga) {
yoga = [[YGLayout alloc] initWithView:self]; yoga = [[YGLayout alloc] initWithView:self];
objc_setAssociatedObject(self, kYGYogaAssociatedKey, yoga, OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(
self, kYGYogaAssociatedKey, yoga, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
} }
return yoga; return yoga;
} }
- (BOOL)isYogaEnabled - (BOOL)isYogaEnabled {
{
return objc_getAssociatedObject(self, kYGYogaAssociatedKey) != nil; return objc_getAssociatedObject(self, kYGYogaAssociatedKey) != nil;
} }
- (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block - (void)configureLayoutWithBlock:(YGLayoutConfigurationBlock)block {
{
if (block != nil) { if (block != nil) {
block(self.yoga); block(self.yoga);
} }

View File

@@ -1,16 +1,17 @@
/* /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#import "YGLayout.h"
#import <yoga/Yoga.h> #import <yoga/Yoga.h>
#import "YGLayout.h"
@interface YGLayout () @interface YGLayout ()
@property (nonatomic, assign, readonly) YGNodeRef node; @property(nonatomic, assign, readonly) YGNodeRef node;
- (instancetype)initWithView:(UIView *)view; - (instancetype)initWithView:(UIView*)view;
@end @end

View File

@@ -1,20 +1,21 @@
/* /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import <yoga/YGEnums.h> #import <yoga/YGEnums.h>
#import <yoga/Yoga.h>
#import <yoga/YGMacros.h> #import <yoga/YGMacros.h>
#import <yoga/Yoga.h>
YG_EXTERN_C_BEGIN YG_EXTERN_C_BEGIN
extern YGValue YGPointValue(CGFloat value) extern YGValue YGPointValue(CGFloat value) NS_SWIFT_UNAVAILABLE(
NS_SWIFT_UNAVAILABLE("Use the swift Int and FloatingPoint extensions instead"); "Use the swift Int and FloatingPoint extensions instead");
extern YGValue YGPercentValue(CGFloat value) extern YGValue YGPercentValue(CGFloat value) NS_SWIFT_UNAVAILABLE(
NS_SWIFT_UNAVAILABLE("Use the swift Int and FloatingPoint extensions instead"); "Use the swift Int and FloatingPoint extensions instead");
YG_EXTERN_C_END YG_EXTERN_C_END
@@ -43,103 +44,107 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
The property that decides if we should include this view when calculating The property that decides if we should include this view when calculating
layout. Defaults to YES. layout. Defaults to YES.
*/ */
@property (nonatomic, readwrite, assign, setter=setIncludedInLayout:) BOOL isIncludedInLayout; @property(nonatomic, readwrite, assign, setter=setIncludedInLayout:)
BOOL isIncludedInLayout;
/** /**
The property that decides during layout/sizing whether or not styling properties should be applied. The property that decides during layout/sizing whether or not styling
Defaults to NO. properties should be applied. Defaults to NO.
*/ */
@property (nonatomic, readwrite, assign, setter=setEnabled:) BOOL isEnabled; @property(nonatomic, readwrite, assign, setter=setEnabled:) BOOL isEnabled;
@property (nonatomic, readwrite, assign) YGDirection direction; @property(nonatomic, readwrite, assign) YGDirection direction;
@property (nonatomic, readwrite, assign) YGFlexDirection flexDirection; @property(nonatomic, readwrite, assign) YGFlexDirection flexDirection;
@property (nonatomic, readwrite, assign) YGJustify justifyContent; @property(nonatomic, readwrite, assign) YGJustify justifyContent;
@property (nonatomic, readwrite, assign) YGAlign alignContent; @property(nonatomic, readwrite, assign) YGAlign alignContent;
@property (nonatomic, readwrite, assign) YGAlign alignItems; @property(nonatomic, readwrite, assign) YGAlign alignItems;
@property (nonatomic, readwrite, assign) YGAlign alignSelf; @property(nonatomic, readwrite, assign) YGAlign alignSelf;
@property (nonatomic, readwrite, assign) YGPositionType position; @property(nonatomic, readwrite, assign) YGPositionType position;
@property (nonatomic, readwrite, assign) YGWrap flexWrap; @property(nonatomic, readwrite, assign) YGWrap flexWrap;
@property (nonatomic, readwrite, assign) YGOverflow overflow; @property(nonatomic, readwrite, assign) YGOverflow overflow;
@property (nonatomic, readwrite, assign) YGDisplay display; @property(nonatomic, readwrite, assign) YGDisplay display;
@property (nonatomic, readwrite, assign) CGFloat flex; @property(nonatomic, readwrite, assign) CGFloat flex;
@property (nonatomic, readwrite, assign) CGFloat flexGrow; @property(nonatomic, readwrite, assign) CGFloat flexGrow;
@property (nonatomic, readwrite, assign) CGFloat flexShrink; @property(nonatomic, readwrite, assign) CGFloat flexShrink;
@property (nonatomic, readwrite, assign) YGValue flexBasis; @property(nonatomic, readwrite, assign) YGValue flexBasis;
@property (nonatomic, readwrite, assign) YGValue left; @property(nonatomic, readwrite, assign) YGValue left;
@property (nonatomic, readwrite, assign) YGValue top; @property(nonatomic, readwrite, assign) YGValue top;
@property (nonatomic, readwrite, assign) YGValue right; @property(nonatomic, readwrite, assign) YGValue right;
@property (nonatomic, readwrite, assign) YGValue bottom; @property(nonatomic, readwrite, assign) YGValue bottom;
@property (nonatomic, readwrite, assign) YGValue start; @property(nonatomic, readwrite, assign) YGValue start;
@property (nonatomic, readwrite, assign) YGValue end; @property(nonatomic, readwrite, assign) YGValue end;
@property (nonatomic, readwrite, assign) YGValue marginLeft; @property(nonatomic, readwrite, assign) YGValue marginLeft;
@property (nonatomic, readwrite, assign) YGValue marginTop; @property(nonatomic, readwrite, assign) YGValue marginTop;
@property (nonatomic, readwrite, assign) YGValue marginRight; @property(nonatomic, readwrite, assign) YGValue marginRight;
@property (nonatomic, readwrite, assign) YGValue marginBottom; @property(nonatomic, readwrite, assign) YGValue marginBottom;
@property (nonatomic, readwrite, assign) YGValue marginStart; @property(nonatomic, readwrite, assign) YGValue marginStart;
@property (nonatomic, readwrite, assign) YGValue marginEnd; @property(nonatomic, readwrite, assign) YGValue marginEnd;
@property (nonatomic, readwrite, assign) YGValue marginHorizontal; @property(nonatomic, readwrite, assign) YGValue marginHorizontal;
@property (nonatomic, readwrite, assign) YGValue marginVertical; @property(nonatomic, readwrite, assign) YGValue marginVertical;
@property (nonatomic, readwrite, assign) YGValue margin; @property(nonatomic, readwrite, assign) YGValue margin;
@property (nonatomic, readwrite, assign) YGValue paddingLeft; @property(nonatomic, readwrite, assign) YGValue paddingLeft;
@property (nonatomic, readwrite, assign) YGValue paddingTop; @property(nonatomic, readwrite, assign) YGValue paddingTop;
@property (nonatomic, readwrite, assign) YGValue paddingRight; @property(nonatomic, readwrite, assign) YGValue paddingRight;
@property (nonatomic, readwrite, assign) YGValue paddingBottom; @property(nonatomic, readwrite, assign) YGValue paddingBottom;
@property (nonatomic, readwrite, assign) YGValue paddingStart; @property(nonatomic, readwrite, assign) YGValue paddingStart;
@property (nonatomic, readwrite, assign) YGValue paddingEnd; @property(nonatomic, readwrite, assign) YGValue paddingEnd;
@property (nonatomic, readwrite, assign) YGValue paddingHorizontal; @property(nonatomic, readwrite, assign) YGValue paddingHorizontal;
@property (nonatomic, readwrite, assign) YGValue paddingVertical; @property(nonatomic, readwrite, assign) YGValue paddingVertical;
@property (nonatomic, readwrite, assign) YGValue padding; @property(nonatomic, readwrite, assign) YGValue padding;
@property (nonatomic, readwrite, assign) CGFloat borderLeftWidth; @property(nonatomic, readwrite, assign) CGFloat borderLeftWidth;
@property (nonatomic, readwrite, assign) CGFloat borderTopWidth; @property(nonatomic, readwrite, assign) CGFloat borderTopWidth;
@property (nonatomic, readwrite, assign) CGFloat borderRightWidth; @property(nonatomic, readwrite, assign) CGFloat borderRightWidth;
@property (nonatomic, readwrite, assign) CGFloat borderBottomWidth; @property(nonatomic, readwrite, assign) CGFloat borderBottomWidth;
@property (nonatomic, readwrite, assign) CGFloat borderStartWidth; @property(nonatomic, readwrite, assign) CGFloat borderStartWidth;
@property (nonatomic, readwrite, assign) CGFloat borderEndWidth; @property(nonatomic, readwrite, assign) CGFloat borderEndWidth;
@property (nonatomic, readwrite, assign) CGFloat borderWidth; @property(nonatomic, readwrite, assign) CGFloat borderWidth;
@property (nonatomic, readwrite, assign) YGValue width; @property(nonatomic, readwrite, assign) YGValue width;
@property (nonatomic, readwrite, assign) YGValue height; @property(nonatomic, readwrite, assign) YGValue height;
@property (nonatomic, readwrite, assign) YGValue minWidth; @property(nonatomic, readwrite, assign) YGValue minWidth;
@property (nonatomic, readwrite, assign) YGValue minHeight; @property(nonatomic, readwrite, assign) YGValue minHeight;
@property (nonatomic, readwrite, assign) YGValue maxWidth; @property(nonatomic, readwrite, assign) YGValue maxWidth;
@property (nonatomic, readwrite, assign) YGValue maxHeight; @property(nonatomic, readwrite, assign) YGValue maxHeight;
// Yoga specific properties, not compatible with flexbox specification // Yoga specific properties, not compatible with flexbox specification
@property (nonatomic, readwrite, assign) CGFloat aspectRatio; @property(nonatomic, readwrite, assign) CGFloat aspectRatio;
/** /**
Get the resolved direction of this node. This won't be YGDirectionInherit Get the resolved direction of this node. This won't be YGDirectionInherit
*/ */
@property (nonatomic, readonly, assign) YGDirection resolvedDirection; @property(nonatomic, readonly, assign) YGDirection resolvedDirection;
/** /**
Perform a layout calculation and update the frames of the views in the hierarchy with the results. Perform a layout calculation and update the frames of the views in the
If the origin is not preserved, the root view's layout results will applied from {0,0}. hierarchy with the results. If the origin is not preserved, the root view's
layout results will applied from {0,0}.
*/ */
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin - (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin
NS_SWIFT_NAME(applyLayout(preservingOrigin:)); NS_SWIFT_NAME(applyLayout(preservingOrigin:));
/** /**
Perform a layout calculation and update the frames of the views in the hierarchy with the results. Perform a layout calculation and update the frames of the views in the
If the origin is not preserved, the root view's layout results will applied from {0,0}. hierarchy with the results. If the origin is not preserved, the root view's
layout results will applied from {0,0}.
*/ */
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin - (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin
dimensionFlexibility:(YGDimensionFlexibility)dimensionFlexibility dimensionFlexibility:(YGDimensionFlexibility)dimensionFlexibility
NS_SWIFT_NAME(applyLayout(preservingOrigin:dimensionFlexibility:)); NS_SWIFT_NAME(applyLayout(preservingOrigin:dimensionFlexibility:));
/** /**
Returns the size of the view if no constraints were given. This could equivalent to calling [self Returns the size of the view if no constraints were given. This could
sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; equivalent to calling [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];
*/ */
@property (nonatomic, readonly, assign) CGSize intrinsicSize; @property(nonatomic, readonly, assign) CGSize intrinsicSize;
/** /**
Returns the size of the view based on provided constraints. Pass NaN for an unconstrained dimension. Returns the size of the view based on provided constraints. Pass NaN for an
unconstrained dimension.
*/ */
- (CGSize)calculateLayoutWithSize:(CGSize)size - (CGSize)calculateLayoutWithSize:(CGSize)size
NS_SWIFT_NAME(calculateLayout(with:)); NS_SWIFT_NAME(calculateLayout(with:));
@@ -147,19 +152,19 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
/** /**
Returns the number of children that are using Flexbox. Returns the number of children that are using Flexbox.
*/ */
@property (nonatomic, readonly, assign) NSUInteger numberOfChildren; @property(nonatomic, readonly, assign) NSUInteger numberOfChildren;
/** /**
Return a BOOL indiciating whether or not we this node contains any subviews that are included in Return a BOOL indiciating whether or not we this node contains any subviews
Yoga's layout. that are included in Yoga's layout.
*/ */
@property (nonatomic, readonly, assign) BOOL isLeaf; @property(nonatomic, readonly, assign) BOOL isLeaf;
/** /**
Return's a BOOL indicating if a view is dirty. When a node is dirty Return's a BOOL indicating if a view is dirty. When a node is dirty
it usually indicates that it will be remeasured on the next layout pass. it usually indicates that it will be remeasured on the next layout pass.
*/ */
@property (nonatomic, readonly, assign) BOOL isDirty; @property(nonatomic, readonly, assign) BOOL isDirty;
/** /**
Mark that a view's layout needs to be recalculated. Only works for leaf views. Mark that a view's layout needs to be recalculated. Only works for leaf views.

View File

@@ -1,157 +1,188 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#import "YGLayout+Private.h"
#import "UIView+Yoga.h" #import "UIView+Yoga.h"
#import "YGLayout+Private.h"
#define YG_PROPERTY(type, lowercased_name, capitalized_name) \ #define YG_PROPERTY(type, lowercased_name, capitalized_name) \
- (type)lowercased_name \ -(type)lowercased_name { \
{ \ return YGNodeStyleGet##capitalized_name(self.node); \
return YGNodeStyleGet##capitalized_name(self.node); \ } \
} \ \
\ -(void)set##capitalized_name : (type)lowercased_name { \
- (void)set##capitalized_name:(type)lowercased_name \ YGNodeStyleSet##capitalized_name(self.node, lowercased_name); \
{ \ }
YGNodeStyleSet##capitalized_name(self.node, lowercased_name); \
#define YG_VALUE_PROPERTY(lowercased_name, capitalized_name) \
-(YGValue)lowercased_name { \
return YGNodeStyleGet##capitalized_name(self.node); \
} \
\
-(void)set##capitalized_name : (YGValue)lowercased_name { \
switch (lowercased_name.unit) { \
case YGUnitUndefined: \
YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \
break; \
case YGUnitPoint: \
YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \
break; \
case YGUnitPercent: \
YGNodeStyleSet##capitalized_name##Percent( \
self.node, lowercased_name.value); \
break; \
default: \
NSAssert(NO, @"Not implemented"); \
} \
}
#define YG_AUTO_VALUE_PROPERTY(lowercased_name, capitalized_name) \
-(YGValue)lowercased_name { \
return YGNodeStyleGet##capitalized_name(self.node); \
} \
\
-(void)set##capitalized_name : (YGValue)lowercased_name { \
switch (lowercased_name.unit) { \
case YGUnitPoint: \
YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \
break; \
case YGUnitPercent: \
YGNodeStyleSet##capitalized_name##Percent( \
self.node, lowercased_name.value); \
break; \
case YGUnitAuto: \
YGNodeStyleSet##capitalized_name##Auto(self.node); \
break; \
default: \
NSAssert(NO, @"Not implemented"); \
} \
}
#define YG_EDGE_PROPERTY_GETTER( \
type, lowercased_name, capitalized_name, property, edge) \
-(type)lowercased_name { \
return YGNodeStyleGet##property(self.node, edge); \
}
#define YG_EDGE_PROPERTY_SETTER( \
lowercased_name, capitalized_name, property, edge) \
-(void)set##capitalized_name : (CGFloat)lowercased_name { \
YGNodeStyleSet##property(self.node, edge, lowercased_name); \
}
#define YG_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_GETTER( \
CGFloat, lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
#define YG_VALUE_EDGE_PROPERTY_SETTER( \
objc_lowercased_name, objc_capitalized_name, c_name, edge) \
-(void)set##objc_capitalized_name : (YGValue)objc_lowercased_name { \
switch (objc_lowercased_name.unit) { \
case YGUnitUndefined: \
YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name.value); \
break; \
case YGUnitPoint: \
YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name.value); \
break; \
case YGUnitPercent: \
YGNodeStyleSet##c_name##Percent( \
self.node, edge, objc_lowercased_name.value); \
break; \
default: \
NSAssert(NO, @"Not implemented"); \
} \
}
#define YG_VALUE_EDGE_PROPERTY( \
lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_GETTER( \
YGValue, lowercased_name, capitalized_name, property, edge) \
YG_VALUE_EDGE_PROPERTY_SETTER( \
lowercased_name, capitalized_name, property, edge)
#define YG_VALUE_EDGES_PROPERTIES(lowercased_name, capitalized_name) \
YG_VALUE_EDGE_PROPERTY( \
lowercased_name##Left, \
capitalized_name##Left, \
capitalized_name, \
YGEdgeLeft) \
YG_VALUE_EDGE_PROPERTY( \
lowercased_name##Top, \
capitalized_name##Top, \
capitalized_name, \
YGEdgeTop) \
YG_VALUE_EDGE_PROPERTY( \
lowercased_name##Right, \
capitalized_name##Right, \
capitalized_name, \
YGEdgeRight) \
YG_VALUE_EDGE_PROPERTY( \
lowercased_name##Bottom, \
capitalized_name##Bottom, \
capitalized_name, \
YGEdgeBottom) \
YG_VALUE_EDGE_PROPERTY( \
lowercased_name##Start, \
capitalized_name##Start, \
capitalized_name, \
YGEdgeStart) \
YG_VALUE_EDGE_PROPERTY( \
lowercased_name##End, \
capitalized_name##End, \
capitalized_name, \
YGEdgeEnd) \
YG_VALUE_EDGE_PROPERTY( \
lowercased_name##Horizontal, \
capitalized_name##Horizontal, \
capitalized_name, \
YGEdgeHorizontal) \
YG_VALUE_EDGE_PROPERTY( \
lowercased_name##Vertical, \
capitalized_name##Vertical, \
capitalized_name, \
YGEdgeVertical) \
YG_VALUE_EDGE_PROPERTY( \
lowercased_name, capitalized_name, capitalized_name, YGEdgeAll)
YGValue YGPointValue(CGFloat value) {
return (YGValue){.value = value, .unit = YGUnitPoint};
} }
#define YG_VALUE_PROPERTY(lowercased_name, capitalized_name) \ YGValue YGPercentValue(CGFloat value) {
- (YGValue)lowercased_name \ return (YGValue){.value = value, .unit = YGUnitPercent};
{ \
return YGNodeStyleGet##capitalized_name(self.node); \
} \
\
- (void)set##capitalized_name:(YGValue)lowercased_name \
{ \
switch (lowercased_name.unit) { \
case YGUnitUndefined: \
YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \
break; \
case YGUnitPoint: \
YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \
break; \
case YGUnitPercent: \
YGNodeStyleSet##capitalized_name##Percent(self.node, lowercased_name.value); \
break; \
default: \
NSAssert(NO, @"Not implemented"); \
} \
}
#define YG_AUTO_VALUE_PROPERTY(lowercased_name, capitalized_name) \
- (YGValue)lowercased_name \
{ \
return YGNodeStyleGet##capitalized_name(self.node); \
} \
\
- (void)set##capitalized_name:(YGValue)lowercased_name \
{ \
switch (lowercased_name.unit) { \
case YGUnitPoint: \
YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \
break; \
case YGUnitPercent: \
YGNodeStyleSet##capitalized_name##Percent(self.node, lowercased_name.value); \
break; \
case YGUnitAuto: \
YGNodeStyleSet##capitalized_name##Auto(self.node); \
break; \
default: \
NSAssert(NO, @"Not implemented"); \
} \
}
#define YG_EDGE_PROPERTY_GETTER(type, lowercased_name, capitalized_name, property, edge) \
- (type)lowercased_name \
{ \
return YGNodeStyleGet##property(self.node, edge); \
}
#define YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge) \
- (void)set##capitalized_name:(CGFloat)lowercased_name \
{ \
YGNodeStyleSet##property(self.node, edge, lowercased_name); \
}
#define YG_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_GETTER(CGFloat, lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
#define YG_VALUE_EDGE_PROPERTY_SETTER(objc_lowercased_name, objc_capitalized_name, c_name, edge) \
- (void)set##objc_capitalized_name:(YGValue)objc_lowercased_name \
{ \
switch (objc_lowercased_name.unit) { \
case YGUnitUndefined: \
YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name.value); \
break; \
case YGUnitPoint: \
YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name.value); \
break; \
case YGUnitPercent: \
YGNodeStyleSet##c_name##Percent(self.node, edge, objc_lowercased_name.value); \
break; \
default: \
NSAssert(NO, @"Not implemented"); \
} \
}
#define YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
YG_EDGE_PROPERTY_GETTER(YGValue, lowercased_name, capitalized_name, property, edge) \
YG_VALUE_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
#define YG_VALUE_EDGES_PROPERTIES(lowercased_name, capitalized_name) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Left, capitalized_name##Left, capitalized_name, YGEdgeLeft) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Top, capitalized_name##Top, capitalized_name, YGEdgeTop) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Right, capitalized_name##Right, capitalized_name, YGEdgeRight) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Bottom, capitalized_name##Bottom, capitalized_name, YGEdgeBottom) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Start, capitalized_name##Start, capitalized_name, YGEdgeStart) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##End, capitalized_name##End, capitalized_name, YGEdgeEnd) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Horizontal, capitalized_name##Horizontal, capitalized_name, YGEdgeHorizontal) \
YG_VALUE_EDGE_PROPERTY(lowercased_name##Vertical, capitalized_name##Vertical, capitalized_name, YGEdgeVertical) \
YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, capitalized_name, YGEdgeAll)
YGValue YGPointValue(CGFloat value)
{
return (YGValue) { .value = value, .unit = YGUnitPoint };
}
YGValue YGPercentValue(CGFloat value)
{
return (YGValue) { .value = value, .unit = YGUnitPercent };
} }
static YGConfigRef globalConfig; static YGConfigRef globalConfig;
@interface YGLayout () @interface YGLayout ()
@property (nonatomic, weak, readonly) UIView *view; @property(nonatomic, weak, readonly) UIView* view;
@property(nonatomic, assign, readonly) BOOL isUIView; @property(nonatomic, assign, readonly) BOOL isUIView;
@end @end
@implementation YGLayout @implementation YGLayout
@synthesize isEnabled=_isEnabled; @synthesize isEnabled = _isEnabled;
@synthesize isIncludedInLayout=_isIncludedInLayout; @synthesize isIncludedInLayout = _isIncludedInLayout;
@synthesize node=_node; @synthesize node = _node;
+ (void)initialize + (void)initialize {
{
globalConfig = YGConfigNew(); globalConfig = YGConfigNew();
YGConfigSetExperimentalFeatureEnabled(globalConfig, YGExperimentalFeatureWebFlexBasis, true); YGConfigSetExperimentalFeatureEnabled(
globalConfig, YGExperimentalFeatureWebFlexBasis, true);
YGConfigSetPointScaleFactor(globalConfig, [UIScreen mainScreen].scale); YGConfigSetPointScaleFactor(globalConfig, [UIScreen mainScreen].scale);
} }
- (instancetype)initWithView:(UIView*)view - (instancetype)initWithView:(UIView*)view {
{
if (self = [super init]) { if (self = [super init]) {
_view = view; _view = view;
_node = YGNodeNewWithConfig(globalConfig); _node = YGNodeNewWithConfig(globalConfig);
YGNodeSetContext(_node, (__bridge void *) view); YGNodeSetContext(_node, (__bridge void*)view);
_isEnabled = NO; _isEnabled = NO;
_isIncludedInLayout = YES; _isIncludedInLayout = YES;
_isUIView = [view isMemberOfClass:[UIView class]]; _isUIView = [view isMemberOfClass:[UIView class]];
@@ -160,18 +191,15 @@ static YGConfigRef globalConfig;
return self; return self;
} }
- (void)dealloc - (void)dealloc {
{
YGNodeFree(self.node); YGNodeFree(self.node);
} }
- (BOOL)isDirty - (BOOL)isDirty {
{
return YGNodeIsDirty(self.node); return YGNodeIsDirty(self.node);
} }
- (void)markDirty - (void)markDirty {
{
if (self.isDirty || !self.isLeaf) { if (self.isDirty || !self.isLeaf) {
return; return;
} }
@@ -187,17 +215,17 @@ static YGConfigRef globalConfig;
YGNodeMarkDirty(node); YGNodeMarkDirty(node);
} }
- (NSUInteger)numberOfChildren - (NSUInteger)numberOfChildren {
{
return YGNodeGetChildCount(self.node); return YGNodeGetChildCount(self.node);
} }
- (BOOL)isLeaf - (BOOL)isLeaf {
{ NSAssert(
NSAssert([NSThread isMainThread], @"This method must be called on the main thread."); [NSThread isMainThread],
@"This method must be called on the main thread.");
if (self.isEnabled) { if (self.isEnabled) {
for (UIView *subview in self.view.subviews) { for (UIView* subview in self.view.subviews) {
YGLayout *const yoga = subview.yoga; YGLayout* const yoga = subview.yoga;
if (yoga.isEnabled && yoga.isIncludedInLayout) { if (yoga.isEnabled && yoga.isIncludedInLayout) {
return NO; return NO;
} }
@@ -209,13 +237,11 @@ static YGConfigRef globalConfig;
#pragma mark - Style #pragma mark - Style
- (YGPositionType)position - (YGPositionType)position {
{
return YGNodeStyleGetPositionType(self.node); return YGNodeStyleGetPositionType(self.node);
} }
- (void)setPosition:(YGPositionType)position - (void)setPosition:(YGPositionType)position {
{
YGNodeStyleSetPositionType(self.node, position); YGNodeStyleSetPositionType(self.node, position);
} }
@@ -261,25 +287,23 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio)
#pragma mark - Layout and Sizing #pragma mark - Layout and Sizing
- (YGDirection)resolvedDirection - (YGDirection)resolvedDirection {
{
return YGNodeLayoutGetDirection(self.node); return YGNodeLayoutGetDirection(self.node);
} }
- (void)applyLayout - (void)applyLayout {
{
[self calculateLayoutWithSize:self.view.bounds.size]; [self calculateLayoutWithSize:self.view.bounds.size];
YGApplyLayoutToViewHierarchy(self.view, NO); YGApplyLayoutToViewHierarchy(self.view, NO);
} }
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin - (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin {
{
[self calculateLayoutWithSize:self.view.bounds.size]; [self calculateLayoutWithSize:self.view.bounds.size];
YGApplyLayoutToViewHierarchy(self.view, preserveOrigin); YGApplyLayoutToViewHierarchy(self.view, preserveOrigin);
} }
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin dimensionFlexibility:(YGDimensionFlexibility)dimensionFlexibility - (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin
{ dimensionFlexibility:
(YGDimensionFlexibility)dimensionFlexibility {
CGSize size = self.view.bounds.size; CGSize size = self.view.bounds.size;
if (dimensionFlexibility & YGDimensionFlexibilityFlexibleWidth) { if (dimensionFlexibility & YGDimensionFlexibilityFlexibleWidth) {
size.width = YGUndefined; size.width = YGUndefined;
@@ -291,18 +315,15 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio)
YGApplyLayoutToViewHierarchy(self.view, preserveOrigin); YGApplyLayoutToViewHierarchy(self.view, preserveOrigin);
} }
- (CGSize)intrinsicSize {
- (CGSize)intrinsicSize
{
const CGSize constrainedSize = { const CGSize constrainedSize = {
.width = YGUndefined, .width = YGUndefined,
.height = YGUndefined, .height = YGUndefined,
}; };
return [self calculateLayoutWithSize:constrainedSize]; return [self calculateLayoutWithSize:constrainedSize];
} }
- (CGSize)calculateLayoutWithSize:(CGSize)size - (CGSize)calculateLayoutWithSize:(CGSize)size {
{
NSAssert([NSThread isMainThread], @"Yoga calculation must be done on main."); NSAssert([NSThread isMainThread], @"Yoga calculation must be done on main.");
NSAssert(self.isEnabled, @"Yoga is not enabled for this view."); NSAssert(self.isEnabled, @"Yoga is not enabled for this view.");
@@ -310,30 +331,28 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio)
const YGNodeRef node = self.node; const YGNodeRef node = self.node;
YGNodeCalculateLayout( YGNodeCalculateLayout(
node, node, size.width, size.height, YGNodeStyleGetDirection(node));
size.width,
size.height,
YGNodeStyleGetDirection(node));
return (CGSize) { return (CGSize){
.width = YGNodeLayoutGetWidth(node), .width = YGNodeLayoutGetWidth(node),
.height = YGNodeLayoutGetHeight(node), .height = YGNodeLayoutGetHeight(node),
}; };
} }
#pragma mark - Private #pragma mark - Private
static YGSize YGMeasureView( static YGSize YGMeasureView(
YGNodeRef node, YGNodeRef node,
float width, float width,
YGMeasureMode widthMode, YGMeasureMode widthMode,
float height, float height,
YGMeasureMode heightMode) YGMeasureMode heightMode) {
{ const CGFloat constrainedWidth =
const CGFloat constrainedWidth = (widthMode == YGMeasureModeUndefined) ? CGFLOAT_MAX : width; (widthMode == YGMeasureModeUndefined) ? CGFLOAT_MAX : width;
const CGFloat constrainedHeight = (heightMode == YGMeasureModeUndefined) ? CGFLOAT_MAX: height; const CGFloat constrainedHeight =
(heightMode == YGMeasureModeUndefined) ? CGFLOAT_MAX : height;
UIView *view = (__bridge UIView*) YGNodeGetContext(node); UIView* view = (__bridge UIView*)YGNodeGetContext(node);
CGSize sizeThatFits = CGSizeZero; CGSize sizeThatFits = CGSizeZero;
// The default implementation of sizeThatFits: returns the existing size of // The default implementation of sizeThatFits: returns the existing size of
@@ -349,17 +368,18 @@ static YGSize YGMeasureView(
}]; }];
} }
return (YGSize) { return (YGSize){
.width = YGSanitizeMeasurement(constrainedWidth, sizeThatFits.width, widthMode), .width = YGSanitizeMeasurement(
.height = YGSanitizeMeasurement(constrainedHeight, sizeThatFits.height, heightMode), constrainedWidth, sizeThatFits.width, widthMode),
.height = YGSanitizeMeasurement(
constrainedHeight, sizeThatFits.height, heightMode),
}; };
} }
static CGFloat YGSanitizeMeasurement( static CGFloat YGSanitizeMeasurement(
CGFloat constrainedSize, CGFloat constrainedSize,
CGFloat measuredSize, CGFloat measuredSize,
YGMeasureMode measureMode) YGMeasureMode measureMode) {
{
CGFloat result; CGFloat result;
if (measureMode == YGMeasureModeExactly) { if (measureMode == YGMeasureModeExactly) {
result = constrainedSize; result = constrainedSize;
@@ -372,13 +392,14 @@ static CGFloat YGSanitizeMeasurement(
return result; return result;
} }
static BOOL YGNodeHasExactSameChildren(const YGNodeRef node, NSArray<UIView *> *subviews) static BOOL YGNodeHasExactSameChildren(
{ const YGNodeRef node,
NSArray<UIView*>* subviews) {
if (YGNodeGetChildCount(node) != subviews.count) { if (YGNodeGetChildCount(node) != subviews.count) {
return NO; return NO;
} }
for (int i=0; i<subviews.count; i++) { for (int i = 0; i < subviews.count; i++) {
if (YGNodeGetChild(node, i) != subviews[i].yoga.node) { if (YGNodeGetChild(node, i) != subviews[i].yoga.node) {
return NO; return NO;
} }
@@ -387,9 +408,8 @@ static BOOL YGNodeHasExactSameChildren(const YGNodeRef node, NSArray<UIView *> *
return YES; return YES;
} }
static void YGAttachNodesFromViewHierachy(UIView *const view) static void YGAttachNodesFromViewHierachy(UIView* const view) {
{ YGLayout* const yoga = view.yoga;
YGLayout *const yoga = view.yoga;
const YGNodeRef node = yoga.node; const YGNodeRef node = yoga.node;
// Only leaf nodes should have a measure function // Only leaf nodes should have a measure function
@@ -399,8 +419,9 @@ static void YGAttachNodesFromViewHierachy(UIView *const view)
} else { } else {
YGNodeSetMeasureFunc(node, NULL); YGNodeSetMeasureFunc(node, NULL);
NSMutableArray<UIView *> *subviewsToInclude = [[NSMutableArray alloc] initWithCapacity:view.subviews.count]; NSMutableArray<UIView*>* subviewsToInclude =
for (UIView *subview in view.subviews) { [[NSMutableArray alloc] initWithCapacity:view.subviews.count];
for (UIView* subview in view.subviews) {
if (subview.yoga.isEnabled && subview.yoga.isIncludedInLayout) { if (subview.yoga.isEnabled && subview.yoga.isIncludedInLayout) {
[subviewsToInclude addObject:subview]; [subviewsToInclude addObject:subview];
} }
@@ -408,19 +429,18 @@ static void YGAttachNodesFromViewHierachy(UIView *const view)
if (!YGNodeHasExactSameChildren(node, subviewsToInclude)) { if (!YGNodeHasExactSameChildren(node, subviewsToInclude)) {
YGRemoveAllChildren(node); YGRemoveAllChildren(node);
for (int i=0; i<subviewsToInclude.count; i++) { for (int i = 0; i < subviewsToInclude.count; i++) {
YGNodeInsertChild(node, subviewsToInclude[i].yoga.node, i); YGNodeInsertChild(node, subviewsToInclude[i].yoga.node, i);
} }
} }
for (UIView *const subview in subviewsToInclude) { for (UIView* const subview in subviewsToInclude) {
YGAttachNodesFromViewHierachy(subview); YGAttachNodesFromViewHierachy(subview);
} }
} }
} }
static void YGRemoveAllChildren(const YGNodeRef node) static void YGRemoveAllChildren(const YGNodeRef node) {
{
if (node == NULL) { if (node == NULL) {
return; return;
} }
@@ -428,52 +448,56 @@ static void YGRemoveAllChildren(const YGNodeRef node)
YGNodeRemoveAllChildren(node); YGNodeRemoveAllChildren(node);
} }
static CGFloat YGRoundPixelValue(CGFloat value) static CGFloat YGRoundPixelValue(CGFloat value) {
{
static CGFloat scale; static CGFloat scale;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^(){ dispatch_once(&onceToken, ^() {
scale = [UIScreen mainScreen].scale; scale = [UIScreen mainScreen].scale;
}); });
return roundf(value * scale) / scale; return roundf(value * scale) / scale;
} }
static void YGApplyLayoutToViewHierarchy(UIView *view, BOOL preserveOrigin) static void YGApplyLayoutToViewHierarchy(UIView* view, BOOL preserveOrigin) {
{ NSCAssert(
NSCAssert([NSThread isMainThread], @"Framesetting should only be done on the main thread."); [NSThread isMainThread],
@"Framesetting should only be done on the main thread.");
const YGLayout *yoga = view.yoga; const YGLayout* yoga = view.yoga;
if (!yoga.isIncludedInLayout) { if (!yoga.isIncludedInLayout) {
return; return;
} }
YGNodeRef node = yoga.node; YGNodeRef node = yoga.node;
const CGPoint topLeft = { const CGPoint topLeft = {
YGNodeLayoutGetLeft(node), YGNodeLayoutGetLeft(node),
YGNodeLayoutGetTop(node), YGNodeLayoutGetTop(node),
}; };
const CGPoint bottomRight = { const CGPoint bottomRight = {
topLeft.x + YGNodeLayoutGetWidth(node), topLeft.x + YGNodeLayoutGetWidth(node),
topLeft.y + YGNodeLayoutGetHeight(node), topLeft.y + YGNodeLayoutGetHeight(node),
}; };
const CGPoint origin = preserveOrigin ? view.frame.origin : CGPointZero; const CGPoint origin = preserveOrigin ? view.frame.origin : CGPointZero;
view.frame = (CGRect) { view.frame = (CGRect){
.origin = { .origin =
.x = YGRoundPixelValue(topLeft.x + origin.x), {
.y = YGRoundPixelValue(topLeft.y + origin.y), .x = YGRoundPixelValue(topLeft.x + origin.x),
}, .y = YGRoundPixelValue(topLeft.y + origin.y),
.size = { },
.width = YGRoundPixelValue(bottomRight.x) - YGRoundPixelValue(topLeft.x), .size =
.height = YGRoundPixelValue(bottomRight.y) - YGRoundPixelValue(topLeft.y), {
}, .width = YGRoundPixelValue(bottomRight.x) -
YGRoundPixelValue(topLeft.x),
.height = YGRoundPixelValue(bottomRight.y) -
YGRoundPixelValue(topLeft.y),
},
}; };
if (!yoga.isLeaf) { if (!yoga.isLeaf) {
for (NSUInteger i=0; i<view.subviews.count; i++) { for (NSUInteger i = 0; i < view.subviews.count; i++) {
YGApplyLayoutToViewHierarchy(view.subviews[i], NO); YGApplyLayoutToViewHierarchy(view.subviews[i], NO);
} }
} }

View File

@@ -1,10 +1,11 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import yoga;
postfix operator % postfix operator %
extension Int { extension Int {

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
@@ -16,17 +16,15 @@
@implementation YogaKitTests @implementation YogaKitTests
- (void)testConfigureLayoutIsNoOpWithNilBlock - (void)testConfigureLayoutIsNoOpWithNilBlock {
{ UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
id block = nil; id block = nil;
XCTAssertNoThrow([view configureLayoutWithBlock:block]); XCTAssertNoThrow([view configureLayoutWithBlock:block]);
} }
- (void)testConfigureLayoutBlockWorksWithValidBlock - (void)testConfigureLayoutBlockWorksWithValidBlock {
{ UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; [view configureLayoutWithBlock:^(YGLayout* layout) {
[view configureLayoutWithBlock:^(YGLayout *layout){
XCTAssertNotNil(layout); XCTAssertNotNil(layout);
layout.isEnabled = YES; layout.isEnabled = YES;
layout.width = YGPointValue(25); layout.width = YGPointValue(25);
@@ -36,12 +34,11 @@
XCTAssertEqual(view.yoga.width.value, 25); XCTAssertEqual(view.yoga.width.value, 25);
} }
- (void)testNodesAreDeallocedWithSingleView - (void)testNodesAreDeallocedWithSingleView {
{ __weak YGLayout* layoutRef = nil;
__weak YGLayout *layoutRef = nil;
@autoreleasepool { @autoreleasepool {
UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.flexBasis = YGPointValue(1); view.yoga.flexBasis = YGPointValue(1);
layoutRef = view.yoga; layoutRef = view.yoga;
@@ -53,17 +50,16 @@
XCTAssertNil(layoutRef); XCTAssertNil(layoutRef);
} }
- (void)testNodesAreDeallocedCascade - (void)testNodesAreDeallocedCascade {
{ __weak YGLayout* topLayout = nil;
__weak YGLayout *topLayout = nil; __weak YGLayout* subviewLayout = nil;
__weak YGLayout *subviewLayout = nil;
@autoreleasepool { @autoreleasepool {
UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
topLayout = view.yoga; topLayout = view.yoga;
topLayout.flexBasis = YGPointValue(1); topLayout.flexBasis = YGPointValue(1);
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview = [[UIView alloc] initWithFrame:CGRectZero];
subviewLayout = subview.yoga; subviewLayout = subview.yoga;
subviewLayout.flexBasis = YGPointValue(1); subviewLayout.flexBasis = YGPointValue(1);
@@ -74,9 +70,8 @@
XCTAssertNil(subviewLayout); XCTAssertNil(subviewLayout);
} }
- (void)testIsEnabled - (void)testIsEnabled {
{ UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
XCTAssertFalse(view.yoga.isEnabled); XCTAssertFalse(view.yoga.isEnabled);
view.yoga.isEnabled = YES; view.yoga.isEnabled = YES;
@@ -86,30 +81,31 @@
XCTAssertFalse(view.yoga.isEnabled); XCTAssertFalse(view.yoga.isEnabled);
} }
- (void)testSizeThatFitsAsserts - (void)testSizeThatFitsAsserts {
{ UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; dispatch_sync(
dispatch_sync(dispatch_queue_create("com.facebook.Yoga.testing", DISPATCH_QUEUE_SERIAL), ^(void){ dispatch_queue_create("com.facebook.Yoga.testing", DISPATCH_QUEUE_SERIAL),
XCTAssertThrows(view.yoga.intrinsicSize); ^(void) {
}); XCTAssertThrows(view.yoga.intrinsicSize);
});
} }
- (void)testSizeThatFitsSmoke - (void)testSizeThatFitsSmoke {
{ UIView* container = [[UIView alloc] initWithFrame:CGRectZero];
UIView *container = [[UIView alloc] initWithFrame:CGRectZero];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
container.yoga.flexDirection = YGFlexDirectionRow; container.yoga.flexDirection = YGFlexDirectionRow;
container.yoga.alignItems = YGAlignFlexStart; container.yoga.alignItems = YGAlignFlexStart;
UILabel *longTextLabel = [[UILabel alloc] initWithFrame:CGRectZero]; UILabel* longTextLabel = [[UILabel alloc] initWithFrame:CGRectZero];
longTextLabel.text = @"This is a very very very very very very very very long piece of text."; longTextLabel.text =
@"This is a very very very very very very very very long piece of text.";
longTextLabel.lineBreakMode = NSLineBreakByTruncatingTail; longTextLabel.lineBreakMode = NSLineBreakByTruncatingTail;
longTextLabel.numberOfLines = 1; longTextLabel.numberOfLines = 1;
longTextLabel.yoga.isEnabled = YES; longTextLabel.yoga.isEnabled = YES;
longTextLabel.yoga.flexShrink = 1; longTextLabel.yoga.flexShrink = 1;
[container addSubview:longTextLabel]; [container addSubview:longTextLabel];
UIView *textBadgeView = [[UIView alloc] initWithFrame:CGRectZero]; UIView* textBadgeView = [[UIView alloc] initWithFrame:CGRectZero];
textBadgeView.yoga.isEnabled = YES; textBadgeView.yoga.isEnabled = YES;
textBadgeView.yoga.margin = YGPointValue(0); textBadgeView.yoga.margin = YGPointValue(0);
textBadgeView.yoga.width = YGPointValue(10); textBadgeView.yoga.width = YGPointValue(10);
@@ -124,7 +120,9 @@
const CGSize longTextLabelSize = longTextLabel.yoga.intrinsicSize; const CGSize longTextLabelSize = longTextLabel.yoga.intrinsicSize;
XCTAssertEqual(longTextLabelSize.height, containerSize.height); XCTAssertEqual(longTextLabelSize.height, containerSize.height);
XCTAssertEqual(longTextLabelSize.width + textBadgeView.yoga.intrinsicSize.width, containerSize.width); XCTAssertEqual(
longTextLabelSize.width + textBadgeView.yoga.intrinsicSize.width,
containerSize.width);
} }
- (void)testSizeThatFitsEmptyView { - (void)testSizeThatFitsEmptyView {
@@ -136,18 +134,17 @@
XCTAssertEqual(viewSize.width, 0); XCTAssertEqual(viewSize.width, 0);
} }
- (void)testPreservingOrigin - (void)testPreservingOrigin {
{ UIView* container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 75)];
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,50,75)];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.isEnabled = YES; view.yoga.isEnabled = YES;
view.yoga.flexBasis = YGPointValue(0); view.yoga.flexBasis = YGPointValue(0);
view.yoga.flexGrow = 1; view.yoga.flexGrow = 1;
[container addSubview:view]; [container addSubview:view];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* view2 = [[UIView alloc] initWithFrame:CGRectZero];
view2.yoga.isEnabled = YES; view2.yoga.isEnabled = YES;
view2.yoga.marginTop = YGPointValue(25); view2.yoga.marginTop = YGPointValue(25);
view2.yoga.flexBasis = YGPointValue(0); view2.yoga.flexBasis = YGPointValue(0);
@@ -161,28 +158,28 @@
XCTAssertEqual(25, view2.frame.origin.y); XCTAssertEqual(25, view2.frame.origin.y);
} }
- (void)testContainerWithFlexibleWidthGetsCorrectlySized - (void)testContainerWithFlexibleWidthGetsCorrectlySized {
{ UIView* container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,200,200)];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.yoga.isEnabled = YES; view.yoga.isEnabled = YES;
view.yoga.width = YGPointValue(100); view.yoga.width = YGPointValue(100);
view.yoga.height = YGPointValue(100); view.yoga.height = YGPointValue(100);
[container addSubview:view]; [container addSubview:view];
[container.yoga applyLayoutPreservingOrigin:YES dimensionFlexibility:YGDimensionFlexibilityFlexibleWidth]; [container.yoga
applyLayoutPreservingOrigin:YES
dimensionFlexibility:YGDimensionFlexibilityFlexibleWidth];
XCTAssertEqual(100, container.frame.size.width); XCTAssertEqual(100, container.frame.size.width);
XCTAssertEqual(200, container.frame.size.height); XCTAssertEqual(200, container.frame.size.height);
} }
- (void)testContainerWithFlexibleHeightGetsCorrectlySized - (void)testContainerWithFlexibleHeightGetsCorrectlySized {
{ UIView* container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,200,200)];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.yoga.isEnabled = YES; view.yoga.isEnabled = YES;
view.yoga.width = YGPointValue(100); view.yoga.width = YGPointValue(100);
view.yoga.height = YGPointValue(100); view.yoga.height = YGPointValue(100);
@@ -195,12 +192,11 @@
XCTAssertEqual(100, container.frame.size.height); XCTAssertEqual(100, container.frame.size.height);
} }
- (void)testContainerWithFlexibleWidthAndHeightGetsCorrectlySized - (void)testContainerWithFlexibleWidthAndHeightGetsCorrectlySized {
{ UIView* container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,200,200)];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.yoga.isEnabled = YES; view.yoga.isEnabled = YES;
view.yoga.width = YGPointValue(100); view.yoga.width = YGPointValue(100);
view.yoga.height = YGPointValue(100); view.yoga.height = YGPointValue(100);
@@ -214,12 +210,11 @@
XCTAssertEqual(100, container.frame.size.height); XCTAssertEqual(100, container.frame.size.height);
} }
- (void)testMarkingDirtyOnlyWorksOnLeafNodes - (void)testMarkingDirtyOnlyWorksOnLeafNodes {
{ UIView* container = [[UIView alloc] initWithFrame:CGRectZero];
UIView *container = [[UIView alloc] initWithFrame:CGRectZero];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview = [[UIView alloc] initWithFrame:CGRectZero];
subview.yoga.isEnabled = YES; subview.yoga.isEnabled = YES;
[container addSubview:subview]; [container addSubview:subview];
@@ -232,14 +227,13 @@
XCTAssertTrue(subview.yoga.isDirty); XCTAssertTrue(subview.yoga.isDirty);
} }
- (void)testThatMarkingLeafsAsDirtyWillTriggerASizeRecalculation - (void)testThatMarkingLeafsAsDirtyWillTriggerASizeRecalculation {
{ UIView* container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 50)];
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 50)];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
container.yoga.flexDirection = YGFlexDirectionRow; container.yoga.flexDirection = YGFlexDirectionRow;
container.yoga.alignItems = YGAlignFlexStart; container.yoga.alignItems = YGAlignFlexStart;
UILabel *view = [[UILabel alloc] initWithFrame:CGRectZero]; UILabel* view = [[UILabel alloc] initWithFrame:CGRectZero];
view.text = @"This is a short text."; view.text = @"This is a short text.";
view.numberOfLines = 1; view.numberOfLines = 1;
view.yoga.isEnabled = YES; view.yoga.isEnabled = YES;
@@ -257,61 +251,70 @@
XCTAssertFalse(CGSizeEqualToSize(view.frame.size, viewSizeAfterFirstPass)); XCTAssertFalse(CGSizeEqualToSize(view.frame.size, viewSizeAfterFirstPass));
} }
- (void)testFrameAndOriginPlacement - (void)testFrameAndOriginPlacement {
{
const CGSize containerSize = CGSizeMake(320, 50); const CGSize containerSize = CGSizeMake(320, 50);
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)]; UIView* container = [[UIView alloc]
initWithFrame:CGRectMake(
0, 0, containerSize.width, containerSize.height)];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
container.yoga.flexDirection = YGFlexDirectionRow; container.yoga.flexDirection = YGFlexDirectionRow;
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview1 = [[UIView alloc] initWithFrame:CGRectZero];
subview1.yoga.isEnabled = YES; subview1.yoga.isEnabled = YES;
subview1.yoga.flexGrow = 1; subview1.yoga.flexGrow = 1;
[container addSubview:subview1]; [container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview2 = [[UIView alloc] initWithFrame:CGRectZero];
subview2.yoga.isEnabled = YES; subview2.yoga.isEnabled = YES;
subview2.yoga.flexGrow = 1; subview2.yoga.flexGrow = 1;
[container addSubview:subview2]; [container addSubview:subview2];
UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview3 = [[UIView alloc] initWithFrame:CGRectZero];
subview3.yoga.isEnabled = YES; subview3.yoga.isEnabled = YES;
subview3.yoga.flexGrow = 1; subview3.yoga.flexGrow = 1;
[container addSubview:subview3]; [container addSubview:subview3];
[container.yoga applyLayoutPreservingOrigin:YES]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqualWithAccuracy(subview2.frame.origin.x, CGRectGetMaxX(subview1.frame), FLT_EPSILON); XCTAssertEqualWithAccuracy(
XCTAssertEqualWithAccuracy(subview3.frame.origin.x, CGRectGetMaxX(subview2.frame), FLT_EPSILON); subview2.frame.origin.x, CGRectGetMaxX(subview1.frame), FLT_EPSILON);
XCTAssertEqualWithAccuracy(
subview3.frame.origin.x, CGRectGetMaxX(subview2.frame), FLT_EPSILON);
CGFloat totalWidth = 0; CGFloat totalWidth = 0;
for (UIView *view in container.subviews) { for (UIView* view in container.subviews) {
totalWidth += view.bounds.size.width; totalWidth += view.bounds.size.width;
} }
XCTAssertEqual(containerSize.width, totalWidth, @"The container's width is %.6f, the subviews take up %.6f", containerSize.width, totalWidth); XCTAssertEqual(
containerSize.width,
totalWidth,
@"The container's width is %.6f, the subviews take up %.6f",
containerSize.width,
totalWidth);
} }
- (void)testThatLayoutIsCorrectWhenWeSwapViewOrder - (void)testThatLayoutIsCorrectWhenWeSwapViewOrder {
{
const CGSize containerSize = CGSizeMake(300, 50); const CGSize containerSize = CGSizeMake(300, 50);
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)]; UIView* container = [[UIView alloc]
initWithFrame:CGRectMake(
0, 0, containerSize.width, containerSize.height)];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
container.yoga.flexDirection = YGFlexDirectionRow; container.yoga.flexDirection = YGFlexDirectionRow;
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview1 = [[UIView alloc] initWithFrame:CGRectZero];
subview1.yoga.isEnabled = YES; subview1.yoga.isEnabled = YES;
subview1.yoga.flexGrow = 1; subview1.yoga.flexGrow = 1;
[container addSubview:subview1]; [container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview2 = [[UIView alloc] initWithFrame:CGRectZero];
subview2.yoga.isEnabled = YES; subview2.yoga.isEnabled = YES;
subview2.yoga.flexGrow = 1; subview2.yoga.flexGrow = 1;
[container addSubview:subview2]; [container addSubview:subview2];
UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview3 = [[UIView alloc] initWithFrame:CGRectZero];
subview3.yoga.isEnabled = YES; subview3.yoga.isEnabled = YES;
subview3.yoga.flexGrow = 1; subview3.yoga.flexGrow = 1;
[container addSubview:subview3]; [container addSubview:subview3];
@@ -333,32 +336,33 @@
XCTAssertTrue(CGRectEqualToRect(subview2.frame, CGRectMake(100, 0, 100, 50))); XCTAssertTrue(CGRectEqualToRect(subview2.frame, CGRectMake(100, 0, 100, 50)));
} }
- (void)testThatWeRespectIncludeInLayoutFlag - (void)testThatWeRespectIncludeInLayoutFlag {
{
const CGSize containerSize = CGSizeMake(300, 50); const CGSize containerSize = CGSizeMake(300, 50);
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)]; UIView* container = [[UIView alloc]
initWithFrame:CGRectMake(
0, 0, containerSize.width, containerSize.height)];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
container.yoga.flexDirection = YGFlexDirectionRow; container.yoga.flexDirection = YGFlexDirectionRow;
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview1 = [[UIView alloc] initWithFrame:CGRectZero];
subview1.yoga.isEnabled = YES; subview1.yoga.isEnabled = YES;
subview1.yoga.flexGrow = 1; subview1.yoga.flexGrow = 1;
[container addSubview:subview1]; [container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview2 = [[UIView alloc] initWithFrame:CGRectZero];
subview2.yoga.isEnabled = YES; subview2.yoga.isEnabled = YES;
subview2.yoga.flexGrow = 1; subview2.yoga.flexGrow = 1;
[container addSubview:subview2]; [container addSubview:subview2];
UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview3 = [[UIView alloc] initWithFrame:CGRectZero];
subview3.yoga.isEnabled = YES; subview3.yoga.isEnabled = YES;
subview3.yoga.flexGrow = 1; subview3.yoga.flexGrow = 1;
[container addSubview:subview3]; [container addSubview:subview3];
[container.yoga applyLayoutPreservingOrigin:YES]; [container.yoga applyLayoutPreservingOrigin:YES];
for (UIView *subview in container.subviews) { for (UIView* subview in container.subviews) {
XCTAssertEqual(subview.bounds.size.width, 100); XCTAssertEqual(subview.bounds.size.width, 100);
} }
@@ -368,27 +372,27 @@
XCTAssertEqual(subview1.bounds.size.width, 150); XCTAssertEqual(subview1.bounds.size.width, 150);
XCTAssertEqual(subview2.bounds.size.width, 150); XCTAssertEqual(subview2.bounds.size.width, 150);
// We don't set the frame to zero, so, it should be set to what it was previously at. // We don't set the frame to zero, so, it should be set to what it was
// previously at.
XCTAssertEqual(subview3.bounds.size.width, 100); XCTAssertEqual(subview3.bounds.size.width, 100);
} }
- (void)testThatNumberOfChildrenIsCorrectWhenWeIgnoreSubviews - (void)testThatNumberOfChildrenIsCorrectWhenWeIgnoreSubviews {
{ UIView* container = [[UIView alloc] initWithFrame:CGRectZero];
UIView *container = [[UIView alloc] initWithFrame:CGRectZero];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
container.yoga.flexDirection = YGFlexDirectionRow; container.yoga.flexDirection = YGFlexDirectionRow;
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview1 = [[UIView alloc] initWithFrame:CGRectZero];
subview1.yoga.isEnabled = YES; subview1.yoga.isEnabled = YES;
subview1.yoga.isIncludedInLayout = NO; subview1.yoga.isIncludedInLayout = NO;
[container addSubview:subview1]; [container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview2 = [[UIView alloc] initWithFrame:CGRectZero];
subview2.yoga.isEnabled = YES; subview2.yoga.isEnabled = YES;
subview2.yoga.isIncludedInLayout = NO; subview2.yoga.isIncludedInLayout = NO;
[container addSubview:subview2]; [container addSubview:subview2];
UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview3 = [[UIView alloc] initWithFrame:CGRectZero];
subview3.yoga.isEnabled = YES; subview3.yoga.isEnabled = YES;
subview3.yoga.isIncludedInLayout = YES; subview3.yoga.isIncludedInLayout = YES;
[container addSubview:subview3]; [container addSubview:subview3];
@@ -401,23 +405,22 @@
XCTAssertEqual(container.yoga.numberOfChildren, 2); XCTAssertEqual(container.yoga.numberOfChildren, 2);
} }
- (void)testThatViewNotIncludedInFirstLayoutPassAreIncludedInSecond - (void)testThatViewNotIncludedInFirstLayoutPassAreIncludedInSecond {
{ UIView* container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
container.yoga.isEnabled = YES; container.yoga.isEnabled = YES;
container.yoga.flexDirection = YGFlexDirectionRow; container.yoga.flexDirection = YGFlexDirectionRow;
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview1 = [[UIView alloc] initWithFrame:CGRectZero];
subview1.yoga.isEnabled = YES; subview1.yoga.isEnabled = YES;
subview1.yoga.flexGrow = 1; subview1.yoga.flexGrow = 1;
[container addSubview:subview1]; [container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview2 = [[UIView alloc] initWithFrame:CGRectZero];
subview2.yoga.isEnabled = YES; subview2.yoga.isEnabled = YES;
subview2.yoga.flexGrow = 1; subview2.yoga.flexGrow = 1;
[container addSubview:subview2]; [container addSubview:subview2];
UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview3 = [[UIView alloc] initWithFrame:CGRectZero];
subview3.yoga.isEnabled = YES; subview3.yoga.isEnabled = YES;
subview3.yoga.flexGrow = 1; subview3.yoga.flexGrow = 1;
subview3.yoga.isIncludedInLayout = NO; subview3.yoga.isIncludedInLayout = NO;
@@ -437,13 +440,12 @@
XCTAssertEqual(subview3.bounds.size.width, 100); XCTAssertEqual(subview3.bounds.size.width, 100);
} }
- (void)testIsLeafFlag - (void)testIsLeafFlag {
{ UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
XCTAssertTrue(view.yoga.isLeaf); XCTAssertTrue(view.yoga.isLeaf);
for (int i=0; i<10; i++) { for (int i = 0; i < 10; i++) {
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview = [[UIView alloc] initWithFrame:CGRectZero];
[view addSubview:subview]; [view addSubview:subview];
} }
XCTAssertTrue(view.yoga.isLeaf); XCTAssertTrue(view.yoga.isLeaf);
@@ -452,99 +454,95 @@
view.yoga.width = YGPointValue(50); view.yoga.width = YGPointValue(50);
XCTAssertTrue(view.yoga.isLeaf); XCTAssertTrue(view.yoga.isLeaf);
UIView *const subview = view.subviews[0]; UIView* const subview = view.subviews[0];
subview.yoga.isEnabled = YES; subview.yoga.isEnabled = YES;
subview.yoga.width = YGPointValue(50); subview.yoga.width = YGPointValue(50);
XCTAssertFalse(view.yoga.isLeaf); XCTAssertFalse(view.yoga.isLeaf);
} }
- (void)testThatWeCorrectlyAttachNestedViews - (void)testThatWeCorrectlyAttachNestedViews {
{ UIView* container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)]; container.yoga.isEnabled = YES;
container.yoga.isEnabled = YES; container.yoga.flexDirection = YGFlexDirectionColumn;
container.yoga.flexDirection = YGFlexDirectionColumn;
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview1 = [[UIView alloc] initWithFrame:CGRectZero];
subview1.yoga.isEnabled = YES; subview1.yoga.isEnabled = YES;
subview1.yoga.width = YGPointValue(100); subview1.yoga.width = YGPointValue(100);
subview1.yoga.flexGrow = 1; subview1.yoga.flexGrow = 1;
subview1.yoga.flexDirection = YGFlexDirectionColumn; subview1.yoga.flexDirection = YGFlexDirectionColumn;
[container addSubview:subview1]; [container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview2 = [[UIView alloc] initWithFrame:CGRectZero];
subview2.yoga.isEnabled = YES; subview2.yoga.isEnabled = YES;
subview2.yoga.width = YGPointValue(150); subview2.yoga.width = YGPointValue(150);
subview2.yoga.flexGrow = 1; subview2.yoga.flexGrow = 1;
subview2.yoga.flexDirection = YGFlexDirectionColumn; subview2.yoga.flexDirection = YGFlexDirectionColumn;
[container addSubview:subview2]; [container addSubview:subview2];
for (UIView *view in @[subview1, subview2]) { for (UIView* view in @[ subview1, subview2 ]) {
UIView *someView = [[UIView alloc] initWithFrame:CGRectZero]; UIView* someView = [[UIView alloc] initWithFrame:CGRectZero];
someView.yoga.isEnabled = YES; someView.yoga.isEnabled = YES;
someView.yoga.flexGrow = 1; someView.yoga.flexGrow = 1;
[view addSubview:someView]; [view addSubview:someView];
} }
[container.yoga applyLayoutPreservingOrigin:YES]; [container.yoga applyLayoutPreservingOrigin:YES];
// Add the same amount of new views, reapply layout. // Add the same amount of new views, reapply layout.
for (UIView *view in @[subview1, subview2]) { for (UIView* view in @[ subview1, subview2 ]) {
UIView *someView = [[UIView alloc] initWithFrame:CGRectZero]; UIView* someView = [[UIView alloc] initWithFrame:CGRectZero];
someView.yoga.isEnabled = YES; someView.yoga.isEnabled = YES;
someView.yoga.flexGrow = 1; someView.yoga.flexGrow = 1;
[view addSubview:someView]; [view addSubview:someView];
} }
[container.yoga applyLayoutPreservingOrigin:YES]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(subview1.bounds.size.width, 100); XCTAssertEqual(subview1.bounds.size.width, 100);
XCTAssertEqual(subview1.bounds.size.height, 25); XCTAssertEqual(subview1.bounds.size.height, 25);
for (UIView *subview in subview1.subviews) { for (UIView* subview in subview1.subviews) {
const CGSize subviewSize = subview.bounds.size; const CGSize subviewSize = subview.bounds.size;
XCTAssertNotEqual(subviewSize.width, 0); XCTAssertNotEqual(subviewSize.width, 0);
XCTAssertNotEqual(subviewSize.height, 0); XCTAssertNotEqual(subviewSize.height, 0);
XCTAssertFalse(isnan(subviewSize.height)); XCTAssertFalse(isnan(subviewSize.height));
XCTAssertFalse(isnan(subviewSize.width)); XCTAssertFalse(isnan(subviewSize.width));
} }
XCTAssertEqual(subview2.bounds.size.width, 150); XCTAssertEqual(subview2.bounds.size.width, 150);
XCTAssertEqual(subview2.bounds.size.height, 25); XCTAssertEqual(subview2.bounds.size.height, 25);
for (UIView *subview in subview2.subviews) { for (UIView* subview in subview2.subviews) {
const CGSize subviewSize = subview.bounds.size; const CGSize subviewSize = subview.bounds.size;
XCTAssertNotEqual(subviewSize.width, 0); XCTAssertNotEqual(subviewSize.width, 0);
XCTAssertNotEqual(subviewSize.height, 0); XCTAssertNotEqual(subviewSize.height, 0);
XCTAssertFalse(isnan(subviewSize.height)); XCTAssertFalse(isnan(subviewSize.height));
XCTAssertFalse(isnan(subviewSize.width)); XCTAssertFalse(isnan(subviewSize.width));
} }
} }
- (void)testThatANonLeafNodeCanBecomeALeafNode - (void)testThatANonLeafNodeCanBecomeALeafNode {
{ UIView* container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)]; container.yoga.isEnabled = YES;
container.yoga.isEnabled = YES;
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview1 = [[UIView alloc] initWithFrame:CGRectZero];
subview1.yoga.isEnabled = YES; subview1.yoga.isEnabled = YES;
[container addSubview:subview1]; [container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero]; UIView* subview2 = [[UIView alloc] initWithFrame:CGRectZero];
subview2.yoga.isEnabled = YES; subview2.yoga.isEnabled = YES;
[subview1 addSubview:subview2]; [subview1 addSubview:subview2];
[container.yoga applyLayoutPreservingOrigin:YES]; [container.yoga applyLayoutPreservingOrigin:YES];
[subview2 removeFromSuperview]; [subview2 removeFromSuperview];
[container.yoga applyLayoutPreservingOrigin:YES]; [container.yoga applyLayoutPreservingOrigin:YES];
} }
- (void)testPointPercent - (void)testPointPercent {
{
XCTAssertEqual(YGPointValue(1).value, 1); XCTAssertEqual(YGPointValue(1).value, 1);
XCTAssertEqual(YGPointValue(1).unit, YGUnitPoint); XCTAssertEqual(YGPointValue(1).unit, YGUnitPoint);
XCTAssertEqual(YGPercentValue(2).value, 2); XCTAssertEqual(YGPercentValue(2).value, 2);
XCTAssertEqual(YGPercentValue(2).unit, YGUnitPercent); XCTAssertEqual(YGPercentValue(2).unit, YGUnitPercent);
} }
- (void)testPositionalPropertiesWork - (void)testPositionalPropertiesWork {
{ UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.left = YGPointValue(1); view.yoga.left = YGPointValue(1);
XCTAssertEqual(view.yoga.left.value, 1); XCTAssertEqual(view.yoga.left.value, 1);
@@ -589,9 +587,8 @@
XCTAssertEqual(view.yoga.end.unit, YGUnitPercent); XCTAssertEqual(view.yoga.end.unit, YGUnitPercent);
} }
- (void)testMarginPropertiesWork - (void)testMarginPropertiesWork {
{ UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.margin = YGPointValue(1); view.yoga.margin = YGPointValue(1);
XCTAssertEqual(view.yoga.margin.value, 1); XCTAssertEqual(view.yoga.margin.value, 1);
@@ -657,9 +654,8 @@
XCTAssertEqual(view.yoga.marginEnd.unit, YGUnitPercent); XCTAssertEqual(view.yoga.marginEnd.unit, YGUnitPercent);
} }
- (void)testPaddingPropertiesWork - (void)testPaddingPropertiesWork {
{ UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.padding = YGPointValue(1); view.yoga.padding = YGPointValue(1);
XCTAssertEqual(view.yoga.padding.value, 1); XCTAssertEqual(view.yoga.padding.value, 1);
@@ -725,9 +721,8 @@
XCTAssertEqual(view.yoga.paddingEnd.unit, YGUnitPercent); XCTAssertEqual(view.yoga.paddingEnd.unit, YGUnitPercent);
} }
- (void)testBorderWidthPropertiesWork - (void)testBorderWidthPropertiesWork {
{ UIView* view = [[UIView alloc] initWithFrame:CGRectZero];
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.borderWidth = 1; view.yoga.borderWidth = 1;
XCTAssertEqual(view.yoga.borderWidth, 1); XCTAssertEqual(view.yoga.borderWidth, 1);

View File

@@ -1,9 +1,8 @@
/** /*
* Copyright 2014-present, Facebook, Inc. * Copyright (c) Facebook, Inc. and its affiliates.
* All rights reserved.
* *
* This source code is licensed under the license found in the * This source code is licensed under the MIT license found in the
* LICENSE-examples file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import Foundation import Foundation

View File

@@ -1,9 +1,8 @@
/** /*
* Copyright 2014-present, Facebook, Inc. * Copyright (c) Facebook, Inc. and its affiliates.
* All rights reserved.
* *
* This source code is licensed under the license found in the * This source code is licensed under the MIT license found in the
* LICENSE-examples file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import UIKit import UIKit

View File

@@ -1,9 +1,8 @@
/** /*
* Copyright 2014-present, Facebook, Inc. * Copyright (c) Facebook, Inc. and its affiliates.
* All rights reserved.
* *
* This source code is licensed under the license found in the * This source code is licensed under the MIT license found in the
* LICENSE-examples file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import UIKit import UIKit

View File

@@ -1,9 +1,8 @@
/** /*
* Copyright 2014-present, Facebook, Inc. * Copyright (c) Facebook, Inc. and its affiliates.
* All rights reserved.
* *
* This source code is licensed under the license found in the * This source code is licensed under the MIT license found in the
* LICENSE-examples file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#import "ViewController.h" #import "ViewController.h"
@@ -12,45 +11,39 @@
@implementation ViewController @implementation ViewController
- (void)viewDidLoad - (void)viewDidLoad {
{ UIView* root = self.view;
UIView *root = self.view; root.backgroundColor = [UIColor redColor];
root.backgroundColor = [UIColor redColor]; root.yoga.isEnabled = YES;
root.yoga.isEnabled = YES; root.yoga.width = YGPointValue(self.view.bounds.size.width);
root.yoga.width = YGPointValue(self.view.bounds.size.width); root.yoga.height = YGPointValue(self.view.bounds.size.height);
root.yoga.height = YGPointValue(self.view.bounds.size.height); root.yoga.alignItems = YGAlignCenter;
root.yoga.alignItems = YGAlignCenter; root.yoga.justifyContent = YGJustifyCenter;
root.yoga.justifyContent = YGJustifyCenter;
UIView *child1 = [UIView new]; UIView* child1 = [UIView new];
child1.backgroundColor = [UIColor blueColor]; child1.backgroundColor = [UIColor blueColor];
child1.yoga.isEnabled = YES; child1.yoga.isEnabled = YES;
child1.yoga.width = YGPointValue(100); child1.yoga.width = YGPointValue(100);
child1.yoga.height = YGPointValue(100); child1.yoga.height = YGPointValue(100);
UIView *child2 = [UIView new]; UIView* child2 = [UIView new];
child2.backgroundColor = [UIColor greenColor]; child2.backgroundColor = [UIColor greenColor];
child2.frame = (CGRect) { child2.frame = (CGRect){.size = {
.size = { .width = 200,
.width = 200, .height = 100,
.height = 100, }};
}
};
UIView *child3 = [UIView new]; UIView* child3 = [UIView new];
child3.backgroundColor = [UIColor yellowColor]; child3.backgroundColor = [UIColor yellowColor];
child3.frame = (CGRect) { child3.frame = (CGRect){.size = {
.size = { .width = 100,
.width = 100, .height = 100,
.height = 100, }};
}
};
[child2 addSubview:child3]; [child2 addSubview:child3];
[root addSubview:child1]; [root addSubview:child1];
[root addSubview:child2]; [root addSubview:child2];
[root.yoga applyLayoutPreservingOrigin:NO]; [root.yoga applyLayoutPreservingOrigin:NO];
} }
@end @end

View File

@@ -1,9 +1,8 @@
/** /*
* Copyright 2014-present, Facebook, Inc. * Copyright (c) Facebook, Inc. and its affiliates.
* All rights reserved.
* *
* This source code is licensed under the license found in the * This source code is licensed under the MIT license found in the
* LICENSE-examples file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import UIKit import UIKit

View File

@@ -1,9 +1,8 @@
/** /*
* Copyright 2014-present, Facebook, Inc. * Copyright (c) Facebook, Inc. and its affiliates.
* All rights reserved.
* *
* This source code is licensed under the license found in the * This source code is licensed under the MIT license found in the
* LICENSE-examples file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import UIKit import UIKit

View File

@@ -1,9 +1,8 @@
/** /*
* Copyright 2014-present, Facebook, Inc. * Copyright (c) Facebook, Inc. and its affiliates.
* All rights reserved.
* *
* This source code is licensed under the license found in the * This source code is licensed under the MIT license found in the
* LICENSE-examples file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import UIKit import UIKit

View File

@@ -3,10 +3,11 @@
# This source code is licensed under the MIT license found in the # This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree. # LICENSE file in the root directory of this source tree.
load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID_JAVA_TARGET", "ANDROID_RES_TARGET", "INFER_ANNOTATIONS_TARGET", "JAVA_TARGET", "PROGRUARD_ANNOTATIONS_TARGET", "yoga_android_aar", "yoga_android_resource") load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID_JAVA_TARGET", "ANDROID_RES_TARGET", "JAVA_TARGET", "PROGUARD_ANNOTATIONS_TARGET", "yoga_android_aar", "yoga_android_resource")
yoga_android_aar( yoga_android_aar(
name = "android", name = "android",
enable_relinker = True,
manifest_skeleton = "src/main/AndroidManifest.xml", manifest_skeleton = "src/main/AndroidManifest.xml",
visibility = [ visibility = [
"PUBLIC", "PUBLIC",
@@ -14,9 +15,8 @@ yoga_android_aar(
deps = [ deps = [
ANDROID_JAVA_TARGET, ANDROID_JAVA_TARGET,
ANDROID_RES_TARGET, ANDROID_RES_TARGET,
INFER_ANNOTATIONS_TARGET,
JAVA_TARGET, JAVA_TARGET,
PROGRUARD_ANNOTATIONS_TARGET, PROGUARD_ANNOTATIONS_TARGET,
], ],
) )

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.samples.yoga; package com.facebook.samples.yoga;
import android.content.Intent; import android.content.Intent;

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.samples.yoga; package com.facebook.samples.yoga;
import java.io.File; import java.io.File;

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.samples.yoga; package com.facebook.samples.yoga;

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.samples.yoga; package com.facebook.samples.yoga;
import android.os.Bundle; import android.os.Bundle;

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.samples.yoga; package com.facebook.samples.yoga;
import android.os.Bundle; import android.os.Bundle;

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.samples.yoga; package com.facebook.samples.yoga;
import android.os.Bundle; import android.os.Bundle;

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.samples.yoga; package com.facebook.samples.yoga;
import android.content.Intent; import android.content.Intent;

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.yoga.android; package com.facebook.yoga.android;
import java.util.HashMap; import java.util.HashMap;
@@ -17,6 +18,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.facebook.yoga.YogaNode; import com.facebook.yoga.YogaNode;
import com.facebook.yoga.YogaNodeFactory;
/** /**
* Much like a {@link YogaLayout}, except this class does not render itself (the container) to the * Much like a {@link YogaLayout}, except this class does not render itself (the container) to the
@@ -32,7 +34,7 @@ public class VirtualYogaLayout extends ViewGroup {
final private List<View> mChildren = new LinkedList<>(); final private List<View> mChildren = new LinkedList<>();
final private Map<View, YogaNode> mYogaNodes = new HashMap<>(); final private Map<View, YogaNode> mYogaNodes = new HashMap<>();
final private YogaNode mYogaNode = YogaNode.create(); final private YogaNode mYogaNode = YogaNodeFactory.create();
public VirtualYogaLayout(Context context) { public VirtualYogaLayout(Context context) {
super(context); super(context);
@@ -72,7 +74,7 @@ public class VirtualYogaLayout extends ViewGroup {
return; return;
} }
YogaNode node = YogaNode.create(); YogaNode node = YogaNodeFactory.create();
YogaLayout.LayoutParams lp = new YogaLayout.LayoutParams(params); YogaLayout.LayoutParams lp = new YogaLayout.LayoutParams(params);
YogaLayout.applyLayoutParams(lp, node, child); YogaLayout.applyLayoutParams(lp, node, child);
node.setData(child); node.setData(child);

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.yoga.android; package com.facebook.yoga.android;
import android.content.Context; import android.content.Context;
@@ -28,6 +29,7 @@ import com.facebook.yoga.YogaMeasureFunction;
import com.facebook.yoga.YogaMeasureMode; import com.facebook.yoga.YogaMeasureMode;
import com.facebook.yoga.YogaMeasureOutput; import com.facebook.yoga.YogaMeasureOutput;
import com.facebook.yoga.YogaNode; import com.facebook.yoga.YogaNode;
import com.facebook.yoga.YogaNodeFactory;
import com.facebook.yoga.YogaOverflow; import com.facebook.yoga.YogaOverflow;
import com.facebook.yoga.YogaPositionType; import com.facebook.yoga.YogaPositionType;
import com.facebook.yoga.YogaWrap; import com.facebook.yoga.YogaWrap;
@@ -77,7 +79,7 @@ public class YogaLayout extends ViewGroup {
public YogaLayout(Context context, AttributeSet attrs, int defStyleAttr) { public YogaLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
mYogaNode = YogaNode.create(); mYogaNode = YogaNodeFactory.create();
mYogaNodes = new HashMap<>(); mYogaNodes = new HashMap<>();
mYogaNode.setData(this); mYogaNode.setData(this);
@@ -154,7 +156,7 @@ public class YogaLayout extends ViewGroup {
if(mYogaNodes.containsKey(child)) { if(mYogaNodes.containsKey(child)) {
childNode = mYogaNodes.get(child); childNode = mYogaNodes.get(child);
} else { } else {
childNode = YogaNode.create(); childNode = YogaNodeFactory.create();
} }
childNode.setData(child); childNode.setData(child);

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.yoga.android; package com.facebook.yoga.android;
import android.content.Context; import android.content.Context;

View File

@@ -1,9 +1,10 @@
/* /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
@@ -34,7 +34,7 @@ ext {
minSdkVersion = 14 minSdkVersion = 14
targetSdkVersion = 25 targetSdkVersion = 25
compileSdkVersion = 26 compileSdkVersion = 26
buildToolsVersion = '26.0.2' buildToolsVersion = '28.0.3'
sourceCompatibilityVersion = JavaVersion.VERSION_1_7 sourceCompatibilityVersion = JavaVersion.VERSION_1_7
targetCompatibilityVersion = JavaVersion.VERSION_1_7 targetCompatibilityVersion = JavaVersion.VERSION_1_7
} }

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,10 +1,7 @@
#!/bin/sh #!/bin/sh
#
# Copyright (c) Facebook, Inc. and its affiliates. # Copyright (c) Facebook, Inc. and its affiliates.
# #
# This source code is licensed under the MIT license found in the # This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree. # LICENSE file in the root directory of this source tree.
#
./csharp/Mac/Facebook.Yoga.Mac.Tests/bin/Release/Facebook.Yoga.Mac.Tests.app/Contents/MacOS/Facebook.Yoga.Mac.Tests ./csharp/Mac/Facebook.Yoga.Mac.Tests/bin/Release/Facebook.Yoga.Mac.Tests.app/Contents/MacOS/Facebook.Yoga.Mac.Tests

View File

@@ -1,3 +1,10 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
using System; using System;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Facebook.Yoga; using Facebook.Yoga;

View File

@@ -1,18 +1,20 @@
/* /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#include "YGInterop.h" #include "YGInterop.h"
static YGInteropLogger gManagedLogger; static YGInteropLogger gManagedLogger;
static int unmanagedLogger(const YGConfigRef config, static int unmanagedLogger(
const YGNodeRef node, const YGConfigRef config,
YGLogLevel level, const YGNodeRef node,
const char *format, YGLogLevel level,
va_list args) { const char* format,
va_list args) {
int result = 0; int result = 0;
if (gManagedLogger) { if (gManagedLogger) {
char message[8192]; char message[8192];

View File

@@ -1,19 +1,21 @@
/* /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#pragma once #pragma once
#include <yoga/Yoga.h> #include <yoga/Yoga.h>
YG_EXTERN_C_BEGIN YG_EXTERN_C_BEGIN
typedef int (*YGInteropLogger)(const void *unmanagedConfigPtr, typedef int (*YGInteropLogger)(
const void *unmanagedNodePtr, const void* unmanagedConfigPtr,
YGLogLevel level, const void* unmanagedNodePtr,
const char *message); YGLogLevel level,
const char* message);
WIN_EXPORT YGConfigRef YGConfigGetDefault(); WIN_EXPORT YGConfigRef YGConfigGetDefault();

View File

@@ -1,13 +1,15 @@
/* /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
// dllmain.cpp : Defines the entry point for the DLL application. // dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h" #include "stdafx.h"
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { BOOL APIENTRY
DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) { switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:

View File

@@ -1,9 +1,10 @@
/* /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
//{{NO_DEPENDENCIES}} //{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file. // Microsoft Visual C++ generated include file.
// Used by Yoga.rc // Used by Yoga.rc

View File

@@ -1,9 +1,10 @@
/* /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
// stdafx.cpp : source file that includes just the standard includes // stdafx.cpp : source file that includes just the standard includes
// Yoga.pch will be the pre-compiled header // Yoga.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information // stdafx.obj will contain the pre-compiled type information

View File

@@ -1,9 +1,10 @@
/* /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
// stdafx.h : include file for standard system include files, // stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but // or project specific include files that are used frequently, but
// are changed infrequently // are changed infrequently

View File

@@ -1,14 +1,16 @@
/* /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#pragma once #pragma once
// Including SDKDDKVer.h defines the highest available Windows platform. // Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and // If you wish to build your application for a previous Windows platform,
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. // include WinSDKVer.h and set the _WIN32_WINNT macro to the platform you wish
// to support before including SDKDDKVer.h.
#include <SDKDDKVer.h> #include <SDKDDKVer.h>

View File

@@ -1,11 +1,8 @@
#!/bin/sh #!/bin/sh
#
# Copyright (c) Facebook, Inc. and its affiliates. # Copyright (c) Facebook, Inc. and its affiliates.
# #
# This source code is licensed under the MIT license found in the # This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree. # LICENSE file in the root directory of this source tree.
#
cd `dirname "$0"` cd `dirname "$0"`
echo $ANDROID_SDK echo $ANDROID_SDK

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the

View File

@@ -1,4 +1,9 @@
#!/bin/sh #!/bin/sh
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
if mcs --version >/dev/null 2>&1 && mono --version >/dev/null 2>&1; then true; else if mcs --version >/dev/null 2>&1 && mono --version >/dev/null 2>&1; then true; else
echo "ERROR: Need to install Mono (brew install mono, or http://www.mono-project.com/download/)" echo "ERROR: Need to install Mono (brew install mono, or http://www.mono-project.com/download/)"
exit 1 exit 1

View File

@@ -150,3 +150,13 @@
<div style="flex: 1; margin-left:auto;"></div> <div style="flex: 1; margin-left:auto;"></div>
<div style="width: 50px; height: 50px;"></div> <div style="width: 50px; height: 50px;"></div>
</div> </div>
<div id="margin_top_auto_overflow_parent" style="flex-direction:column; height: 500px; width: 20px;">
<div style="height: 300px;"></div>
<div style="margin-top: auto; height: 300px;"></div>
</div>
<div id="margin_bottom_auto_overflow_parent" style="flex-direction:column; height: 500px; width: 20px;">
<div style="height: 300px;"></div>
<div style="margin-top: auto; height: 300px;"></div>
</div>

View File

@@ -72,7 +72,7 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, {
this.push('public void test_' + name + '() {'); this.push('public void test_' + name + '() {');
this.pushIndent(); this.pushIndent();
this.push("YogaConfig config = new YogaConfig();") this.push("YogaConfig config = YogaConfigFactory.create();")
for (var i in experiments) { for (var i in experiments) {
this.push('config.setExperimentalFeatureEnabled(YogaExperimentalFeature.' + toJavaUpper(experiments[i]) +', true);'); this.push('config.setExperimentalFeatureEnabled(YogaExperimentalFeature.' + toJavaUpper(experiments[i]) +', true);');
} }

View File

@@ -1,4 +1,8 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
require 'watir' require 'watir'
require 'fileutils' require 'fileutils'

View File

@@ -9,7 +9,7 @@
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
VERSION_NAME=1.16.0 VERSION_NAME=1.16.0-SNAPSHOT
POM_URL=https://github.com/facebook/yoga POM_URL=https://github.com/facebook/yoga
POM_SCM_URL=https://github.com/facebook/yoga.git POM_SCM_URL=https://github.com/facebook/yoga.git
POM_SCM_CONNECTION=scm:git:https://github.com/facebook/yoga.git POM_SCM_CONNECTION=scm:git:https://github.com/facebook/yoga.git

View File

@@ -1,3 +1,10 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// Configure the Android maven publication // Configure the Android maven publication
apply plugin: 'com.github.dcendents.android-maven' apply plugin: 'com.github.dcendents.android-maven'

View File

@@ -1,3 +1,10 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// Android tasks for Javadoc and sources.jar generation // Android tasks for Javadoc and sources.jar generation
afterEvaluate { project -> afterEvaluate { project ->

View File

@@ -1,3 +1,10 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// Upload to Bintray // Upload to Bintray
apply plugin: 'com.jfrog.bintray' apply plugin: 'com.jfrog.bintray'

View File

@@ -1,3 +1,10 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// Set up everything required for releasing on Bintray // Set up everything required for releasing on Bintray
ext { ext {
bintrayRepo = 'maven' bintrayRepo = 'maven'

View File

@@ -1,3 +1,10 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// Common Android tasks for all releases that generate Javadocs, sources, etc. // Common Android tasks for all releases that generate Javadocs, sources, etc.
apply from: rootProject.file('gradle/android-tasks.gradle') apply from: rootProject.file('gradle/android-tasks.gradle')

View File

@@ -3,13 +3,31 @@
# This source code is licensed under the MIT license found in the # This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree. # LICENSE file in the root directory of this source tree.
load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID", "CXX_LIBRARY_WHITELIST", "FBJNI_JAVA_TARGET", "FBJNI_TARGET", "INFER_ANNOTATIONS_TARGET", "JNI_TARGET", "JSR_305_TARGET", "JUNIT_TARGET", "PROGRUARD_ANNOTATIONS_TARGET", "SOLOADER_TARGET", "yoga_cxx_lib", "yoga_cxx_library", "yoga_dep", "yoga_java_binary", "yoga_java_library", "yoga_java_test") load("//tools/build_defs/oss:yoga_defs.bzl", "ANDROID", "CXX_LIBRARY_WHITELIST", "JNI_TARGET", "JSR_305_TARGET", "JUNIT_TARGET", "PROGUARD_ANNOTATIONS_TARGET", "SOLOADER_TARGET", "YOGA_ROOTS", "yoga_cxx_lib", "yoga_cxx_library", "yoga_dep", "yoga_java_binary", "yoga_java_library", "yoga_java_test", "yoga_prebuilt_cxx_library")
CXX_LIBRARY_WHITELIST_FOR_TESTS = CXX_LIBRARY_WHITELIST + [ CXX_LIBRARY_WHITELIST_FOR_TESTS = CXX_LIBRARY_WHITELIST + [
yoga_cxx_lib("testutil:jni"), yoga_cxx_lib("testutil:jni"),
yoga_cxx_lib("testutil:testutil"), yoga_cxx_lib("testutil:testutil-jni"),
] ]
YOGA_JAVA_IMPLEMENTATION_FILES = [
"com/facebook/yoga/*JNI*.java",
"com/facebook/yoga/*Factory.java",
"com/facebook/yoga/YogaNative.java",
]
yoga_prebuilt_cxx_library(
name = "ndklog",
exported_platform_linker_flags = [
(
"^android.*",
["-llog"],
),
],
header_only = True,
visibility = YOGA_ROOTS,
)
yoga_cxx_library( yoga_cxx_library(
name = "jni", name = "jni",
srcs = glob(["jni/*.cpp"]), srcs = glob(["jni/*.cpp"]),
@@ -19,6 +37,9 @@ yoga_cxx_library(
compiler_flags = [ compiler_flags = [
"-fno-omit-frame-pointer", "-fno-omit-frame-pointer",
"-fexceptions", "-fexceptions",
"-fvisibility=hidden",
"-ffunction-sections",
"-fdata-sections",
"-fPIC", "-fPIC",
"-Wall", "-Wall",
"-Werror", "-Werror",
@@ -32,15 +53,45 @@ yoga_cxx_library(
soname = "libyoga.$(ext)", soname = "libyoga.$(ext)",
visibility = ["PUBLIC"], visibility = ["PUBLIC"],
deps = [ deps = [
FBJNI_TARGET,
JNI_TARGET, JNI_TARGET,
yoga_dep(":yoga"), yoga_dep(":yoga-static"),
":ndklog",
],
)
yoga_java_library(
name = "java-interface",
srcs = glob(
["com/facebook/yoga/*.java"],
exclude = YOGA_JAVA_IMPLEMENTATION_FILES,
),
required_for_source_only_abi = True,
source = "1.7",
target = "1.7",
visibility = ["PUBLIC"],
deps = [
JSR_305_TARGET,
PROGUARD_ANNOTATIONS_TARGET,
],
)
yoga_java_library(
name = "java-impl",
srcs = glob(YOGA_JAVA_IMPLEMENTATION_FILES),
required_for_source_only_abi = True,
source = "1.7",
target = "1.7",
deps = [
":java-interface",
":jni",
JSR_305_TARGET,
PROGUARD_ANNOTATIONS_TARGET,
SOLOADER_TARGET,
], ],
) )
yoga_java_library( yoga_java_library(
name = "java", name = "java",
srcs = glob(["com/facebook/yoga/*.java"]),
required_for_source_only_abi = True, required_for_source_only_abi = True,
source = "1.7", source = "1.7",
target = "1.7", target = "1.7",
@@ -48,13 +99,9 @@ yoga_java_library(
yoga_dep("java:tests"), yoga_dep("java:tests"),
], ],
visibility = ["PUBLIC"], visibility = ["PUBLIC"],
deps = [ exported_deps = [
":jni", ":java-impl",
FBJNI_JAVA_TARGET, ":java-interface",
INFER_ANNOTATIONS_TARGET,
JSR_305_TARGET,
PROGRUARD_ANNOTATIONS_TARGET,
SOLOADER_TARGET,
], ],
) )
@@ -75,6 +122,5 @@ yoga_java_binary(
name = "yoga", name = "yoga",
deps = [ deps = [
":java", ":java",
FBJNI_JAVA_TARGET,
], ],
) )

View File

@@ -1,38 +1,40 @@
#
# Copyright (c) Facebook, Inc. and its affiliates. # Copyright (c) Facebook, Inc. and its affiliates.
# #
# This source code is licensed under the MIT license found in the # This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree. # LICENSE file in the root directory of this source tree.
#
cmake_minimum_required(VERSION 3.4.1) cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_VERBOSE_MAKEFILE on) set(CMAKE_VERBOSE_MAKEFILE on)
# configure import libs # configure import libs
set(libfb_DIR ${CMAKE_SOURCE_DIR}/../lib/fb/src/main/cpp)
set(yogacore_DIR ${CMAKE_SOURCE_DIR}/..) set(yogacore_DIR ${CMAKE_SOURCE_DIR}/..)
set(build_DIR ${CMAKE_SOURCE_DIR}/build) set(build_DIR ${CMAKE_SOURCE_DIR}/build)
set(libfb_build_DIR ${build_DIR}/libfb/${ANDROID_ABI})
set(yogacore_build_DIR ${build_DIR}/yogacore/${ANDROID_ABI}) set(yogacore_build_DIR ${build_DIR}/yogacore/${ANDROID_ABI})
file(MAKE_DIRECTORY ${build_DIR}) file(MAKE_DIRECTORY ${build_DIR})
add_subdirectory(${libfb_DIR} ${libfb_build_DIR})
add_subdirectory(${yogacore_DIR} ${yogacore_build_DIR}) add_subdirectory(${yogacore_DIR} ${yogacore_build_DIR})
add_compile_options( add_compile_options(
-fno-omit-frame-pointer -fno-omit-frame-pointer
-fexceptions -fexceptions
-fvisibility=hidden
-ffunction-sections
-fdata-sections
-Wall -Wall
-std=c++11) -std=c++11)
add_library(yoga SHARED jni/YGJNI.cpp jni/YGJTypes.cpp) file(GLOB jni_SRC
jni/*.cpp)
file(GLOB yogajni_version_script
yogajni.version)
add_library(yoga SHARED ${jni_SRC})
target_include_directories(yoga PRIVATE target_include_directories(yoga PRIVATE
${libfb_DIR}/include
${yogacore_DIR}) ${yogacore_DIR})
target_link_libraries(yoga yogacore fb) target_link_libraries(yoga -Wl,--gc-sections,--version-script=${yogajni_version_script} yogacore)

View File

@@ -1,4 +1,4 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
@@ -58,11 +58,11 @@ android {
} }
dependencies { dependencies {
compileOnly 'com.google.code.findbugs:jsr305:3.0.1' implementation 'com.google.code.findbugs:jsr305:3.0.1'
compileOnly project(':yoga:proguard-annotations') implementation project(':yoga:proguard-annotations')
implementation 'com.facebook.soloader:soloader:0.5.1' implementation 'com.facebook.soloader:soloader:0.5.1'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
testCompile project(':testutil') testImplementation project(':testutil')
} }
task sourcesJar(type: Jar) { task sourcesJar(type: Jar) {

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.yoga; package com.facebook.yoga;
public enum LayoutPassReason { public enum LayoutPassReason {

View File

@@ -1,14 +1,12 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.yoga; package com.facebook.yoga;
import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip
public enum YogaAlign { public enum YogaAlign {
AUTO(0), AUTO(0),
FLEX_START(1), FLEX_START(1),

View File

@@ -1,19 +1,16 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.yoga; package com.facebook.yoga;
import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip
public interface YogaBaselineFunction { public interface YogaBaselineFunction {
/** /**
* Return the baseline of the node in points. When no baseline function is set the baseline * Return the baseline of the node in points. When no baseline function is set the baseline
* default to the computed height of the node. * default to the computed height of the node.
*/ */
@DoNotStrip
float baseline(YogaNode node, float width, float height); float baseline(YogaNode node, float width, float height);
} }

View File

@@ -1,79 +1,41 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.yoga; package com.facebook.yoga;
import com.facebook.soloader.SoLoader; public abstract class YogaConfig {
public class YogaConfig {
public static int SPACING_TYPE = 1; public static int SPACING_TYPE = 1;
long mNativePointer; public abstract void setExperimentalFeatureEnabled(YogaExperimentalFeature feature, boolean enabled);
private YogaLogger mLogger;
private YogaNodeCloneFunction mYogaNodeCloneFunction;
public YogaConfig() { public abstract void setUseWebDefaults(boolean useWebDefaults);
mNativePointer = YogaNative.jni_YGConfigNew();
if (mNativePointer == 0) {
throw new IllegalStateException("Failed to allocate native memory");
}
}
@Override public abstract void setPrintTreeFlag(boolean enable);
protected void finalize() throws Throwable {
try {
YogaNative.jni_YGConfigFree(mNativePointer);
} finally {
super.finalize();
}
}
public void setExperimentalFeatureEnabled(YogaExperimentalFeature feature, boolean enabled) {
YogaNative.jni_YGConfigSetExperimentalFeatureEnabled(mNativePointer, feature.intValue(), enabled);
}
public void setUseWebDefaults(boolean useWebDefaults) {
YogaNative.jni_YGConfigSetUseWebDefaults(mNativePointer, useWebDefaults);
}
public void setPrintTreeFlag(boolean enable) {
YogaNative.jni_YGConfigSetPrintTreeFlag(mNativePointer, enable);
}
public void setPointScaleFactor(float pixelsInPoint) {
YogaNative.jni_YGConfigSetPointScaleFactor(mNativePointer, pixelsInPoint);
}
public abstract void setPointScaleFactor(float pixelsInPoint);
/** /**
* Yoga previously had an error where containers would take the maximum space possible instead of the minimum * Yoga previously had an error where containers would take the maximum space possible instead of the minimum
* like they are supposed to. In practice this resulted in implicit behaviour similar to align-self: stretch; * like they are supposed to. In practice this resulted in implicit behaviour similar to align-self: stretch;
* Because this was such a long-standing bug we must allow legacy users to switch back to this behaviour. * Because this was such a long-standing bug we must allow legacy users to switch back to this behaviour.
*/ */
public void setUseLegacyStretchBehaviour(boolean useLegacyStretchBehaviour) { public abstract void setUseLegacyStretchBehaviour(boolean useLegacyStretchBehaviour);
YogaNative.jni_YGConfigSetUseLegacyStretchBehaviour(mNativePointer, useLegacyStretchBehaviour);
}
/** /**
* If this flag is set then yoga would diff the layout without legacy flag and would set a bool in * If this flag is set then yoga would diff the layout without legacy flag and would set a bool in
* YogaNode(mDoesLegacyStretchFlagAffectsLayout) with true if the layouts were different and false * YogaNode(mDoesLegacyStretchFlagAffectsLayout) with true if the layouts were different and false
* if not * if not
*/ */
public void setShouldDiffLayoutWithoutLegacyStretchBehaviour( public abstract void setShouldDiffLayoutWithoutLegacyStretchBehaviour(
boolean shouldDiffLayoutWithoutLegacyStretchBehaviour) { boolean shouldDiffLayoutWithoutLegacyStretchBehaviour);
YogaNative.jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
mNativePointer, shouldDiffLayoutWithoutLegacyStretchBehaviour);
}
public void setLogger(YogaLogger logger) { public abstract void setLogger(YogaLogger logger);
mLogger = logger;
YogaNative.jni_YGConfigSetLogger(mNativePointer, logger);
}
public YogaLogger getLogger() { public abstract YogaLogger getLogger();
return mLogger;
} abstract long getNativePointer();
} }

View File

@@ -1,7 +1,14 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.yoga; package com.facebook.yoga;
public abstract class YogaConfigFactory { public abstract class YogaConfigFactory {
public static YogaConfig create() { public static YogaConfig create() {
return new YogaConfig(); return new YogaConfigJNIFinalizer();
} }
} }

View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.yoga;
public abstract class YogaConfigJNIBase extends YogaConfig {
long mNativePointer;
private YogaLogger mLogger;
private YogaConfigJNIBase(long nativePointer) {
if (nativePointer == 0) {
throw new IllegalStateException("Failed to allocate native memory");
}
mNativePointer = nativePointer;
}
YogaConfigJNIBase() {
this(YogaNative.jni_YGConfigNewJNI());
}
YogaConfigJNIBase(boolean useVanillaJNI) {
this(YogaNative.jni_YGConfigNewJNI());
}
public void setExperimentalFeatureEnabled(YogaExperimentalFeature feature, boolean enabled) {
YogaNative.jni_YGConfigSetExperimentalFeatureEnabledJNI(mNativePointer, feature.intValue(), enabled);
}
public void setUseWebDefaults(boolean useWebDefaults) {
YogaNative.jni_YGConfigSetUseWebDefaultsJNI(mNativePointer, useWebDefaults);
}
public void setPrintTreeFlag(boolean enable) {
YogaNative.jni_YGConfigSetPrintTreeFlagJNI(mNativePointer, enable);
}
public void setPointScaleFactor(float pixelsInPoint) {
YogaNative.jni_YGConfigSetPointScaleFactorJNI(mNativePointer, pixelsInPoint);
}
/**
* Yoga previously had an error where containers would take the maximum space possible instead of the minimum
* like they are supposed to. In practice this resulted in implicit behaviour similar to align-self: stretch;
* Because this was such a long-standing bug we must allow legacy users to switch back to this behaviour.
*/
public void setUseLegacyStretchBehaviour(boolean useLegacyStretchBehaviour) {
YogaNative.jni_YGConfigSetUseLegacyStretchBehaviourJNI(mNativePointer, useLegacyStretchBehaviour);
}
/**
* If this flag is set then yoga would diff the layout without legacy flag and would set a bool in
* YogaNode(mDoesLegacyStretchFlagAffectsLayout) with true if the layouts were different and false
* if not
*/
public void setShouldDiffLayoutWithoutLegacyStretchBehaviour(
boolean shouldDiffLayoutWithoutLegacyStretchBehaviour) {
YogaNative.jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviourJNI(
mNativePointer, shouldDiffLayoutWithoutLegacyStretchBehaviour);
}
public void setLogger(YogaLogger logger) {
mLogger = logger;
YogaNative.jni_YGConfigSetLoggerJNI(mNativePointer, logger);
}
public YogaLogger getLogger() {
return mLogger;
}
long getNativePointer() {
return mNativePointer;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.yoga;
public class YogaConfigJNIFinalizer extends YogaConfigJNIBase {
public YogaConfigJNIFinalizer() {
super();
}
@Override
protected void finalize() throws Throwable {
try {
freeNatives();
} finally {
super.finalize();
}
}
public void freeNatives() {
if (mNativePointer != 0) {
long nativePointer = mNativePointer;
mNativePointer = 0;
YogaNative.jni_YGConfigFreeJNI(nativePointer);
}
}
}

View File

@@ -1,9 +1,10 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.yoga; package com.facebook.yoga;
public class YogaConstants { public class YogaConstants {

View File

@@ -1,14 +1,12 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.yoga; package com.facebook.yoga;
import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip
public enum YogaDimension { public enum YogaDimension {
WIDTH(0), WIDTH(0),
HEIGHT(1); HEIGHT(1);

View File

@@ -1,14 +1,12 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.yoga; package com.facebook.yoga;
import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip
public enum YogaDirection { public enum YogaDirection {
INHERIT(0), INHERIT(0),
LTR(1), LTR(1),

View File

@@ -1,14 +1,12 @@
/** /*
* Copyright (c) Facebook, Inc. and its affiliates. * Copyright (c) Facebook, Inc. and its affiliates.
* *
* This source code is licensed under the MIT license found in the LICENSE * This source code is licensed under the MIT license found in the
* file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.facebook.yoga; package com.facebook.yoga;
import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip
public enum YogaDisplay { public enum YogaDisplay {
FLEX(0), FLEX(0),
NONE(1); NONE(1);

Some files were not shown because too many files have changed in this diff Show More