Commit 8f83b0ea authored by hyatt's avatar hyatt

Fix for REGRESSION bug 13108, frame borders being painted when they...

        Fix for REGRESSION bug 13108, frame borders being painted when they shouldn't be.  Rework both frame borders
        and resizing to be more like other browsers.

        Reviewed by ggaren

        fast/frames/no-frame-borders.html

        * html/HTMLFrameElement.cpp:
        (WebCore::HTMLFrameElement::HTMLFrameElement):
        (WebCore::HTMLFrameElement::attach):
        (WebCore::HTMLFrameElement::parseMappedAttribute):
        * html/HTMLFrameElement.h:
        (WebCore::HTMLFrameElement::hasFrameBorder):
        * html/HTMLFrameElementBase.cpp:
        (WebCore::HTMLFrameElementBase::HTMLFrameElementBase):
        (WebCore::HTMLFrameElementBase::parseMappedAttribute):
        * html/HTMLFrameElementBase.h:
        * html/HTMLFrameSetElement.cpp:
        (WebCore::HTMLFrameSetElement::attach):
        * html/HTMLFrameSetElement.h:
        (WebCore::HTMLFrameSetElement::hasFrameBorder):
        * html/HTMLIFrameElement.cpp:
        (WebCore::HTMLIFrameElement::HTMLIFrameElement):
        * rendering/RenderFrame.cpp:
        (WebCore::RenderFrame::edgeInfo):
        * rendering/RenderFrame.h:
        * rendering/RenderFrameSet.cpp:
        (WebCore::RenderFrameSet::paint):
        (WebCore::RenderFrameSet::GridAxis::resize):
        (WebCore::RenderFrameSet::fillFromEdgeInfo):
        (WebCore::RenderFrameSet::computeEdgeInfo):
        (WebCore::RenderFrameSet::edgeInfo):
        (WebCore::RenderFrameSet::layout):
        (WebCore::RenderFrameSet::startResizing):
        (WebCore::RenderFrameSet::continueResizing):
        (WebCore::RenderFrameSet::canResizeRow):
        (WebCore::RenderFrameSet::canResizeColumn):
        (WebCore::RenderFrameSet::splitPosition):
        (WebCore::RenderFrameSet::hitTestSplit):
        (WebCore::RenderFrameSet::dump):
        * rendering/RenderFrameSet.h:
        (WebCore::):
        (WebCore::FrameEdgeInfo::FrameEdgeInfo):
        (WebCore::FrameEdgeInfo::preventResize):
        (WebCore::FrameEdgeInfo::allowBorder):
        (WebCore::FrameEdgeInfo::setPreventResize):
        (WebCore::FrameEdgeInfo::setAllowBorder):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@20305 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent c8738505
2007-03-18 David Hyatt <hyatt@apple.com>
Fix for REGRESSION bug 13108, frame borders being painted when they shouldn't be. Rework both frame borders
and resizing to be more like other browsers.
Reviewed by ggaren
fast/frames/no-frame-borders.html
* html/HTMLFrameElement.cpp:
(WebCore::HTMLFrameElement::HTMLFrameElement):
(WebCore::HTMLFrameElement::attach):
(WebCore::HTMLFrameElement::parseMappedAttribute):
* html/HTMLFrameElement.h:
(WebCore::HTMLFrameElement::hasFrameBorder):
* html/HTMLFrameElementBase.cpp:
(WebCore::HTMLFrameElementBase::HTMLFrameElementBase):
(WebCore::HTMLFrameElementBase::parseMappedAttribute):
* html/HTMLFrameElementBase.h:
* html/HTMLFrameSetElement.cpp:
(WebCore::HTMLFrameSetElement::attach):
* html/HTMLFrameSetElement.h:
(WebCore::HTMLFrameSetElement::hasFrameBorder):
* html/HTMLIFrameElement.cpp:
(WebCore::HTMLIFrameElement::HTMLIFrameElement):
* rendering/RenderFrame.cpp:
(WebCore::RenderFrame::edgeInfo):
* rendering/RenderFrame.h:
* rendering/RenderFrameSet.cpp:
(WebCore::RenderFrameSet::paint):
(WebCore::RenderFrameSet::GridAxis::resize):
(WebCore::RenderFrameSet::fillFromEdgeInfo):
(WebCore::RenderFrameSet::computeEdgeInfo):
(WebCore::RenderFrameSet::edgeInfo):
(WebCore::RenderFrameSet::layout):
(WebCore::RenderFrameSet::startResizing):
(WebCore::RenderFrameSet::continueResizing):
(WebCore::RenderFrameSet::canResizeRow):
(WebCore::RenderFrameSet::canResizeColumn):
(WebCore::RenderFrameSet::splitPosition):
(WebCore::RenderFrameSet::hitTestSplit):
(WebCore::RenderFrameSet::dump):
* rendering/RenderFrameSet.h:
(WebCore::):
(WebCore::FrameEdgeInfo::FrameEdgeInfo):
(WebCore::FrameEdgeInfo::preventResize):
(WebCore::FrameEdgeInfo::allowBorder):
(WebCore::FrameEdgeInfo::setPreventResize):
(WebCore::FrameEdgeInfo::setAllowBorder):
2007-03-19 Mark Rowe <mrowe@apple.com>
Rubber-stamped by Brady.
......
......@@ -37,6 +37,8 @@ using namespace HTMLNames;
HTMLFrameElement::HTMLFrameElement(Document* doc)
: HTMLFrameElementBase(frameTag, doc)
, m_frameBorder(true)
, m_frameBorderSet(false)
{
}
......@@ -65,10 +67,20 @@ void HTMLFrameElement::attach()
if (HTMLFrameSetElement* frameSetElement = containingFrameSetElement(this)) {
if (!m_frameBorderSet)
m_frameBorder = frameSetElement->frameBorder();
m_frameBorder = frameSetElement->hasFrameBorder();
if (!m_noResize)
m_noResize = frameSetElement->noResize();
}
}
void HTMLFrameElement::parseMappedAttribute(MappedAttribute *attr)
{
if (attr->name() == frameborderAttr) {
m_frameBorder = attr->value().toInt();
m_frameBorderSet = !attr->isNull();
// FIXME: If we are already attached, this has no effect.
} else
HTMLFrameElementBase::parseMappedAttribute(attr);
}
} // namespace WebCore
......@@ -47,6 +47,14 @@ public:
virtual bool rendererIsNeeded(RenderStyle*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual void parseMappedAttribute(MappedAttribute*);
bool hasFrameBorder() const { return m_frameBorder; }
private:
bool m_frameBorder;
bool m_frameBorderSet;
};
} // namespace WebCore
......
......@@ -50,8 +50,6 @@ HTMLFrameElementBase::HTMLFrameElementBase(const QualifiedName& tagName, Documen
, m_scrolling(ScrollbarAuto)
, m_marginWidth(-1)
, m_marginHeight(-1)
, m_frameBorder(true)
, m_frameBorderSet(false)
, m_noResize(false)
, m_viewSource(false)
{
......@@ -123,10 +121,6 @@ void HTMLFrameElementBase::parseMappedAttribute(MappedAttribute *attr)
// FIXME: If we are already attached, this doesn't actually change the frame's name.
// FIXME: If we are already attached, this doesn't check for frame name
// conflicts and generate a unique frame name.
} else if (attr->name() == frameborderAttr) {
m_frameBorder = attr->value().toInt();
m_frameBorderSet = !attr->isNull();
// FIXME: If we are already attached, this has no effect.
} else if (attr->name() == marginwidthAttr) {
m_marginWidth = attr->value().toInt();
// FIXME: If we are already attached, this has no effect.
......
......@@ -48,7 +48,7 @@ public:
virtual bool isURLAttribute(Attribute*) const;
ScrollbarMode scrollingMode() const { return m_scrolling; }
bool hasFrameBorder() const { return m_frameBorder; }
int getMarginWidth() const { return m_marginWidth; }
int getMarginHeight() const { return m_marginHeight; }
......@@ -97,8 +97,6 @@ protected:
int m_marginWidth;
int m_marginHeight;
bool m_frameBorder;
bool m_frameBorderSet;
bool m_noResize;
bool m_viewSource;
};
......
......@@ -156,7 +156,7 @@ void HTMLFrameSetElement::attach()
if (node->hasTagName(framesetTag)) {
HTMLFrameSetElement* frameset = static_cast<HTMLFrameSetElement*>(node);
if (!frameBorderSet)
frameborder = frameset->frameBorder();
frameborder = frameset->hasFrameBorder();
if (frameborder) {
if (!m_borderSet)
m_border = frameset->border();
......
......@@ -49,7 +49,7 @@ public:
virtual void defaultEventHandler(Event*);
bool frameBorder() const { return frameborder; }
bool hasFrameBorder() const { return frameborder; }
bool noResize() const { return noresize; }
int totalRows() const { return m_totalRows; }
......
......@@ -38,7 +38,6 @@ using namespace HTMLNames;
HTMLIFrameElement::HTMLIFrameElement(Document* doc)
: HTMLFrameElementBase(iframeTag, doc)
{
m_frameBorder = false;
}
bool HTMLIFrameElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
......
......@@ -25,7 +25,7 @@
#include "config.h"
#include "RenderFrame.h"
#include "RenderFrameSet.h"
#include "FrameView.h"
#include "HTMLFrameSetElement.h"
#include "HTMLNames.h"
......@@ -40,6 +40,11 @@ RenderFrame::RenderFrame(HTMLFrameElement* frame)
setInline(false);
}
FrameEdgeInfo RenderFrame::edgeInfo() const
{
return FrameEdgeInfo(element()->noResize(), element()->hasFrameBorder());
}
void RenderFrame::viewCleared()
{
if (element() && m_widget && m_widget->isFrameView()) {
......
......@@ -27,6 +27,7 @@
#include "HTMLFrameElement.h"
#include "RenderPart.h"
#include "RenderFrameSet.h"
namespace WebCore {
......@@ -38,6 +39,8 @@ public:
HTMLFrameElement* element() const { return static_cast<HTMLFrameElement*>(RenderPart::element()); }
FrameEdgeInfo edgeInfo() const;
virtual void viewCleared();
};
......
......@@ -142,7 +142,7 @@ void RenderFrameSet::paint(PaintInfo& paintInfo, int tx, int ty)
for (int c = 0; c < cols; c++) {
child->paint(paintInfo, tx, ty);
xPos += m_cols.m_sizes[c];
if (borderThickness) {
if (borderThickness && m_cols.m_allowBorder[c + 1]) {
paintColumnBorder(paintInfo, IntRect(tx + xPos, ty + yPos, borderThickness, height()));
xPos += borderThickness;
}
......@@ -151,7 +151,7 @@ void RenderFrameSet::paint(PaintInfo& paintInfo, int tx, int ty)
return;
}
yPos += m_rows.m_sizes[r];
if (borderThickness) {
if (borderThickness && m_rows.m_allowBorder[r + 1]) {
paintRowBorder(paintInfo, IntRect(tx, ty + yPos, width(), borderThickness));
yPos += borderThickness;
}
......@@ -181,7 +181,12 @@ void RenderFrameSet::GridAxis::resize(int size)
m_sizes.resize(size);
m_deltas.resize(size);
m_deltas.fill(0);
m_isSplitResizable.resize(size);
// To track edges for resizability and borders, we need to be (size + 1). This is because a parent frameset
// may ask us for information about our left/top/right/bottom edges in order to make its own decisions about
// what to do. We are capable of tainting that parent frameset's borders, so we have to cache this info.
m_preventResize.resize(size + 1);
m_allowBorder.resize(size + 1);
}
void RenderFrameSet::layOutAxis(GridAxis& axis, const Length* grid, int availableLen)
......@@ -376,11 +381,34 @@ void RenderFrameSet::layOutAxis(GridAxis& axis, const Length* grid, int availabl
}
}
void RenderFrameSet::findNonResizableSplits()
void RenderFrameSet::fillFromEdgeInfo(const FrameEdgeInfo& edgeInfo, int r, int c)
{
m_rows.m_isSplitResizable.fill(true);
m_cols.m_isSplitResizable.fill(true);
if (edgeInfo.allowBorder(LeftFrameEdge))
m_cols.m_allowBorder[c] = true;
if (edgeInfo.allowBorder(RightFrameEdge))
m_cols.m_allowBorder[c + 1] = true;
if (edgeInfo.preventResize(LeftFrameEdge))
m_cols.m_preventResize[c] = true;
if (edgeInfo.preventResize(RightFrameEdge))
m_cols.m_preventResize[c + 1] = true;
if (edgeInfo.allowBorder(TopFrameEdge))
m_rows.m_allowBorder[r] = true;
if (edgeInfo.allowBorder(BottomFrameEdge))
m_rows.m_allowBorder[r + 1] = true;
if (edgeInfo.preventResize(TopFrameEdge))
m_rows.m_preventResize[r] = true;
if (edgeInfo.preventResize(BottomFrameEdge))
m_rows.m_preventResize[r + 1] = true;
}
void RenderFrameSet::computeEdgeInfo()
{
m_rows.m_preventResize.fill(frameSet()->noResize());
m_rows.m_allowBorder.fill(false);
m_cols.m_preventResize.fill(frameSet()->noResize());
m_cols.m_allowBorder.fill(false);
RenderObject* child = firstChild();
if (!child)
return;
......@@ -389,23 +417,12 @@ void RenderFrameSet::findNonResizableSplits()
int cols = frameSet()->totalCols();
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
bool fixed;
FrameEdgeInfo edgeInfo;
if (child->isFrameSet())
fixed = static_cast<RenderFrameSet*>(child)->frameSet()->noResize();
edgeInfo = static_cast<RenderFrameSet*>(child)->edgeInfo();
else
fixed = static_cast<RenderFrame*>(child)->element()->noResize();
if (fixed) {
if (cols > 1) {
if (c > 0)
m_cols.m_isSplitResizable[c - 1] = false;
m_cols.m_isSplitResizable[c] = false;
}
if (rows > 1) {
if (r > 0)
m_rows.m_isSplitResizable[r - 1] = false;
m_rows.m_isSplitResizable[r] = false;
}
}
edgeInfo = static_cast<RenderFrame*>(child)->edgeInfo();
fillFromEdgeInfo(edgeInfo, r, c);
child = child->nextSibling();
if (!child)
return;
......@@ -413,6 +430,26 @@ void RenderFrameSet::findNonResizableSplits()
}
}
FrameEdgeInfo RenderFrameSet::edgeInfo() const
{
FrameEdgeInfo result(frameSet()->noResize(), true);
int rows = frameSet()->totalRows();
int cols = frameSet()->totalCols();
if (rows && cols) {
result.setPreventResize(LeftFrameEdge, m_cols.m_preventResize[0]);
result.setAllowBorder(LeftFrameEdge, m_cols.m_allowBorder[0]);
result.setPreventResize(RightFrameEdge, m_cols.m_preventResize[cols]);
result.setAllowBorder(RightFrameEdge, m_cols.m_allowBorder[cols]);
result.setPreventResize(TopFrameEdge, m_rows.m_preventResize[0]);
result.setAllowBorder(TopFrameEdge, m_rows.m_allowBorder[0]);
result.setPreventResize(BottomFrameEdge, m_rows.m_preventResize[rows]);
result.setAllowBorder(BottomFrameEdge, m_rows.m_allowBorder[rows]);
}
return result;
}
void RenderFrameSet::layout()
{
ASSERT(needsLayout());
......@@ -430,7 +467,6 @@ void RenderFrameSet::layout()
if (m_rows.m_sizes.size() != rows || m_cols.m_sizes.size() != cols) {
m_rows.resize(rows);
m_cols.resize(cols);
findNonResizableSplits();
}
int borderThickness = frameSet()->border();
......@@ -441,6 +477,8 @@ void RenderFrameSet::layout()
RenderContainer::layout();
computeEdgeInfo();
setNeedsLayout(false);
}
......@@ -490,7 +528,7 @@ void RenderFrameSet::positionFrames()
void RenderFrameSet::startResizing(GridAxis& axis, int position)
{
int split = hitTestSplit(axis, position);
if (split == noSplit || !axis.m_isSplitResizable[split]) {
if (split == noSplit || !axis.m_allowBorder[split] || axis.m_preventResize[split]) {
axis.m_splitBeingResized = noSplit;
return;
}
......@@ -506,8 +544,10 @@ void RenderFrameSet::continueResizing(GridAxis& axis, int position)
return;
int currentSplitPosition = splitPosition(axis, axis.m_splitBeingResized);
int delta = (position - currentSplitPosition) - axis.m_splitResizeOffset;
axis.m_deltas[axis.m_splitBeingResized] += delta;
axis.m_deltas[axis.m_splitBeingResized + 1] -= delta;
if (delta == 0)
return;
axis.m_deltas[axis.m_splitBeingResized - 1] += delta;
axis.m_deltas[axis.m_splitBeingResized] -= delta;
setNeedsLayout(true);
}
......@@ -567,13 +607,13 @@ bool RenderFrameSet::canResize(const IntPoint& p) const
bool RenderFrameSet::canResizeRow(const IntPoint& p) const
{
int r = hitTestSplit(m_rows, p.y() - yPos());
return r != noSplit && m_rows.m_isSplitResizable[r];
return r != noSplit && m_rows.m_allowBorder[r] && !m_rows.m_preventResize[r];
}
bool RenderFrameSet::canResizeColumn(const IntPoint& p) const
{
int c = hitTestSplit(m_cols, p.x() - xPos());
return c != noSplit && m_cols.m_isSplitResizable[c];
return c != noSplit && m_cols.m_allowBorder[c] && !m_cols.m_preventResize[c];
}
int RenderFrameSet::splitPosition(const GridAxis& axis, int split) const
......@@ -588,7 +628,7 @@ int RenderFrameSet::splitPosition(const GridAxis& axis, int split) const
return 0;
int position = 0;
for (int i = 0; i <= split && i < size; ++i)
for (int i = 0; i < split && i < size; ++i)
position += axis.m_sizes[i] + borderThickness;
return position - borderThickness;
}
......@@ -609,7 +649,7 @@ int RenderFrameSet::hitTestSplit(const GridAxis& axis, int position) const
int splitPosition = axis.m_sizes[0];
for (size_t i = 1; i < size; ++i) {
if (position >= splitPosition && position < splitPosition + borderThickness)
return i - 1;
return i;
splitPosition += borderThickness + axis.m_sizes[i];
}
return noSplit;
......@@ -621,11 +661,11 @@ void RenderFrameSet::dump(TextStream* stream, DeprecatedString ind) const
*stream << " totalrows=" << frameSet()->totalRows();
*stream << " totalcols=" << frameSet()->totalCols();
for (int i = 0; i < frameSet()->totalRows(); i++)
*stream << " hSplitvar(" << i << ")=" << m_rows.m_isSplitResizable[i];
for (int i = 1; i <= frameSet()->totalRows(); i++)
*stream << " hSplitvar(" << i << ")=" << m_rows.m_preventResize[i];
for (int i = 0; i < frameSet()->totalCols(); i++)
*stream << " vSplitvar(" << i << ")=" << m_cols.m_isSplitResizable[i];
for (int i = 1; i < frameSet()->totalCols(); i++)
*stream << " vSplitvar(" << i << ")=" << m_cols.m_preventResize[i];
RenderContainer::dump(stream,ind);
}
......
......@@ -32,6 +32,29 @@ namespace WebCore {
class HTMLFrameSetElement;
class MouseEvent;
enum FrameEdge { LeftFrameEdge, RightFrameEdge, TopFrameEdge, BottomFrameEdge };
struct FrameEdgeInfo
{
FrameEdgeInfo(bool preventResize = false, bool allowBorder = true)
{
m_preventResize.resize(4);
m_preventResize.fill(preventResize);
m_allowBorder.resize(4);
m_allowBorder.fill(allowBorder);
}
bool preventResize(FrameEdge edge) const { return m_preventResize[edge]; }
bool allowBorder(FrameEdge edge) const { return m_allowBorder[edge]; }
void setPreventResize(FrameEdge edge, bool preventResize) { m_preventResize[edge] = preventResize; }
void setAllowBorder(FrameEdge edge, bool allowBorder) { m_allowBorder[edge] = allowBorder; }
private:
Vector<bool> m_preventResize;
Vector<bool> m_allowBorder;
};
class RenderFrameSet : public RenderContainer {
public:
RenderFrameSet(HTMLFrameSetElement*);
......@@ -44,6 +67,8 @@ public:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, HitTestAction);
virtual void paint(PaintInfo& paintInfo, int tx, int ty);
FrameEdgeInfo edgeInfo() const;
bool userResize(MouseEvent*);
bool isResizingRow() const;
......@@ -65,7 +90,8 @@ private:
void resize(int);
Vector<int> m_sizes;
Vector<int> m_deltas;
Vector<bool> m_isSplitResizable;
Vector<bool> m_preventResize;
Vector<bool> m_allowBorder;
int m_splitBeingResized;
int m_splitResizeOffset;
};
......@@ -76,7 +102,8 @@ private:
void setIsResizing(bool);
void layOutAxis(GridAxis&, const Length*, int availableSpace);
void findNonResizableSplits();
void computeEdgeInfo();
void fillFromEdgeInfo(const FrameEdgeInfo& edgeInfo, int r, int c);
void positionFrames();
int splitPosition(const GridAxis&, int split) const;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment