diff --git a/mozilla/content/html/content/src/nsHTMLFrameSetElement.cpp b/mozilla/content/html/content/src/nsHTMLFrameSetElement.cpp
index 523d3fba98e..5ba3b876762 100644
--- a/mozilla/content/html/content/src/nsHTMLFrameSetElement.cpp
+++ b/mozilla/content/html/content/src/nsHTMLFrameSetElement.cpp
@@ -91,9 +91,6 @@ 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
@@ -111,33 +108,24 @@ private:
/**
* The parsed representation of the "rows" attribute
*/
- nsFramesetSpec* mRowSpecs; // parsed, non-computed dimensions
+ nsAutoArrayPtr mRowSpecs; // parsed, non-computed dimensions
/**
* The parsed representation of the "cols" attribute
*/
- nsFramesetSpec* mColSpecs; // parsed, non-computed dimensions
-
- static PRInt32 gMaxNumRowColSpecs;
+ nsAutoArrayPtr mColSpecs; // parsed, non-computed dimensions
};
-PRInt32 nsHTMLFrameSetElement::gMaxNumRowColSpecs = 25;
-
-
NS_IMPL_NS_NEW_HTML_ELEMENT(FrameSet)
nsHTMLFrameSetElement::nsHTMLFrameSetElement(nsINodeInfo *aNodeInfo)
: nsGenericHTMLElement(aNodeInfo), mNumRows(0), mNumCols(0),
- mCurrentRowColHint(NS_STYLE_HINT_REFLOW), mRowSpecs(nsnull),
- mColSpecs(nsnull)
+ mCurrentRowColHint(NS_STYLE_HINT_REFLOW)
{
}
nsHTMLFrameSetElement::~nsHTMLFrameSetElement()
{
- delete [] mRowSpecs;
- delete [] mColSpecs;
- mRowSpecs = mColSpecs = nsnull;
}
@@ -178,11 +166,7 @@ nsHTMLFrameSetElement::SetAttr(PRInt32 aNameSpaceID,
*/
if (aAttribute == nsHTMLAtoms::rows && aNameSpaceID == kNameSpaceID_None) {
PRInt32 oldRows = mNumRows;
- delete [] mRowSpecs;
- mRowSpecs = nsnull;
- mNumRows = 0;
-
- ParseRowCol(aValue, mNumRows, &mRowSpecs);
+ ParseRowCol(aValue, mNumRows, getter_Transfers(mRowSpecs));
if (mNumRows != oldRows) {
mCurrentRowColHint = NS_STYLE_HINT_FRAMECHANGE;
@@ -190,11 +174,7 @@ nsHTMLFrameSetElement::SetAttr(PRInt32 aNameSpaceID,
} else if (aAttribute == nsHTMLAtoms::cols &&
aNameSpaceID == kNameSpaceID_None) {
PRInt32 oldCols = mNumCols;
- delete [] mColSpecs;
- mColSpecs = nsnull;
- mNumCols = 0;
-
- ParseRowCol(aValue, mNumCols, &mColSpecs);
+ ParseRowCol(aValue, mNumCols, getter_Transfers(mColSpecs));
if (mNumCols != oldCols) {
mCurrentRowColHint = NS_STYLE_HINT_FRAMECHANGE;
@@ -220,7 +200,8 @@ nsHTMLFrameSetElement::GetRowSpec(PRInt32 *aNumValues,
if (!mRowSpecs) {
const nsAttrValue* value = GetParsedAttr(nsHTMLAtoms::rows);
if (value && value->Type() == nsAttrValue::eString) {
- nsresult rv = ParseRowCol(value->GetStringValue(), mNumRows, &mRowSpecs);
+ nsresult rv = ParseRowCol(value->GetStringValue(), mNumRows,
+ getter_Transfers(mRowSpecs));
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -253,7 +234,8 @@ nsHTMLFrameSetElement::GetColSpec(PRInt32 *aNumValues,
if (!mColSpecs) {
const nsAttrValue* value = GetParsedAttr(nsHTMLAtoms::cols);
if (value && value->Type() == nsAttrValue::eString) {
- nsresult rv = ParseRowCol(value->GetStringValue(), mNumCols, &mColSpecs);
+ nsresult rv = ParseRowCol(value->GetStringValue(), mNumCols,
+ getter_Transfers(mColSpecs));
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -306,129 +288,112 @@ nsHTMLFrameSetElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
return retval;
}
+/**
+ * Translate a "rows" or "cols" spec into an array of nsFramesetSpecs
+ */
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;
+ if (aValue.IsEmpty()) {
+ aNumSpecs = 0;
+ *aSpecs = nsnull;
+ return NS_OK;
}
- 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(',');
+ nsAutoString spec(aValue);
// remove whitespace (Bug 33699) and quotation marks (bug 224598)
// also remove leading/trailing commas (bug 31482)
- aSpec.StripChars(" \n\r\t\"\'");
- aSpec.Trim(",");
+ spec.StripChars(" \n\r\t\"\'");
+ spec.Trim(",");
// Count the commas
- PRInt32 commaX = aSpec.FindChar(sComma);
+ PRInt32 commaX = spec.FindChar(sComma);
PRInt32 count = 1;
- while (commaX >= 0) {
+ while (commaX != kNotFound) {
count++;
- commaX = aSpec.FindChar(sComma, commaX + 1);
+ commaX = spec.FindChar(sComma, commaX + 1);
}
- if (count > aMaxNumValues) {
- NS_ASSERTION(0, "Not enough space for values");
- count = aMaxNumValues;
+ nsFramesetSpec* specs = new nsFramesetSpec[count];
+ if (!specs) {
+ *aSpecs = nsnull;
+ aNumSpecs = 0;
+ return NS_ERROR_OUT_OF_MEMORY;
}
+ // Pre-grab the compat mode; we may need it later in the loop.
+ nsCompatibility mode = eCompatibility_FullStandards;
+ nsCOMPtr htmlDocument =
+ do_QueryInterface(GetOwnerDoc());
+ if (htmlDocument) {
+ mode = htmlDocument->GetCompatibilityMode();
+ }
+
// Parse each comma separated token
PRInt32 start = 0;
- PRInt32 specLen = aSpec.Length();
+ PRInt32 specLen = spec.Length();
for (PRInt32 i = 0; i < count; i++) {
// Find our comma
- commaX = aSpec.FindChar(sComma, start);
- PRInt32 end = (commaX < 0) ? specLen : commaX;
+ commaX = spec.FindChar(sComma, start);
+ NS_ASSERTION(i == count - 1 || commaX != kNotFound,
+ "Failed to find comma, somehow");
+ PRInt32 end = (commaX == kNotFound) ? 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;
+ // data in it other than a terminating comma (or the end of the spec).
+ // So default to a fixed width of 0.
+ specs[i].mUnit = eFramesetUnit_Fixed;
+ specs[i].mValue = 0;
if (end > start) {
PRInt32 numberEnd = end;
- PRUnichar ch = aSpec.CharAt(numberEnd - 1);
+ PRUnichar ch = spec.CharAt(numberEnd - 1);
if (sAster == ch) {
- aSpecs[i].mUnit = eFramesetUnit_Relative;
+ specs[i].mUnit = eFramesetUnit_Relative;
numberEnd--;
} else if (sPercent == ch) {
- aSpecs[i].mUnit = eFramesetUnit_Percent;
+ specs[i].mUnit = eFramesetUnit_Percent;
numberEnd--;
// check for "*%"
if (numberEnd > start) {
- ch = aSpec.CharAt(numberEnd - 1);
+ ch = spec.CharAt(numberEnd - 1);
if (sAster == ch) {
- aSpecs[i].mUnit = eFramesetUnit_Relative;
+ specs[i].mUnit = eFramesetUnit_Relative;
numberEnd--;
}
}
}
// Translate value to an integer
- nsString token;
- aSpec.Mid(token, start, numberEnd - start);
+ nsAutoString token;
+ spec.Mid(token, start, numberEnd - start);
// Treat * as 1*
- if ((eFramesetUnit_Relative == aSpecs[i].mUnit) &&
+ if ((eFramesetUnit_Relative == specs[i].mUnit) &&
(0 == token.Length())) {
- aSpecs[i].mValue = 1;
+ specs[i].mValue = 1;
}
else {
// Otherwise just convert to integer.
PRInt32 err;
- aSpecs[i].mValue = token.ToInteger(&err);
+ specs[i].mValue = token.ToInteger(&err);
if (err) {
- aSpecs[i].mValue = 0;
+ specs[i].mValue = 0;
}
}
// Treat 0* as 1* in quirks mode (bug 40383)
- nsCompatibility mode = eCompatibility_FullStandards;
- nsCOMPtr htmlDocument =
- do_QueryInterface(GetOwnerDoc());
- if (htmlDocument) {
- mode = htmlDocument->GetCompatibilityMode();
- }
-
if (eCompatibility_NavQuirks == mode) {
- if ((eFramesetUnit_Relative == aSpecs[i].mUnit) &&
- (0 == aSpecs[i].mValue)) {
- aSpecs[i].mValue = 1;
+ if ((eFramesetUnit_Relative == specs[i].mUnit) &&
+ (0 == specs[i].mValue)) {
+ specs[i].mValue = 1;
}
}
@@ -436,21 +401,26 @@ nsHTMLFrameSetElement::ParseRowColSpec(nsString& aSpec,
// 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;
+ //if ((eCompatibility_NavQuirks == aMode) && (specs[i].mValue <= 0)) {
+ // if (eFramesetUnit_Percent == specs[i].mUnit) {
+ // specs[i].mValue = 100 / count;
// } else {
- // aSpecs[i].mValue = 1;
+ // specs[i].mValue = 1;
// }
//} else {
// In standards mode, just set negative sizes to zero
- if (aSpecs[i].mValue < 0) {
- aSpecs[i].mValue = 0;
+ if (specs[i].mValue < 0) {
+ specs[i].mValue = 0;
}
start = end + 1;
}
}
- return count;
+
+ aNumSpecs = count;
+ // Transfer ownership to caller here
+ *aSpecs = specs;
+
+ return NS_OK;
}