📄 renderobjectchildlist.cpp
字号:
if (owner->style()->visibility() != VISIBLE && child->style()->visibility() == VISIBLE && !child->hasLayer()) { if (!layer) layer = owner->enclosingLayer(); if (layer) layer->setHasVisibleContent(true); } if (!child->isFloating() && owner->childrenInline()) owner->dirtyLinesFromChangedChild(child); } child->setNeedsLayoutAndPrefWidthsRecalc(); if (!owner->normalChildNeedsLayout()) owner->setChildNeedsLayout(true); // We may supply the static position for an absolute positioned child. if (AXObjectCache::accessibilityEnabled()) owner->document()->axObjectCache()->childrenChanged(owner);}static RenderObject* beforeAfterContainer(RenderObject* container, PseudoId type){ if (type == BEFORE) { RenderObject* first = container; do { // Skip list markers. first = first->firstChild(); while (first && first->isListMarker()) first = first->nextSibling(); } while (first && first->isAnonymous() && first->style()->styleType() == NOPSEUDO); if (first && first->style()->styleType() != type) return 0; return first; } if (type == AFTER) { RenderObject* last = container; do { last = last->lastChild(); } while (last && last->isAnonymous() && last->style()->styleType() == NOPSEUDO && !last->isListMarker()); if (last && last->style()->styleType() != type) return 0; return last; } ASSERT_NOT_REACHED(); return 0;}static RenderObject* findBeforeAfterParent(RenderObject* object){ // Only table parts need to search for the :before or :after parent if (!(object->isTable() || object->isTableSection() || object->isTableRow())) return object; RenderObject* beforeAfterParent = object; while (beforeAfterParent && !(beforeAfterParent->isText() || beforeAfterParent->isImage())) beforeAfterParent = beforeAfterParent->firstChild(); return beforeAfterParent;}static void invalidateCountersInContainer(RenderObject* container){ if (!container) return; container = findBeforeAfterParent(container); if (!container) return; for (RenderObject* content = container->firstChild(); content; content = content->nextSibling()) { if (content->isCounter()) static_cast<RenderCounter*>(content)->invalidate(); }}void RenderObjectChildList::invalidateCounters(RenderObject* owner){ ASSERT(!owner->documentBeingDestroyed()); invalidateCountersInContainer(beforeAfterContainer(owner, BEFORE)); invalidateCountersInContainer(beforeAfterContainer(owner, AFTER));}void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, PseudoId type, RenderObject* styledObject){ // Double check that the document did in fact use generated content rules. Otherwise we should not have been called. ASSERT(owner->document()->usesBeforeAfterRules()); // In CSS2, before/after pseudo-content cannot nest. Check this first. if (owner->style()->styleType() == BEFORE || owner->style()->styleType() == AFTER) return; if (!styledObject) styledObject = owner; RenderStyle* pseudoElementStyle = styledObject->getCachedPseudoStyle(type); RenderObject* child = beforeAfterContainer(owner, type); // Whether or not we currently have generated content attached. bool oldContentPresent = child; // Whether or not we now want generated content. bool newContentWanted = pseudoElementStyle && pseudoElementStyle->display() != NONE; // For <q><p/></q>, if this object is the inline continuation of the <q>, we only want to generate // :after content and not :before content. if (newContentWanted && type == BEFORE && owner->isRenderInline() && toRenderInline(owner)->isInlineContinuation()) newContentWanted = false; // Similarly, if we're the beginning of a <q>, and there's an inline continuation for our object, // then we don't generate the :after content. if (newContentWanted && type == AFTER && owner->isRenderInline() && toRenderInline(owner)->continuation()) newContentWanted = false; // If we don't want generated content any longer, or if we have generated content, but it's no longer // identical to the new content data we want to build render objects for, then we nuke all // of the old generated content. if (!newContentWanted || (oldContentPresent && Node::diff(child->style(), pseudoElementStyle) == Node::Detach)) { // Nuke the child. if (child && child->style()->styleType() == type) { oldContentPresent = false; child->destroy(); child = (type == BEFORE) ? owner->virtualChildren()->firstChild() : owner->virtualChildren()->lastChild(); } } // If we have no pseudo-element style or if the pseudo-element style's display type is NONE, then we // have no generated content and can now return. if (!newContentWanted) return; if (owner->isRenderInline() && !pseudoElementStyle->isDisplayInlineType() && pseudoElementStyle->floating() == FNONE && !(pseudoElementStyle->position() == AbsolutePosition || pseudoElementStyle->position() == FixedPosition)) // According to the CSS2 spec (the end of section 12.1), the only allowed // display values for the pseudo style are NONE and INLINE for inline flows. // FIXME: CSS2.1 lifted this restriction, but block display types will crash. // For now we at least relax the restriction to allow all inline types like inline-block // and inline-table. pseudoElementStyle->setDisplay(INLINE); if (oldContentPresent) { if (child && child->style()->styleType() == type) { // We have generated content present still. We want to walk this content and update our // style information with the new pseudo-element style. child->setStyle(pseudoElementStyle); RenderObject* beforeAfterParent = findBeforeAfterParent(child); if (!beforeAfterParent) return; // Note that if we ever support additional types of generated content (which should be way off // in the future), this code will need to be patched. for (RenderObject* genChild = beforeAfterParent->firstChild(); genChild; genChild = genChild->nextSibling()) { if (genChild->isText()) // Generated text content is a child whose style also needs to be set to the pseudo-element style. genChild->setStyle(pseudoElementStyle); else if (genChild->isImage()) { // Images get an empty style that inherits from the pseudo. RefPtr<RenderStyle> style = RenderStyle::create(); style->inheritFrom(pseudoElementStyle); genChild->setStyle(style.release()); } else // Must be a first-letter container. updateFirstLetter() will take care of it. ASSERT(genChild->style()->styleType() == FIRST_LETTER); } } return; // We've updated the generated content. That's all we needed to do. } RenderObject* insertBefore = (type == BEFORE) ? owner->virtualChildren()->firstChild() : 0; // Generated content consists of a single container that houses multiple children (specified // by the content property). This generated content container gets the pseudo-element style set on it. RenderObject* generatedContentContainer = 0; // Walk our list of generated content and create render objects for each. for (const ContentData* content = pseudoElementStyle->contentData(); content; content = content->m_next) { RenderObject* renderer = 0; switch (content->m_type) { case CONTENT_NONE: break; case CONTENT_TEXT: renderer = new (owner->renderArena()) RenderTextFragment(owner->document() /* anonymous object */, content->m_content.m_text); renderer->setStyle(pseudoElementStyle); break; case CONTENT_OBJECT: { RenderImageGeneratedContent* image = new (owner->renderArena()) RenderImageGeneratedContent(owner->document()); // anonymous object RefPtr<RenderStyle> style = RenderStyle::create(); style->inheritFrom(pseudoElementStyle); image->setStyle(style.release()); if (StyleImage* styleImage = content->m_content.m_image) image->setStyleImage(styleImage); renderer = image; break; } case CONTENT_COUNTER: renderer = new (owner->renderArena()) RenderCounter(owner->document(), *content->m_content.m_counter); renderer->setStyle(pseudoElementStyle); break; } if (renderer) { if (!generatedContentContainer) { // Make a generated box that might be any display type now that we are able to drill down into children // to find the original content properly. generatedContentContainer = RenderObject::createObject(owner->document(), pseudoElementStyle); generatedContentContainer->setStyle(pseudoElementStyle); owner->addChild(generatedContentContainer, insertBefore); } generatedContentContainer->addChild(renderer); } }}} // namespace WebCore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -