bool RenderThemeChromiumSkia::paintSearchFieldResultsDecoration(RenderObject* magnifierObject, const RenderObject::PaintInfo& paintInfo, const IntRect& r) { // Get the renderer of <input> element. Node* input = magnifierObject->node()->shadowAncestorNode(); if (!input->renderer()->isBox()) return false; RenderBox* inputRenderBox = toRenderBox(input->renderer()); IntRect inputContentBox = inputRenderBox->contentBoxRect(); // Make sure the scaled decoration stays square and will fit in its parent's box. int magnifierSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), r.height())); // Calculate decoration's coordinates relative to the input element. // Center the decoration vertically. Round up though, so if it has to be one pixel off-center, it will // be one pixel closer to the bottom of the field. This tends to look better with the text. IntRect magnifierRect(magnifierObject->offsetFromAncestorContainer(inputRenderBox).width(), inputContentBox.y() + (inputContentBox.height() - magnifierSize + 1) / 2, magnifierSize, magnifierSize); IntRect paintingRect = convertToPaintingRect(inputRenderBox, magnifierObject, magnifierRect, r); static Image* magnifierImage = Image::loadPlatformResource("searchMagnifier").releaseRef(); paintInfo.context->drawImage(magnifierImage, magnifierObject->style()->colorSpace(), paintingRect); return false; }
bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const FloatRect& objectBoundingBox) { // If the current clip-path gets clipped itself, we have to fallback to masking. if (!style()->svgStyle()->clipperResource().isEmpty()) return false; WindRule clipRule = RULE_NONZERO; Path clipPath = Path(); // If clip-path only contains one visible shape or path, we can use path-based clipping. Invisible // shapes don't affect the clipping and can be ignored. If clip-path contains more than one // visible shape, the additive clipping may not work, caused by the clipRule. EvenOdd // as well as NonZero can cause self-clipping of the elements. // See also http://www.w3.org/TR/SVG/painting.html#FillRuleProperty for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) { RenderObject* renderer = childNode->renderer(); if (!renderer) continue; // Only shapes or paths are supported for direct clipping. We need to fallback to masking for texts. if (renderer->isSVGText()) return false; if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyledTransformable()) continue; SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(childNode); RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; const SVGRenderStyle* svgStyle = style->svgStyle(); // Current shape in clip-path gets clipped too. Fallback to masking. if (!svgStyle->clipperResource().isEmpty()) return false; // Fallback to masking, if there is more than one clipping path. if (clipPath.isEmpty()) { styled->toClipPath(clipPath); clipRule = svgStyle->clipRule(); } else return false; } // Only one visible shape/path was found. Directly continue clipping and transform the content to userspace if necessary. if (static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { AffineTransform transform; transform.translate(objectBoundingBox.x(), objectBoundingBox.y()); transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); clipPath.transform(transform); } // The SVG specification wants us to clip everything, if clip-path doesn't have a child. if (clipPath.isEmpty()) clipPath.addRect(FloatRect()); context->clipPath(clipPath, clipRule); return true; }
static RenderObject* nextSiblingRenderer(const Element& element, const ContainerNode* renderingParentNode) { // Avoid an O(N^2) problem with this function by not checking for // nextRenderer() when the parent element hasn't attached yet. // FIXME: Why would we get here anyway if parent is not attached? if (renderingParentNode && !renderingParentNode->attached()) return 0; for (Node* sibling = NodeRenderingTraversal::nextSibling(&element); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) { RenderObject* renderer = sibling->renderer(); if (renderer && !isRendererReparented(renderer)) return renderer; } return 0; }
void MediaControlInputElement::attach() { RefPtr<RenderStyle> style = styleForElement(); if (!style) return; bool needsRenderer = rendererIsNeeded(style.get()); if (!needsRenderer) return; RenderObject* renderer = createRenderer(mediaElement()->renderer()->renderArena(), style.get()); if (!renderer) return; renderer->setStyle(style.get()); setRenderer(renderer); if (parent() && parent()->renderer()) { // Find next sibling with a renderer to determine where to insert. Node* sibling = nextSibling(); while (sibling && !sibling->renderer()) sibling = sibling->nextSibling(); parent()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0); } ContainerNode::attach(); }
void RenderSVGResourceMasker::drawContentIntoMaskImage(MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object) { GraphicsContext* maskImageContext = maskerData->maskImage->context(); ASSERT(maskImageContext); // Eventually adjust the mask image context according to the target objectBoundingBox. AffineTransform maskContentTransformation; if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { FloatRect objectBoundingBox = object->objectBoundingBox(); maskContentTransformation.translate(objectBoundingBox.x(), objectBoundingBox.y()); maskContentTransformation.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); maskImageContext->concatCTM(maskContentTransformation); } // Draw the content into the ImageBuffer. for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) { RenderObject* renderer = node->renderer(); if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !renderer) continue; RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; SVGImageBufferTools::renderSubtreeToImageBuffer(maskerData->maskImage.get(), renderer, maskContentTransformation); } maskImageContext->restore(); #if !USE(CG) maskerData->maskImage->transformColorSpace(ColorSpaceDeviceRGB, ColorSpaceLinearRGB); #endif // Create the luminance mask. IntRect maskImageRect(IntPoint(), maskerData->maskImage->size()); RefPtr<ByteArray> srcPixelArray = maskerData->maskImage->getUnmultipliedImageData(maskImageRect); unsigned pixelArrayLength = srcPixelArray->length(); for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) { unsigned char a = srcPixelArray->get(pixelOffset + 3); if (!a) continue; unsigned char r = srcPixelArray->get(pixelOffset); unsigned char g = srcPixelArray->get(pixelOffset + 1); unsigned char b = srcPixelArray->get(pixelOffset + 2); double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0); srcPixelArray->set(pixelOffset + 3, luma); } maskerData->maskImage->putUnmultipliedImageData(srcPixelArray.get(), maskImageRect.size(), maskImageRect, IntPoint()); }
void Document::activeChainNodeDetached(Node* node) { if (!m_activeHoverElement) return; if (node != m_activeHoverElement) return; Node* activeNode = NodeRenderingTraversal::parent(node); while (activeNode && activeNode->isElementNode() && !activeNode->renderer()) activeNode = NodeRenderingTraversal::parent(activeNode); m_activeHoverElement = activeNode && activeNode->isElementNode() ? toElement(activeNode) : 0; }
bool HTMLEmbedElement::rendererIsNeeded(RenderStyle* style) { Frame* frame = document()->frame(); if (!frame) return false; Node* p = parentNode(); if (p && p->hasTagName(objectTag)) { ASSERT(p->renderer()); return false; } return true; }
VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint) const { HitTestResult result = eventHandler().hitTestResultAtPoint(framePoint, HitTestRequest::ReadOnly | HitTestRequest::Active); Node* node = result.innerNonSharedNode(); if (!node) return VisiblePosition(); auto renderer = node->renderer(); if (!renderer) return VisiblePosition(); VisiblePosition visiblePos = renderer->positionForPoint(result.localPoint(), nullptr); if (visiblePos.isNull()) visiblePos = firstPositionInOrBeforeNode(node); return visiblePos; }
bool HitTestResult::allowsCopy() const { Node* node = innerNode(); if (!node) return false; RenderObject* renderer = node->renderer(); if (!renderer) return false; bool isUserSelectNone = renderer->style().userSelect() == SELECT_NONE; bool isPasswordField = is<HTMLInputElement>(node) && downcast<HTMLInputElement>(*node).isPasswordField(); return !isPasswordField && !isUserSelectNone; }
VisiblePosition LocalFrame::visiblePositionForPoint(const IntPoint& framePoint) { HitTestResult result = eventHandler().hitTestResultAtPoint(framePoint); Node* node = result.innerNonSharedNode(); if (!node) return VisiblePosition(); RenderObject* renderer = node->renderer(); if (!renderer) return VisiblePosition(); VisiblePosition visiblePos = VisiblePosition(renderer->positionForPoint(result.localPoint())); if (visiblePos.isNull()) visiblePos = VisiblePosition(firstPositionInOrBeforeNode(node)); return visiblePos; }
void RenderCounter::rendererSubtreeAttached(RenderObject* renderer) { if (!renderer->view().hasRenderCounters()) return; Node* node = renderer->node(); if (node && !node->isPseudoElement()) node = node->parentNode(); else node = renderer->generatingNode(); if (node && !node->renderer()) return; // No need to update if the parent is not attached yet for (RenderObject* descendant = renderer; descendant; descendant = descendant->nextInPreOrder(renderer)) updateCounters(descendant); }
bool RenderThemeSafari::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect&) { ASSERT(SafariThemeLibrary()); Node* input = o->node()->shadowAncestorNode(); ASSERT(input); RenderObject* renderer = input->renderer(); ASSERT(renderer); IntRect searchRect = renderer->absoluteBoundingBoxRect(); paintThemePart(SafariTheme::SearchFieldCancelButtonPart, paintInfo.context->platformContext(), searchRect, controlSizeFromRect(searchRect, searchFieldSizes()), determineState(o)); return false; }
PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternAttributes& attributes, const FloatRect& tileBoundaries, const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform, FloatRect& clampedAbsoluteTileBoundaries) const { clampedAbsoluteTileBoundaries = SVGImageBufferTools::clampedAbsoluteTargetRect(absoluteTileBoundaries); OwnPtr<ImageBuffer> tileImage; if (!SVGImageBufferTools::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, tileImage, ColorSpaceDeviceRGB)) return nullptr; GraphicsContext* tileImageContext = tileImage->context(); ASSERT(tileImageContext); // The image buffer represents the final rendered size, so the content has to be scaled (to avoid pixelation). tileImageContext->scale(FloatSize(clampedAbsoluteTileBoundaries.width() / tileBoundaries.width(), clampedAbsoluteTileBoundaries.height() / tileBoundaries.height())); // Apply tile image transformations. if (!tileImageTransform.isIdentity()) tileImageContext->concatCTM(tileImageTransform); AffineTransform contentTransformation; if (attributes.boundingBoxModeContent()) contentTransformation = tileImageTransform; // Draw the content into the ImageBuffer. for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) { if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer()) continue; SVGImageBufferTools::renderSubtreeToImageBuffer(tileImage.get(), node->renderer(), contentTransformation); } return tileImage.release(); }
void InputMethodController::setCompositionFromExistingText(const Vector<CompositionUnderline>& underlines, unsigned compositionStart, unsigned compositionEnd) { Element* editable = frame().selection().rootEditableElement(); Position base = frame().selection().base().downstream(); Node* baseNode = base.anchorNode(); if (editable->firstChild() == baseNode && editable->lastChild() == baseNode && baseNode->isTextNode()) { m_compositionNode = nullptr; m_customCompositionUnderlines.clear(); if (base.anchorType() != Position::PositionIsOffsetInAnchor) return; if (!baseNode || baseNode != frame().selection().extent().anchorNode()) return; m_compositionNode = toText(baseNode); RefPtrWillBeRawPtr<Range> range = PlainTextRange(compositionStart, compositionEnd).createRange(*editable); if (!range) return; m_compositionStart = range->startOffset(); m_compositionEnd = range->endOffset(); m_customCompositionUnderlines = underlines; size_t numUnderlines = m_customCompositionUnderlines.size(); for (size_t i = 0; i < numUnderlines; ++i) { m_customCompositionUnderlines[i].startOffset += m_compositionStart; m_customCompositionUnderlines[i].endOffset += m_compositionStart; } if (baseNode->renderer()) baseNode->renderer()->setShouldDoFullPaintInvalidation(true); return; } Editor::RevealSelectionScope revealSelectionScope(&editor()); SelectionOffsetsScope selectionOffsetsScope(this); setSelectionOffsets(PlainTextRange(compositionStart, compositionEnd)); setComposition(frame().selectedText(), underlines, 0, 0); }
String RenderTextControl::textWithHardLineBreaks() { if (!m_innerText) return ""; Node* firstChild = m_innerText->firstChild(); if (!firstChild) return ""; document()->updateLayout(); RenderObject* renderer = firstChild->renderer(); if (!renderer) return ""; InlineBox* box = renderer->isText() ? toRenderText(renderer)->firstTextBox() : toRenderBox(renderer)->inlineBoxWrapper(); if (!box) return ""; Node* breakNode; unsigned breakOffset; RootInlineBox* line = box->root(); getNextSoftBreak(line, breakNode, breakOffset); Vector<UChar> result; for (Node* n = firstChild; n; n = n->traverseNextNode(m_innerText.get())) { if (n->hasTagName(brTag)) result.append(&newlineCharacter, 1); else if (n->isTextNode()) { Text* text = static_cast<Text*>(n); String data = text->data(); unsigned length = data.length(); unsigned position = 0; while (breakNode == n && breakOffset <= length) { if (breakOffset > position) { result.append(data.characters() + position, breakOffset - position); position = breakOffset; result.append(&newlineCharacter, 1); } getNextSoftBreak(line, breakNode, breakOffset); } result.append(data.characters() + position, length - position); } while (breakNode == n) getNextSoftBreak(line, breakNode, breakOffset); } return finishText(result); }
bool RenderThemeSafari::paintSearchFieldResultsButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect&) { ASSERT(SafariThemeLibrary()); Node* input = o.node()->shadowHost(); if (!input) input = o.node(); RenderObject* renderer = input->renderer(); ASSERT(renderer); IntRect searchRect = renderer->absoluteBoundingBoxRectIgnoringTransforms(); paintThemePart(SafariTheme::SearchFieldResultsButtonPart, paintInfo.context->platformContext(), searchRect, controlSizeFromRect(searchRect, searchFieldSizes()), determineState(o)); return false; }
static bool hasNonInlineOrReplacedElements(const Range& range) { Node* stopNode = range.pastLastNode(); for (Node* node = range.firstNode(); node != stopNode; node = NodeTraversal::next(*node)) { if (!node) continue; RenderObject* renderer = node->renderer(); if (!renderer) continue; if ((!renderer->isInline() || renderer->isReplaced()) && range.intersectsNode(node, ASSERT_NO_EXCEPTION)) return true; } return false; }
static VisiblePosition visiblePositionForPoint(Frame* frame, IntPoint outerPoint) { ASSERT(frame); HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(outerPoint, true); Node* node = result.innerNode(); if (!node) return VisiblePosition(); RenderObject* renderer = node->renderer(); if (!renderer) return VisiblePosition(); VisiblePosition visiblePos = renderer->positionForCoordinates(result.localPoint().x(), result.localPoint().y()); if (visiblePos.isNull()) visiblePos = VisiblePosition(Position(node, 0)); return visiblePos; }
void RenderTextControlSingleLine::updatePlaceholderVisibility() { RenderStyle* parentStyle = m_innerBlock ? m_innerBlock->renderer()->style() : style(); RefPtr<RenderStyle> textBlockStyle = createInnerTextStyle(parentStyle); HTMLElement* innerText = innerTextElement(); innerText->renderer()->setStyle(textBlockStyle); for (Node* n = innerText->firstChild(); n; n = n->traverseNextNode(innerText)) { if (RenderObject* renderer = n->renderer()) renderer->setStyle(textBlockStyle); } updateFromElement(); }
void AndroidHitTestResult::buildHighlightRects() { m_highlightRects.clear(); Node* node = m_hitTestResult.URLElement(); if (!node || !node->renderer()) node = m_hitTestResult.innerNode(); if (!node || !node->renderer()) return; if (!WebViewCore::nodeIsClickableOrFocusable(node)) return; Frame* frame = node->document()->frame(); IntPoint frameOffset = m_webViewCore->convertGlobalContentToFrameContent(IntPoint(), frame); RenderObject* renderer = node->renderer(); Vector<FloatQuad> quads; if (renderer->isInline()) renderer->absoluteFocusRingQuads(quads); if (!quads.size()) renderer->absoluteQuads(quads); // No fancy rings, grab a bounding box for (size_t i = 0; i < quads.size(); i++) { IntRect boundingBox = quads[i].enclosingBoundingBox(); boundingBox.move(-frameOffset.x(), -frameOffset.y()); m_highlightRects.append(boundingBox); } }
void RenderSVGResourceClipper::calculateClipContentRepaintRect() { // This is a rough heuristic to appraise the clip size and doesn't consider clip on clip. for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) { RenderObject* renderer = childNode->renderer(); if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer) continue; if (!renderer->isSVGPath() && !renderer->isSVGText() && !renderer->isSVGShadowTreeRootContainer()) continue; RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; m_clipBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates())); } }
static RenderListItem* previousListItem(Node* list, RenderListItem* item) { for (Node* n = item->node()->traversePreviousNode(); n != list; n = n->traversePreviousNode()) { RenderObject* o = n->renderer(); if (o && o->isListItem()) { Node* otherList = enclosingList(n); // This item is part of our current list, so it's what we're looking for. if (list == otherList) return static_cast<RenderListItem*>(o); // We found ourself inside another list; lets skip the rest of it. if (otherList) n = otherList; } } return 0; }
bool canBeScrolledIntoView(FocusType type, const FocusCandidate& candidate) { ASSERT(candidate.visibleNode && candidate.isOffscreen); LayoutRect candidateRect = candidate.rect; for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; parentNode = parentNode->parentNode()) { LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); if (!candidateRect.intersects(parentRect)) { if (((type == FocusTypeLeft || type == FocusTypeRight) && parentNode->renderer()->style()->overflowX() == OHIDDEN) || ((type == FocusTypeUp || type == FocusTypeDown) && parentNode->renderer()->style()->overflowY() == OHIDDEN)) return false; } if (parentNode == candidate.enclosingScrollableBox) return canScrollInDirection(parentNode, type); } return true; }
void RenderSVGResourceClipper::calculateClipContentRepaintRect() { // This is a rough heuristic to appraise the clip size and doesn't consider clip on clip. for (Node* childNode = clipPathElement().firstChild(); childNode; childNode = childNode->nextSibling()) { RenderObject* renderer = childNode->renderer(); if (!childNode->isSVGElement() || !renderer) continue; if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag)) continue; const RenderStyle& style = renderer->style(); if (style.display() == NONE || style.visibility() != VISIBLE) continue; m_clipBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates())); } m_clipBoundaries = clipPathElement().animatedLocalTransform().mapRect(m_clipBoundaries); }
String HitTestResult::title(TextDirection& dir) const { dir = LTR; // Find the title in the nearest enclosing DOM node. // For <area> tags in image maps, walk the tree for the <area>, not the <img> using it. for (Node* titleNode = m_innerNode.get(); titleNode; titleNode = titleNode->parentNode()) { if (titleNode->isElementNode()) { String title = toElement(titleNode)->title(); if (!title.isNull()) { if (RenderObject* renderer = titleNode->renderer()) dir = renderer->style()->direction(); return title; } } } return String(); }
bool DumpRenderTreeSupportQt::elementDoesAutoCompleteForElementWithId(QWebFrameAdapter *adapter, const QString& elementId) { Frame* coreFrame = adapter->frame; if (!coreFrame) return false; Document* doc = coreFrame->document(); Q_ASSERT(doc); Node* coreNode = doc->getElementById(elementId); if (!coreNode || !coreNode->renderer()) return false; HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(coreNode); return inputElement->isTextField() && !inputElement->isPasswordField() && inputElement->shouldAutocomplete(); }
static RootInlineBox *rootBoxForLine(const VisiblePosition &c) { Position p = c.deepEquivalent(); Node *node = p.node(); if (!node) return 0; RenderObject *renderer = node->renderer(); if (!renderer) return 0; InlineBox* box; int offset; c.getInlineBoxAndOffset(box, offset); return box ? box->root() : 0; }
static HTMLElement* highestAncestorToWrapMarkup(const Range* range, EAnnotateForInterchange shouldAnnotate, Node* constrainingAncestor) { Node* commonAncestor = range->commonAncestorContainer(); ASSERT(commonAncestor); HTMLElement* specialCommonAncestor = 0; Node* checkAncestor = specialCommonAncestor ? specialCommonAncestor : commonAncestor; if (checkAncestor->renderer()) { HTMLElement* newSpecialCommonAncestor = toHTMLElement(highestEnclosingNodeOfType(firstPositionInNode(checkAncestor), &isPresentationalHTMLElement, CanCrossEditingBoundary, constrainingAncestor)); if (newSpecialCommonAncestor) specialCommonAncestor = newSpecialCommonAncestor; } if (HTMLAnchorElement* enclosingAnchor = toHTMLAnchorElement(enclosingElementWithTag(firstPositionInNode(specialCommonAncestor ? specialCommonAncestor : commonAncestor), HTMLNames::aTag))) specialCommonAncestor = enclosingAnchor; return specialCommonAncestor; }
void NodeRendererFactory::createRendererIfNeeded() { Node* node = m_context.node(); Document* document = node->document(); if (!document->shouldCreateRenderers()) return; ASSERT(!node->renderer()); ASSERT(document->shouldCreateRenderers()); // FIXME: This side effect should be visible from attach() code. m_context.hostChildrenChanged(); if (!m_context.shouldCreateRenderer()) return; Element* element = node->isElementNode() ? toElement(node) : 0; if (element) m_context.setStyle(element->styleForRenderer()); else if (RenderObject* parentRenderer = m_context.parentRenderer()) m_context.setStyle(parentRenderer->style()); if (!node->rendererIsNeeded(m_context)) { if (element && m_context.style()->affectedByEmpty()) element->setStyleAffectedByEmpty(); return; } RenderObject* parentRenderer = m_context.hasFlowThreadParent() ? m_context.parentFlowRenderer() : m_context.parentRenderer(); // Do not call m_context.nextRenderer() here in the first clause, because it expects to have // the renderer added to its parent already. RenderObject* nextRenderer = m_context.hasFlowThreadParent() ? m_context.parentFlowRenderer()->nextRendererForNode(node) : m_context.nextRenderer(); RenderObject* newRenderer = createRenderer(); #if ENABLE(FULLSCREEN_API) if (document->webkitIsFullScreen() && document->webkitCurrentFullScreenElement() == node) newRenderer = RenderFullScreen::wrapRenderer(newRenderer, document); #endif if (!newRenderer) return; // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer. parentRenderer->addChild(newRenderer, nextRenderer); }
void attachRenderTree(Element* current, const AttachContext& context) { PostAttachCallbackDisabler callbackDisabler(current); WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates; if (current->hasCustomStyleResolveCallbacks()) current->willAttachRenderers(); createRendererIfNeeded(current, context); if (current->parentElement() && current->parentElement()->isInCanvasSubtree()) current->setIsInCanvasSubtree(true); current->updateBeforePseudoElement(NoChange); StyleResolverParentPusher parentPusher(current); // When a shadow root exists, it does the work of attaching the children. if (ShadowRoot* shadowRoot = current->shadowRoot()) { parentPusher.push(); attachShadowRoot(shadowRoot, context); } else if (current->firstChild()) parentPusher.push(); attachChildren(current, context); Node* sibling = current->nextSibling(); if (current->renderer() && sibling && !sibling->renderer() && sibling->attached()) Text::createTextRenderersForSiblingsAfterAttachIfNeeded(sibling); current->setAttached(true); current->clearNeedsStyleRecalc(); if (Document* document = current->document()) { if (AXObjectCache* cache = document->axObjectCache()) cache->updateCacheAfterNodeIsAttached(current); } current->updateAfterPseudoElement(NoChange); current->updateFocusAppearanceAfterAttachIfNeeded(); if (current->hasCustomStyleResolveCallbacks()) current->didAttachRenderers(); }