Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "config.h" | |
| 6 #include "core/dom/MarkerPseudoElement.h" | |
| 7 | |
| 8 #include "core/layout/LayoutBlockFlow.h" | |
| 9 #include "core/layout/LayoutListItem.h" | |
| 10 #include "core/layout/LayoutListMarker.h" | |
| 11 | |
| 12 namespace blink { | |
| 13 | |
| 14 MarkerPseudoElement::MarkerPseudoElement(Element* parent) | |
| 15 : PseudoElement(parent, MARKER) | |
| 16 { | |
| 17 } | |
| 18 | |
| 19 MarkerPseudoElement::~MarkerPseudoElement() | |
| 20 { | |
| 21 } | |
| 22 | |
| 23 LayoutObject* MarkerPseudoElement::parentOfFirstLineBox(LayoutBlockFlow* curr, c onst LayoutObject* marker) | |
| 24 { | |
| 25 LayoutObject* firstChild = curr->firstChild(); | |
| 26 if (!firstChild) | |
| 27 return nullptr; | |
| 28 | |
| 29 bool inQuirksMode = curr->document().inQuirksMode(); | |
| 30 for (LayoutObject* currChild = firstChild; currChild; currChild = currChild- >nextSibling()) { | |
| 31 if (currChild == marker) | |
| 32 continue; | |
| 33 | |
| 34 if (currChild->isInline() && (!currChild->isLayoutInline() || curr->gene ratesLineBoxesForInlineChild(currChild))) | |
| 35 return curr; | |
| 36 | |
| 37 if (currChild->isFloating() || currChild->isOutOfFlowPositioned()) | |
| 38 continue; | |
| 39 | |
| 40 if (!currChild->isLayoutBlockFlow() || (currChild->isBox() && toLayoutBo x(currChild)->isWritingModeRoot())) | |
| 41 break; | |
| 42 | |
| 43 if (curr->isListItem() && inQuirksMode && currChild->node() | |
| 44 && (isHTMLUListElement(*currChild->node()) || isHTMLOListElement(*cu rrChild->node()))) | |
| 45 break; | |
| 46 | |
| 47 if (LayoutObject* lineBox = parentOfFirstLineBox(toLayoutBlockFlow(currC hild), marker)) | |
| 48 return lineBox; | |
| 49 } | |
| 50 | |
| 51 return nullptr; | |
| 52 } | |
| 53 | |
| 54 PassRefPtr<ComputedStyle> MarkerPseudoElement::customStyleForLayoutObject() | |
| 55 { | |
| 56 if (!layoutObject()) | |
|
esprehn
2015/04/22 07:45:45
This isn't right, you should never look at the lay
dsinclair
2015/04/22 20:00:38
Removed customStyleForLayoutObjects and did calls
| |
| 57 return nullptr; | |
| 58 | |
| 59 LayoutObject* parent = layoutObject()->parent(); | |
|
esprehn
2015/04/22 07:45:45
You need to call LayoutTreeBuilderTraversal::paren
dsinclair
2015/04/22 20:00:38
Removed.
| |
| 60 if (!parent) | |
| 61 return nullptr; | |
| 62 | |
| 63 return styleForListMarkerLayoutObject(*parent, layoutObject()->style()); | |
| 64 } | |
| 65 | |
| 66 PassRefPtr<ComputedStyle> MarkerPseudoElement::styleForListMarkerLayoutObject(La youtObject& parent, const ComputedStyle* style) | |
|
esprehn
2015/04/22 07:45:45
styleForListMarker(...) no need for LayoutObject i
dsinclair
2015/04/22 20:00:38
Done.
| |
| 67 { | |
| 68 RefPtr<ComputedStyle> newStyle = ComputedStyle::create(); | |
| 69 | |
| 70 // The marker always inherits from the list item, regardless of where it mig ht end | |
| 71 // up (e.g., in some deeply nested line box). See CSS3 spec. | |
| 72 newStyle->inheritFrom(*parent.style()); | |
| 73 if (style) { | |
| 74 // Reuse the current margins. Otherwise resetting the margins to initial values | |
| 75 // would trigger unnecessary layout. | |
| 76 newStyle->setMarginStart(style->marginStart()); | |
| 77 newStyle->setMarginEnd(style->marginRight()); | |
|
esprehn
2015/04/22 07:45:45
This code should just be inlined in the above meth
dsinclair
2015/04/22 20:00:38
It can be in the future when we remove the old cod
| |
| 78 } | |
| 79 return newStyle; | |
| 80 } | |
| 81 | |
| 82 LayoutObject* MarkerPseudoElement::firstNonMarkerChild(LayoutObject* parent) | |
| 83 { | |
| 84 LayoutObject* result = parent->slowFirstChild(); | |
| 85 while (result && result->isListMarker()) | |
| 86 result = result->nextSibling(); | |
| 87 return result; | |
| 88 } | |
| 89 | |
| 90 LayoutObject* MarkerPseudoElement::createLayoutObject(const ComputedStyle& style ) | |
| 91 { | |
| 92 ASSERT(parentElement()->layoutObject()); | |
| 93 LayoutListMarker* marker = new LayoutListMarker(this, toLayoutListItem(paren tElement()->layoutObject())); | |
| 94 marker->setStyle(ComputedStyle::clone(style)); | |
|
esprehn
2015/04/22 07:45:45
Don't clone the style, you never need to do that i
dsinclair
2015/04/22 20:00:38
Done.
| |
| 95 return marker; | |
| 96 } | |
| 97 | |
| 98 void MarkerPseudoElement::attachListMarkerLayoutObject() | |
| 99 { | |
| 100 LayoutListItem* parentLayoutObject = toLayoutListItem(parentElement()->layou tObject()); | |
| 101 ASSERT(parentLayoutObject); | |
| 102 ASSERT(layoutObject()); | |
| 103 | |
| 104 LayoutListMarker* marker = toLayoutListMarker(layoutObject()); | |
| 105 LayoutObject* markerParent = marker->parent(); | |
| 106 | |
| 107 LayoutObject* insertionLayoutObject = MarkerPseudoElement::parentOfFirstLine Box(parentLayoutObject, marker); | |
| 108 | |
| 109 // We didn't find any line boxes so make the insertion point the LI layoutOb ject. | |
| 110 if (!insertionLayoutObject) | |
| 111 insertionLayoutObject = parentLayoutObject; | |
| 112 ASSERT(insertionLayoutObject); | |
| 113 | |
| 114 // Check if we're already inserted into the right parent as the first child. | |
| 115 if (markerParent && marker == markerParent->slowFirstChild() | |
| 116 && (markerParent == insertionLayoutObject || markerParent == insertionLa youtObject->slowFirstChild())) | |
| 117 return; | |
| 118 | |
| 119 marker->remove(); | |
| 120 insertionLayoutObject->addChild(marker, MarkerPseudoElement::firstNonMarkerC hild(insertionLayoutObject)); | |
| 121 marker->updateMarginsAndContent(); | |
|
esprehn
2015/04/22 07:45:45
Layout calls this for isImage(), make it call it e
dsinclair
2015/04/22 20:00:38
That will mean we'll do it on every layout, where
| |
| 122 | |
| 123 // If markerParent is an anonymous block with no children, destroy it. | |
| 124 if (markerParent && markerParent->isAnonymousBlock() && !toLayoutBlock(marke rParent)->firstChild() && !toLayoutBlock(markerParent)->continuation()) | |
| 125 markerParent->destroy(); | |
| 126 | |
| 127 if (marker->isInside()) | |
| 128 parentLayoutObject->containingBlock()->updateLogicalWidth(); | |
|
esprehn
2015/04/22 07:45:45
You can't update logical widths inside style recal
dsinclair
2015/04/22 20:00:38
Done.
| |
| 129 } | |
| 130 | |
| 131 void MarkerPseudoElement::attach(const AttachContext& context) | |
| 132 { | |
| 133 PseudoElement::attach(context); | |
| 134 ASSERT(layoutObject()); | |
| 135 | |
| 136 LayoutListMarker* marker = toLayoutListMarker(layoutObject()); | |
| 137 | |
| 138 RefPtr<ComputedStyle> newStyle = MarkerPseudoElement::styleForListMarkerLayo utObject(*(marker->mutableListItem()), marker->style()); | |
| 139 marker->setStyle(newStyle.release()); | |
|
esprehn
2015/04/22 07:45:45
::attach went through the customStyleForLayoutObje
dsinclair
2015/04/22 20:00:38
Style is set here only now.
| |
| 140 | |
| 141 attachListMarkerLayoutObject(); | |
| 142 } | |
| 143 | |
| 144 void MarkerPseudoElement::didRecalcStyle(StyleRecalcChange) | |
| 145 { | |
| 146 attachListMarkerLayoutObject(); | |
| 147 } | |
| 148 | |
| 149 } // namespace blink | |
| OLD | NEW |