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
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev