void DragCaretController::nodeWillBeRemoved(Node& node) { if (!hasCaret() || !node.inActiveDocument()) return; if (!removingNodeRemovesPosition(node, m_position.deepEquivalent())) return; m_position.deepEquivalent().document()->renderView()->clearSelection(); clear(); }
void BlockPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) { Optional<SubtreeRecorder> subtreeRecorder; if (needsSubtreeRecorder(m_layoutBlock)) { subtreeRecorder.emplace(*paintInfo.context, m_layoutBlock, paintInfo.phase); if (subtreeRecorder->canUseCache()) return; } PaintInfo localPaintInfo(paintInfo); LayoutPoint adjustedPaintOffset = paintOffset + m_layoutBlock.location(); PaintPhase originalPhase = localPaintInfo.phase; // Check if we need to do anything at all. LayoutRect overflowBox = overflowRectForPaintRejection(); m_layoutBlock.flipForWritingMode(overflowBox); overflowBox.moveBy(adjustedPaintOffset); if (!overflowBox.intersects(LayoutRect(localPaintInfo.rect))) return; // There are some cases where not all clipped visual overflow is accounted for. // FIXME: reduce the number of such cases. ContentsClipBehavior contentsClipBehavior = ForceContentsClip; if (m_layoutBlock.hasOverflowClip() && !m_layoutBlock.hasControlClip() && !(m_layoutBlock.shouldPaintSelectionGaps() && originalPhase == PaintPhaseForeground) && !hasCaret()) contentsClipBehavior = SkipContentsClipIfPossible; if (localPaintInfo.phase == PaintPhaseOutline) { localPaintInfo.phase = PaintPhaseChildOutlines; } else if (localPaintInfo.phase == PaintPhaseChildBlockBackground) { localPaintInfo.phase = PaintPhaseBlockBackground; m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset); localPaintInfo.phase = PaintPhaseChildBlockBackgrounds; } { BoxClipper boxClipper(m_layoutBlock, localPaintInfo, adjustedPaintOffset, contentsClipBehavior); m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset); } if (originalPhase == PaintPhaseOutline) { localPaintInfo.phase = PaintPhaseSelfOutline; m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset); localPaintInfo.phase = originalPhase; } else if (originalPhase == PaintPhaseChildBlockBackground) { localPaintInfo.phase = originalPhase; } // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with // z-index. We paint after we painted the background/border, so that the scrollbars will // sit above the background/border. paintOverflowControlsIfNeeded(localPaintInfo, adjustedPaintOffset); }
void BlockPainter::paintObject(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) { const PaintPhase paintPhase = paintInfo.phase; if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && m_layoutBlock.style()->visibility() == VISIBLE && m_layoutBlock.hasBoxDecorationBackground()) m_layoutBlock.paintBoxDecorationBackground(paintInfo, paintOffset); if (paintPhase == PaintPhaseMask && m_layoutBlock.style()->visibility() == VISIBLE) { m_layoutBlock.paintMask(paintInfo, paintOffset); return; } if (paintPhase == PaintPhaseClippingMask && m_layoutBlock.style()->visibility() == VISIBLE) { BoxPainter(m_layoutBlock).paintClippingMask(paintInfo, paintOffset); return; } // FIXME: When Skia supports annotation rect covering (https://code.google.com/p/skia/issues/detail?id=3872), // this rect may be covered by foreground and descendant drawings. Then we may need a dedicated paint phase. if (paintPhase == PaintPhaseForeground && paintInfo.isPrinting()) ObjectPainter(m_layoutBlock).addPDFURLRectIfNeeded(paintInfo, paintOffset); { Optional<ScrollRecorder> scrollRecorder; Optional<PaintInfo> scrolledPaintInfo; if (m_layoutBlock.hasOverflowClip()) { IntSize scrollOffset = m_layoutBlock.scrolledContentOffset(); if (m_layoutBlock.layer()->scrollsOverflow() || !scrollOffset.isZero()) { scrollRecorder.emplace(*paintInfo.context, m_layoutBlock, paintPhase, scrollOffset); scrolledPaintInfo.emplace(paintInfo); scrolledPaintInfo->rect.move(scrollOffset); } } // We're done. We don't bother painting any children. if (paintPhase == PaintPhaseBlockBackground || paintInfo.paintRootBackgroundOnly()) return; const PaintInfo& contentsPaintInfo = scrolledPaintInfo ? *scrolledPaintInfo : paintInfo; if (paintPhase != PaintPhaseSelfOutline) paintContents(contentsPaintInfo, paintOffset); if (paintPhase == PaintPhaseForeground && !paintInfo.isPrinting()) m_layoutBlock.paintSelection(contentsPaintInfo, paintOffset); // Fill in gaps in selection on lines and between blocks. if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) m_layoutBlock.paintFloats(contentsPaintInfo, paintOffset, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip); } if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && m_layoutBlock.style()->hasOutline() && m_layoutBlock.style()->visibility() == VISIBLE) { // Don't paint focus ring for anonymous block continuation because the // inline element having outline-style:auto paints the whole focus ring. if (!m_layoutBlock.style()->outlineStyleIsAuto() || !m_layoutBlock.isAnonymousBlockContinuation()) ObjectPainter(m_layoutBlock).paintOutline(paintInfo, LayoutRect(paintOffset, m_layoutBlock.size()), visualOverflowRectWithPaintOffset(m_layoutBlock, paintOffset)); } if (paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines) paintContinuationOutlines(paintInfo, paintOffset); // If the caret's node's layout object's containing block is this block, and the paint action is PaintPhaseForeground, // then paint the caret. if (paintPhase == PaintPhaseForeground && hasCaret() && !LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*paintInfo.context, m_layoutBlock, DisplayItem::Caret)) { LayoutObjectDrawingRecorder recorder(*paintInfo.context, m_layoutBlock, DisplayItem::Caret, visualOverflowRectWithPaintOffset(m_layoutBlock, paintOffset)); paintCarets(paintInfo, paintOffset); } }