void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event) { ASSERT(parent()->isFrameView()); // We cache the parent FrameView here as the plugin widget could be deleted // in the call to HandleEvent. See http://b/issue?id=1362948 FrameView* parentView = static_cast<FrameView*>(parent()); WebMouseEventBuilder webEvent(parentView, *event); if (webEvent.type == WebInputEvent::Undefined) return; if (event->type() == eventNames().mousedownEvent) { // Ensure that the frame containing the plugin has focus. Frame* containingFrame = parentView->frame(); if (Page* currentPage = containingFrame->page()) currentPage->focusController()->setFocusedFrame(containingFrame); // Give focus to our containing HTMLPluginElement. containingFrame->document()->setFocusedNode(m_element); } WebCursorInfo cursorInfo; if (m_webPlugin->handleInputEvent(webEvent, cursorInfo)) event->setDefaultHandled(); // A windowless plugin can change the cursor in response to a mouse move // event. We need to reflect the changed cursor in the frame view as the // mouse is moved in the boundaries of the windowless plugin. Page* page = parentView->frame()->page(); if (!page) return; ChromeClientImpl* chromeClient = static_cast<ChromeClientImpl*>(page->chrome()->client()); chromeClient->setCursorForPlugin(cursorInfo); }
void ScrollbarThemeComposite::paintScrollCorner(ScrollView* view, GraphicsContext* context, const IntRect& cornerRect) { FrameView* frameView = static_cast<FrameView*>(view); Page* page = frameView->frame() ? frameView->frame()->page() : 0; if (page && page->settings()->shouldPaintCustomScrollbars() && page->chrome()->client()->paintCustomScrollCorner(context, cornerRect)) return; context->fillRect(cornerRect, Color::white, DeviceColorSpace); }
void RenderPartObject::layout() { ASSERT(needsLayout()); calcWidth(); calcHeight(); #ifdef FLATTEN_IFRAME // Some IFrames have a width and/or height of 1 when they are meant to be // hidden. If that is the case, don't try to expand. if (m_widget && m_widget->isFrameView() && m_width > 1 && m_height > 1) { FrameView* view = static_cast<FrameView*>(m_widget); RenderView* root = NULL; if (view->frame() && view->frame()->document() && view->frame()->document()->renderer() && view->frame()->document()->renderer()->isRenderView()) root = static_cast<RenderView*>(view->frame()->document()->renderer()); if (root) { // Update the dimensions to get the correct minimum preferred width updateWidgetPosition(); // Use the preferred width if it is larger. m_width = max(m_width, root->minPrefWidth()); int extraWidth = paddingLeft() + paddingRight() + borderLeft() + borderRight(); int extraHeight = paddingTop() + paddingBottom() + borderTop() + borderBottom(); // Resize the view to recalc the height. int height = m_height - extraHeight; int width = m_width - extraWidth; if (width > view->width()) height = 0; if (width != view->width() || height != view->height()) { view->resize(width, height); root->setNeedsLayout(true, false); } // Layout the view. if (view->needsLayout()) view->layout(); int contentHeight = view->contentsHeight(); int contentWidth = view->contentsWidth(); // Do not shrink iframes with specified sizes if (contentHeight > m_height || style()->height().isAuto()) m_height = contentHeight; m_width = std::min(contentWidth, 800); } } #endif adjustOverflowForBoxShadow(); RenderPart::layout(); if (!m_widget && m_view) m_view->addWidgetToUpdate(this); setNeedsLayout(false); }
static Page* pageForScrollView(ScrollView* view) { if (!view) return 0; if (!view->isFrameView()) return 0; FrameView* frameView = static_cast<FrameView*>(view); if (!frameView->frame()) return 0; return frameView->frame()->page(); }
TEST(RemoteFrameThrottlingTest, ThrottledLocalRoot) { FrameTestHelpers::TestWebViewClient viewClient; WebViewImpl* webView = WebViewImpl::create(&viewClient); webView->resize(WebSize(640, 480)); // Create a remote root frame with a local child frame. FrameTestHelpers::TestWebRemoteFrameClient remoteClient; webView->setMainFrame(remoteClient.frame()); remoteClient.frame()->setReplicatedOrigin(WebSecurityOrigin::createUnique()); WebFrameOwnerProperties properties; FrameTestHelpers::TestWebFrameClient localFrameClient; WebRemoteFrame* rootFrame = webView->mainFrame()->toWebRemoteFrame(); WebLocalFrame* localFrame = rootFrame->createLocalChild(WebTreeScopeType::Document, "", WebSandboxFlags::None, &localFrameClient, nullptr, properties); WebString baseURL("http://internal.test/"); URLTestHelpers::registerMockedURLFromBaseURL(baseURL, "simple_div.html"); FrameTestHelpers::loadFrame(localFrame, baseURL.utf8() + "simple_div.html"); FrameView* frameView = toWebLocalFrameImpl(localFrame)->frameView(); EXPECT_TRUE(frameView->frame().isLocalRoot()); // Enable throttling for the child frame. frameView->setFrameRect(IntRect(0, 480, frameView->width(), frameView->height())); frameView->frame().securityContext()->setSecurityOrigin(SecurityOrigin::createUnique()); frameView->updateAllLifecyclePhases(); testing::runPendingTasks(); EXPECT_TRUE(frameView->shouldThrottleRendering()); Document* frameDocument = frameView->frame().document(); if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) EXPECT_EQ(DocumentLifecycle::PaintClean, frameDocument->lifecycle().state()); else EXPECT_EQ(DocumentLifecycle::PaintInvalidationClean, frameDocument->lifecycle().state()); // Mutate the local child frame contents. auto* divElement = frameDocument->getElementById("div"); divElement->setAttribute(styleAttr, "width: 50px"); EXPECT_EQ(DocumentLifecycle::VisualUpdatePending, frameDocument->lifecycle().state()); // Update the lifecycle again. The frame's lifecycle should not advance // because of throttling even though it is the local root. frameView->updateAllLifecyclePhases(); testing::runPendingTasks(); EXPECT_EQ(DocumentLifecycle::VisualUpdatePending, frameDocument->lifecycle().state()); webView->close(); }
void RenderPartObject::calcHeight() { RenderPart::calcHeight(); if (!node()->hasTagName(iframeTag) || !widget() || !widget()->isFrameView()) return; FrameView* view = static_cast<FrameView*>(widget()); RenderView* root = static_cast<RenderView*>(view->frame()->contentRenderer()); if (!root) return; // Do not expand if the scrollbars are suppressed and the height is fixed. bool scrolling = static_cast<HTMLIFrameElement*>(node())->scrollingMode() != ScrollbarAlwaysOff; if (!scrolling && style()->height().isFixed()) return; // Update the widget updateWidgetPosition(); //SAMSUNG CHANGE >> // Browser freeze issue in http://www.enuri.com/ /* do { view->layout(); } while (view->layoutPending() || root->needsLayout()); */ node()->document()->page()->mainFrame()->view()->layoutIfNeededRecursive(); //SAMSUNG CHANGE << int extraHeight = paddingTop() + paddingBottom() + borderTop() + borderBottom(); setHeight(max(width(), view->contentsHeight() + extraHeight)); // Update one last time to ensure the dimensions. updateWidgetPosition(); }
void RenderFrame::layout() { FrameView* view = static_cast<FrameView*>(widget()); RenderView* root = view ? view->frame()->contentRenderer() : 0; // Do not expand frames which has zero width or height if (!width() || !height() || !root) { updateWidgetPosition(); if (view) view->layout(); setNeedsLayout(false); return; } HTMLFrameElementBase* element = static_cast<HTMLFrameElementBase*>(node()); if (element->scrollingMode() == ScrollbarAlwaysOff && !root->isFrameSet()) { setNeedsLayout(false); return; } // Update the dimensions to get the correct width and height updateWidgetPosition(); if (root->preferredLogicalWidthsDirty()) root->computePreferredLogicalWidths(); // Expand the frame by setting frame height = content height setWidth(max(view->contentsWidth() + borderAndPaddingWidth(), width())); setHeight(max(view->contentsHeight() + borderAndPaddingHeight(), height())); // Update one more time updateWidgetPosition(); setNeedsLayout(false); }
void write(TextStream& ts, const RenderObject& o, int indent) { #if ENABLE(SVG) if (o.isRenderPath()) { write(ts, *toRenderPath(&o), indent); return; } if (o.isSVGContainer()) { writeSVGContainer(ts, o, indent); return; } if (o.isSVGRoot()) { write(ts, *toRenderSVGRoot(&o), indent); return; } if (o.isSVGText()) { if (!o.isText()) writeSVGText(ts, *toRenderBlock(&o), indent); else writeSVGInlineText(ts, *toRenderText(&o), indent); return; } if (o.isSVGImage()) { writeSVGImage(ts, *toRenderImage(&o), indent); return; } #endif writeIndent(ts, indent); ts << o << "\n"; if (o.isText() && !o.isBR()) { const RenderText& text = *toRenderText(&o); for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) { writeIndent(ts, indent + 1); writeTextRun(ts, text, *box); } } for (RenderObject* child = o.firstChild(); child; child = child->nextSibling()) { if (child->hasLayer()) continue; write(ts, *child, indent + 1); } if (o.isWidget()) { Widget* widget = toRenderWidget(&o)->widget(); if (widget && widget->isFrameView()) { FrameView* view = static_cast<FrameView*>(widget); RenderView* root = view->frame()->contentRenderer(); if (root) { view->layout(); RenderLayer* l = root->layer(); if (l) writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()), indent + 1); } } } }
static EA::WebKit::View* GetEAWebKitMediaView(MediaPlayer* pPlayer) { EA::WebKit::View* pView = NULL; if (pPlayer) { FrameView* pFV = pPlayer->frameView(); if (pFV) { const Frame* pFrame = pFV->frame(); const EA::WebKit::WebFrame* pWebFrame = EA::WebKit::WebFramePrivate::kit(pFrame); if (pWebFrame) { pView = pWebFrame->page()->view(); } } // If we fail to get the view from the player (might not be set yet by WebKit), we can try to get it from the document directly. if (!pView) { MediaPlayerClient* pMPClient = pPlayer->mediaPlayerClient(); if ( (pMPClient) && (pMPClient->mediaPlayerOwningDocument()) ) { Document* pDoc = pMPClient->mediaPlayerOwningDocument(); const Frame* pFrame = pDoc->frame(); const EA::WebKit::WebFrame* pWebFrame = EA::WebKit::WebFramePrivate::kit(pFrame); if (pWebFrame) { pView = pWebFrame->page()->view(); } } } } return pView; }
// FIXME: This should not be necessary. Remove this once WebKit knows to properly schedule // layouts using WebCore when objects resize. void RenderPart::updateWidgetPosition() { if (!m_widget) return; int x, y, width, height; absolutePosition(x, y); x += borderLeft() + paddingLeft(); y += borderTop() + paddingTop(); width = m_width - borderLeft() - borderRight() - paddingLeft() - paddingRight(); height = m_height - borderTop() - borderBottom() - paddingTop() - paddingBottom(); IntRect newBounds(x,y,width,height); if (newBounds != m_widget->frameGeometry()) { // The widget changed positions. Update the frame geometry. RenderArena *arena = ref(); element()->ref(); m_widget->setFrameGeometry(newBounds); element()->deref(); deref(arena); FrameView* frameView = m_widget->isFrameView() ? static_cast<FrameView*>(m_widget) : 0; if (frameView && !frameView->frame()->settings()->flatFrameSetLayoutEnabled()) frameView->layout(); } }
RenderView* RenderIFrame::contentRootRenderer() const { // FIXME: Is this always a valid cast? What about plugins? ASSERT(!widget() || widget()->isFrameView()); FrameView* childFrameView = toFrameView(widget()); return childFrameView ? childFrameView->frame()->contentRenderer() : 0; }
WebRenderObject::WebRenderObject(RenderObject* renderer) { m_name = renderer->renderName(); // FIXME: broken with transforms m_absolutePosition = flooredIntPoint(renderer->localToAbsolute(FloatPoint())); if (renderer->isBox()) m_frameRect = toRenderBox(renderer)->frameRect(); else if (renderer->isText()) { m_frameRect = toRenderText(renderer)->linesBoundingBox(); m_frameRect.setX(toRenderText(renderer)->firstRunX()); m_frameRect.setY(toRenderText(renderer)->firstRunY()); } else if (renderer->isRenderInline()) m_frameRect = toRenderBoxModelObject(renderer)->borderBoundingBox(); m_children = MutableArray::create(); for (RenderObject* coreChild = renderer->firstChild(); coreChild; coreChild = coreChild->nextSibling()) { RefPtr<WebRenderObject> child = adoptRef(new WebRenderObject(coreChild)); m_children->append(child.get()); } if (!renderer->isWidget()) return; Widget* widget = toRenderWidget(renderer)->widget(); if (!widget || !widget->isFrameView()) return; FrameView* frameView = static_cast<FrameView*>(widget); if (RenderView* coreContentRenderer = frameView->frame()->contentRenderer()) { RefPtr<WebRenderObject> contentRenderer = adoptRef(new WebRenderObject(coreContentRenderer)); m_children->append(contentRenderer.get()); } }
void ScrollView::scrollTo(const IntSize& newOffset) { IntSize scrollDelta = newOffset - m_scrollOffset; if (scrollDelta == IntSize()) return; m_scrollOffset = newOffset; #if PLATFORM(ANDROID) if (parent()) { FrameView* frameView = this->frameView(); // IFrames are composited on a layer, we do not need to repaint them // when scrolling if (frameView) { RenderView* renderer = frameView->frame()->contentRenderer(); if (renderer) { RenderLayer* layer = renderer->layer(); if (layer->backing()) { GraphicsLayerAndroid* backing = static_cast<GraphicsLayerAndroid*>( layer->backing()->graphicsLayer()); backing->updateScrollOffset(); } } return; } } #endif if (scrollbarsSuppressed()) return; repaintFixedElementsAfterScrolling(); scrollContents(scrollDelta); }
void PaintPropertyTreeBuilder::buildTreeRootNodes(FrameView& rootFrame, PaintPropertyTreeBuilderContext& context) { // Only create extra root clip and transform nodes when RLS is enabled, because the main frame // unconditionally create frame translation / clip nodes otherwise. if (rootFrame.frame().settings() && rootFrame.frame().settings()->rootLayerScrolls()) { transformRoot = TransformPaintPropertyNode::create(TransformationMatrix(), FloatPoint3D(), nullptr); context.currentTransform = context.transformForAbsolutePosition = context.transformForFixedPosition = transformRoot.get(); clipRoot = ClipPaintPropertyNode::create(transformRoot, FloatRoundedRect(LayoutRect::infiniteIntRect()), nullptr); context.currentClip = context.clipForAbsolutePosition = context.clipForFixedPosition = clipRoot.get(); } // The root frame never creates effect node so we unconditionally create a root node here. effectRoot = EffectPaintPropertyNode::create(1.0, nullptr); context.currentEffect = effectRoot.get(); }
Document* AXObject::document() const { FrameView* frameView = documentFrameView(); if (!frameView) return 0; return frameView->frame().document(); }
Document* AccessibilityObject::document() const { FrameView* frameView = documentFrameView(); if (!frameView) return 0; return frameView->frame()->document(); }
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 } }
void PluginView::setParent(ScrollView* parentWidget) { // If parentWidget is 0, lets unregister the plugin with the current parent. if (m_private && (!parentWidget || parentWidget != parent())) { if (FrameView* frameView = toFrameView(parent())) { if (m_private->m_isBackgroundPlaying) frameView->hostWindow()->platformPageClient()->onPluginStopBackgroundPlay(this, m_private->m_pluginUniquePrefix.c_str()); if (m_private->m_isFullScreen) handleFullScreenExitEvent(); // This will unlock the idle (if we have locked it). m_private->preventIdle(false); // This will release any keepVisibleRects if they were set. m_private->clearVisibleRects(); #if USE(ACCELERATED_COMPOSITING) // If we had a hole punch rect set, clear it. if (m_private->m_platformLayer && !m_private->m_holePunchRect.isEmpty()) m_private->m_platformLayer->setHolePunchRect(IntRect()); #endif frameView->hostWindow()->platformPageClient()->registerPlugin(this, false /*shouldRegister*/); } } Widget::setParent(parentWidget); if (parentWidget) { init(); FrameView* frameView = toFrameView(parentWidget); if (frameView && m_private) { frameView->hostWindow()->platformPageClient()->registerPlugin(this, true /*shouldRegister*/); if (frameView->frame() && frameView->frame()->loader() && frameView->frame()->loader()->frameHasLoaded()) handleOnLoadEvent(); if (m_private->m_isBackgroundPlaying) frameView->hostWindow()->platformPageClient()->onPluginStartBackgroundPlay(this, m_private->m_pluginUniquePrefix.c_str()); } } }
void HTMLBodyElement::setScrollLeft(int scrollLeft) { FrameView* sview = ownerDocument()->view(); if (sview) { // Update the document's layout document()->updateLayoutIgnorePendingStylesheets(); sview->setScrollPosition(IntPoint(static_cast<int>(scrollLeft * sview->frame()->zoomFactor()), sview->scrollY())); } }
void ScrollingCoordinator::updateSynchronousScrollingReasons(FrameView& frameView) { // FIXME: Once we support async scrolling of iframes, we'll have to track the synchronous scrolling // reasons per frame (maybe on scrolling tree nodes). if (!frameView.frame().isMainFrame()) return; setSynchronousScrollingReasons(synchronousScrollingReasons(frameView)); }
void AsyncScrollingCoordinator::frameViewLayoutUpdated(FrameView& frameView) { ASSERT(isMainThread()); ASSERT(m_page); // If there isn't a root node yet, don't do anything. We'll be called again after creating one. if (!m_scrollingStateTree->rootStateNode()) return; // Compute the region of the page that we can't do fast scrolling for. This currently includes // all scrollable areas, such as subframes, overflow divs and list boxes. We need to do this even if the // frame view whose layout was updated is not the main frame. // In the future, we may want to have the ability to set non-fast scrolling regions for more than // just the root node. But right now, this concept only applies to the root. m_scrollingStateTree->rootStateNode()->setNonFastScrollableRegion(computeNonFastScrollableRegion(m_page->mainFrame(), IntPoint())); m_nonFastScrollableRegionDirty = false; if (!coordinatesScrollingForFrameView(frameView)) return; ScrollingStateFrameScrollingNode* node = downcast<ScrollingStateFrameScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID())); if (!node) return; Scrollbar* verticalScrollbar = frameView.verticalScrollbar(); Scrollbar* horizontalScrollbar = frameView.horizontalScrollbar(); node->setScrollbarPaintersFromScrollbars(verticalScrollbar, horizontalScrollbar); node->setFrameScaleFactor(frameView.frame().frameScaleFactor()); node->setHeaderHeight(frameView.headerHeight()); node->setFooterHeight(frameView.footerHeight()); node->setTopContentInset(frameView.topContentInset()); node->setScrollOrigin(frameView.scrollOrigin()); node->setScrollableAreaSize(frameView.visibleContentRect().size()); node->setTotalContentsSize(frameView.totalContentsSize()); node->setReachableContentsSize(frameView.totalContentsSize()); #if ENABLE(CSS_SCROLL_SNAP) frameView.updateSnapOffsets(); if (const Vector<LayoutUnit>* horizontalSnapOffsets = frameView.horizontalSnapOffsets()) setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Horizontal, *horizontalSnapOffsets, m_page->deviceScaleFactor()); if (const Vector<LayoutUnit>* verticalSnapOffsets = frameView.verticalSnapOffsets()) setStateScrollingNodeSnapOffsetsAsFloat(*node, ScrollEventAxis::Vertical, *verticalSnapOffsets, m_page->deviceScaleFactor()); #endif ScrollableAreaParameters scrollParameters; scrollParameters.horizontalScrollElasticity = frameView.horizontalScrollElasticity(); scrollParameters.verticalScrollElasticity = frameView.verticalScrollElasticity(); scrollParameters.hasEnabledHorizontalScrollbar = horizontalScrollbar && horizontalScrollbar->enabled(); scrollParameters.hasEnabledVerticalScrollbar = verticalScrollbar && verticalScrollbar->enabled(); scrollParameters.horizontalScrollbarMode = frameView.horizontalScrollbarMode(); scrollParameters.verticalScrollbarMode = frameView.verticalScrollbarMode(); node->setScrollableAreaParameters(scrollParameters); }
static ChromeClientImpl* toChromeClientImpl(Widget* widget) { if (!widget) return 0; FrameView* view; if (widget->isFrameView()) view = static_cast<FrameView*>(widget); else if (widget->parent() && widget->parent()->isFrameView()) view = static_cast<FrameView*>(widget->parent()); else return 0; Page* page = view->frame() ? view->frame()->page() : 0; if (!page) return 0; return static_cast<ChromeClientImpl*>(page->chrome()->client()); }
void RenderFrameBase::layoutWithFlattening(bool fixedWidth, bool fixedHeight) { FrameView* childFrameView = static_cast<FrameView*>(widget()); RenderView* childRoot = childFrameView ? static_cast<RenderView*>(childFrameView->frame()->contentRenderer()) : 0; // Do not expand frames which has zero width or height if (!width() || !height() || !childRoot) { updateWidgetPosition(); if (childFrameView) childFrameView->layout(); setNeedsLayout(false); return; } // need to update to calculate min/max correctly updateWidgetPosition(); if (childRoot->preferredLogicalWidthsDirty()) childRoot->computePreferredLogicalWidths(); // if scrollbars are off, and the width or height are fixed // we obey them and do not expand. With frame flattening // no subframe much ever become scrollable. HTMLFrameElementBase* element = static_cast<HTMLFrameElementBase*>(node()); bool isScrollable = element->scrollingMode() != ScrollbarAlwaysOff; // consider iframe inset border int hBorder = borderLeft() + borderRight(); int vBorder = borderTop() + borderBottom(); // make sure minimum preferred width is enforced if (isScrollable || !fixedWidth) { setWidth(max(width(), childRoot->minPreferredLogicalWidth() + hBorder)); // update again to pass the new width to the child frame updateWidgetPosition(); childFrameView->layout(); } // expand the frame by setting frame height = content height if (isScrollable || !fixedHeight || childRoot->isFrameSet()) setHeight(max(height(), childFrameView->contentsHeight() + vBorder)); if (isScrollable || !fixedWidth || childRoot->isFrameSet()) setWidth(max(width(), childFrameView->contentsWidth() + hBorder)); updateWidgetPosition(); ASSERT(!childFrameView->layoutPending()); ASSERT(!childRoot->needsLayout()); ASSERT(!childRoot->firstChild() || !childRoot->firstChild()->firstChild() || !childRoot->firstChild()->firstChild()->needsLayout()); setNeedsLayout(false); }
void RenderFrameSet::layout() { ASSERT(needsLayout()); bool doFullRepaint = selfNeedsLayout() && checkForRepaintDuringLayout(); IntRect oldBounds; if (doFullRepaint) oldBounds = absoluteClippedOverflowRect(); if (!parent()->isFrameSet()) { FrameView* v = view()->frameView(); m_width = v->visibleWidth(); m_height = v->visibleHeight(); if (flattenFrameset()) { // make the top level frameset at least 800*600 wide/high calcPrefWidths(); m_width = max(m_width, m_minPrefWidth); if (!v->frame()->ownerElement()) m_height = max(m_height, 600); } } size_t cols = frameSet()->totalCols(); size_t rows = frameSet()->totalRows(); if (m_rows.m_sizes.size() != rows || m_cols.m_sizes.size() != cols) { m_rows.resize(rows); m_cols.resize(cols); } int borderThickness = frameSet()->border(); layOutAxis(m_rows, frameSet()->rowLengths(), m_height - (rows - 1) * borderThickness); layOutAxis(m_cols, frameSet()->colLengths(), m_width - (cols - 1) * borderThickness); if (flattenFrameset()) positionFramesWithFlattening(); else positionFrames(); RenderContainer::layout(); computeEdgeInfo(); if (doFullRepaint) { view()->repaintViewRectangle(oldBounds); IntRect newBounds = absoluteClippedOverflowRect(); if (newBounds != oldBounds) view()->repaintViewRectangle(newBounds); } setNeedsLayout(false); }
void ChromeClientImpl::scheduleAnimation(Widget* widget) { DCHECK(widget->isFrameView()); FrameView* view = toFrameView(widget); LocalFrame* frame = view->frame().localFrameRoot(); // If the frame is still being created, it might not yet have a WebWidget. // FIXME: Is this the right thing to do? Is there a way to avoid having // a local frame root that doesn't have a WebWidget? During initialization // there is no content to draw so this call serves no purpose. if (WebLocalFrameImpl::fromFrame(frame) && WebLocalFrameImpl::fromFrame(frame)->frameWidget()) WebLocalFrameImpl::fromFrame(frame)->frameWidget()->scheduleAnimation(); }
bool ScrollingCoordinator::coordinatesScrollingForFrameView(const FrameView& frameView) const { ASSERT(isMainThread()); ASSERT(m_page); if (!frameView.frame().isMainFrame() && !m_page->settings().scrollingTreeIncludesFrames()) return false; RenderView* renderView = m_page->mainFrame().contentRenderer(); if (!renderView) return false; return renderView->usesCompositing(); }
SynchronousScrollingReasons ScrollingCoordinator::synchronousScrollingReasons(const FrameView& frameView) const { SynchronousScrollingReasons synchronousScrollingReasons = (SynchronousScrollingReasons)0; if (m_forceSynchronousScrollLayerPositionUpdates) synchronousScrollingReasons |= ForcedOnMainThread; #if ENABLE(WEB_REPLAY) InputCursor& cursor = m_page->replayController().activeInputCursor(); if (cursor.isCapturing() || cursor.isReplaying()) synchronousScrollingReasons |= ForcedOnMainThread; #endif if (frameView.hasSlowRepaintObjects()) synchronousScrollingReasons |= HasSlowRepaintObjects; if (!supportsFixedPositionLayers() && frameView.hasViewportConstrainedObjects()) synchronousScrollingReasons |= HasViewportConstrainedObjectsWithoutSupportingFixedLayers; if (supportsFixedPositionLayers() && hasVisibleSlowRepaintViewportConstrainedObjects(frameView)) synchronousScrollingReasons |= HasNonLayerViewportConstrainedObjects; if (frameView.frame().mainFrame().document() && frameView.frame().document()->isImageDocument()) synchronousScrollingReasons |= IsImageDocument; return synchronousScrollingReasons; }
// Return a set of rectangles that should not be overdrawn by the // plugin ("cutouts"). This helps implement the "iframe shim" // technique of overlaying a windowed plugin with content from the // page. In a nutshell, iframe elements should occlude plugins when // they occur higher in the stacking order. void getPluginOcclusions(Element* element, Widget* parentWidget, const IntRect& frameRect, Vector<IntRect>& occlusions) { RenderObject* pluginNode = element->renderer(); ASSERT(pluginNode); if (!pluginNode->style()) return; Vector<const RenderObject*> pluginZstack; Vector<const RenderObject*> iframeZstack; getObjectStack(pluginNode, &pluginZstack); if (!parentWidget->isFrameView()) return; FrameView* parentFrameView = toFrameView(parentWidget); // Occlusions by iframes. const FrameView::ChildrenWidgetSet* children = parentFrameView->children(); for (FrameView::ChildrenWidgetSet::const_iterator it = children->begin(); it != children->end(); ++it) { // We only care about FrameView's because iframes show up as FrameViews. if (!(*it)->isFrameView()) continue; const FrameView* frameView = toFrameView(it->get()); // Check to make sure we can get both the element and the RenderObject // for this FrameView, if we can't just move on to the next object. // FIXME: Plugin occlusion by remote frames is probably broken. HTMLElement* element = frameView->frame().deprecatedLocalOwner(); if (!element || !element->renderer()) continue; RenderObject* iframeRenderer = element->renderer(); if (isHTMLIFrameElement(*element) && intersectsRect(iframeRenderer, frameRect)) { getObjectStack(iframeRenderer, &iframeZstack); if (iframeIsAbovePlugin(iframeZstack, pluginZstack)) addToOcclusions(toRenderBox(iframeRenderer), occlusions); } } // Occlusions by top layer elements. // FIXME: There's no handling yet for the interaction between top layer and // iframes. For example, a plugin in the top layer will be occluded by an // iframe. And a plugin inside an iframe in the top layer won't be respected // as being in the top layer. const Element* ancestor = topLayerAncestor(element); Document* document = parentFrameView->frame().document(); const WillBeHeapVector<RefPtrWillBeMember<Element> >& elements = document->topLayerElements(); size_t start = ancestor ? elements.find(ancestor) + 1 : 0; for (size_t i = start; i < elements.size(); ++i) addTreeToOcclusions(elements[i]->renderer(), frameRect, occlusions); }
static WebWidgetClient* toWebWidgetClient(Widget* widget) { if (!widget) return 0; FrameView* view; if (widget->isFrameView()) view = static_cast<FrameView*>(widget); else if (widget->parent() && widget->parent()->isFrameView()) view = static_cast<FrameView*>(widget->parent()); else return 0; Page* page = view->frame() ? view->frame()->page() : 0; if (!page) return 0; void* webView = page->chrome()->client()->webView(); if (!webView) return 0; return static_cast<WebViewImpl*>(webView)->client(); }
bool AsyncScrollingCoordinator::requestScrollPositionUpdate(FrameView& frameView, const IntPoint& scrollPosition) { ASSERT(isMainThread()); ASSERT(m_page); if (!coordinatesScrollingForFrameView(frameView)) return false; bool isProgrammaticScroll = frameView.inProgrammaticScroll(); if (isProgrammaticScroll || frameView.frame().document()->inPageCache()) updateScrollPositionAfterAsyncScroll(frameView.scrollLayerID(), scrollPosition, isProgrammaticScroll, SetScrollingLayerPosition); // If this frame view's document is being put into the page cache, we don't want to update our // main frame scroll position. Just let the FrameView think that we did. if (frameView.frame().document()->inPageCache()) return true; ScrollingStateScrollingNode* stateNode = downcast<ScrollingStateScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollLayerID())); if (!stateNode) return false; stateNode->setRequestedScrollPosition(scrollPosition, isProgrammaticScroll); return true; }