зеркало из https://github.com/mozilla/gecko-dev.git
Setting rows/cols on a frameset should try to reflow, not reframe. Bug
48422, r=jkeiser, sr=jst
This commit is contained in:
Родитель
2a4fb9e6d8
Коммит
c4caf1665b
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче