diff --git a/CSSLayout/CSSLayout.c b/CSSLayout/CSSLayout.c index dd38a20c..461bb78b 100644 --- a/CSSLayout/CSSLayout.c +++ b/CSSLayout/CSSLayout.c @@ -341,6 +341,13 @@ bool CSSNodeIsDirty(const CSSNodeRef node) { return node->isDirty; } +void CSSNodeCopyStyle(const CSSNodeRef dstNode, const CSSNodeRef srcNode) { + if (memcmp(&dstNode->style, &srcNode->style, sizeof(CSSStyle)) != 0) { + memcpy(&dstNode->style, &srcNode->style, sizeof(CSSStyle)); + _CSSNodeMarkDirty(dstNode); + } +} + inline float CSSNodeStyleGetFlexGrow(CSSNodeRef node) { if (!CSSValueIsUndefined(node->style.flexGrow)) { return node->style.flexGrow; diff --git a/CSSLayout/CSSLayout.h b/CSSLayout/CSSLayout.h index 07a8f6ec..8e28e4f7 100644 --- a/CSSLayout/CSSLayout.h +++ b/CSSLayout/CSSLayout.h @@ -98,6 +98,8 @@ WIN_EXPORT bool CSSNodeCanUseCachedMeasurement(const CSSMeasureMode widthMode, const float marginRow, const float marginColumn); +WIN_EXPORT void CSSNodeCopyStyle(const CSSNodeRef dstNode, const CSSNodeRef srcNode); + #define CSS_NODE_PROPERTY(type, name, paramName) \ WIN_EXPORT void CSSNodeSet##name(const CSSNodeRef node, type paramName); \ WIN_EXPORT type CSSNodeGet##name(const CSSNodeRef node); diff --git a/tests/CSSLayoutStyleTest.cpp b/tests/CSSLayoutStyleTest.cpp new file mode 100644 index 00000000..6b7579af --- /dev/null +++ b/tests/CSSLayoutStyleTest.cpp @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include +#include + +TEST(CSSLayoutTest, copy_style_same) { + const CSSNodeRef node0 = CSSNodeNew(); + const CSSNodeRef node1 = CSSNodeNew(); + ASSERT_FALSE(CSSNodeIsDirty(node0)); + + CSSNodeCopyStyle(node0, node1); + ASSERT_FALSE(CSSNodeIsDirty(node0)); + + CSSNodeFree(node0); + CSSNodeFree(node1); +} + +TEST(CSSLayoutTest, copy_style_modified) { + const CSSNodeRef node0 = CSSNodeNew(); + ASSERT_FALSE(CSSNodeIsDirty(node0)); + ASSERT_EQ(CSSFlexDirectionColumn, CSSNodeStyleGetFlexDirection(node0)); + ASSERT_TRUE(CSSValueIsUndefined(CSSNodeStyleGetMaxHeight(node0))); + + const CSSNodeRef node1 = CSSNodeNew(); + CSSNodeStyleSetFlexDirection(node1, CSSFlexDirectionRow); + CSSNodeStyleSetMaxHeight(node1, 10); + + CSSNodeCopyStyle(node0, node1); + ASSERT_TRUE(CSSNodeIsDirty(node0)); + ASSERT_EQ(CSSFlexDirectionRow, CSSNodeStyleGetFlexDirection(node0)); + ASSERT_EQ(10, CSSNodeStyleGetMaxHeight(node0)); + + CSSNodeFree(node0); + CSSNodeFree(node1); +} + +TEST(CSSLayoutTest, copy_style_modified_same) { + const CSSNodeRef node0 = CSSNodeNew(); + CSSNodeStyleSetFlexDirection(node0, CSSFlexDirectionRow); + CSSNodeStyleSetMaxHeight(node0, 10); + CSSNodeCalculateLayout(node0, CSSUndefined, CSSUndefined, CSSDirectionLTR); + ASSERT_FALSE(CSSNodeIsDirty(node0)); + + const CSSNodeRef node1 = CSSNodeNew(); + CSSNodeStyleSetFlexDirection(node1, CSSFlexDirectionRow); + CSSNodeStyleSetMaxHeight(node1, 10); + + CSSNodeCopyStyle(node0, node1); + ASSERT_FALSE(CSSNodeIsDirty(node0)); + + CSSNodeFree(node0); + CSSNodeFree(node1); +}