diff --git a/engine/core/dom/Element.cpp b/engine/core/dom/Element.cpp index c3b6a981518..c6452401ce2 100644 --- a/engine/core/dom/Element.cpp +++ b/engine/core/dom/Element.cpp @@ -945,6 +945,32 @@ void Element::setHeight(double height) return box->setHeight(height); } +double Element::minContentWidth() const +{ + if (RenderBox* box = renderBox()) + return box->minPreferredLogicalWidth(); + return 0; +} + +void Element::setMinContentWidth(double width) +{ + if (RenderBox* box = renderBox()) + return box->setMinPreferredLogicalWidth(width); +} + +double Element::maxContentWidth() const +{ + if (RenderBox* box = renderBox()) + return box->maxPreferredLogicalWidth(); + return 0; +} + +void Element::setMaxContentWidth(double width) +{ + if (RenderBox* box = renderBox()) + return box->setMaxPreferredLogicalWidth(width); +} + void Element::setNeedsLayout() { if (RenderBox* box = renderBox()) @@ -962,19 +988,26 @@ LayoutCallback* Element::layoutManager() const return m_layoutManager.get(); } -void Element::setLayoutManager(PassOwnPtr callback) +LayoutCallback* Element::intrinsicWidthsComputer() const +{ + return m_intrinsicWidthsComputer.get(); +} + +void Element::setLayoutManager(PassOwnPtr layoutManager, + PassOwnPtr intrinsicWidthsComputer) { bool isAlreadyCustomLayout = renderer() && renderer()->isRenderCustomLayout(); - bool requiresCustomLayout = callback; + bool requiresCustomLayout = layoutManager; if (requiresCustomLayout != isAlreadyCustomLayout) { // We don't go through the normal reattach codepaths because // those are all tied to changes to the RenderStyle. markAncestorsWithChildNeedsStyleRecalc(); detach(); - } else if (callback.get() != m_layoutManager) { + } else if (layoutManager.get() != m_layoutManager) { setNeedsLayout(); } - m_layoutManager = callback; + m_layoutManager = layoutManager; + m_intrinsicWidthsComputer = intrinsicWidthsComputer; } void Element::childrenChanged(const ChildrenChange& change) diff --git a/engine/core/dom/Element.h b/engine/core/dom/Element.h index 0ed9f01a2dc..b497c7533ec 100644 --- a/engine/core/dom/Element.h +++ b/engine/core/dom/Element.h @@ -215,11 +215,19 @@ public: double height() const; void setHeight(double); + double minContentWidth() const; + void setMinContentWidth(double); + + double maxContentWidth() const; + void setMaxContentWidth(double); + void setNeedsLayout(); void layout(); + LayoutCallback* intrinsicWidthsComputer() const; LayoutCallback* layoutManager() const; - void setLayoutManager(PassOwnPtr); + void setLayoutManager(PassOwnPtr layoutManager, + PassOwnPtr intrinsicWidthsComputer); RenderStyle* computedStyle(); @@ -370,6 +378,7 @@ private: RefPtr m_elementData; OwnPtr m_layoutManager; + OwnPtr m_intrinsicWidthsComputer; }; DEFINE_NODE_TYPE_CASTS(Element, isElementNode()); diff --git a/engine/core/dom/Element.idl b/engine/core/dom/Element.idl index 1ad2d6f9dbb..95736905098 100644 --- a/engine/core/dom/Element.idl +++ b/engine/core/dom/Element.idl @@ -20,7 +20,7 @@ void setNeedsLayout(); void layout(); - void setLayoutManager(LayoutCallback callback); + void setLayoutManager(LayoutCallback layout, LayoutCallback computeIntrinsicWidths); // TODO(abarth): Move to Node. readonly attribute CSSStyleDeclaration style; @@ -48,4 +48,6 @@ attribute double y; attribute double width; attribute double height; + attribute double minContentWidth; // Intrinsic width if all wrappable points wrap. + attribute double maxContentWidth; // Intrinsic width if no wrappable points wrap. }; diff --git a/engine/core/rendering/RenderBox.cpp b/engine/core/rendering/RenderBox.cpp index 2b0716e0eae..59acacea1dc 100644 --- a/engine/core/rendering/RenderBox.cpp +++ b/engine/core/rendering/RenderBox.cpp @@ -388,6 +388,16 @@ LayoutUnit RenderBox::maxPreferredLogicalWidth() const return m_maxPreferredLogicalWidth; } +void RenderBox::setMinPreferredLogicalWidth(LayoutUnit width) +{ + m_minPreferredLogicalWidth = width; +} + +void RenderBox::setMaxPreferredLogicalWidth(LayoutUnit width) +{ + m_maxPreferredLogicalWidth = width; +} + bool RenderBox::hasOverrideHeight() const { return m_rareData && m_rareData->m_overrideLogicalContentHeight != -1; diff --git a/engine/core/rendering/RenderBox.h b/engine/core/rendering/RenderBox.h index 0361c04a114..bbf8283a8ea 100644 --- a/engine/core/rendering/RenderBox.h +++ b/engine/core/rendering/RenderBox.h @@ -301,6 +301,9 @@ public: virtual LayoutUnit minPreferredLogicalWidth() const override; virtual LayoutUnit maxPreferredLogicalWidth() const override; + void setMinPreferredLogicalWidth(LayoutUnit); + void setMaxPreferredLogicalWidth(LayoutUnit); + // FIXME: We should rename these back to overrideLogicalHeight/Width and have them store // the border-box height/width like the regular height/width accessors on RenderBox. // Right now, these are different than contentHeight/contentWidth because they still diff --git a/engine/core/rendering/RenderCustomLayout.cpp b/engine/core/rendering/RenderCustomLayout.cpp index 5f55b5f51ee..9001e37940f 100644 --- a/engine/core/rendering/RenderCustomLayout.cpp +++ b/engine/core/rendering/RenderCustomLayout.cpp @@ -19,6 +19,13 @@ RenderCustomLayout::~RenderCustomLayout() { } +void RenderCustomLayout::computePreferredLogicalWidths() +{ + ASSERT(node()->isElementNode()); + toElement(node())->intrinsicWidthsComputer()->handleEvent(); + clearPreferredLogicalWidthsDirty(); +} + void RenderCustomLayout::layout() { ASSERT(node()->isElementNode()); diff --git a/engine/core/rendering/RenderCustomLayout.h b/engine/core/rendering/RenderCustomLayout.h index 0b1c5da4213..826a787fb42 100644 --- a/engine/core/rendering/RenderCustomLayout.h +++ b/engine/core/rendering/RenderCustomLayout.h @@ -12,7 +12,8 @@ namespace blink { class RenderCustomLayout : public RenderBlock { public: explicit RenderCustomLayout(ContainerNode* node); - virtual void layout() override; + void computePreferredLogicalWidths() final; + void layout() final; const char* renderName() const; bool isRenderCustomLayout() const final { return true; } diff --git a/tests/layout/custom-dirty-bits.sky b/tests/layout/custom-dirty-bits.sky index ec5b750956d..d8ecf25085c 100644 --- a/tests/layout/custom-dirty-bits.sky +++ b/tests/layout/custom-dirty-bits.sky @@ -11,6 +11,6 @@ void main() { // don't need laying out. // This test passes if it doesn't crash and the render tree // has no RenderTexts. - document.querySelector('block').setLayoutManager(() => {}); + document.querySelector('block').setLayoutManager(() {}, () {}); } diff --git a/tests/layout/custom-expected.txt b/tests/layout/custom-expected.txt index 6b56ff06943..3ad6888a023 100644 --- a/tests/layout/custom-expected.txt +++ b/tests/layout/custom-expected.txt @@ -1,6 +1,7 @@ CONSOLE: unittest-suite-wait-for-done CONSOLE: PASS: should have the right sizes after layout +CONSOLE: PASS: intrinsic sizes should apply CONSOLE: -CONSOLE: All 1 tests passed. +CONSOLE: All 2 tests passed. CONSOLE: unittest-suite-success DONE diff --git a/tests/layout/custom.sky b/tests/layout/custom.sky index e212a6e7a01..538fa754413 100644 --- a/tests/layout/custom.sky +++ b/tests/layout/custom.sky @@ -7,6 +7,12 @@ + + + + + +