Hi, I want to flatten frames within a frameset so that no individual scrollbars of frames would appear. This is the behavior of most mobile browsers including iPhone and Android.
I found the patch from the Android WebKit source code with FLATTEN_FRAMESET. I applied the patch to the latest version of WebKit and adjusted it the latest changes, but it does not seem to work. WebCore/rendering/RenderFrame.cpp +#if USE(FLATTEN_FRAMESET) +void RenderFrame::layout() +{ + if (widget() && widget()->isFrameView()) { + FrameView* view = static_cast<FrameView*>(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) { + // Resize the widget so that the RenderView will layout according to those dimensions. + view->resize(m_width, m_height); + view->layout(); + // We can only grow in width and height because if positionFrames gives us a width and we become smaller, + // then the fixup process of forcing the frame to fill extra space will fail. + if (m_width > root->docWidth()) { + view->resize(root->docWidth(), 0); + view->layout(); + } + // Honor the height set by RenderFrameSet::positionFrames unless our document height is larger. + setHeight(max(root->docHeight(), height())); + setWidth(max(root->docWidth(), width())); + } + } + setNeedsLayout(false); +} +#endif + I tested it with http://java.sun.com/j2se/1.5.0/docs/api/ which has three frames within a frameset. GtkLauncher hangs when it loads the Java API page. However, after I remove the following two lines from the patch, it seems to work and frames are correctly flattened. if (root) { // Resize the widget so that the RenderView will layout according to those dimensions. - view->resize(m_width, m_height); - view->layout(); // We can only grow in width and height because if positionFrames gives us a width and we become smaller, // then the fixup process of forcing the frame to fill extra space will fail. What's the problem here? I attached the whole patch. Thanks, K Seo
Index: WebCore/config.h =================================================================== --- WebCore/config.h (revision 45369) +++ WebCore/config.h (working copy) @@ -176,3 +176,8 @@ typedef float CGFloat; #if PLATFORM(WIN) && PLATFORM(CG) #define WTF_USE_SAFARI_THEME 1 #endif + +#if PLATFORM(GTK) +#define WTF_USE_FLATTEN_FRAMESET 1 +#endif + Index: WebCore/html/HTMLFrameSetElement.cpp =================================================================== --- WebCore/html/HTMLFrameSetElement.cpp (revision 45369) +++ WebCore/html/HTMLFrameSetElement.cpp (working copy) @@ -203,6 +203,9 @@ void HTMLFrameSetElement::recalcStyle(St { if (needsStyleRecalc() && renderer()) { renderer()->setNeedsLayout(true); +#if USE(FLATTEN_FRAMESET) + static_cast<RenderFrameSet*>(renderer())->setGridNeedsLayout(); +#endif setNeedsStyleRecalc(NoStyleChange); } HTMLElement::recalcStyle(ch); Index: WebCore/page/FrameView.cpp =================================================================== --- WebCore/page/FrameView.cpp (revision 45369) +++ WebCore/page/FrameView.cpp (working copy) @@ -953,6 +953,11 @@ void FrameView::scheduleRelayout() printf("Scheduling layout for %d\n", delay); #endif +#if USE(FLATTEN_FRAMESET) + if (m_frame->ownerRenderer()) + m_frame->ownerRenderer()->setNeedsLayoutAndPrefWidthsRecalc(); +#endif + m_layoutTimer.startOneShot(delay * 0.001); } Index: WebCore/rendering/RenderFrame.cpp =================================================================== --- WebCore/rendering/RenderFrame.cpp (revision 45369) +++ WebCore/rendering/RenderFrame.cpp (working copy) @@ -27,6 +27,12 @@ #include "FrameView.h" #include "HTMLFrameElement.h" +#if USE(FLATTEN_FRAMESET) +#include "Frame.h" +#include "Document.h" +#include "RenderView.h" +#endif + namespace WebCore { RenderFrame::RenderFrame(HTMLFrameElement* frame) @@ -58,4 +64,32 @@ void RenderFrame::viewCleared() view->setMarginHeight(marginh); } +#if USE(FLATTEN_FRAMESET) +void RenderFrame::layout() +{ + if (widget() && widget()->isFrameView()) { + FrameView* view = static_cast<FrameView*>(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) { + // Resize the widget so that the RenderView will layout according to those dimensions. + view->resize(m_width, m_height); + view->layout(); + // We can only grow in width and height because if positionFrames gives us a width and we become smaller, + // then the fixup process of forcing the frame to fill extra space will fail. + if (m_width > root->docWidth()) { + view->resize(root->docWidth(), 0); + view->layout(); + } + // Honor the height set by RenderFrameSet::positionFrames unless our document height is larger. + setHeight(max(root->docHeight(), height())); + setWidth(max(root->docWidth(), width())); + } + } + setNeedsLayout(false); +} +#endif + } // namespace WebCore Index: WebCore/rendering/RenderFrame.h =================================================================== --- WebCore/rendering/RenderFrame.h (revision 45369) +++ WebCore/rendering/RenderFrame.h (working copy) @@ -36,6 +36,10 @@ public: FrameEdgeInfo edgeInfo() const; +#if USE(FLATTEN_FRAMESET) + virtual void layout(); +#endif + private: virtual const char* renderName() const { return "RenderFrame"; } virtual bool isFrame() const { return true; } Index: WebCore/rendering/RenderFrameSet.cpp =================================================================== --- WebCore/rendering/RenderFrameSet.cpp (revision 45369) +++ WebCore/rendering/RenderFrameSet.cpp (working copy) @@ -45,6 +45,9 @@ RenderFrameSet::RenderFrameSet(HTMLFrame : RenderBox(frameSet) , m_isResizing(false) , m_isChildResizing(false) +#if USE(FLATTEN_FRAMESET) + , m_gridCalculated(false) +#endif { setInline(false); } @@ -459,6 +462,10 @@ void RenderFrameSet::layout() if (!parent()->isFrameSet() && !document()->printing()) { setWidth(view()->viewWidth()); setHeight(view()->viewHeight()); +#if USE(FLATTEN_FRAMESET) + // Force a grid recalc. + m_gridCalculated = false; +#endif } size_t cols = frameSet()->totalCols(); @@ -467,11 +474,27 @@ void RenderFrameSet::layout() if (m_rows.m_sizes.size() != rows || m_cols.m_sizes.size() != cols) { m_rows.resize(rows); m_cols.resize(cols); +#if USE(FLATTEN_FRAMESET) + m_gridCalculated = false; +#endif } +#if USE(FLATTEN_FRAMESET) + if (!m_gridCalculated) { + m_gridCalculated = true; + // Make all the child framesets recalculates their grid. + RenderObject* child = firstChild(); + for (; child; child = child->nextSibling()) { + if (child->isFrameSet()) + static_cast<RenderFrameSet*>(child)->setGridNeedsLayout(); + } +#endif int borderThickness = frameSet()->border(); layOutAxis(m_rows, frameSet()->rowLengths(), height() - (rows - 1) * borderThickness); layOutAxis(m_cols, frameSet()->colLengths(), width() - (cols - 1) * borderThickness); +#if USE(FLATTEN_FRAMESET) + } +#endif positionFrames(); @@ -500,6 +523,86 @@ void RenderFrameSet::positionFrames() int yPos = 0; int borderThickness = frameSet()->border(); +#if USE(FLATTEN_FRAMESET) + // Keep track of the maximum width of a row which will become the maximum width of the frameset. + int maxWidth = 0; + const Length* rowLengths = frameSet()->rowLengths(); + const Length* colLengths = frameSet()->colLengths(); + + for (int r = 0; r < rows && child; r++) { + int xPos = 0; + int height = m_rows.m_sizes[r]; + int rowHeight = -1; + if (rowLengths) { + Length l = rowLengths[r]; + if (l.isFixed()) + rowHeight = l.value(); + } + for (int c = 0; c < cols && child; c++) { + child->setX(xPos); + child->setY(yPos); + child->setWidth(m_cols.m_sizes[c]); + child->setHeight(height); + int colWidth = -1; + if (colLengths) { + Length l = colLengths[c]; + if (l.isFixed()) + colWidth = l.value(); + } + if (colWidth && rowHeight) { + child->setNeedsLayout(true); + child->layout(); + } else { + child->layoutIfNeeded(); + } + + ASSERT(child->width() >= m_cols.m_sizes[c]); + m_cols.m_sizes[c] = child->width(); + + height = max(child->height(), height); + xPos += child->width() + borderThickness; + child = static_cast<RenderBox*>(child->nextSibling()); + } + ASSERT(height >= m_rows.m_sizes[r]); + m_rows.m_sizes[r] = height; + maxWidth = max(xPos, maxWidth); + yPos += height + borderThickness; + } + + // Compute a new width and height according to the positioning of each expanded child frame. + // Note: we subtract borderThickness because we only count borders between frames. + int newWidth = maxWidth - borderThickness; + int newHeight = yPos - borderThickness; + + // Distribute the extra width and height evenly across the grid. + int dWidth = (width() - newWidth) / cols; + int dHeight = (height() - newHeight) / rows; + if (dWidth > 0) { + int availableWidth = width() - (cols - 1) * borderThickness; + for (int c = 0; c < cols; c++) + availableWidth -= m_cols.m_sizes[c] += dWidth; + // If the extra width did not distribute evenly, add the remainder to + // the last column. + if (availableWidth) + m_cols.m_sizes[cols - 1] += availableWidth; + } + if (dHeight > 0) { + int availableHeight = height() - (rows - 1) * borderThickness; + for (int r = 0; r < rows; r++) + availableHeight -= m_rows.m_sizes[r] += dHeight; + // If the extra height did not distribute evenly, add the remainder to + // the last row. + if (availableHeight) + m_rows.m_sizes[rows - 1] += availableHeight; + } + // Ensure the rows and columns are filled by falling through to the normal + // layout + setHeight(max(height(), newHeight)); + setWidth(max(width(), newWidth)); + child = static_cast<RenderBox*>(firstChild()); + yPos = 0; +#endif // USE(FLATTEN_FRAMESET) + for (int r = 0; r < rows; r++) { int xPos = 0; int height = m_rows.m_sizes[r]; Index: WebCore/rendering/RenderFrameSet.h =================================================================== --- WebCore/rendering/RenderFrameSet.h (revision 45369) +++ WebCore/rendering/RenderFrameSet.h (working copy) @@ -81,6 +81,10 @@ public: bool canResizeRow(const IntPoint&) const; bool canResizeColumn(const IntPoint&) const; +#if USE(FLATTEN_FRAMESET) + void setGridNeedsLayout() { m_gridCalculated = false; } +#endif + private: static const int noSplit = -1; @@ -121,6 +125,9 @@ private: bool m_isResizing; bool m_isChildResizing; +#if USE(FLATTEN_FRAMESET) + bool m_gridCalculated; +#endif }; } // namespace WebCore Index: WebCore/rendering/RenderView.h =================================================================== --- WebCore/rendering/RenderView.h (revision 45369) +++ WebCore/rendering/RenderView.h (working copy) @@ -170,6 +170,9 @@ protected: private: bool shouldRepaint(const IntRect& r) const; +#if USE(FLATTEN_FRAMESET) +public: +#endif int docHeight() const; int docWidth() const;
_______________________________________________ webkit-dev mailing list webkit-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev