void PseudoElement::attach(const AttachContext& context) { ASSERT(!layoutObject()); Element::attach(context); LayoutObject* renderer = this->layoutObject(); if (!renderer) return; ComputedStyle& style = renderer->mutableStyleRef(); if (style.styleType() != BEFORE && style.styleType() != AFTER) return; ASSERT(style.contentData()); for (const ContentData* content = style.contentData(); content; content = content->next()) { LayoutObject* child = content->createLayoutObject(document(), style); if (renderer->isChildAllowed(child, style)) { renderer->addChild(child); if (child->isQuote()) toLayoutQuote(child)->attachQuote(); } else child->destroy(); } }
bool LayoutListItem::updateMarkerLocation() { ASSERT(m_marker); LayoutObject* markerParent = m_marker->parent(); LayoutObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker); if (!lineBoxParent) { // If the marker is currently contained inside an anonymous box, then we // are the only item in that anonymous box (since no line box parent was // found). It's ok to just leave the marker where it is in this case. if (markerParent && markerParent->isAnonymousBlock()) lineBoxParent = markerParent; else lineBoxParent = this; } if (markerParent != lineBoxParent) { m_marker->remove(); lineBoxParent->addChild(m_marker, firstNonMarkerChild(lineBoxParent)); m_marker->updateMarginsAndContent(); // If markerParent is an anonymous block with no children, destroy it. if (markerParent && markerParent->isAnonymousBlock() && !toLayoutBlock(markerParent)->firstChild() && !toLayoutBlock(markerParent)->continuation()) markerParent->destroy(); return true; } return false; }
void LayoutTreeBuilderForElement::createLayoutObject() { ComputedStyle& style = this->style(); LayoutObject* newLayoutObject = m_node->createLayoutObject(style); if (!newLayoutObject) return; LayoutObject* parentLayoutObject = this->parentLayoutObject(); if (!parentLayoutObject->isChildAllowed(newLayoutObject, style)) { newLayoutObject->destroy(); return; } // Make sure the LayoutObject already knows it is going to be added to a LayoutFlowThread before we set the style // for the first time. Otherwise code using inLayoutFlowThread() in the styleWillChange and styleDidChange will fail. newLayoutObject->setIsInsideFlowThread(parentLayoutObject->isInsideFlowThread()); LayoutObject* nextLayoutObject = this->nextLayoutObject(); m_node->setLayoutObject(newLayoutObject); newLayoutObject->setStyle(&style); // setStyle() can depend on layoutObject() already being set. if (Fullscreen::isActiveFullScreenElement(*m_node)) { newLayoutObject = LayoutFullScreen::wrapLayoutObject(newLayoutObject, parentLayoutObject, &m_node->document()); if (!newLayoutObject) return; } // Note: Adding newLayoutObject instead of layoutObject(). layoutObject() may be a child of newLayoutObject. parentLayoutObject->addChild(newLayoutObject, nextLayoutObject); }
void PseudoElement::attachLayoutTree(const AttachContext& context) { DCHECK(!layoutObject()); Element::attachLayoutTree(context); LayoutObject* layoutObject = this->layoutObject(); if (!layoutObject) return; ComputedStyle& style = layoutObject->mutableStyleRef(); if (style.styleType() != PseudoIdBefore && style.styleType() != PseudoIdAfter) return; DCHECK(style.contentData()); for (const ContentData* content = style.contentData(); content; content = content->next()) { LayoutObject* child = content->createLayoutObject(document(), style); if (layoutObject->isChildAllowed(child, style)) { layoutObject->addChild(child); if (child->isQuote()) toLayoutQuote(child)->attachQuote(); } else { child->destroy(); } } }
TEST_F(LayoutPartTest, DestroyUpdatesImageQualityController) { RawPtr<Element> element = HTMLElement::create(HTMLNames::divTag, document()); LayoutObject* part = new OverriddenLayoutPart(element.get()); // The third and forth arguments are not important in this test. ImageQualityController::imageQualityController()->set(*part, 0, this, LayoutSize(1, 1), false); EXPECT_TRUE(ImageQualityController::has(*part)); part->destroy(); EXPECT_FALSE(ImageQualityController::has(*part)); }
void FirstLetterPseudoElement::attachFirstLetterTextLayoutObjects() { LayoutObject* nextLayoutObject = FirstLetterPseudoElement::firstLetterTextLayoutObject(*this); ASSERT(nextLayoutObject); ASSERT(nextLayoutObject->isText()); // The original string is going to be either a generated content string or a DOM node's // string. We want the original string before it got transformed in case first-letter has // no text-transform or a different text-transform applied to it. String oldText = toLayoutText(nextLayoutObject)->isTextFragment() ? toLayoutTextFragment(nextLayoutObject)->completeText() : toLayoutText(nextLayoutObject)->originalText(); ASSERT(oldText.impl()); ComputedStyle* pseudoStyle = styleForFirstLetter(nextLayoutObject->parent()); layoutObject()->setStyle(pseudoStyle); // FIXME: This would already have been calculated in firstLetterLayoutObject. Can we pass the length through? unsigned length = FirstLetterPseudoElement::firstLetterLength(oldText); // Construct a text fragment for the text after the first letter. // This text fragment might be empty. LayoutTextFragment* remainingText = new LayoutTextFragment(nextLayoutObject->node() ? nextLayoutObject->node() : &nextLayoutObject->document(), oldText.impl(), length, oldText.length() - length); remainingText->setFirstLetterPseudoElement(this); remainingText->setIsRemainingTextLayoutObject(true); remainingText->setStyle(nextLayoutObject->mutableStyle()); if (remainingText->node()) remainingText->node()->setLayoutObject(remainingText); m_remainingTextLayoutObject = remainingText; LayoutObject* nextSibling = layoutObject()->nextSibling(); layoutObject()->parent()->addChild(remainingText, nextSibling); // Construct text fragment for the first letter. LayoutTextFragment* letter = new LayoutTextFragment(&nextLayoutObject->document(), oldText.impl(), 0, length); letter->setFirstLetterPseudoElement(this); letter->setStyle(pseudoStyle); layoutObject()->addChild(letter); nextLayoutObject->destroy(); }