[LFC] Use the used margin values in outOfFlowReplacedVerticalGeometry consistently
[WebKit-https.git] / Tools / LayoutReloaded / LayoutState.js
1 /*
2  * Copyright (C) 2018 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 /*
27 class LayoutState {
28 public:
29     Container& rootContainer();
30
31     FormattingContext& formattingContext(const Layout::Container& formattingRoot);
32     FormattingState& establishedFormattingState(const Layout::Container& formattingRoot);
33     FormattingState& formattingStateForBox(const Layout::Box&);
34
35     Display::Box* displayBox(const Layout::Box&);
36
37     void markNeedsLayout(const Layout::Box&);
38     bool needsLayout();
39 };
40 */
41
42 class LayoutState {
43     constructor(rootContainer, rootDisplayBox) {
44         ASSERT(rootContainer.establishesFormattingContext());
45         this.m_rootContainer = rootContainer;
46         this.m_rootDisplayBox = rootDisplayBox;
47
48         this.m_formattingStates = new Map();
49     }
50
51     formattingContext(formattingRoot) {
52         return this._formattingContext(this.establishedFormattingState(formattingRoot));
53     }
54
55     rootContainer() {
56         return this.m_rootContainer;
57     }
58
59     establishedFormattingState(formattingRoot) {
60         ASSERT(formattingRoot.establishesFormattingContext());
61         let formattingState = this.m_formattingStates.get(formattingRoot);
62         if (formattingState)
63             return formattingState;
64         formattingState = this._createFormattingState(formattingRoot);
65         this.m_formattingStates.set(formattingRoot, formattingState);
66         return formattingState;
67     }
68
69     formattingStateForBox(layoutBox) {
70         for (let formattingEntry of this.m_formattingStates) {
71             let formattingRoot = formattingEntry[0];
72             let formattingState = formattingEntry[1];
73             if (FormattingContext.isInFormattingContext(layoutBox, formattingRoot))
74                 return formattingState;
75         }
76         ASSERT_NOT_REACHED();
77         return null;
78     }
79
80     markNeedsLayout(layoutBox) {
81         let formattingState = this.formattingStateForBox(layoutBox);
82         // Newly created formatting state will obviously mark all the boxes dirty.
83         if (!formattingState)
84             return;
85         formattingState.markNeedsLayout(layoutBox);
86     }
87
88     needsLayout() {
89         for (let formattingEntry of this.m_formattingStates) {
90             let formattingState = formattingEntry[1];
91             if (formattingState.layoutNeeded())
92                 return true;
93         }
94         return false;
95     }
96
97     displayBox(layoutBox) {
98         for (let formattingEntry of this.m_formattingStates) {
99             let formattingState = formattingEntry[1];
100             let displayBox = formattingState.displayBoxes().get(layoutBox);
101             if (displayBox)
102                 return displayBox;
103         }
104         // It must be the root container.
105         ASSERT(layoutBox == this.m_rootContainer);
106         return this.m_rootDisplayBox;
107     }
108
109     _createFormattingState(formattingRoot) {
110         ASSERT(formattingRoot.establishesFormattingContext());
111         if (formattingRoot.establishesInlineFormattingContext())
112             return new InlineFormattingState(formattingRoot, this);
113         if (formattingRoot.establishesBlockFormattingContext())
114             return new BlockFormattingState(formattingRoot, this);
115         ASSERT_NOT_REACHED();
116         return null;
117     }
118
119     _formattingContext(formattingState) {
120         if (formattingState instanceof BlockFormattingState)
121             return new BlockFormattingContext(formattingState);
122         if (formattingState instanceof InlineFormattingState)
123             return new InlineFormattingContext(formattingState);
124         ASSERT_NOT_REACHED();
125         return null;
126     }
127 }