Implementation
List<RenderBox> get paintingOrder {
if (_paintingOrder != null) {
return _paintingOrder!;
}
if (childCount == 0) {
// No child.
return _paintingOrder = const [];
} else if (childCount == 1) {
// Only one child.
final List<RenderBox> order = <RenderBox>[];
order.add(firstChild!);
return _paintingOrder = order;
} else {
// Sort by zIndex.
List<RenderBox> children = getChildren();
if (_childrenNeedsSort) {
children.sort((RenderBox left, RenderBox right) {
// @FIXME: Add patch to handle nested fixed element paint priority, need to remove
// this logic after Kraken has implemented stacking context tree.
if (left is RenderBoxModel &&
left.renderStyle.position == CSSPositionType.fixed &&
right is RenderBoxModel &&
right.renderStyle.position == CSSPositionType.fixed) {
// Child element always paint after parent element when their position are both fixed
// as W3C stacking context specified.
// Kraken will place these two renderObjects as siblings of the children of HTML renderObject
// due to lack stacking context support, so it needs to add this patch to handle this case.
if (right.renderStyle.isAncestorOf(left.renderStyle)) return 1;
if (left.renderStyle.isAncestorOf(right.renderStyle)) return -1;
}
bool isLeftNeedsStacking = left is RenderBoxModel && left.needsStacking;
bool isRightNeedsStacking = right is RenderBoxModel && right.needsStacking;
if (!isLeftNeedsStacking && isRightNeedsStacking) {
return 0 <= (right.renderStyle.zIndex ?? 0) ? -1 : 1;
} else if (isLeftNeedsStacking && !isRightNeedsStacking) {
return (left.renderStyle.zIndex ?? 0) < 0 ? -1 : 1;
} else if (isLeftNeedsStacking && isRightNeedsStacking) {
return (left.renderStyle.zIndex ?? 0) <= (right.renderStyle.zIndex ?? 0) ? -1 : 1;
} else {
return -1;
}
});
}
return _paintingOrder = children;
}
}