#include "AXObjectCache.h"
#include "CSSStyleSelector.h"
+#include "CachedResourceLoader.h"
#include "Chrome.h"
#include "ChromeClient.h"
-#include "CachedResourceLoader.h"
#include "EventHandler.h"
#include "FloatRect.h"
#include "FocusController.h"
#include "HTMLFrameSetElement.h"
#include "HTMLNames.h"
#include "HTMLPlugInImageElement.h"
-#include "InspectorTimelineAgent.h"
+#include "InspectorInstrumentation.h"
#include "OverflowEvent.h"
#include "RenderEmbeddedObject.h"
#include "RenderLayer.h"
RefPtr<Node> m_eventTarget;
};
-static inline float parentZoomFactor(Frame* frame)
-{
- Frame* parent = frame->tree()->parent();
- if (!parent)
- return 1;
- FrameView* parentView = parent->view();
- if (!parentView)
- return 1;
- return parentView->zoomFactor();
-}
-
FrameView::FrameView(Frame* frame)
: m_frame(frame)
, m_canHaveScrollbars(true)
, m_deferSetNeedsLayouts(0)
, m_setNeedsLayoutWasDeferred(false)
, m_scrollCorner(0)
- , m_zoomFactor(parentZoomFactor(frame))
{
init();
}
m_wasScrolledByUser = false;
m_lastLayoutSize = IntSize();
m_lastZoomFactor = 1.0f;
- m_pageHeight = 0;
m_deferringRepaints = 0;
m_repaintCount = 0;
m_repaintRects.clear();
ScrollbarMode vMode;
scrollbarModes(hMode, vMode);
if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
- m_canHaveScrollbars = false;
+ setCanHaveScrollbars(false);
else
- m_canHaveScrollbars = true;
+ setCanHaveScrollbars(true);
}
PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
m_viewportRenderer = o;
}
+void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode)
+{
+ if (m_canHaveScrollbars) {
+ hMode = ScrollbarAuto;
+ vMode = ScrollbarAuto;
+ } else {
+ hMode = ScrollbarAlwaysOff;
+ vMode = ScrollbarAlwaysOff;
+ }
+
+ if (!m_layoutRoot) {
+ Document* document = m_frame->document();
+ Node* documentElement = document->documentElement();
+ RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
+ Node* body = document->body();
+ if (body && body->renderer()) {
+ if (body->hasTagName(framesetTag) && m_frame->settings() && !m_frame->settings()->frameFlatteningEnabled()) {
+#if !defined(ANDROID_FLATTEN_IFRAME) && !defined(ANDROID_FLATTEN_FRAMESET)
+ body->renderer()->setChildNeedsLayout(true);
+ vMode = ScrollbarAlwaysOff;
+ hMode = ScrollbarAlwaysOff;
+#endif
+ } else if (body->hasTagName(bodyTag)) {
+ // It's sufficient to just check the X overflow,
+ // since it's illegal to have visible in only one direction.
+ RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && document->documentElement()->hasTagName(htmlTag) ? body->renderer() : rootRenderer;
+ applyOverflowToViewport(o, hMode, vMode);
+ }
+ } else if (rootRenderer) {
+#if ENABLE(SVG)
+ if (documentElement->isSVGElement()) {
+ if (!m_firstLayout && (m_size.width() != layoutWidth() || m_size.height() != layoutHeight()))
+ rootRenderer->setChildNeedsLayout(true);
+ } else
+ applyOverflowToViewport(rootRenderer, hMode, vMode);
+#else
+ applyOverflowToViewport(rootRenderer, hMode, vMode);
+#endif
+ }
+#ifdef INSTRUMENT_LAYOUT_SCHEDULING
+ if (m_firstLayout && !document->ownerElement())
+ printf("Elapsed time before first layout: %d\n", document->elapsedTime());
+#endif
+ }
+
+ HTMLFrameOwnerElement* owner = m_frame->ownerElement();
+ if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) {
+ hMode = ScrollbarAlwaysOff;
+ vMode = ScrollbarAlwaysOff;
+ }
+}
+
#if USE(ACCELERATED_COMPOSITING)
void FrameView::updateCompositingLayers()
{
if (isPainting())
return;
-#if ENABLE(INSPECTOR)
- if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
- timelineAgent->willLayout();
-#endif
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(m_frame.get());
if (!allowSubtree && m_layoutRoot) {
m_layoutRoot->markContainingBlocksForLayout(false);
ScrollbarMode hMode;
ScrollbarMode vMode;
- if (m_canHaveScrollbars) {
- hMode = ScrollbarAuto;
- vMode = ScrollbarAuto;
- } else {
- hMode = ScrollbarAlwaysOff;
- vMode = ScrollbarAlwaysOff;
- }
-
- if (!subtree) {
- Node* documentElement = document->documentElement();
- RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
- Node* body = document->body();
- if (body && body->renderer()) {
- if (body->hasTagName(framesetTag) && m_frame->settings() && !m_frame->settings()->frameFlatteningEnabled()) {
-#if !defined(ANDROID_FLATTEN_IFRAME) && !defined(ANDROID_FLATTEN_FRAMESET)
- body->renderer()->setChildNeedsLayout(true);
- vMode = ScrollbarAlwaysOff;
- hMode = ScrollbarAlwaysOff;
-#endif
- } else if (body->hasTagName(bodyTag)) {
- if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox()->stretchesToViewHeight())
- body->renderer()->setChildNeedsLayout(true);
- // It's sufficient to just check the X overflow,
- // since it's illegal to have visible in only one direction.
- RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && document->documentElement()->hasTagName(htmlTag) ? body->renderer() : rootRenderer;
- applyOverflowToViewport(o, hMode, vMode);
- }
- } else if (rootRenderer) {
-#if ENABLE(SVG)
- if (documentElement->isSVGElement()) {
- if (!m_firstLayout && (m_size.width() != layoutWidth() || m_size.height() != layoutHeight()))
- rootRenderer->setChildNeedsLayout(true);
- } else
- applyOverflowToViewport(rootRenderer, hMode, vMode);
-#else
- applyOverflowToViewport(rootRenderer, hMode, vMode);
-#endif
- }
-#ifdef INSTRUMENT_LAYOUT_SCHEDULING
- if (m_firstLayout && !document->ownerElement())
- printf("Elapsed time before first layout: %d\n", document->elapsedTime());
-#endif
- }
+
+ calculateScrollbarModesForLayout(hMode, vMode);
m_doFullRepaint = !subtree && (m_firstLayout || toRenderView(root)->printing());
m_size = IntSize(layoutWidth(), layoutHeight());
- if (oldSize != m_size)
+ if (oldSize != m_size) {
m_doFullRepaint = true;
+ if (!m_firstLayout) {
+ RenderBox* rootRenderer = document->documentElement() ? document->documentElement()->renderBox() : 0;
+ RenderBox* bodyRenderer = rootRenderer && document->body() ? document->body()->renderBox() : 0;
+ if (bodyRenderer && bodyRenderer->stretchesToViewport())
+ bodyRenderer->setChildNeedsLayout(true);
+ else if (rootRenderer && rootRenderer->stretchesToViewport())
+ rootRenderer->setChildNeedsLayout(true);
+ }
+ }
}
RenderLayer* layer = root->enclosingLayer();
if (subtree) {
RenderView* view = root->view();
- view->popLayoutState();
+ view->popLayoutState(root);
if (disableLayoutState)
view->enableLayoutState();
}
m_layoutCount++;
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || PLATFORM(CHROMIUM)
if (AXObjectCache::accessibilityEnabled())
root->document()->axObjectCache()->postNotification(root, AXObjectCache::AXLayoutComplete, true);
#endif
ASSERT(m_enqueueEvents);
}
-#if ENABLE(INSPECTOR)
- if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
- timelineAgent->didLayout();
-#endif
+ InspectorInstrumentation::didLayout(cookie);
m_nestedLayoutCount--;
}
return false;
}
+void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (RenderPart* frameRenderer = m_frame->ownerRenderer()) {
+ if (frameRenderer->containerForRepaint()) {
+ IntRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(),
+ frameRenderer->borderTop() + frameRenderer->paddingTop(),
+ visibleWidth(), visibleHeight());
+ frameRenderer->repaintRectangle(rect);
+ return;
+ }
+ }
+#endif
+
+ ScrollView::scrollContentsSlowPath(updateRect);
+}
+
// Note that this gets called at painting time.
void FrameView::setIsOverlapped(bool isOverlapped)
{
frame()->loader()->client()->didChangeScrollOffset();
}
+void FrameView::valueChanged(const IntSize& scrollDelta)
+{
+ ScrollView::valueChanged(scrollDelta);
+ frame()->eventHandler()->sendScrollEvent();
+ frame()->loader()->client()->didChangeScrollOffset();
+}
+
void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
{
// Add in our offset within the FrameView.
if (!frame())
return;
-#if ENABLE(INSPECTOR)
- if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
- timelineAgent->willPaint(rect);
-#endif
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_frame.get(), rect);
Document* document = frame()->document();
fillWithRed = true;
if (fillWithRed)
- p->fillRect(rect, Color(0xFF, 0, 0), DeviceColorSpace);
+ p->fillRect(rect, Color(0xFF, 0, 0), ColorSpaceDeviceRGB);
#endif
bool isTopLevelPainter = !sCurrentPaintTimeStamp;
if (isTopLevelPainter)
sCurrentPaintTimeStamp = 0;
-#if ENABLE(INSPECTOR)
- if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
- timelineAgent->didPaint();
-#endif
+ InspectorInstrumentation::didPaint(cookie);
}
void FrameView::setPaintBehavior(PaintBehavior behavior)
void FrameView::forceLayout(bool allowSubtree)
{
layout(allowSubtree);
- // We cannot unschedule a pending relayout, since the force can be called with
- // a tiny rectangle from a drawRect update. By unscheduling we in effect
- // "validate" and stop the necessary full repaint from occurring. Basically any basic
- // append/remove DHTML is broken by this call. For now, I have removed the optimization
- // until we have a better invalidation stategy. -dwh
- //unscheduleRelayout();
}
void FrameView::forceLayoutForPagination(const FloatSize& pageSize, float maximumShrinkFactor, Frame::AdjustViewSizeOrNot shouldAdjustViewSize)
RenderView *root = toRenderView(m_frame->document()->renderer());
if (root) {
int pageW = ceilf(pageSize.width());
- m_pageHeight = pageSize.height() ? pageSize.height() : visibleHeight();
root->setWidth(pageW);
+ root->setPageHeight(pageSize.height());
root->setNeedsLayoutAndPrefWidthsRecalc();
forceLayout();
if (rightmostPos > pageSize.width()) {
pageW = std::min<int>(rightmostPos, ceilf(pageSize.width() * maximumShrinkFactor));
if (pageSize.height())
- m_pageHeight = pageW / pageSize.width() * pageSize.height();
+ root->setPageHeight(pageW / pageSize.width() * pageSize.height());
root->setWidth(pageW);
root->setNeedsLayoutAndPrefWidthsRecalc();
forceLayout();
+ int docHeight = root->bottomLayoutOverflow();
+ root->clearLayoutOverflow();
+ root->addLayoutOverflow(IntRect(0, 0, pageW, docHeight)); // This is how we clip in case we overflow again.
}
}
if (shouldAdjustViewSize)
adjustViewSize();
- m_pageHeight = 0;
}
-void FrameView::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
+void FrameView::adjustPageHeightDeprecated(float *newBottom, float oldTop, float oldBottom, float /*bottomLimit*/)
{
RenderView* root = m_frame->contentRenderer();
if (root) {
GraphicsContext context((PlatformGraphicsContext*)0);
root->setTruncatedAt((int)floorf(oldBottom));
IntRect dirtyRect(0, (int)floorf(oldTop), root->rightLayoutOverflow(), (int)ceilf(oldBottom - oldTop));
+ root->setPrintRect(dirtyRect);
root->layer()->paint(&context, dirtyRect);
*newBottom = root->bestTruncatedAt();
if (*newBottom == 0)
*newBottom = oldBottom;
+ root->setPrintRect(IntRect());
} else
*newBottom = oldBottom;
}
return parentPoint;
}
-bool FrameView::shouldApplyTextZoom() const
-{
- if (m_zoomFactor == 1)
- return false;
- if (!m_frame)
- return false;
- Page* page = m_frame->page();
- return page && page->settings()->zoomMode() == ZoomTextOnly;
-}
-
-bool FrameView::shouldApplyPageZoom() const
-{
- if (m_zoomFactor == 1)
- return false;
- if (!m_frame)
- return false;
- Page* page = m_frame->page();
- return page && page->settings()->zoomMode() == ZoomPage;
-}
-
-void FrameView::setZoomFactor(float percent, ZoomMode mode)
-{
- if (!m_frame)
- return;
-
- Page* page = m_frame->page();
- if (!page)
- return;
-
- if (m_zoomFactor == percent && page->settings()->zoomMode() == mode)
- return;
-
- Document* document = m_frame->document();
- if (!document)
- return;
-
-#if ENABLE(SVG)
- // Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
- // FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
- if (document->isSVGDocument()) {
- if (!static_cast<SVGDocument*>(document)->zoomAndPanEnabled())
- return;
- if (document->renderer())
- document->renderer()->setNeedsLayout(true);
- }
-#endif
-
- if (mode == ZoomPage) {
- // Update the scroll position when doing a full page zoom, so the content stays in relatively the same position.
- IntPoint scrollPosition = this->scrollPosition();
- float percentDifference = (percent / m_zoomFactor);
- setScrollPosition(IntPoint(scrollPosition.x() * percentDifference, scrollPosition.y() * percentDifference));
- }
-
- m_zoomFactor = percent;
- page->settings()->setZoomMode(mode);
-
- document->recalcStyle(Node::Force);
-
- for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
- if (FrameView* childView = child->view())
- childView->setZoomFactor(m_zoomFactor, mode);
- }
-
- if (document->renderer() && document->renderer()->needsLayout() && didFirstLayout())
- layout();
-}
-
-
// Normal delay
void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p)
{