-
Notifications
You must be signed in to change notification settings - Fork 302
/
display.dart
103 lines (84 loc) · 3.19 KB
/
display.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
* Copyright (C) 2019-present Alibaba Inc. All rights reserved.
* Author: Kraken Team.
*/
import 'package:kraken/css.dart';
import 'package:kraken/rendering.dart';
enum CSSDisplay {
inline,
block,
inlineBlock,
flex,
inlineFlex,
sliver,
none
}
mixin CSSDisplayMixin on RenderStyleBase {
CSSDisplay? _display;
CSSDisplay get display => _display ?? CSSDisplay.inline;
set display(CSSDisplay value) {
if (_display != value) {
_display = value;
renderBoxModel?.markNeedsLayout();
}
}
void initDisplay() {
// Must take from style because it inited before flush pending properties.
_display ??= resolveDisplay(target.style[DISPLAY]);
}
static CSSDisplay resolveDisplay(String? displayString) {
switch (displayString) {
case 'none':
return CSSDisplay.none;
case 'sliver':
return CSSDisplay.sliver;
case 'block':
return CSSDisplay.block;
case 'inline-block':
return CSSDisplay.inlineBlock;
case 'flex':
return CSSDisplay.flex;
case 'inline-flex':
return CSSDisplay.inlineFlex;
case 'inline':
default:
return CSSDisplay.inline;
}
}
/// Some layout effects require blockification or inlinification of the box type
/// https://www.w3.org/TR/css-display-3/#transformations
CSSDisplay? get effectiveDisplay {
RenderStyle renderStyle = this as RenderStyle;
CSSDisplay? transformedDisplay = renderStyle.display;
// Must take from style because it inited before flush pending properties.
CSSPositionType position = renderStyle.position;
// Display as inline-block when element is positioned
if (position == CSSPositionType.absolute || position == CSSPositionType.fixed) {
return CSSDisplay.inlineBlock;
}
if (renderBoxModel != null) {
if (renderBoxModel!.parent is! RenderBoxModel) {
return transformedDisplay;
} else if (renderBoxModel!.parent is RenderFlexLayout) {
// Margin change in flex layout may affect transformed display
// https://www.w3.org/TR/css-display-3/#transformations
// Display as inline-block if parent node is flex
transformedDisplay = CSSDisplay.inlineBlock;
RenderBoxModel parent = renderBoxModel!.parent as RenderBoxModel;
RenderStyle parentRenderStyle = parent.renderStyle;
CSSLengthValue marginLeft = renderStyle.marginLeft;
CSSLengthValue marginRight = renderStyle.marginRight;
bool isVerticalDirection = parentRenderStyle.flexDirection == FlexDirection.column ||
parentRenderStyle.flexDirection == FlexDirection.columnReverse;
// Flex item will not stretch in stretch alignment when flex wrap is set to wrap or wrap-reverse
bool isFlexNoWrap = parentRenderStyle.flexWrap == FlexWrap.nowrap;
bool isAlignItemsStretch = parentRenderStyle.effectiveAlignItems == AlignItems.stretch;
// Display as block if flex vertical layout children and stretch children
if (!marginLeft.isAuto && !marginRight.isAuto && isVerticalDirection && isFlexNoWrap && isAlignItemsStretch) {
transformedDisplay = CSSDisplay.block;
}
}
}
return transformedDisplay;
}
}