From 6ee0c5817cc4eac6e36d19a91e5639164dfe98ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Oghin=C4=83?= Date: Thu, 20 Nov 2014 17:28:54 +0000 Subject: [PATCH] Add support for marginVertical and marginHorizontal * implement margin as an array of values * apply margins with the correct priority (e.g. left, horizontal, all) * update transpiler & tests --- src/JavaTranspiler.js | 9 +- .../src/com/facebook/csslayout/CSSNode.java | 65 ++++++--- .../src/com/facebook/csslayout/CSSStyle.java | 10 +- .../com/facebook/csslayout/LayoutEngine.java | 8 +- .../facebook/csslayout/LayoutCachingTest.java | 2 +- .../facebook/csslayout/LayoutEngineTest.java | 126 +++++++++--------- 6 files changed, 124 insertions(+), 96 deletions(-) diff --git a/src/JavaTranspiler.js b/src/JavaTranspiler.js index 2769e346..83306327 100644 --- a/src/JavaTranspiler.js +++ b/src/JavaTranspiler.js @@ -54,17 +54,22 @@ function __transpileSingleTestToJava(code) { return 'layout.' + (match1 == 'TOP' ? 'y' : 'x'); }) .replace( // style.position[CSS_TOP] => style.positionTop - /style\.(position|margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]/g, + /style\.(position|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]/g, function (str, match1, match2) { return 'style.' + match1 + match2[0] + match2.substring(1).toLowerCase(); }) + .replace( // style.margin[CSS_TOP] => style.margin[CSSStyle.SPACING_TOP] + /style\.(margin)\[CSS_(TOP|BOTTOM|LEFT|RIGHT)\]/g, + function (str, match1, match2) { + return 'style.' + match1 + '[CSSStyle.SPACING_' + match2 + ']'; + }) .replace(/get_child\(.*context\,\s([^\)]+)\)/g, 'getChildAt($1)') .replace(/init_css_node_children/g, 'addChildren') .replace(/css_node_t(\s)\*/g, 'TestCSSNode$1') .replace(/\->/g, '.') .replace(/(\d+\.\d+)/g, '$1f') .replace( // style.flex_direction => style.flexDirection - /style\.([^_\s]+)_(\w)(\w+)/g, + /style\.([^_\[\]\s]+)_(\w)(\w+)/g, function (str, match1, match2, match3) { return 'style.' + match1 + match2.toUpperCase() + match3; }) diff --git a/src/java/src/com/facebook/csslayout/CSSNode.java b/src/java/src/com/facebook/csslayout/CSSNode.java index d2fbefc1..0a08107e 100644 --- a/src/java/src/com/facebook/csslayout/CSSNode.java +++ b/src/java/src/com/facebook/csslayout/CSSNode.java @@ -35,6 +35,24 @@ public class CSSNode { UP_TO_DATE, } + public static final int SPACING_ALL = 0; + public static final int SPACING_VERTICAL = 1; + public static final int SPACING_HORIZONTAL = 2; + public static final int SPACING_LEFT = 3; + public static final int SPACING_RIGHT = 4; + public static final int SPACING_TOP = 5; + public static final int SPACING_BOTTOM = 6; + + private final float[] mMargin = new float[] { + Float.NaN, + Float.NaN, + Float.NaN, + Float.NaN, + Float.NaN, + Float.NaN, + Float.NaN + }; + // Only one copy kept around to keep from allocating a bunch of MeasureOutput objects // NOT THREAD SAFE! NOT RE-ENTRANT SAFE! private static final MeasureOutput MEASURE_OUTPUT = new MeasureOutput(); @@ -243,30 +261,33 @@ public class CSSNode { } } - public void setMarginTop(float marginTop) { - if (!valuesEqual(style.marginTop, marginTop)) { - style.marginTop = marginTop; - dirty(); - } + public void setMargin(int spacingType, float margin) { + setSpacing(mMargin, spacingType, margin, style.margin); } - public void setMarginBottom(float marginBottom) { - if (!valuesEqual(style.marginBottom, marginBottom)) { - style.marginBottom = marginBottom; - dirty(); - } - } - - public void setMarginLeft(float marginLeft) { - if (!valuesEqual(style.marginLeft, marginLeft)) { - style.marginLeft = marginLeft; - dirty(); - } - } - - public void setMarginRight(float marginRight) { - if (!valuesEqual(style.marginRight, marginRight)) { - style.marginRight = marginRight; + protected void setSpacing(float[] spacingDef, int spacingType, float spacing, float[] cssStyle) { + if (!valuesEqual(spacingDef[spacingType], spacing)) { + spacingDef[spacingType] = spacing; + cssStyle[CSSStyle.SPACING_TOP] = + !Float.isNaN(spacingDef[SPACING_TOP]) ? spacingDef[SPACING_TOP] + : !Float.isNaN(spacingDef[SPACING_VERTICAL]) ? spacingDef[SPACING_VERTICAL] + : !Float.isNaN(spacingDef[SPACING_ALL]) ? spacingDef[SPACING_ALL] + : 0; + cssStyle[CSSStyle.SPACING_BOTTOM] = + !Float.isNaN(spacingDef[SPACING_BOTTOM]) ? spacingDef[SPACING_BOTTOM] + : !Float.isNaN(spacingDef[SPACING_VERTICAL]) ? spacingDef[SPACING_VERTICAL] + : !Float.isNaN(spacingDef[SPACING_ALL]) ? spacingDef[SPACING_ALL] + : 0; + cssStyle[CSSStyle.SPACING_LEFT] = + !Float.isNaN(spacingDef[SPACING_LEFT]) ? spacingDef[SPACING_LEFT] + : !Float.isNaN(spacingDef[SPACING_HORIZONTAL]) ? spacingDef[SPACING_HORIZONTAL] + : !Float.isNaN(spacingDef[SPACING_ALL]) ? spacingDef[SPACING_ALL] + : 0; + cssStyle[CSSStyle.SPACING_RIGHT] = + !Float.isNaN(spacingDef[SPACING_RIGHT]) ? spacingDef[SPACING_RIGHT] + : !Float.isNaN(spacingDef[SPACING_HORIZONTAL]) ? spacingDef[SPACING_HORIZONTAL] + : !Float.isNaN(spacingDef[SPACING_ALL]) ? spacingDef[SPACING_ALL] + : 0; dirty(); } } diff --git a/src/java/src/com/facebook/csslayout/CSSStyle.java b/src/java/src/com/facebook/csslayout/CSSStyle.java index 2c21caba..e359a04c 100644 --- a/src/java/src/com/facebook/csslayout/CSSStyle.java +++ b/src/java/src/com/facebook/csslayout/CSSStyle.java @@ -13,6 +13,11 @@ package com.facebook.csslayout; */ public class CSSStyle { + public static final int SPACING_TOP = 0; + public static final int SPACING_RIGHT = 1; + public static final int SPACING_BOTTOM = 2; + public static final int SPACING_LEFT = 3; + public CSSFlexDirection flexDirection = CSSFlexDirection.COLUMN; public CSSJustify justifyContent = CSSJustify.FLEX_START; public CSSAlign alignItems = CSSAlign.STRETCH; @@ -20,10 +25,7 @@ public class CSSStyle { public CSSPositionType positionType = CSSPositionType.RELATIVE; public float flex; - public float marginTop; - public float marginBottom; - public float marginLeft; - public float marginRight; + public float[] margin = new float[4]; public float paddingTop; public float paddingBottom; diff --git a/src/java/src/com/facebook/csslayout/LayoutEngine.java b/src/java/src/com/facebook/csslayout/LayoutEngine.java index 18c5871b..f4ce5629 100644 --- a/src/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/src/java/src/com/facebook/csslayout/LayoutEngine.java @@ -131,13 +131,13 @@ public class LayoutEngine { private static float getMargin(CSSNode node, PositionIndex position) { switch (position) { case TOP: - return node.style.marginTop; + return node.style.margin[CSSStyle.SPACING_TOP]; case BOTTOM: - return node.style.marginBottom; + return node.style.margin[CSSStyle.SPACING_BOTTOM]; case LEFT: - return node.style.marginLeft; + return node.style.margin[CSSStyle.SPACING_LEFT]; case RIGHT: - return node.style.marginRight; + return node.style.margin[CSSStyle.SPACING_RIGHT]; default: throw new RuntimeException("Someone added a new cardinal direction..."); } diff --git a/src/java/tests/com/facebook/csslayout/LayoutCachingTest.java b/src/java/tests/com/facebook/csslayout/LayoutCachingTest.java index 9bda0200..9f0103ec 100644 --- a/src/java/tests/com/facebook/csslayout/LayoutCachingTest.java +++ b/src/java/tests/com/facebook/csslayout/LayoutCachingTest.java @@ -114,7 +114,7 @@ public class LayoutCachingTest { root.calculateLayout(); markLayoutAppliedForTree(root); - c1.setMarginLeft(10); + c1.setMargin(CSSNode.SPACING_LEFT, 10); root.calculateLayout(); assertTrue(root.hasNewLayout()); diff --git a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java index d2e7fdc0..b69e51a8 100644 --- a/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java +++ b/src/java/tests/com/facebook/csslayout/LayoutEngineTest.java @@ -242,10 +242,10 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.width = 100; node_0.style.height = 200; - node_0.style.marginLeft = 10; - node_0.style.marginTop = 10; - node_0.style.marginRight = 10; - node_0.style.marginBottom = 10; + node_0.style.margin[CSSStyle.SPACING_LEFT] = 10; + node_0.style.margin[CSSStyle.SPACING_TOP] = 10; + node_0.style.margin[CSSStyle.SPACING_RIGHT] = 10; + node_0.style.margin[CSSStyle.SPACING_BOTTOM] = 10; } TestCSSNode root_layout = new TestCSSNode(); @@ -268,34 +268,34 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.width = 1000; node_0.style.height = 1000; - node_0.style.marginLeft = 10; - node_0.style.marginTop = 10; - node_0.style.marginRight = 10; - node_0.style.marginBottom = 10; + node_0.style.margin[CSSStyle.SPACING_LEFT] = 10; + node_0.style.margin[CSSStyle.SPACING_TOP] = 10; + node_0.style.margin[CSSStyle.SPACING_RIGHT] = 10; + node_0.style.margin[CSSStyle.SPACING_BOTTOM] = 10; addChildren(node_0, 3); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.marginLeft = 50; - node_1.style.marginTop = 50; - node_1.style.marginRight = 50; - node_1.style.marginBottom = 50; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 50; + node_1.style.margin[CSSStyle.SPACING_TOP] = 50; + node_1.style.margin[CSSStyle.SPACING_RIGHT] = 50; + node_1.style.margin[CSSStyle.SPACING_BOTTOM] = 50; node_1 = node_0.getChildAt(1); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.marginLeft = 25; - node_1.style.marginTop = 25; - node_1.style.marginRight = 25; - node_1.style.marginBottom = 25; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 25; + node_1.style.margin[CSSStyle.SPACING_TOP] = 25; + node_1.style.margin[CSSStyle.SPACING_RIGHT] = 25; + node_1.style.margin[CSSStyle.SPACING_BOTTOM] = 25; node_1 = node_0.getChildAt(2); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.marginLeft = 10; - node_1.style.marginTop = 10; - node_1.style.marginRight = 10; - node_1.style.marginBottom = 10; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 10; + node_1.style.margin[CSSStyle.SPACING_TOP] = 10; + node_1.style.margin[CSSStyle.SPACING_RIGHT] = 10; + node_1.style.margin[CSSStyle.SPACING_BOTTOM] = 10; } } @@ -546,21 +546,21 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.width = 1000; node_0.style.height = 1000; - node_0.style.marginLeft = 5; - node_0.style.marginTop = 10; + node_0.style.margin[CSSStyle.SPACING_LEFT] = 5; + node_0.style.margin[CSSStyle.SPACING_TOP] = 10; addChildren(node_0, 2); { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.marginLeft = 15; - node_1.style.marginTop = 50; - node_1.style.marginBottom = 20; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 15; + node_1.style.margin[CSSStyle.SPACING_TOP] = 50; + node_1.style.margin[CSSStyle.SPACING_BOTTOM] = 20; node_1 = node_0.getChildAt(1); node_1.style.width = 100; node_1.style.height = 100; - node_1.style.marginLeft = 30; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 30; } } @@ -1135,10 +1135,10 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.marginLeft = 5; - node_1.style.marginTop = 5; - node_1.style.marginRight = 5; - node_1.style.marginBottom = 5; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 5; + node_1.style.margin[CSSStyle.SPACING_TOP] = 5; + node_1.style.margin[CSSStyle.SPACING_RIGHT] = 5; + node_1.style.margin[CSSStyle.SPACING_BOTTOM] = 5; } } @@ -1239,7 +1239,7 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.marginTop = 10; + node_1.style.margin[CSSStyle.SPACING_TOP] = 10; } } @@ -1279,10 +1279,10 @@ public class LayoutEngineTest { { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.style.marginLeft = 10; - node_2.style.marginTop = 10; - node_2.style.marginRight = 10; - node_2.style.marginBottom = 10; + node_2.style.margin[CSSStyle.SPACING_LEFT] = 10; + node_2.style.margin[CSSStyle.SPACING_TOP] = 10; + node_2.style.margin[CSSStyle.SPACING_RIGHT] = 10; + node_2.style.margin[CSSStyle.SPACING_BOTTOM] = 10; node_2 = node_1.getChildAt(1); node_2.style.height = 100; } @@ -1370,7 +1370,7 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.marginLeft = 10; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 10; } } @@ -1471,10 +1471,10 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.marginLeft = 5; - node_1.style.marginTop = 5; - node_1.style.marginRight = 5; - node_1.style.marginBottom = 5; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 5; + node_1.style.margin[CSSStyle.SPACING_TOP] = 5; + node_1.style.margin[CSSStyle.SPACING_RIGHT] = 5; + node_1.style.margin[CSSStyle.SPACING_BOTTOM] = 5; } } @@ -1596,10 +1596,10 @@ public class LayoutEngineTest { { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.style.marginLeft = 16; - node_2.style.marginTop = 16; - node_2.style.marginRight = 16; - node_2.style.marginBottom = 16; + node_2.style.margin[CSSStyle.SPACING_LEFT] = 16; + node_2.style.margin[CSSStyle.SPACING_TOP] = 16; + node_2.style.margin[CSSStyle.SPACING_RIGHT] = 16; + node_2.style.margin[CSSStyle.SPACING_BOTTOM] = 16; } } } @@ -1799,7 +1799,7 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.positionType = CSSPositionType.ABSOLUTE; - node_1.style.marginRight = 15; + node_1.style.margin[CSSStyle.SPACING_RIGHT] = 15; } } @@ -2096,7 +2096,7 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.positionType = CSSPositionType.ABSOLUTE; - node_1.style.marginTop = 5; + node_1.style.margin[CSSStyle.SPACING_TOP] = 5; node_1.style.positionTop = 5; } } @@ -2133,7 +2133,7 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.positionType = CSSPositionType.ABSOLUTE; - node_1.style.marginLeft = 5; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 5; node_1.style.positionLeft = 5; } } @@ -2215,7 +2215,7 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.flex = 1; - node_1.style.marginLeft = 5; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 5; } } @@ -2300,7 +2300,7 @@ public class LayoutEngineTest { node_1.style.flex = 1; node_1 = node_0.getChildAt(1); node_1.style.flex = 1; - node_1.style.marginLeft = 5; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 5; } } @@ -2568,7 +2568,7 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.alignSelf = CSSAlign.STRETCH; - node_1.style.marginLeft = 20; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 20; node_1.style.paddingLeft = 20; node_1.style.paddingTop = 20; node_1.style.paddingRight = 20; @@ -2644,7 +2644,7 @@ public class LayoutEngineTest { { TestCSSNode node_1; node_1 = node_0.getChildAt(0); - node_1.style.marginRight = -8; + node_1.style.margin[CSSStyle.SPACING_RIGHT] = -8; } } @@ -3003,10 +3003,10 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.style.alignSelf = CSSAlign.FLEX_START; - node_1.style.marginLeft = 10; - node_1.style.marginTop = 10; - node_1.style.marginRight = 10; - node_1.style.marginBottom = 10; + node_1.style.margin[CSSStyle.SPACING_LEFT] = 10; + node_1.style.margin[CSSStyle.SPACING_TOP] = 10; + node_1.style.margin[CSSStyle.SPACING_RIGHT] = 10; + node_1.style.margin[CSSStyle.SPACING_BOTTOM] = 10; addChildren(node_1, 1); { TestCSSNode node_2; @@ -3144,10 +3144,10 @@ public class LayoutEngineTest { { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.style.marginLeft = 20; - node_2.style.marginTop = 20; - node_2.style.marginRight = 20; - node_2.style.marginBottom = 20; + node_2.style.margin[CSSStyle.SPACING_LEFT] = 20; + node_2.style.margin[CSSStyle.SPACING_TOP] = 20; + node_2.style.margin[CSSStyle.SPACING_RIGHT] = 20; + node_2.style.margin[CSSStyle.SPACING_BOTTOM] = 20; node_2.setMeasureFunction(sTestMeasureFunction); node_2.context = "loooooooooong with space"; } @@ -3199,10 +3199,10 @@ public class LayoutEngineTest { { TestCSSNode node_2; node_2 = node_1.getChildAt(0); - node_2.style.marginLeft = 20; - node_2.style.marginTop = 20; - node_2.style.marginRight = 20; - node_2.style.marginBottom = 20; + node_2.style.margin[CSSStyle.SPACING_LEFT] = 20; + node_2.style.margin[CSSStyle.SPACING_TOP] = 20; + node_2.style.margin[CSSStyle.SPACING_RIGHT] = 20; + node_2.style.margin[CSSStyle.SPACING_BOTTOM] = 20; node_2.setMeasureFunction(sTestMeasureFunction); node_2.context = "loooooooooong with space"; }