bool RenderIFrame::flattenFrame() { if (!node() || !node()->hasTagName(iframeTag)) return false; // CAPPFIX_WEB_HTML5: SECURITY if (isSeamless()) return false; // Seamless iframes are already "flat", don't try to flatten them. // CAPPFIX_WEB_HTML5_END HTMLIFrameElement* element = static_cast<HTMLIFrameElement*>(node()); bool isScrollable = element->scrollingMode() != ScrollbarAlwaysOff; if (!isScrollable && style()->width().isFixed() && style()->height().isFixed()) return false; Frame* frame = element->document()->frame(); bool enabled = frame && frame->settings()->frameFlatteningEnabled(); if (!enabled || !frame->page()) return false; FrameView* view = frame->page()->mainFrame()->view(); if (!view) return false; // Do not flatten offscreen inner frames during frame flattening. return absoluteBoundingBoxRect().intersects(IntRect(IntPoint(0, 0), view->contentsSize())); }
bool RenderIFrame::flattenFrame() { if (!node() || !node()->hasTagName(iframeTag)) return false; HTMLIFrameElement* element = static_cast<HTMLIFrameElement*>(node()); bool isScrollable = element->scrollingMode() != ScrollbarAlwaysOff; if (style()->width().isFixed() && style()->height().isFixed()) { if (!isScrollable) return false; if (style()->width().value() <= 0 || style()->height().value() <= 0) return false; } Frame* frame = element->document()->frame(); bool enabled = frame && frame->settings()->frameFlatteningEnabled(); if (!enabled || !frame->page()) return false; FrameView* view = frame->page()->mainFrame()->view(); if (!view) return false; // Do not flatten offscreen inner frames during frame flattening. return absoluteBoundingBoxRect().intersects(IntRect(IntPoint(0, 0), view->contentsSize())); }
void TouchEventHandler::drawTapHighlight() { Element* elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable(); if (!elementUnderFatFinger) return; Element* element = elementForTapHighlight(elementUnderFatFinger); if (!element) return; // Get the element bounding rect in transformed coordinates so we can extract // the focus ring relative position each rect. RenderObject* renderer = element->renderer(); ASSERT(renderer); Frame* elementFrame = element->document()->frame(); ASSERT(elementFrame); FrameView* elementFrameView = elementFrame->view(); if (!elementFrameView) return; // Tell the client if the element is either in a scrollable container or in a fixed positioned container. // On the client side, this info is being used to hide the tap highlight window on scroll. RenderLayer* layer = m_webPage->enclosingFixedPositionedAncestorOrSelfIfFixedPositioned(renderer->enclosingLayer()); bool shouldHideTapHighlightRightAfterScrolling = !layer->renderer()->isRenderView(); shouldHideTapHighlightRightAfterScrolling |= !!m_webPage->m_inRegionScroller->d->node(); IntPoint framePos(m_webPage->frameOffset(elementFrame)); // FIXME: We can get more precise on the <map> case by calculating the rect with HTMLAreaElement::computeRect(). IntRect absoluteRect(renderer->absoluteClippedOverflowRect()); absoluteRect.move(framePos.x(), framePos.y()); IntRect clippingRect; if (elementFrame == m_webPage->mainFrame()) clippingRect = IntRect(IntPoint(0, 0), elementFrameView->contentsSize()); else clippingRect = m_webPage->mainFrame()->view()->windowToContents(m_webPage->getRecursiveVisibleWindowRect(elementFrameView, true /*noClipToMainFrame*/)); clippingRect = intersection(absoluteRect, clippingRect); Vector<FloatQuad> focusRingQuads; renderer->absoluteFocusRingQuads(focusRingQuads); Platform::IntRectRegion region; for (size_t i = 0; i < focusRingQuads.size(); ++i) { IntRect rect = focusRingQuads[i].enclosingBoundingBox(); rect.move(framePos.x(), framePos.y()); IntRect clippedRect = intersection(clippingRect, rect); clippedRect.inflate(2); region = unionRegions(region, Platform::IntRect(clippedRect)); } Color highlightColor = element->renderStyle()->tapHighlightColor(); m_webPage->m_tapHighlight->draw(region, highlightColor.red(), highlightColor.green(), highlightColor.blue(), highlightColor.alpha(), shouldHideTapHighlightRightAfterScrolling); }
InRegionScrollableArea::InRegionScrollableArea(WebPagePrivate* webPage, RenderLayer* layer) : m_webPage(webPage) , m_layer(layer) { ASSERT(webPage); ASSERT(layer); m_isNull = false; // FIXME: Add an ASSERT here as the 'layer' must be scrollable. RenderObject* layerRenderer = layer->renderer(); ASSERT(layerRenderer); if (layerRenderer->isRenderView()) { // #document case FrameView* view = toRenderView(layerRenderer)->frameView(); ASSERT(view); Frame* frame = view->frame(); ASSERT_UNUSED(frame, frame); m_scrollPosition = m_webPage->mapToTransformed(view->scrollPosition()); m_contentsSize = m_webPage->mapToTransformed(view->contentsSize()); m_viewportSize = m_webPage->mapToTransformed(view->visibleContentRect(false /*includeScrollbars*/)).size(); m_visibleWindowRect = m_webPage->mapToTransformed(m_webPage->getRecursiveVisibleWindowRect(view)); IntRect transformedWindowRect = IntRect(IntPoint::zero(), m_webPage->transformedViewportSize()); m_visibleWindowRect.intersect(transformedWindowRect); m_scrollsHorizontally = view->contentsWidth() > view->visibleWidth(); m_scrollsVertically = view->contentsHeight() > view->visibleHeight(); m_overscrollLimitFactor = 0.0; // FIXME eventually support overscroll } else { // RenderBox-based elements case (scrollable boxes (div's, p's, textarea's, etc)). RenderBox* box = m_layer->renderBox(); ASSERT(box); ASSERT(box->canBeScrolledAndHasScrollableArea()); ScrollableArea* scrollableArea = static_cast<ScrollableArea*>(m_layer); m_scrollPosition = m_webPage->mapToTransformed(scrollableArea->scrollPosition()); m_contentsSize = m_webPage->mapToTransformed(scrollableArea->contentsSize()); m_viewportSize = m_webPage->mapToTransformed(scrollableArea->visibleContentRect(false /*includeScrollbars*/)).size(); m_visibleWindowRect = m_layer->renderer()->absoluteClippedOverflowRect(); m_visibleWindowRect = m_layer->renderer()->frame()->view()->contentsToWindow(m_visibleWindowRect); IntRect visibleFrameWindowRect = m_webPage->getRecursiveVisibleWindowRect(m_layer->renderer()->frame()->view()); m_visibleWindowRect.intersect(visibleFrameWindowRect); m_visibleWindowRect = m_webPage->mapToTransformed(m_visibleWindowRect); IntRect transformedWindowRect = IntRect(IntPoint::zero(), m_webPage->transformedViewportSize()); m_visibleWindowRect.intersect(transformedWindowRect); m_scrollsHorizontally = box->scrollWidth() != box->clientWidth() && box->scrollsOverflowX(); m_scrollsVertically = box->scrollHeight() != box->clientHeight() && box->scrollsOverflowY(); m_overscrollLimitFactor = 0.0; // FIXME eventually support overscroll } }
IntSize WebFrame::size() const { if (!m_coreFrame) return IntSize(); FrameView* frameView = m_coreFrame->view(); if (!frameView) return IntSize(); return frameView->contentsSize(); }
void WebViewBenchmarkSupportImpl::softwarePaint(PaintClient* paintClient, PaintMode paintMode) { WebSize size = m_webViewImpl->size(); WebRect paintSize; switch (paintMode) { case PaintModeEverything: if (m_webViewImpl->page() && m_webViewImpl->page()->mainFrame()) { FrameView* view = m_webViewImpl->page()->mainFrame()->view(); IntSize contentsSize = view->contentsSize(); paintSize = WebRect(0, 0, contentsSize.width(), contentsSize.height()); } else paintSize = WebRect(0, 0, size.width, size.height); break; } WebSize canvasSize(paintSize.width, paintSize.height); WebCanvas* canvas = paintClient->willPaint(canvasSize); m_webViewImpl->paint(canvas, paintSize); paintClient->didPaint(canvas); }
void InspectorEmulationAgent::viewportChanged() { if (!m_webViewImpl->devToolsEmulator()->deviceEmulationEnabled() || !frontend()) return; FrameView* view = m_webViewImpl->mainFrameImpl()->frameView(); IntSize contentsSize = view->contentsSize(); FloatPoint scrollOffset; scrollOffset = FloatPoint(view->scrollableArea()->visibleContentRectDouble().location()); RefPtr<TypeBuilder::Emulation::Viewport> viewport = TypeBuilder::Emulation::Viewport::create() .setScrollX(scrollOffset.x()) .setScrollY(scrollOffset.y()) .setContentsWidth(contentsSize.width()) .setContentsHeight(contentsSize.height()) .setPageScaleFactor(m_webViewImpl->page()->pageScaleFactor()) .setMinimumPageScaleFactor(m_webViewImpl->minimumPageScaleFactor()) .setMaximumPageScaleFactor(m_webViewImpl->maximumPageScaleFactor()); frontend()->viewportChanged(viewport); }
void PaintPropertyTreeBuilder::buildTreeNodes( FrameView& frameView, PaintPropertyTreeBuilderContext& context) { if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { LayoutView* layoutView = frameView.layoutView(); if (!layoutView) return; TransformationMatrix frameTranslate; frameTranslate.translate(frameView.x() + layoutView->location().x() + context.current.paintOffset.x(), frameView.y() + layoutView->location().y() + context.current.paintOffset.y()); context.current.transform = layoutView->getMutableForPainting() .ensurePaintProperties() .updatePaintOffsetTranslation(context.current.transform, frameTranslate, FloatPoint3D()); context.current.paintOffset = LayoutPoint(); context.current.renderingContextID = 0; context.current.shouldFlattenInheritedTransform = true; context.absolutePosition = context.current; context.containerForAbsolutePosition = nullptr; // This will get set in updateOutOfFlowContext(). context.fixedPosition = context.current; return; } TransformationMatrix frameTranslate; frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), frameView.y() + context.current.paintOffset.y()); context.current.transform = updateFrameViewPreTranslation( frameView, context.current.transform, frameTranslate, FloatPoint3D()); FloatRoundedRect contentClip( IntRect(IntPoint(), frameView.visibleContentSize())); context.current.clip = updateFrameViewContentClip( frameView, context.current.clip, frameView.preTranslation(), contentClip); // Record the fixed properties before any scrolling occurs. const auto* fixedTransformNode = context.current.transform; auto* fixedScrollNode = context.current.scroll; ScrollOffset scrollOffset = frameView.scrollOffset(); if (frameView.isScrollable() || !scrollOffset.isZero()) { TransformationMatrix frameScroll; frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); context.current.transform = updateFrameViewScrollTranslation( frameView, frameView.preTranslation(), frameScroll, FloatPoint3D()); IntSize scrollClip = frameView.visibleContentSize(); IntSize scrollBounds = frameView.contentsSize(); bool userScrollableHorizontal = frameView.userInputScrollable(HorizontalScrollbar); bool userScrollableVertical = frameView.userInputScrollable(VerticalScrollbar); context.current.scroll = updateFrameViewScroll( frameView, context.current.scroll, frameView.scrollTranslation(), scrollClip, scrollBounds, userScrollableHorizontal, userScrollableVertical); } else { // Ensure pre-existing properties are cleared when there is no scrolling. frameView.setScrollTranslation(nullptr); frameView.setScroll(nullptr); } // Initialize the context for current, absolute and fixed position cases. // They are the same, except that scroll translation does not apply to // fixed position descendants. context.current.paintOffset = LayoutPoint(); context.current.renderingContextID = 0; context.current.shouldFlattenInheritedTransform = true; context.absolutePosition = context.current; context.containerForAbsolutePosition = nullptr; context.fixedPosition = context.current; context.fixedPosition.transform = fixedTransformNode; context.fixedPosition.scroll = fixedScrollNode; std::unique_ptr<PropertyTreeState> contentsState( new PropertyTreeState(context.current.transform, context.current.clip, context.currentEffect, context.current.scroll)); frameView.setTotalPropertyTreeStateForContents(std::move(contentsState)); }
void PaintPropertyTreeBuilder::updateFramePropertiesAndContext( FrameView& frameView, PaintPropertyTreeBuilderContext& context) { if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { // With root layer scrolling, the LayoutView (a LayoutObject) properties are // updated like other objects (see updatePropertiesAndContextForSelf and // updatePropertiesAndContextForChildren) instead of needing LayoutView- // specific property updates here. context.current.paintOffset.moveBy(frameView.location()); context.current.renderingContextID = 0; context.current.shouldFlattenInheritedTransform = true; context.absolutePosition = context.current; context.containerForAbsolutePosition = nullptr; context.fixedPosition = context.current; return; } TransformationMatrix frameTranslate; frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), frameView.y() + context.current.paintOffset.y()); updateFrameViewPreTranslation(frameView, context.current.transform, frameTranslate, FloatPoint3D()); FloatRoundedRect contentClip( IntRect(IntPoint(), frameView.visibleContentSize())); updateFrameViewContentClip(frameView, context.current.clip, frameView.preTranslation(), contentClip); ScrollOffset scrollOffset = frameView.scrollOffset(); if (frameView.isScrollable() || !scrollOffset.isZero()) { TransformationMatrix frameScroll; frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); updateFrameViewScrollTranslation(frameView, frameView.preTranslation(), frameScroll, FloatPoint3D()); IntSize scrollClip = frameView.visibleContentSize(); IntSize scrollBounds = frameView.contentsSize(); bool userScrollableHorizontal = frameView.userInputScrollable(HorizontalScrollbar); bool userScrollableVertical = frameView.userInputScrollable(VerticalScrollbar); updateFrameViewScroll(frameView, context.current.scroll, frameView.scrollTranslation(), scrollClip, scrollBounds, userScrollableHorizontal, userScrollableVertical); } else { // Ensure pre-existing properties are cleared when there is no scrolling. frameView.setScrollTranslation(nullptr); frameView.setScroll(nullptr); } // Initialize the context for current, absolute and fixed position cases. // They are the same, except that scroll translation does not apply to // fixed position descendants. const auto* fixedTransformNode = frameView.preTranslation() ? frameView.preTranslation() : context.current.transform; auto* fixedScrollNode = context.current.scroll; DCHECK(frameView.preTranslation()); context.current.transform = frameView.preTranslation(); DCHECK(frameView.contentClip()); context.current.clip = frameView.contentClip(); if (const auto* scrollTranslation = frameView.scrollTranslation()) context.current.transform = scrollTranslation; if (auto* scroll = frameView.scroll()) context.current.scroll = scroll; context.current.paintOffset = LayoutPoint(); context.current.renderingContextID = 0; context.current.shouldFlattenInheritedTransform = true; context.absolutePosition = context.current; context.containerForAbsolutePosition = nullptr; context.fixedPosition = context.current; context.fixedPosition.transform = fixedTransformNode; context.fixedPosition.scroll = fixedScrollNode; std::unique_ptr<PropertyTreeState> contentsState( new PropertyTreeState(context.current.transform, context.current.clip, context.currentEffect, context.current.scroll)); frameView.setTotalPropertyTreeStateForContents(std::move(contentsState)); }
InRegionScrollableArea::InRegionScrollableArea(WebPagePrivate* webPage, RenderLayer* layer) : m_webPage(webPage) , m_layer(layer) , m_document(0) , m_hasWindowVisibleRectCalculated(false) { ASSERT(webPage); ASSERT(layer); m_isNull = false; // Add a pointer to the enclosing document as the pointer to layer or node along the way may become invalid. if (m_layer->enclosingElement()) m_document = m_layer->enclosingElement()->document(); // FIXME: Add an ASSERT here as the 'layer' must be scrollable. RenderObject* layerRenderer = layer->renderer(); ASSERT(layerRenderer); if (layerRenderer->isRenderView()) { // #document case RenderView* renderView = toRenderView(layerRenderer); ASSERT(renderView); FrameView* view = toRenderView(layerRenderer)->frameView(); ASSERT(view); Frame* frame = view->frame(); ASSERT_UNUSED(frame, frame); const Platform::ViewportAccessor* viewportAccessor = m_webPage->m_webkitThreadViewportAccessor; m_scrollPosition = viewportAccessor->roundToPixelFromDocumentContents(WebCore::FloatPoint(view->scrollPosition())); m_contentsSize = viewportAccessor->roundToPixelFromDocumentContents(Platform::FloatRect(Platform::FloatPoint::zero(), WebCore::FloatSize(view->contentsSize()))).size(); m_viewportSize = viewportAccessor->roundToPixelFromDocumentContents(WebCore::FloatRect(view->visibleContentRect(ScrollableArea::ExcludeScrollbars))).size(); m_documentViewportRect = view->frameRect(); m_scrollsHorizontally = view->contentsWidth() > view->visibleWidth(); m_scrollsVertically = view->contentsHeight() > view->visibleHeight(); m_supportsCompositedScrolling = true; m_scrollTarget = InnerFrame; ASSERT(!m_cachedNonCompositedScrollableNode); m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(renderView->compositor()->scrollLayer()->platformLayer()); m_cachedCompositedScrollableLayer = renderView->compositor()->scrollLayer()->platformLayer(); } else { // RenderBox-based elements case (scrollable boxes (div's, p's, textarea's, etc)). RenderBox* box = m_layer->renderBox(); ASSERT(box); ASSERT(InRegionScrollerPrivate::canScrollRenderBox(box)); const Platform::ViewportAccessor* viewportAccessor = m_webPage->m_webkitThreadViewportAccessor; ScrollableArea* scrollableArea = static_cast<ScrollableArea*>(m_layer); m_scrollPosition = viewportAccessor->roundToPixelFromDocumentContents(WebCore::FloatPoint(scrollableArea->scrollPosition())); m_contentsSize = viewportAccessor->roundToPixelFromDocumentContents(Platform::FloatRect(Platform::FloatPoint::zero(), WebCore::FloatSize(scrollableArea->contentsSize()))).size(); m_viewportSize = viewportAccessor->roundToPixelFromDocumentContents(WebCore::FloatRect(scrollableArea->visibleContentRect(ScrollableArea::ExcludeScrollbars))).size(); m_documentViewportRect = enclosingIntRect(box->absoluteClippedOverflowRect()); m_scrollsHorizontally = box->scrollWidth() != box->clientWidth(); m_scrollsVertically = box->scrollHeight() != box->clientHeight(); // Check the overflow if its not an input field because overflow can be set to hidden etc. by the content. if (!DOMSupport::isShadowHostTextInputElement(box->node())) { m_scrollsHorizontally = m_scrollsHorizontally && box->scrollsOverflowX(); m_scrollsVertically = m_scrollsVertically && box->scrollsOverflowY(); } m_scrollTarget = BlockElement; // Both caches below are self-exclusive. if (m_layer->usesCompositedScrolling()) { m_forceContentToBeHorizontallyScrollable = m_scrollsHorizontally; m_forceContentToBeVerticallyScrollable = m_scrollsVertically; // Force content to be scrollable even if it doesn't need to scroll in either direction. if (!m_scrollsHorizontally && !m_scrollsVertically) { if (box->scrollsOverflowY()) m_forceContentToBeVerticallyScrollable = true; else if (box->scrollsOverflowX()) // If it's already forced scrollable vertically, don't force it to scroll horizontally m_forceContentToBeHorizontallyScrollable = true; } m_supportsCompositedScrolling = true; ASSERT(m_layer->backing()->hasScrollingLayer()); m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(m_layer->backing()->scrollingContentsLayer()->platformLayer()); m_cachedCompositedScrollableLayer = m_layer->backing()->scrollingContentsLayer()->platformLayer(); ASSERT(!m_cachedNonCompositedScrollableNode); } else { m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(m_layer->enclosingElement()); m_cachedNonCompositedScrollableNode = m_layer->enclosingElement(); ASSERT(!m_cachedCompositedScrollableLayer); } } }
InRegionScrollableArea::InRegionScrollableArea(WebPagePrivate* webPage, RenderLayer* layer) : m_webPage(webPage) , m_layer(layer) , m_document(0) , m_hasWindowVisibleRectCalculated(false) { ASSERT(webPage); ASSERT(layer); m_isNull = false; // Add a pointer to the enclosing document as the pointer to layer or node along the way may become invalid. if (m_layer->enclosingElement()) m_document = m_layer->enclosingElement()->document(); // FIXME: Add an ASSERT here as the 'layer' must be scrollable. RenderObject* layerRenderer = layer->renderer(); ASSERT(layerRenderer); if (layerRenderer->isRenderView()) { // #document case RenderView* renderView = toRenderView(layerRenderer); ASSERT(renderView); FrameView* view = toRenderView(layerRenderer)->frameView(); ASSERT(view); Frame* frame = view->frame(); ASSERT_UNUSED(frame, frame); m_scrollPosition = m_webPage->mapToTransformed(view->scrollPosition()); m_contentsSize = m_webPage->mapToTransformed(view->contentsSize()); m_viewportSize = m_webPage->mapToTransformed(view->visibleContentRect(ScrollableArea::ExcludeScrollbars)).size(); m_documentViewportRect = view->frameRect(); m_scrollsHorizontally = view->contentsWidth() > view->visibleWidth(); m_scrollsVertically = view->contentsHeight() > view->visibleHeight(); m_supportsCompositedScrolling = true; m_scrollTarget = InnerFrame; ASSERT(!m_cachedNonCompositedScrollableNode); m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(renderView->compositor()->scrollLayer()->platformLayer()); m_cachedCompositedScrollableLayer = renderView->compositor()->scrollLayer()->platformLayer(); } else { // RenderBox-based elements case (scrollable boxes (div's, p's, textarea's, etc)). RenderBox* box = m_layer->renderBox(); ASSERT(box); ASSERT(InRegionScrollerPrivate::canScrollRenderBox(box)); ScrollableArea* scrollableArea = static_cast<ScrollableArea*>(m_layer); m_scrollPosition = m_webPage->mapToTransformed(scrollableArea->scrollPosition()); m_contentsSize = m_webPage->mapToTransformed(scrollableArea->contentsSize()); m_viewportSize = m_webPage->mapToTransformed(scrollableArea->visibleContentRect(ScrollableArea::ExcludeScrollbars)).size(); m_documentViewportRect = enclosingIntRect(box->absoluteClippedOverflowRect()); m_scrollsHorizontally = box->scrollWidth() != box->clientWidth(); m_scrollsVertically = box->scrollHeight() != box->clientHeight(); // Check the overflow if its not an input field because overflow can be set to hidden etc. by the content. if (!box->node() || !box->node()->rendererIsEditable()) { m_scrollsHorizontally = m_scrollsHorizontally && box->scrollsOverflowX(); m_scrollsVertically = m_scrollsVertically && box->scrollsOverflowY(); } m_scrollTarget = BlockElement; // Both caches below are self-exclusive. if (m_layer->usesCompositedScrolling()) { m_forceContentToBeVerticallyScrollable = true; m_supportsCompositedScrolling = true; ASSERT(m_layer->backing()->hasScrollingLayer()); m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(m_layer->backing()->scrollingContentsLayer()->platformLayer()); m_cachedCompositedScrollableLayer = m_layer->backing()->scrollingContentsLayer()->platformLayer(); ASSERT(!m_cachedNonCompositedScrollableNode); } else { m_camouflagedCompositedScrollableLayer = reinterpret_cast<unsigned>(m_layer->enclosingElement()); m_cachedNonCompositedScrollableNode = m_layer->enclosingElement(); ASSERT(!m_cachedCompositedScrollableLayer); } } }