Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Unified Diff: third_party/WebKit/Source/core/dom/Text.cpp

Issue 2450093005: Support display: contents for elements, first-line and first-letter pseudos. (Closed)
Patch Set: Rebased Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/dom/Text.cpp
diff --git a/third_party/WebKit/Source/core/dom/Text.cpp b/third_party/WebKit/Source/core/dom/Text.cpp
index a105811975803ddc44edf75f845d6386a3f5d22c..a0adf4ea2996e522aea9f0ecc9d27cf550c29788 100644
--- a/third_party/WebKit/Source/core/dom/Text.cpp
+++ b/third_party/WebKit/Source/core/dom/Text.cpp
@@ -254,6 +254,9 @@ static inline bool canHaveWhitespaceChildren(const LayoutObject& parent) {
bool Text::textLayoutObjectIsNeeded(const ComputedStyle& style,
const LayoutObject& parent) const {
+ const LayoutObject* prev = nullptr;
+ bool lookedForPrev = false;
+
if (!parent.canHaveChildren())
return false;
@@ -269,6 +272,26 @@ bool Text::textLayoutObjectIsNeeded(const ComputedStyle& style,
if (!containsOnlyWhitespace())
return true;
+ // We may have multiple text layout object siblings as part of a layout tree
+ // affected by display: contents. In the case we have something like:
+ //
+ // <div>Foo<div style="display: contents"> </div>Bar</div>
+ //
+ // We can't just bail out and don't create a text layout object for the
+ // whitespace text node inside the display: contents element.
+ //
+ // We can check whether our style parent or our previous light-tree sibling
+ // has display contents to to avoid doing the previous layout object lookup
rune 2017/01/27 13:09:23 double "to"
+ // more than necessary.
+ if (style.display() == EDisplay::Contents ||
+ (previousSibling() && previousSibling()->isElementNode() &&
+ toElement(previousSibling())->hasDisplayContentsStyle())) {
+ prev = LayoutTreeBuilderTraversal::previousSiblingLayoutObject(*this);
+ lookedForPrev = true;
+ if (prev && prev->node() && prev->node()->isTextNode())
rune 2017/01/27 13:09:23 Not strictly true if the previous sibling is also
emilio 2017/01/27 22:13:15 Right, I guess we could avoid creating it if the p
+ return true;
+ }
+
if (!canHaveWhitespaceChildren(parent))
return false;
@@ -290,9 +313,12 @@ bool Text::textLayoutObjectIsNeeded(const ComputedStyle& style,
// the number of siblings to visit.
unsigned maxSiblingsToVisit = 50;
- const LayoutObject* prev =
- LayoutTreeBuilderTraversal::previousSiblingLayoutObject(
- *this, maxSiblingsToVisit);
+ if (!lookedForPrev) {
+ lookedForPrev = true;
+ prev = LayoutTreeBuilderTraversal::previousSiblingLayoutObject(
+ *this, maxSiblingsToVisit);
+ }
+
if (prev && prev->isBR()) // <span><br/> <br/></span>
return false;
@@ -349,12 +375,17 @@ LayoutText* Text::createTextLayoutObject(const ComputedStyle& style) {
}
void Text::attachLayoutTree(const AttachContext& context) {
- if (ContainerNode* layoutParent = LayoutTreeBuilderTraversal::parent(*this)) {
- if (LayoutObject* parentLayoutObject = layoutParent->layoutObject()) {
- if (textLayoutObjectIsNeeded(*parentLayoutObject->style(),
- *parentLayoutObject))
- LayoutTreeBuilderForText(*this, parentLayoutObject)
- .createLayoutObject();
+ ContainerNode* styleParent = LayoutTreeBuilderTraversal::parent(*this);
+ LayoutObject* parentLayoutObject =
+ LayoutTreeBuilderTraversal::parentLayoutObject(*this);
+
+ if (styleParent && parentLayoutObject) {
+ DCHECK(styleParent->computedStyle());
+ if (textLayoutObjectIsNeeded(*styleParent->computedStyle(),
+ *parentLayoutObject)) {
+ LayoutTreeBuilderForText(*this, parentLayoutObject,
+ styleParent->mutableComputedStyle())
rune 2017/01/27 13:09:23 Using mutableComputedStyle() here looks worrying,
emilio 2017/01/27 22:13:15 Yes, I agree, though this was pre-existing (the pr
+ .createLayoutObject();
}
}
CharacterData::attachLayoutTree(context);
@@ -362,13 +393,13 @@ void Text::attachLayoutTree(const AttachContext& context) {
void Text::reattachLayoutTreeIfNeeded(const AttachContext& context) {
bool layoutObjectIsNeeded = false;
- ContainerNode* layoutParent = LayoutTreeBuilderTraversal::parent(*this);
- if (layoutParent) {
- if (LayoutObject* parentLayoutObject = layoutParent->layoutObject()) {
- if (textLayoutObjectIsNeeded(*parentLayoutObject->style(),
- *parentLayoutObject))
- layoutObjectIsNeeded = true;
- }
+ ContainerNode* styleParent = LayoutTreeBuilderTraversal::parent(*this);
+ LayoutObject* parentLayoutObject =
+ LayoutTreeBuilderTraversal::parentLayoutObject(*this);
+ if (styleParent && parentLayoutObject) {
+ DCHECK(styleParent->computedStyle());
+ layoutObjectIsNeeded = textLayoutObjectIsNeeded(
+ *styleParent->computedStyle(), *parentLayoutObject);
}
if (layoutObjectIsNeeded == !!layoutObject())
@@ -382,9 +413,11 @@ void Text::reattachLayoutTreeIfNeeded(const AttachContext& context) {
if (getStyleChangeType() < NeedsReattachStyleChange)
detachLayoutTree(reattachContext);
- if (layoutObjectIsNeeded)
- LayoutTreeBuilderForText(*this, layoutParent->layoutObject())
+ if (layoutObjectIsNeeded) {
+ LayoutTreeBuilderForText(*this, parentLayoutObject,
+ styleParent->mutableComputedStyle())
.createLayoutObject();
+ }
CharacterData::attachLayoutTree(reattachContext);
}

Powered by Google App Engine
This is Rietveld 408576698