BalPoint WebFrame::scrollOffset() { Frame* coreFrame = core(this); if (!coreFrame) return IntPoint(); FrameView* view = coreFrame->view(); if (!view) return IntPoint(); IntPoint p(view->scrollOffset().width(), view->scrollOffset().height()); return p; }
void RenderDialog::layout() { LayoutRepainter repainter(*this, true); LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode()); RenderBlock::layout(); RenderStyle* styleToUse = style(); if (styleToUse->position() != AbsolutePosition || !styleToUse->top().isAuto() || !styleToUse->bottom().isAuto()) { statePusher.pop(); return; } // Adjust the dialog's position to be centered in or at the top of the viewport. // FIXME: Figure out what to do in vertical writing mode. FrameView* frameView = document()->view(); int scrollTop = frameView->scrollOffset().height(); FloatPoint absolutePoint(0, scrollTop); int visibleHeight = frameView->visibleContentRect(true).height(); if (height() < visibleHeight) absolutePoint.move(0, (visibleHeight - height()) / 2); FloatPoint localPoint = containingBlock()->absoluteToLocal(absolutePoint); LayoutUnit localTop = LayoutSize(localPoint.x(), localPoint.y()).height(); setY(localTop); statePusher.pop(); // FIXME: Since there is always a layer here, repainter shouldn't be necessary. But without it, the dialog is sometimes not painted (see bug 90670). repainter.repaintAfterLayout(); }
void RenderView::positionDialog(RenderBox* box) { HTMLDialogElement* dialog = toHTMLDialogElement(box->node()); if (dialog->centeringMode() == HTMLDialogElement::NotCentered) return; if (dialog->centeringMode() == HTMLDialogElement::Centered) { if (canCenterDialog(box->style())) box->setY(dialog->centeredPosition()); return; } ASSERT(dialog->centeringMode() == HTMLDialogElement::NeedsCentering); if (!canCenterDialog(box->style())) { dialog->setNotCentered(); return; } FrameView* frameView = document().view(); int scrollTop = frameView->scrollOffset().height(); int visibleHeight = frameView->visibleContentRect(ScrollableArea::IncludeScrollbars).height(); LayoutUnit top = scrollTop; if (box->height() < visibleHeight) top += (visibleHeight - box->height()) / 2; box->setY(top); dialog->setCentered(top); }
IntSize WebFrame::scrollOffset() const { if (!m_coreFrame) return IntSize(); FrameView* view = m_coreFrame->view(); if (!view) return IntSize(); return view->scrollOffset(); }
IntSize WebFrame::scrollOffset() { Frame* coreFrame = core(this); if (!coreFrame) return IntSize(); FrameView* view = coreFrame->view(); if (!view) return IntSize(); return view->scrollOffset(); }
static bool pointWithScrollAndZoomIfPossible(const Document& document, IntPoint& point) { LocalFrame* frame = document.frame(); if (!frame) return false; FrameView* frameView = frame->view(); if (!frameView) return false; FloatPoint pointInDocument(point); pointInDocument.scale(frame->pageZoomFactor(), frame->pageZoomFactor()); pointInDocument.move(frameView->scrollOffset()); IntPoint roundedPointInDocument = roundedIntPoint(pointInDocument); if (!frameView->visibleContentRect().contains(roundedPointInDocument)) return false; point = roundedPointInDocument; return true; }
bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) { if (request.allowsChildFrameContent() && widget() && widget()->isFrameView() && toFrameView(widget())->renderView()) { FrameView* childFrameView = toFrameView(widget()); RenderView* childRoot = childFrameView->renderView(); LayoutPoint adjustedLocation = accumulatedOffset + location(); LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - childFrameView->scrollOffset(); HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset); HitTestRequest newHitTestRequest(request.type() | HitTestRequest::ChildFrameHitTest); HitTestResult childFrameResult(newHitTestLocation); bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTestLocation, childFrameResult); if (newHitTestLocation.isRectBasedTest()) result.append(childFrameResult); else if (isInsideChildFrame) result = childFrameResult; if (isInsideChildFrame) return true; } bool hadResult = result.innerNode(); bool inside = RenderReplaced::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action); // Check to see if we are really over the widget itself (and not just in the border/padding area). if ((inside || result.isRectBasedTest()) && !hadResult && result.innerNode() == &frameOwnerElement()) result.setIsOverWidget(contentBoxRect().contains(result.localPoint())); return inside; }
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)); }
bool LayoutPart::nodeAtPoint(HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) { if (!widget() || !widget()->isFrameView() || !result.hitTestRequest().allowsChildFrameContent()) return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, action); // A hit test can never hit an off-screen element; only off-screen iframes are throttled; // therefore, hit tests can skip descending into throttled iframes. if (toFrameView(widget())->shouldThrottleRendering()) return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, action); ASSERT(document().lifecycle().state() >= DocumentLifecycle::CompositingClean); if (action == HitTestForeground) { FrameView* childFrameView = toFrameView(widget()); LayoutView* childRoot = childFrameView->layoutView(); if (visibleToHitTestRequest(result.hitTestRequest()) && childRoot) { LayoutPoint adjustedLocation = accumulatedOffset + location(); LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - LayoutSize(childFrameView->scrollOffset()); HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset); HitTestRequest newHitTestRequest(result.hitTestRequest().type() | HitTestRequest::ChildFrameHitTest); HitTestResult childFrameResult(newHitTestRequest, newHitTestLocation); // The frame's layout and style must be up-to-date if we reach here. bool isInsideChildFrame = childRoot->hitTestNoLifecycleUpdate(childFrameResult); if (result.hitTestRequest().listBased()) { result.append(childFrameResult); } else if (isInsideChildFrame) { // Force the result not to be cacheable because the parent // frame should not cache this result; as it won't be notified of // changes in the child. childFrameResult.setCacheable(false); result = childFrameResult; } // Don't trust |isInsideChildFrame|. For rect-based hit-test, returns // true only when the hit test rect is totally within the iframe, // i.e. nodeAtPointOverWidget() also returns true. // Use a temporary HitTestResult because we don't want to collect the // iframe element itself if the hit-test rect is totally within the iframe. if (isInsideChildFrame) { if (!locationInContainer.isRectBasedTest()) return true; HitTestResult pointOverWidgetResult = result; bool pointOverWidget = nodeAtPointOverWidget(pointOverWidgetResult, locationInContainer, accumulatedOffset, action); if (pointOverWidget) return true; result = pointOverWidgetResult; return false; } } } return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, action); }
bool RenderPart::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) { if (!widget() || !widget()->isFrameView() || !request.allowsChildFrameContent()) return RenderWidget::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action); FrameView* childFrameView = toFrameView(widget()); RenderView* childRoot = childFrameView->renderView(); if (childRoot) { LayoutPoint adjustedLocation = accumulatedOffset + location(); LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - childFrameView->scrollOffset(); HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset); HitTestRequest newHitTestRequest(request.type() | HitTestRequest::ChildFrameHitTest); HitTestResult childFrameResult(newHitTestLocation); bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTestLocation, childFrameResult); if (newHitTestLocation.isRectBasedTest()) result.append(childFrameResult); else if (isInsideChildFrame) result = childFrameResult; if (isInsideChildFrame) return true; if (request.allowsFrameScrollbars()) { // ScrollView scrollbars are not the same as RenderLayer scrollbars tested by RenderLayer::hitTestOverflowControls, // so we need to test ScrollView scrollbars separately here. // FIXME: Consider if this test could be done unconditionally. Scrollbar* frameScrollbar = childFrameView->scrollbarAtPoint(newHitTestLocation.roundedPoint()); if (frameScrollbar) result.setScrollbar(frameScrollbar); } } return RenderWidget::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action); }
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)); }
bool LayoutPart::nodeAtPoint(HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action) { if (!widget() || !widget()->isFrameView() || !result.hitTestRequest().allowsChildFrameContent()) return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, action); FrameView* childFrameView = toFrameView(widget()); LayoutView* childRoot = childFrameView->layoutView(); if (visibleToHitTestRequest(result.hitTestRequest()) && childRoot) { LayoutPoint adjustedLocation = accumulatedOffset + location(); LayoutPoint contentOffset = LayoutPoint(borderLeft() + paddingLeft(), borderTop() + paddingTop()) - LayoutSize(childFrameView->scrollOffset()); HitTestLocation newHitTestLocation(locationInContainer, -adjustedLocation - contentOffset); HitTestRequest newHitTestRequest(result.hitTestRequest().type() | HitTestRequest::ChildFrameHitTest); HitTestResult childFrameResult(newHitTestRequest, newHitTestLocation); bool isInsideChildFrame = childRoot->hitTest(newHitTestRequest, newHitTestLocation, childFrameResult); if (result.hitTestRequest().listBased()) result.append(childFrameResult); else if (isInsideChildFrame) result = childFrameResult; if (isInsideChildFrame) return true; } return nodeAtPointOverWidget(result, locationInContainer, accumulatedOffset, action); }