Setting rows/cols on a frameset should try to reflow, not reframe. Bug

48422, r=jkeiser, sr=jst
This commit is contained in:
bzbarsky%mit.edu 2002-08-06 01:06:50 +00:00
Родитель 2a4fb9e6d8
Коммит c4caf1665b
9 изменённых файлов: 599 добавлений и 431 удалений

Просмотреть файл

@ -4,6 +4,7 @@
nsIForm.h
nsIFormControl.h
nsIFormSubmission.h
nsIFrameSetElement.h
nsIHTMLContent.h
nsILink.h
nsIOptionElement.h

Просмотреть файл

@ -47,7 +47,8 @@ EXPORTS = \
nsITextControlElement.h \
nsIScriptElement.h \
nsIFormSubmission.h \
$(NULL)
nsIFrameSetElement.h \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -38,6 +38,7 @@ EXPORTS= \
nsIScriptElement.h \
nsITextControlElement.h \
nsIFormSubmission.h \
nsIFrameSetElement.h \
$(NULL)
MODULE=content

Просмотреть файл

@ -0,0 +1,99 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Boris Zbarsky <bzbarsky@mit.edu> (Original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsIFramesetElement_h___
#define nsIFramesetElement_h___
#include "nsISupports.h"
// IID for the nsIFramesetElement interface
#define NS_IFRAMESETELEMENT_IID \
{ 0xeefe0fe5, 0x44ac, 0x4d7f, \
{ 0xa7, 0x51, 0xf4, 0xaa, 0x5f, 0x22, 0xb0, 0xbf } }
/**
* The nsFramesetUnit enum is used to denote the type of each entry
* in the row or column spec.
*/
enum nsFramesetUnit {
eFramesetUnit_Fixed = 0,
eFramesetUnit_Percent,
eFramesetUnit_Relative
};
/**
* The nsFramesetSpec struct is used to hold a single entry in the
* row or column spec.
*/
struct nsFramesetSpec {
nsFramesetUnit mUnit;
nscoord mValue;
};
/**
* This interface is used by the nsFramesetFrame to access the parsed
* values of the "rows" and "cols" attributes
*/
class nsIFrameSetElement : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFRAMESETELEMENT_IID)
/**
* GetRowSpec is used to get the "rows" spec.
* @param out PRInt32 aNumValues The number of row sizes specified.
* @param out nsFramesetSpec* aSpecs The array of size specifications.
This is _not_ owned by the caller, but by the nsIFrameSetElement
implementation. DO NOT DELETE IT.
* @exceptions NS_ERROR_OUT_OF_MEMORY
*/
NS_IMETHOD GetRowSpec(PRInt32 *aNumValues, const nsFramesetSpec** aSpecs) = 0;
/**
* GetColSpec is used to get the "cols" spec
* @param out PRInt32 aNumValues The number of row sizes specified.
* @param out nsFramesetSpec* aSpecs The array of size specifications.
This is _not_ owned by the caller, but by the nsIFrameSetElement
implementation. DO NOT DELETE IT.
* @exceptions NS_ERROR_OUT_OF_MEMORY
*/
NS_IMETHOD GetColSpec(PRInt32 *aNumValues, const nsFramesetSpec** aSpecs) = 0;
};
#endif // nsIFramesetElement_h___

Просмотреть файл

@ -43,10 +43,13 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIFrameSetElement.h"
#include "nsIHTMLDocument.h"
#include "nsIDocument.h"
class nsHTMLFrameSetElement : public nsGenericHTMLContainerElement,
public nsIDOMHTMLFrameSetElement
public nsIDOMHTMLFrameSetElement,
public nsIFrameSetElement
{
public:
nsHTMLFrameSetElement();
@ -67,6 +70,18 @@ public:
// nsIDOMHTMLFrameSetElement
NS_DECL_NSIDOMHTMLFRAMESETELEMENT
// These override the SetAttr methods in nsGenericHTMLElement (need
// both here to silence compiler warnings).
NS_IMETHOD SetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
const nsAString& aValue, PRBool aNotify);
NS_IMETHOD SetAttr(nsINodeInfo* aNodeInfo,
const nsAString& aValue,
PRBool aNotify);
// nsIFramesetElement
NS_IMETHOD GetRowSpec(PRInt32 *aNumValues, const nsFramesetSpec** aSpecs);
NS_IMETHOD GetColSpec(PRInt32 *aNumValues, const nsFramesetSpec** aSpecs);
NS_IMETHOD StringToAttribute(nsIAtom* aAttribute,
const nsAString& aValue,
nsHTMLValue& aResult);
@ -78,8 +93,41 @@ public:
#ifdef DEBUG
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
#endif
private:
nsresult ParseRowCol(const nsAString& aValue,
PRInt32& aNumSpecs,
nsFramesetSpec** aSpecs);
PRInt32 ParseRowColSpec(nsString& aSpec,
PRInt32 aMaxNumValues,
nsFramesetSpec* aSpecs);
/**
* The number of size specs in our "rows" attr
*/
PRInt32 mNumRows;
/**
* The number of size specs in our "cols" attr
*/
PRInt32 mNumCols;
/**
* The style hint to return for the rows/cols attrs in
* GetMappedAttributeImpact
*/
PRInt32 mCurrentRowColHint;
/**
* The parsed representation of the "rows" attribute
*/
nsFramesetSpec* mRowSpecs; // parsed, non-computed dimensions
/**
* The parsed representation of the "cols" attribute
*/
nsFramesetSpec* mColSpecs; // parsed, non-computed dimensions
static PRInt32 gMaxNumRowColSpecs;
};
PRInt32 nsHTMLFrameSetElement::gMaxNumRowColSpecs = 25;
nsresult
NS_NewHTMLFrameSetElement(nsIHTMLContent** aInstancePtrResult,
nsINodeInfo *aNodeInfo)
@ -108,11 +156,16 @@ NS_NewHTMLFrameSetElement(nsIHTMLContent** aInstancePtrResult,
nsHTMLFrameSetElement::nsHTMLFrameSetElement()
: mNumRows(0), mNumCols(0), mCurrentRowColHint(NS_STYLE_HINT_REFLOW),
mRowSpecs(nsnull), mColSpecs(nsnull)
{
}
nsHTMLFrameSetElement::~nsHTMLFrameSetElement()
{
delete [] mRowSpecs;
delete [] mColSpecs;
mRowSpecs = mColSpecs = nsnull;
}
@ -124,6 +177,7 @@ NS_IMPL_RELEASE_INHERITED(nsHTMLFrameSetElement, nsGenericElement)
NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLFrameSetElement,
nsGenericHTMLContainerElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLFrameSetElement)
NS_INTERFACE_MAP_ENTRY(nsIFrameSetElement)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLFrameSetElement)
NS_HTML_CONTENT_INTERFACE_MAP_END
@ -156,10 +210,143 @@ nsHTMLFrameSetElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
return NS_OK;
}
NS_IMPL_STRING_ATTR(nsHTMLFrameSetElement, Cols, cols)
NS_IMPL_STRING_ATTR(nsHTMLFrameSetElement, Rows, rows)
NS_IMETHODIMP
nsHTMLFrameSetElement::SetAttr(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
PRBool aNotify)
{
nsresult rv;
/* The main goal here is to see whether the _number_ of rows or
* columns has changed. If it has, we need to reframe; otherwise
* we want to reflow. So we set mCurrentRowColHint here, then call
* nsGenericHTMLContainerElement::SetAttr, which will end up
* calling GetMappedAttributeImpact and notifying layout with that
* hint. Once nsGenericHTMLContainerElement::SetAttr returns, we
* want to go back to our normal hint, which is
* NS_STYLE_HINT_REFLOW.
*/
if (aAttribute == nsHTMLAtoms::rows && aNameSpaceID == kNameSpaceID_None) {
PRInt32 oldRows = mNumRows;
delete [] mRowSpecs;
mRowSpecs = nsnull;
mNumRows = 0;
ParseRowCol(aValue, mNumRows, &mRowSpecs);
if (mNumRows != oldRows) {
mCurrentRowColHint = NS_STYLE_HINT_FRAMECHANGE;
}
} else if (aAttribute == nsHTMLAtoms::cols &&
aNameSpaceID == kNameSpaceID_None) {
PRInt32 oldCols = mNumCols;
delete [] mColSpecs;
mColSpecs = nsnull;
mNumCols = 0;
ParseRowCol(aValue, mNumCols, &mColSpecs);
if (mNumCols != oldCols) {
mCurrentRowColHint = NS_STYLE_HINT_FRAMECHANGE;
}
}
rv = nsGenericHTMLContainerElement::SetAttr(aNameSpaceID,
aAttribute,
aValue,
aNotify);
mCurrentRowColHint = NS_STYLE_HINT_REFLOW;
return rv;
}
NS_IMETHODIMP
nsHTMLFrameSetElement::SetAttr(nsINodeInfo* aNodeInfo,
const nsAString& aValue,
PRBool aNotify)
{
return nsGenericHTMLContainerElement::SetAttr(aNodeInfo,
aValue,
aNotify);
}
NS_IMETHODIMP
nsHTMLFrameSetElement::GetRowSpec(PRInt32 *aNumValues,
const nsFramesetSpec** aSpecs)
{
NS_PRECONDITION(aNumValues, "Must have a pointer to an integer here!");
NS_PRECONDITION(aSpecs, "Must have a pointer to an array of nsFramesetSpecs");
*aNumValues = 0;
*aSpecs = nsnull;
if (!mRowSpecs) {
nsHTMLValue value;
if (NS_CONTENT_ATTR_HAS_VALUE == GetHTMLAttribute(nsHTMLAtoms::rows, value) &&
eHTMLUnit_String == value.GetUnit()) {
nsAutoString rows;
value.GetStringValue(rows);
nsresult rv = ParseRowCol(rows, mNumRows, &mRowSpecs);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!mRowSpecs) { // we may not have had an attr or had an empty attr
mRowSpecs = new nsFramesetSpec[1];
if (!mRowSpecs) {
mNumRows = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
mNumRows = 1;
mRowSpecs[0].mUnit = eFramesetUnit_Relative;
mRowSpecs[0].mValue = 1;
}
}
*aSpecs = mRowSpecs;
*aNumValues = mNumRows;
return NS_OK;
}
NS_IMETHODIMP
nsHTMLFrameSetElement::GetColSpec(PRInt32 *aNumValues,
const nsFramesetSpec** aSpecs)
{
NS_PRECONDITION(aNumValues, "Must have a pointer to an integer here!");
NS_PRECONDITION(aSpecs, "Must have a pointer to an array of nsFramesetSpecs");
*aNumValues = 0;
*aSpecs = nsnull;
if (!mColSpecs) {
nsHTMLValue value;
if (NS_CONTENT_ATTR_HAS_VALUE == GetHTMLAttribute(nsHTMLAtoms::cols, value) &&
eHTMLUnit_String == value.GetUnit()) {
nsAutoString cols;
value.GetStringValue(cols);
nsresult rv = ParseRowCol(cols, mNumCols, &mColSpecs);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!mColSpecs) { // we may not have had an attr or had an empty attr
mColSpecs = new nsFramesetSpec[1];
if (!mColSpecs) {
mNumCols = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
mNumCols = 1;
mColSpecs[0].mUnit = eFramesetUnit_Relative;
mColSpecs[0].mValue = 1;
}
}
*aSpecs = mColSpecs;
*aNumValues = mNumCols;
return NS_OK;
}
NS_IMETHODIMP
nsHTMLFrameSetElement::StringToAttribute(nsIAtom* aAttribute,
const nsAString& aValue,
@ -202,7 +389,7 @@ nsHTMLFrameSetElement::GetMappedAttributeImpact(const nsIAtom* aAttribute, PRInt
{
if ((aAttribute == nsHTMLAtoms::rows) ||
(aAttribute == nsHTMLAtoms::cols)) {
aHint = NS_STYLE_HINT_FRAMECHANGE;
aHint = mCurrentRowColHint;
}
else if (! nsGenericHTMLElement::GetCommonMappedAttributesImpact(aAttribute, aHint)) {
aHint = NS_STYLE_HINT_CONTENT;
@ -221,3 +408,158 @@ nsHTMLFrameSetElement::SizeOf(nsISizeOfHandler* aSizer,
return NS_OK;
}
#endif
nsresult
nsHTMLFrameSetElement::ParseRowCol(const nsAString & aValue,
PRInt32& aNumSpecs,
nsFramesetSpec** aSpecs)
{
NS_ASSERTION(!*aSpecs, "Someone called us with a pointer to an already allocated array of specs!");
if (!aValue.IsEmpty()) {
nsAutoString rowsCols(aValue);
nsFramesetSpec* specs = new nsFramesetSpec[gMaxNumRowColSpecs];
if (!specs) {
*aSpecs = nsnull;
aNumSpecs = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
aNumSpecs = ParseRowColSpec(rowsCols, gMaxNumRowColSpecs, specs);
*aSpecs = new nsFramesetSpec[aNumSpecs];
if (!*aSpecs) {
aNumSpecs = 0;
delete [] specs;
return NS_ERROR_OUT_OF_MEMORY;
}
for (PRInt32 i = 0; i < aNumSpecs; ++i) {
(*aSpecs)[i] = specs[i];
}
delete [] specs;
}
return NS_OK;
}
/**
* Translate a "rows" or "cols" spec into an array of nsFramesetSpecs
*/
PRInt32
nsHTMLFrameSetElement::ParseRowColSpec(nsString& aSpec,
PRInt32 aMaxNumValues,
nsFramesetSpec* aSpecs)
{
static const PRUnichar sAster('*');
static const PRUnichar sPercent('%');
static const PRUnichar sComma(',');
// remove whitespace (Bug 33699)
// also remove leading/trailing commas (bug 31482)
aSpec.StripChars(" \n\r\t");
aSpec.Trim(",");
// Count the commas
PRInt32 commaX = aSpec.FindChar(sComma);
PRInt32 count = 1;
while (commaX >= 0) {
count++;
commaX = aSpec.FindChar(sComma, commaX + 1);
}
if (count > aMaxNumValues) {
NS_ASSERTION(0, "Not enough space for values");
count = aMaxNumValues;
}
// Parse each comma separated token
PRInt32 start = 0;
PRInt32 specLen = aSpec.Length();
for (PRInt32 i = 0; i < count; i++) {
// Find our comma
commaX = aSpec.FindChar(sComma, start);
PRInt32 end = (commaX < 0) ? specLen : commaX;
// Note: If end == start then it means that the token has no
// data in it other than a terminating comma (or the end of the spec)
aSpecs[i].mUnit = eFramesetUnit_Fixed;
if (end > start) {
PRInt32 numberEnd = end;
PRUnichar ch = aSpec.CharAt(numberEnd - 1);
if (sAster == ch) {
aSpecs[i].mUnit = eFramesetUnit_Relative;
numberEnd--;
} else if (sPercent == ch) {
aSpecs[i].mUnit = eFramesetUnit_Percent;
numberEnd--;
// check for "*%"
if (numberEnd > start) {
ch = aSpec.CharAt(numberEnd - 1);
if (sAster == ch) {
aSpecs[i].mUnit = eFramesetUnit_Relative;
numberEnd--;
}
}
}
// Translate value to an integer
nsString token;
aSpec.Mid(token, start, numberEnd - start);
// Treat * as 1*
if ((eFramesetUnit_Relative == aSpecs[i].mUnit) &&
(0 == token.Length())) {
aSpecs[i].mValue = 1;
}
else {
// Otherwise just convert to integer.
PRInt32 err;
aSpecs[i].mValue = token.ToInteger(&err);
if (err) {
aSpecs[i].mValue = 0;
}
}
// Treat 0* as 1* in quirks mode (bug 40383)
nsCompatibility mode = eCompatibility_FullStandards;
nsCOMPtr<nsIHTMLDocument> htmlDocument;
if (mDocument) {
htmlDocument = do_QueryInterface(mDocument);
} else {
nsCOMPtr<nsIDocument> doc;
mNodeInfo->GetDocument(*getter_AddRefs(doc));
htmlDocument = do_QueryInterface(doc);
}
if (htmlDocument) {
htmlDocument->GetCompatibilityMode(mode);
}
if (eCompatibility_NavQuirks == mode) {
if ((eFramesetUnit_Relative == aSpecs[i].mUnit) &&
(0 == aSpecs[i].mValue)) {
aSpecs[i].mValue = 1;
}
}
// Catch zero and negative frame sizes for Nav compatability
// Nav resized absolute and relative frames to "1" and
// percent frames to an even percentage of the width
//
//if ((eCompatibility_NavQuirks == aMode) && (aSpecs[i].mValue <= 0)) {
// if (eFramesetUnit_Percent == aSpecs[i].mUnit) {
// aSpecs[i].mValue = 100 / count;
// } else {
// aSpecs[i].mValue = 1;
// }
//} else {
// In standards mode, just set negative sizes to zero
if (aSpecs[i].mValue < 0) {
aSpecs[i].mValue = 0;
}
start = end + 1;
}
}
return count;
}

Просмотреть файл

@ -191,7 +191,6 @@ protected:
/*******************************************************************************
* nsHTMLFramesetFrame
******************************************************************************/
PRInt32 nsHTMLFramesetFrame::gMaxNumRowColSpecs = 25;
PRBool nsHTMLFramesetFrame::gDragInProgress = PR_FALSE;
#define kFrameResizePref "layout.frames.force_resizability"
#define DEFAULT_BORDER_WIDTH_PX 6
@ -200,10 +199,8 @@ nsHTMLFramesetFrame::nsHTMLFramesetFrame()
: nsHTMLContainerFrame()
{
mNumRows = 0;
mRowSpecs = nsnull;
mRowSizes = nsnull;
mNumCols = 0;
mColSpecs = nsnull;
mColSizes = nsnull;
mEdgeVisibility = 0;
mParentFrameborder = eFrameborder_Yes; // default
@ -229,14 +226,11 @@ nsHTMLFramesetFrame::nsHTMLFramesetFrame()
nsHTMLFramesetFrame::~nsHTMLFramesetFrame()
{
delete [] mRowSizes;
delete [] mRowSpecs;
delete [] mColSizes;
delete [] mColSpecs;
delete[] mVerBorders;
delete[] mHorBorders;
mRowSizes = mColSizes = nsnull;
mRowSpecs = mColSpecs = nsnull;
nsCOMPtr<nsIPrefBranchInternal> prefBranch =
do_QueryReferent(mPrefBranchWeakRef);
@ -299,7 +293,6 @@ nsHTMLFramesetFrame::Observe(nsISupports* aObject, const char* aAction,
prefBranch->GetBoolPref(kFrameResizePref, &mForceFrameResizability);
}
RecalculateBorderResize();
mRect.width = mRect.height = -1; // force a recalculation of frame sizes
if (doc) {
doc->AttributeChanged(mContent,
kNameSpaceID_None,
@ -370,9 +363,15 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext,
PRInt32 borderWidth = GetBorderWidth(aPresContext, PR_FALSE);
nscolor borderColor = GetBorderColor();
// parse the rows= cols= data
ParseRowCol(aPresContext, nsHTMLAtoms::rows, mNumRows, &mRowSpecs);
ParseRowCol(aPresContext, nsHTMLAtoms::cols, mNumCols, &mColSpecs);
// Get the rows= cols= data
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
const nsFramesetSpec* rowSpecs = nsnull;
const nsFramesetSpec* colSpecs = nsnull;
result = ourContent->GetRowSpec(&mNumRows, &rowSpecs);
NS_ENSURE_SUCCESS(result, result);
result = ourContent->GetColSpec(&mNumCols, &colSpecs);
NS_ENSURE_SUCCESS(result, result);
mRowSizes = new nscoord[mNumRows];
mColSizes = new nscoord[mNumCols];
@ -517,11 +516,11 @@ void nsHTMLFramesetFrame::Scale(nscoord aDesired,
* specifier - fixed sizes have the highest priority, percentage sizes have the next
* highest priority and relative sizes have the lowest.
*/
void nsHTMLFramesetFrame::CalculateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
nsFramesetSpec* aSpecs,
nscoord* aValues)
void nsHTMLFramesetFrame::CalculateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
const nsFramesetSpec* aSpecs,
nscoord* aValues)
{
PRInt32 fixedTotal = 0;
PRInt32 numFixed = 0;
@ -604,26 +603,30 @@ void nsHTMLFramesetFrame::CalculateRowCol(nsIPresContext* aPresContext,
* each cell in the frameset. Reverse of CalculateRowCol() behaviour.
* This allows us to maintain the user size info through reflows.
*/
void nsHTMLFramesetFrame::GenerateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
nsFramesetSpec* aSpecs,
nscoord* aValues)
void nsHTMLFramesetFrame::GenerateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
const nsFramesetSpec* aSpecs,
nscoord* aValues,
nsString& aNewAttr)
{
float t2p;
aPresContext->GetTwipsToPixels(&t2p);
PRInt32 i;
for (i = 0; i < aNumSpecs; i++) {
for (i = 0; i < aNumSpecs; i++) {
if (!aNewAttr.IsEmpty())
aNewAttr.Append(PRUnichar(','));
switch (aSpecs[i].mUnit) {
case eFramesetUnit_Fixed:
aSpecs[i].mValue = NSToCoordRound(t2p * aValues[i]);
aNewAttr.AppendInt(NSToCoordRound(t2p * aValues[i]));
break;
case eFramesetUnit_Percent: // XXX Only accurate to 1%, need 1 pixel
aSpecs[i].mValue = (100*aValues[i])/aSize;
break;
case eFramesetUnit_Relative:
aSpecs[i].mValue = aValues[i];
// Add 0.5 to the percentage to make rounding work right.
aNewAttr.AppendInt(PRUint32((100.0*aValues[i])/aSize + 0.5));
aNewAttr.Append(PRUnichar('%'));
break;
}
}
@ -853,148 +856,6 @@ nsHTMLFramesetFrame::Paint(nsIPresContext* aPresContext,
aDirtyRect, aWhichLayer);
}
void nsHTMLFramesetFrame::ParseRowCol(nsIPresContext* aPresContext, nsIAtom* aAttrType, PRInt32& aNumSpecs, nsFramesetSpec** aSpecs)
{
nsHTMLValue value;
nsAutoString rowsCols;
nsCOMPtr<nsIHTMLContent> content(do_QueryInterface(mContent));
if (content) {
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetHTMLAttribute(aAttrType, value)) {
if (eHTMLUnit_String == value.GetUnit()) {
value.GetStringValue(rowsCols);
nsFramesetSpec* specs = new nsFramesetSpec[gMaxNumRowColSpecs];
aNumSpecs = ParseRowColSpec(aPresContext, rowsCols, gMaxNumRowColSpecs, specs);
*aSpecs = new nsFramesetSpec[aNumSpecs];
for (int i = 0; i < aNumSpecs; i++) {
(*aSpecs)[i] = specs[i];
}
delete [] specs;
return;
}
}
}
aNumSpecs = 1;
*aSpecs = new nsFramesetSpec[1];
aSpecs[0]->mUnit = eFramesetUnit_Relative;
aSpecs[0]->mValue = 1;
}
/**
* Translate a "rows" or "cols" spec into an array of nsFramesetSpecs
*/
PRInt32
nsHTMLFramesetFrame::ParseRowColSpec(nsIPresContext* aPresContext,
nsString& aSpec,
PRInt32 aMaxNumValues,
nsFramesetSpec* aSpecs)
{
static const PRUnichar ASTER('*');
static const PRUnichar PERCENT('%');
static const PRUnichar COMMA(',');
// remove whitespace (Bug 33699)
// also remove leading/trailing commas (bug 31482)
aSpec.StripChars(" \n\r\t");
aSpec.Trim(",");
// Count the commas
PRInt32 commaX = aSpec.FindChar(COMMA);
PRInt32 count = 1;
while (commaX >= 0) {
count++;
commaX = aSpec.FindChar(COMMA, commaX + 1);
}
if (count > aMaxNumValues) {
NS_ASSERTION(0, "Not enough space for values");
count = aMaxNumValues;
}
// Parse each comma separated token
PRInt32 start = 0;
PRInt32 specLen = aSpec.Length();
for (PRInt32 i = 0; i < count; i++) {
// Find our comma
commaX = aSpec.FindChar(COMMA, start);
PRInt32 end = (commaX < 0) ? specLen : commaX;
// Note: If end == start then it means that the token has no
// data in it other than a terminating comma (or the end of the spec)
aSpecs[i].mUnit = eFramesetUnit_Fixed;
if (end > start) {
PRInt32 numberEnd = end;
PRUnichar ch = aSpec.CharAt(numberEnd - 1);
if (ASTER == ch) {
aSpecs[i].mUnit = eFramesetUnit_Relative;
numberEnd--;
} else if (PERCENT == ch) {
aSpecs[i].mUnit = eFramesetUnit_Percent;
numberEnd--;
// check for "*%"
if (numberEnd > start) {
ch = aSpec.CharAt(numberEnd - 1);
if (ASTER == ch) {
aSpecs[i].mUnit = eFramesetUnit_Relative;
numberEnd--;
}
}
}
// Translate value to an integer
nsString token;
aSpec.Mid(token, start, numberEnd - start);
// Treat * as 1*
if ((eFramesetUnit_Relative == aSpecs[i].mUnit) &&
(0 == token.Length())) {
aSpecs[i].mValue = 1;
}
// Otherwise just convert to integer.
else {
PRInt32 err;
aSpecs[i].mValue = token.ToInteger(&err);
if (err) {
aSpecs[i].mValue = 0;
}
}
// Treat 0* as 1* in quirks mode (bug 40383)
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);
if (eCompatibility_NavQuirks == mode) {
if ((eFramesetUnit_Relative == aSpecs[i].mUnit) &&
(0 == aSpecs[i].mValue)) {
aSpecs[i].mValue = 1;
}
}
// Catch zero and negative frame sizes for Nav compatability
// Nav resized absolute and relative frames to "1" and
// percent frames to an even percentage of the width
//
//if ((eCompatibility_NavQuirks == aMode) && (aSpecs[i].mValue <= 0)) {
// if (eFramesetUnit_Percent == aSpecs[i].mUnit) {
// aSpecs[i].mValue = 100 / count;
// } else {
// aSpecs[i].mValue = 1;
// }
//} else {
// In standards mode, just set negative sizes to zero
if (aSpecs[i].mValue < 0) {
aSpecs[i].mValue = 0;
}
start = end + 1;
}
}
return count;
}
void
nsHTMLFramesetFrame::ReflowPlaceChild(nsIFrame* aChild,
nsIPresContext* aPresContext,
@ -1164,12 +1025,15 @@ nsHTMLFramesetFrame::Reflow(nsIPresContext* aPresContext,
height -= (mNumRows - 1) * borderWidth;
if (height < 0) height = 0;
if (!mDrag.mActive && ( (firstTime) ||
( (mRect.width != 0) && (mRect.height != 0) &&
(aDesiredSize.width != 0) && (aDesiredSize.height != 0) &&
((aDesiredSize.width != mRect.width) || (aDesiredSize.height != mRect.height))) ) ) {
CalculateRowCol(aPresContext, width, mNumCols, mColSpecs, mColSizes);
CalculateRowCol(aPresContext, height, mNumRows, mRowSpecs, mRowSizes);
if (!mDrag.mActive) {
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
const nsFramesetSpec* rowSpecs = nsnull;
const nsFramesetSpec* colSpecs = nsnull;
ourContent->GetRowSpec(&mNumRows, &rowSpecs);
ourContent->GetColSpec(&mNumCols, &colSpecs);
CalculateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes);
CalculateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes);
}
PRBool* verBordersVis = nsnull; // vertical borders visibility
@ -1640,9 +1504,19 @@ nsHTMLFramesetFrame::MouseDrag(nsIPresContext* aPresContext,
mColSizes[mDragger->mPrevNeighbor] = mPrevNeighborOrigSize + change;
mColSizes[mDragger->mNextNeighbor] = mNextNeighborOrigSize - change;
// Recompute the specs from the new sizes.
nscoord width = mRect.width - (mNumCols - 1) * GetBorderWidth(aPresContext, PR_TRUE);
GenerateRowCol(aPresContext, width, mNumCols, mColSpecs, mColSizes);
if (change != 0) {
// Recompute the specs from the new sizes.
nscoord width = mRect.width - (mNumCols - 1) * GetBorderWidth(aPresContext, PR_TRUE);
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
const nsFramesetSpec* colSpecs = nsnull;
ourContent->GetColSpec(&mNumCols, &colSpecs);
nsAutoString newColAttr;
GenerateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes,
newColAttr);
// Setting the attr will trigger a reflow
mContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::cols, newColAttr, PR_TRUE);
}
} else {
change = aEvent->point.y - mFirstDragPoint.y;
if (change > mNextNeighborOrigSize - mMinDrag) {
@ -1653,9 +1527,19 @@ nsHTMLFramesetFrame::MouseDrag(nsIPresContext* aPresContext,
mRowSizes[mDragger->mPrevNeighbor] = mPrevNeighborOrigSize + change;
mRowSizes[mDragger->mNextNeighbor] = mNextNeighborOrigSize - change;
// Recompute the specs from the new sizes.
nscoord height = mRect.height - (mNumRows - 1) * GetBorderWidth(aPresContext, PR_TRUE);
GenerateRowCol(aPresContext, height, mNumRows, mRowSpecs, mRowSizes);
if (change != 0) {
// Recompute the specs from the new sizes.
nscoord height = mRect.height - (mNumRows - 1) * GetBorderWidth(aPresContext, PR_TRUE);
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
const nsFramesetSpec* rowSpecs = nsnull;
ourContent->GetRowSpec(&mNumRows, &rowSpecs);
nsAutoString newRowAttr;
GenerateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes,
newRowAttr);
// Setting the attr will trigger a reflow
mContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::rows, newRowAttr, PR_TRUE);
}
}
if (change != 0) {
@ -1672,8 +1556,6 @@ nsHTMLFramesetFrame::MouseDrag(nsIPresContext* aPresContext,
return;
}
parentFrame->ReflowDirtyChild(shell, this);
// Update the view immediately (make drag appear snappier)
nsCOMPtr<nsIViewManager> vm;
shell->GetViewManager(getter_AddRefs(vm));

Просмотреть файл

@ -42,6 +42,7 @@
#include "nsColor.h"
#include "nsIObserver.h"
#include "nsWeakPtr.h"
#include "nsIFrameSetElement.h"
class nsIContent;
class nsIFrame;
@ -74,23 +75,12 @@ struct nsBorderColor
void Set(nscolor aColor) { mLeft = mRight = mTop = mBottom = aColor; }
};
enum nsFramesetUnit {
eFramesetUnit_Fixed = 0,
eFramesetUnit_Percent,
eFramesetUnit_Relative
};
enum nsFrameborder {
eFrameborder_Yes = 0,
eFrameborder_No,
eFrameborder_Notset
};
struct nsFramesetSpec {
nsFramesetUnit mUnit;
nscoord mValue;
};
struct nsFramesetDrag {
PRBool mVertical; // vertical if true, otherwise horizontal
PRInt32 mIndex; // index of left col or top row of effected area
@ -135,8 +125,6 @@ public:
static PRBool gDragInProgress;
static PRInt32 gMaxNumRowColSpecs;
void GetSizeOfChild(nsIFrame* aChild, nsSize& aSize);
void GetSizeOfChildAt(PRInt32 aIndexInParent,
@ -195,17 +183,18 @@ protected:
PRInt32 aNumItems,
PRInt32* aItems);
void CalculateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
nsFramesetSpec* aSpecs,
nscoord* aValues);
void CalculateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
const nsFramesetSpec* aSpecs,
nscoord* aValues);
void GenerateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
nsFramesetSpec* aSpecs,
nscoord* aValues);
void GenerateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
const nsFramesetSpec* aSpecs,
nscoord* aValues,
nsString& aNewAttr);
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
@ -234,13 +223,6 @@ protected:
virtual PRIntn GetSkipSides() const;
void ParseRowCol(nsIPresContext* aPresContext, nsIAtom* aAttrType, PRInt32& aNumSpecs, nsFramesetSpec** aSpecs);
PRInt32 ParseRowColSpec(nsIPresContext* aPresContext,
nsString& aSpec,
PRInt32 aMaxNumValues,
nsFramesetSpec* aSpecs);
void ReflowPlaceChild(nsIFrame* aChild,
nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
@ -262,10 +244,8 @@ protected:
PRBool ChildIsFrameset(nsIFrame* aChild);
PRInt32 mNumRows;
nsFramesetSpec* mRowSpecs; // parsed, non-computed dimensions
nscoord* mRowSizes; // currently computed row sizes
PRInt32 mNumCols;
nsFramesetSpec* mColSpecs; // parsed, non-computed dimensions
nscoord* mColSizes; // currently computed col sizes
PRInt32 mNonBorderChildCount;
PRInt32 mNonBlankChildCount;

Просмотреть файл

@ -191,7 +191,6 @@ protected:
/*******************************************************************************
* nsHTMLFramesetFrame
******************************************************************************/
PRInt32 nsHTMLFramesetFrame::gMaxNumRowColSpecs = 25;
PRBool nsHTMLFramesetFrame::gDragInProgress = PR_FALSE;
#define kFrameResizePref "layout.frames.force_resizability"
#define DEFAULT_BORDER_WIDTH_PX 6
@ -200,10 +199,8 @@ nsHTMLFramesetFrame::nsHTMLFramesetFrame()
: nsHTMLContainerFrame()
{
mNumRows = 0;
mRowSpecs = nsnull;
mRowSizes = nsnull;
mNumCols = 0;
mColSpecs = nsnull;
mColSizes = nsnull;
mEdgeVisibility = 0;
mParentFrameborder = eFrameborder_Yes; // default
@ -229,14 +226,11 @@ nsHTMLFramesetFrame::nsHTMLFramesetFrame()
nsHTMLFramesetFrame::~nsHTMLFramesetFrame()
{
delete [] mRowSizes;
delete [] mRowSpecs;
delete [] mColSizes;
delete [] mColSpecs;
delete[] mVerBorders;
delete[] mHorBorders;
mRowSizes = mColSizes = nsnull;
mRowSpecs = mColSpecs = nsnull;
nsCOMPtr<nsIPrefBranchInternal> prefBranch =
do_QueryReferent(mPrefBranchWeakRef);
@ -299,7 +293,6 @@ nsHTMLFramesetFrame::Observe(nsISupports* aObject, const char* aAction,
prefBranch->GetBoolPref(kFrameResizePref, &mForceFrameResizability);
}
RecalculateBorderResize();
mRect.width = mRect.height = -1; // force a recalculation of frame sizes
if (doc) {
doc->AttributeChanged(mContent,
kNameSpaceID_None,
@ -370,9 +363,15 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext,
PRInt32 borderWidth = GetBorderWidth(aPresContext, PR_FALSE);
nscolor borderColor = GetBorderColor();
// parse the rows= cols= data
ParseRowCol(aPresContext, nsHTMLAtoms::rows, mNumRows, &mRowSpecs);
ParseRowCol(aPresContext, nsHTMLAtoms::cols, mNumCols, &mColSpecs);
// Get the rows= cols= data
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
const nsFramesetSpec* rowSpecs = nsnull;
const nsFramesetSpec* colSpecs = nsnull;
result = ourContent->GetRowSpec(&mNumRows, &rowSpecs);
NS_ENSURE_SUCCESS(result, result);
result = ourContent->GetColSpec(&mNumCols, &colSpecs);
NS_ENSURE_SUCCESS(result, result);
mRowSizes = new nscoord[mNumRows];
mColSizes = new nscoord[mNumCols];
@ -517,11 +516,11 @@ void nsHTMLFramesetFrame::Scale(nscoord aDesired,
* specifier - fixed sizes have the highest priority, percentage sizes have the next
* highest priority and relative sizes have the lowest.
*/
void nsHTMLFramesetFrame::CalculateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
nsFramesetSpec* aSpecs,
nscoord* aValues)
void nsHTMLFramesetFrame::CalculateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
const nsFramesetSpec* aSpecs,
nscoord* aValues)
{
PRInt32 fixedTotal = 0;
PRInt32 numFixed = 0;
@ -604,26 +603,30 @@ void nsHTMLFramesetFrame::CalculateRowCol(nsIPresContext* aPresContext,
* each cell in the frameset. Reverse of CalculateRowCol() behaviour.
* This allows us to maintain the user size info through reflows.
*/
void nsHTMLFramesetFrame::GenerateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
nsFramesetSpec* aSpecs,
nscoord* aValues)
void nsHTMLFramesetFrame::GenerateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
const nsFramesetSpec* aSpecs,
nscoord* aValues,
nsString& aNewAttr)
{
float t2p;
aPresContext->GetTwipsToPixels(&t2p);
PRInt32 i;
for (i = 0; i < aNumSpecs; i++) {
for (i = 0; i < aNumSpecs; i++) {
if (!aNewAttr.IsEmpty())
aNewAttr.Append(PRUnichar(','));
switch (aSpecs[i].mUnit) {
case eFramesetUnit_Fixed:
aSpecs[i].mValue = NSToCoordRound(t2p * aValues[i]);
aNewAttr.AppendInt(NSToCoordRound(t2p * aValues[i]));
break;
case eFramesetUnit_Percent: // XXX Only accurate to 1%, need 1 pixel
aSpecs[i].mValue = (100*aValues[i])/aSize;
break;
case eFramesetUnit_Relative:
aSpecs[i].mValue = aValues[i];
// Add 0.5 to the percentage to make rounding work right.
aNewAttr.AppendInt(PRUint32((100.0*aValues[i])/aSize + 0.5));
aNewAttr.Append(PRUnichar('%'));
break;
}
}
@ -853,148 +856,6 @@ nsHTMLFramesetFrame::Paint(nsIPresContext* aPresContext,
aDirtyRect, aWhichLayer);
}
void nsHTMLFramesetFrame::ParseRowCol(nsIPresContext* aPresContext, nsIAtom* aAttrType, PRInt32& aNumSpecs, nsFramesetSpec** aSpecs)
{
nsHTMLValue value;
nsAutoString rowsCols;
nsCOMPtr<nsIHTMLContent> content(do_QueryInterface(mContent));
if (content) {
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetHTMLAttribute(aAttrType, value)) {
if (eHTMLUnit_String == value.GetUnit()) {
value.GetStringValue(rowsCols);
nsFramesetSpec* specs = new nsFramesetSpec[gMaxNumRowColSpecs];
aNumSpecs = ParseRowColSpec(aPresContext, rowsCols, gMaxNumRowColSpecs, specs);
*aSpecs = new nsFramesetSpec[aNumSpecs];
for (int i = 0; i < aNumSpecs; i++) {
(*aSpecs)[i] = specs[i];
}
delete [] specs;
return;
}
}
}
aNumSpecs = 1;
*aSpecs = new nsFramesetSpec[1];
aSpecs[0]->mUnit = eFramesetUnit_Relative;
aSpecs[0]->mValue = 1;
}
/**
* Translate a "rows" or "cols" spec into an array of nsFramesetSpecs
*/
PRInt32
nsHTMLFramesetFrame::ParseRowColSpec(nsIPresContext* aPresContext,
nsString& aSpec,
PRInt32 aMaxNumValues,
nsFramesetSpec* aSpecs)
{
static const PRUnichar ASTER('*');
static const PRUnichar PERCENT('%');
static const PRUnichar COMMA(',');
// remove whitespace (Bug 33699)
// also remove leading/trailing commas (bug 31482)
aSpec.StripChars(" \n\r\t");
aSpec.Trim(",");
// Count the commas
PRInt32 commaX = aSpec.FindChar(COMMA);
PRInt32 count = 1;
while (commaX >= 0) {
count++;
commaX = aSpec.FindChar(COMMA, commaX + 1);
}
if (count > aMaxNumValues) {
NS_ASSERTION(0, "Not enough space for values");
count = aMaxNumValues;
}
// Parse each comma separated token
PRInt32 start = 0;
PRInt32 specLen = aSpec.Length();
for (PRInt32 i = 0; i < count; i++) {
// Find our comma
commaX = aSpec.FindChar(COMMA, start);
PRInt32 end = (commaX < 0) ? specLen : commaX;
// Note: If end == start then it means that the token has no
// data in it other than a terminating comma (or the end of the spec)
aSpecs[i].mUnit = eFramesetUnit_Fixed;
if (end > start) {
PRInt32 numberEnd = end;
PRUnichar ch = aSpec.CharAt(numberEnd - 1);
if (ASTER == ch) {
aSpecs[i].mUnit = eFramesetUnit_Relative;
numberEnd--;
} else if (PERCENT == ch) {
aSpecs[i].mUnit = eFramesetUnit_Percent;
numberEnd--;
// check for "*%"
if (numberEnd > start) {
ch = aSpec.CharAt(numberEnd - 1);
if (ASTER == ch) {
aSpecs[i].mUnit = eFramesetUnit_Relative;
numberEnd--;
}
}
}
// Translate value to an integer
nsString token;
aSpec.Mid(token, start, numberEnd - start);
// Treat * as 1*
if ((eFramesetUnit_Relative == aSpecs[i].mUnit) &&
(0 == token.Length())) {
aSpecs[i].mValue = 1;
}
// Otherwise just convert to integer.
else {
PRInt32 err;
aSpecs[i].mValue = token.ToInteger(&err);
if (err) {
aSpecs[i].mValue = 0;
}
}
// Treat 0* as 1* in quirks mode (bug 40383)
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);
if (eCompatibility_NavQuirks == mode) {
if ((eFramesetUnit_Relative == aSpecs[i].mUnit) &&
(0 == aSpecs[i].mValue)) {
aSpecs[i].mValue = 1;
}
}
// Catch zero and negative frame sizes for Nav compatability
// Nav resized absolute and relative frames to "1" and
// percent frames to an even percentage of the width
//
//if ((eCompatibility_NavQuirks == aMode) && (aSpecs[i].mValue <= 0)) {
// if (eFramesetUnit_Percent == aSpecs[i].mUnit) {
// aSpecs[i].mValue = 100 / count;
// } else {
// aSpecs[i].mValue = 1;
// }
//} else {
// In standards mode, just set negative sizes to zero
if (aSpecs[i].mValue < 0) {
aSpecs[i].mValue = 0;
}
start = end + 1;
}
}
return count;
}
void
nsHTMLFramesetFrame::ReflowPlaceChild(nsIFrame* aChild,
nsIPresContext* aPresContext,
@ -1164,12 +1025,15 @@ nsHTMLFramesetFrame::Reflow(nsIPresContext* aPresContext,
height -= (mNumRows - 1) * borderWidth;
if (height < 0) height = 0;
if (!mDrag.mActive && ( (firstTime) ||
( (mRect.width != 0) && (mRect.height != 0) &&
(aDesiredSize.width != 0) && (aDesiredSize.height != 0) &&
((aDesiredSize.width != mRect.width) || (aDesiredSize.height != mRect.height))) ) ) {
CalculateRowCol(aPresContext, width, mNumCols, mColSpecs, mColSizes);
CalculateRowCol(aPresContext, height, mNumRows, mRowSpecs, mRowSizes);
if (!mDrag.mActive) {
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
const nsFramesetSpec* rowSpecs = nsnull;
const nsFramesetSpec* colSpecs = nsnull;
ourContent->GetRowSpec(&mNumRows, &rowSpecs);
ourContent->GetColSpec(&mNumCols, &colSpecs);
CalculateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes);
CalculateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes);
}
PRBool* verBordersVis = nsnull; // vertical borders visibility
@ -1640,9 +1504,19 @@ nsHTMLFramesetFrame::MouseDrag(nsIPresContext* aPresContext,
mColSizes[mDragger->mPrevNeighbor] = mPrevNeighborOrigSize + change;
mColSizes[mDragger->mNextNeighbor] = mNextNeighborOrigSize - change;
// Recompute the specs from the new sizes.
nscoord width = mRect.width - (mNumCols - 1) * GetBorderWidth(aPresContext, PR_TRUE);
GenerateRowCol(aPresContext, width, mNumCols, mColSpecs, mColSizes);
if (change != 0) {
// Recompute the specs from the new sizes.
nscoord width = mRect.width - (mNumCols - 1) * GetBorderWidth(aPresContext, PR_TRUE);
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
const nsFramesetSpec* colSpecs = nsnull;
ourContent->GetColSpec(&mNumCols, &colSpecs);
nsAutoString newColAttr;
GenerateRowCol(aPresContext, width, mNumCols, colSpecs, mColSizes,
newColAttr);
// Setting the attr will trigger a reflow
mContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::cols, newColAttr, PR_TRUE);
}
} else {
change = aEvent->point.y - mFirstDragPoint.y;
if (change > mNextNeighborOrigSize - mMinDrag) {
@ -1653,9 +1527,19 @@ nsHTMLFramesetFrame::MouseDrag(nsIPresContext* aPresContext,
mRowSizes[mDragger->mPrevNeighbor] = mPrevNeighborOrigSize + change;
mRowSizes[mDragger->mNextNeighbor] = mNextNeighborOrigSize - change;
// Recompute the specs from the new sizes.
nscoord height = mRect.height - (mNumRows - 1) * GetBorderWidth(aPresContext, PR_TRUE);
GenerateRowCol(aPresContext, height, mNumRows, mRowSpecs, mRowSizes);
if (change != 0) {
// Recompute the specs from the new sizes.
nscoord height = mRect.height - (mNumRows - 1) * GetBorderWidth(aPresContext, PR_TRUE);
nsCOMPtr<nsIFrameSetElement> ourContent(do_QueryInterface(mContent));
NS_ASSERTION(ourContent, "Someone gave us a broken frameset element!");
const nsFramesetSpec* rowSpecs = nsnull;
ourContent->GetRowSpec(&mNumRows, &rowSpecs);
nsAutoString newRowAttr;
GenerateRowCol(aPresContext, height, mNumRows, rowSpecs, mRowSizes,
newRowAttr);
// Setting the attr will trigger a reflow
mContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::rows, newRowAttr, PR_TRUE);
}
}
if (change != 0) {
@ -1672,8 +1556,6 @@ nsHTMLFramesetFrame::MouseDrag(nsIPresContext* aPresContext,
return;
}
parentFrame->ReflowDirtyChild(shell, this);
// Update the view immediately (make drag appear snappier)
nsCOMPtr<nsIViewManager> vm;
shell->GetViewManager(getter_AddRefs(vm));

Просмотреть файл

@ -42,6 +42,7 @@
#include "nsColor.h"
#include "nsIObserver.h"
#include "nsWeakPtr.h"
#include "nsIFrameSetElement.h"
class nsIContent;
class nsIFrame;
@ -74,23 +75,12 @@ struct nsBorderColor
void Set(nscolor aColor) { mLeft = mRight = mTop = mBottom = aColor; }
};
enum nsFramesetUnit {
eFramesetUnit_Fixed = 0,
eFramesetUnit_Percent,
eFramesetUnit_Relative
};
enum nsFrameborder {
eFrameborder_Yes = 0,
eFrameborder_No,
eFrameborder_Notset
};
struct nsFramesetSpec {
nsFramesetUnit mUnit;
nscoord mValue;
};
struct nsFramesetDrag {
PRBool mVertical; // vertical if true, otherwise horizontal
PRInt32 mIndex; // index of left col or top row of effected area
@ -135,8 +125,6 @@ public:
static PRBool gDragInProgress;
static PRInt32 gMaxNumRowColSpecs;
void GetSizeOfChild(nsIFrame* aChild, nsSize& aSize);
void GetSizeOfChildAt(PRInt32 aIndexInParent,
@ -195,17 +183,18 @@ protected:
PRInt32 aNumItems,
PRInt32* aItems);
void CalculateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
nsFramesetSpec* aSpecs,
nscoord* aValues);
void CalculateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
const nsFramesetSpec* aSpecs,
nscoord* aValues);
void GenerateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
nsFramesetSpec* aSpecs,
nscoord* aValues);
void GenerateRowCol(nsIPresContext* aPresContext,
nscoord aSize,
PRInt32 aNumSpecs,
const nsFramesetSpec* aSpecs,
nscoord* aValues,
nsString& aNewAttr);
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
@ -234,13 +223,6 @@ protected:
virtual PRIntn GetSkipSides() const;
void ParseRowCol(nsIPresContext* aPresContext, nsIAtom* aAttrType, PRInt32& aNumSpecs, nsFramesetSpec** aSpecs);
PRInt32 ParseRowColSpec(nsIPresContext* aPresContext,
nsString& aSpec,
PRInt32 aMaxNumValues,
nsFramesetSpec* aSpecs);
void ReflowPlaceChild(nsIFrame* aChild,
nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
@ -262,10 +244,8 @@ protected:
PRBool ChildIsFrameset(nsIFrame* aChild);
PRInt32 mNumRows;
nsFramesetSpec* mRowSpecs; // parsed, non-computed dimensions
nscoord* mRowSizes; // currently computed row sizes
PRInt32 mNumCols;
nsFramesetSpec* mColSpecs; // parsed, non-computed dimensions
nscoord* mColSizes; // currently computed col sizes
PRInt32 mNonBorderChildCount;
PRInt32 mNonBlankChildCount;