Bug 513162 - Add 'top, right, bottom, left' margin support in nsAttrValue. r=smaug.

This commit is contained in:
Jim Mathies 2010-06-24 21:01:07 -05:00
parent 51f395c646
commit c4ca2d639c
5 changed files with 150 additions and 3 deletions

View File

@ -401,6 +401,16 @@ public:
*/ */
static PRBool IsHTMLWhitespace(PRUnichar aChar); static PRBool IsHTMLWhitespace(PRUnichar aChar);
/**
* Parse a margin string of format 'top, right, bottom, left' into
* an nsIntMargin.
*
* @param aString the string to parse
* @param aResult the resulting integer
* @return whether the value could be parsed
*/
static PRBool ParseIntMarginValue(const nsAString& aString, nsIntMargin& aResult);
static void Shutdown(); static void Shutdown();
/** /**

View File

@ -39,11 +39,13 @@
#include "nsIDocumentLoaderFactory.h" #include "nsIDocumentLoaderFactory.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsAString.h"
#include "nsMargin.h"
// C4EA618E-A3D9-4524-8EEA-E92F26FC44DB // {3682DD99-8560-44f4-9B8F-CCCE9D7B96FB}
#define NS_ICONTENTUTILS_IID \ #define NS_ICONTENTUTILS_IID \
{ 0xC4EA618E, 0xA3D9, 0x4524, \ { 0x3682dd99, 0x8560, 0x44f4, \
{ 0x8E, 0xEA, 0xE9, 0x2F, 0x26, 0xFC, 0x44, 0xDB } } { 0x9b, 0x8f, 0xcc, 0xce, 0x9d, 0x7b, 0x96, 0xfb } }
class nsIContentUtils : public nsISupports class nsIContentUtils : public nsISupports
{ {
@ -52,6 +54,7 @@ public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
virtual PRBool IsSafeToRunScript(); virtual PRBool IsSafeToRunScript();
virtual PRBool ParseIntMarginValue(const nsAString& aString, nsIntMargin& result);
enum ContentViewerType enum ContentViewerType
{ {

View File

@ -92,6 +92,12 @@ nsAttrValue::nsAttrValue(nsISVGValue* aValue)
} }
#endif #endif
nsAttrValue::nsAttrValue(const nsIntMargin& aValue)
: mBits(0)
{
SetTo(aValue);
}
nsAttrValue::~nsAttrValue() nsAttrValue::~nsAttrValue()
{ {
ResetIfSet(); ResetIfSet();
@ -259,6 +265,12 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
cont->mFloatValue = otherCont->mFloatValue; cont->mFloatValue = otherCont->mFloatValue;
break; break;
} }
case eIntMarginValue:
{
if (otherCont->mIntMargin)
cont->mIntMargin = new nsIntMargin(*otherCont->mIntMargin);
break;
}
default: default:
{ {
NS_NOTREACHED("unknown type stored in MiscContainer"); NS_NOTREACHED("unknown type stored in MiscContainer");
@ -320,6 +332,16 @@ nsAttrValue::SetTo(nsISVGValue* aValue)
} }
#endif #endif
void
nsAttrValue::SetTo(const nsIntMargin& aValue)
{
if (EnsureEmptyMiscContainer()) {
MiscContainer* cont = GetMiscContainer();
cont->mIntMargin = new nsIntMargin(aValue);
cont->mType = eIntMarginValue;
}
}
void void
nsAttrValue::SwapValueWith(nsAttrValue& aOther) nsAttrValue::SwapValueWith(nsAttrValue& aOther)
{ {
@ -585,6 +607,10 @@ nsAttrValue::HashValue() const
// XXX this is crappy, but oh well // XXX this is crappy, but oh well
return cont->mFloatValue; return cont->mFloatValue;
} }
case eIntMarginValue:
{
return NS_PTR_TO_INT32(cont->mIntMargin);
}
default: default:
{ {
NS_NOTREACHED("unknown type stored in MiscContainer"); NS_NOTREACHED("unknown type stored in MiscContainer");
@ -687,6 +713,10 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
{ {
return thisCont->mFloatValue == otherCont->mFloatValue; return thisCont->mFloatValue == otherCont->mFloatValue;
} }
case eIntMarginValue:
{
return thisCont->mIntMargin == otherCont->mIntMargin;
}
default: default:
{ {
NS_NOTREACHED("unknown type stored in MiscContainer"); NS_NOTREACHED("unknown type stored in MiscContainer");
@ -1204,6 +1234,26 @@ PRBool nsAttrValue::ParseFloatValue(const nsAString& aString)
return PR_FALSE; return PR_FALSE;
} }
PRBool
nsAttrValue::ParseIntMarginValue(const nsAString& aString)
{
ResetIfSet();
nsIntMargin margins;
if (!nsContentUtils::ParseIntMarginValue(aString, margins))
return PR_FALSE;
if (EnsureEmptyMiscContainer()) {
MiscContainer* cont = GetMiscContainer();
cont->mIntMargin = new nsIntMargin(margins);
cont->mType = eIntMarginValue;
SetMiscAtomOrString(&aString);
return PR_TRUE;
}
return PR_FALSE;
}
void void
nsAttrValue::SetMiscAtomOrString(const nsAString* aValue) nsAttrValue::SetMiscAtomOrString(const nsAString* aValue)
{ {
@ -1269,6 +1319,11 @@ nsAttrValue::EnsureEmptyMiscContainer()
break; break;
} }
#endif #endif
case eIntMarginValue:
{
delete cont->mIntMargin;
break;
}
default: default:
{ {
break; break;

View File

@ -49,6 +49,7 @@
#include "nsStringBuffer.h" #include "nsStringBuffer.h"
#include "nsColor.h" #include "nsColor.h"
#include "nsCaseTreatment.h" #include "nsCaseTreatment.h"
#include "nsMargin.h"
typedef PRUptrdiff PtrBits; typedef PRUptrdiff PtrBits;
class nsAString; class nsAString;
@ -98,6 +99,7 @@ public:
#ifdef MOZ_SVG #ifdef MOZ_SVG
explicit nsAttrValue(nsISVGValue* aValue); explicit nsAttrValue(nsISVGValue* aValue);
#endif #endif
explicit nsAttrValue(const nsIntMargin& aValue);
~nsAttrValue(); ~nsAttrValue();
static nsresult Init(); static nsresult Init();
@ -120,6 +122,7 @@ public:
,eSVGValue = 0x12 ,eSVGValue = 0x12
#endif #endif
,eFloatValue = 0x13 ,eFloatValue = 0x13
,eIntMarginValue = 0x14
}; };
ValueType Type() const; ValueType Type() const;
@ -133,6 +136,7 @@ public:
#ifdef MOZ_SVG #ifdef MOZ_SVG
void SetTo(nsISVGValue* aValue); void SetTo(nsISVGValue* aValue);
#endif #endif
void SetTo(const nsIntMargin& aValue);
void SwapValueWith(nsAttrValue& aOther); void SwapValueWith(nsAttrValue& aOther);
@ -153,6 +157,7 @@ public:
inline nsISVGValue* GetSVGValue() const; inline nsISVGValue* GetSVGValue() const;
#endif #endif
inline float GetFloatValue() const; inline float GetFloatValue() const;
PRBool GetIntMarginValue(nsIntMargin& aMargin) const;
/** /**
* Returns the string corresponding to the stored enum value. * Returns the string corresponding to the stored enum value.
@ -297,6 +302,15 @@ public:
*/ */
PRBool ParseLazyURIValue(const nsAString& aString); PRBool ParseLazyURIValue(const nsAString& aString);
/**
* Parse a margin string of format 'top, right, bottom, left' into
* an nsIntMargin.
*
* @param aString the string to parse
* @return whether the value could be parsed
*/
PRBool ParseIntMarginValue(const nsAString& aString);
private: private:
// These have to be the same as in ValueType // These have to be the same as in ValueType
enum ValueBaseType { enum ValueBaseType {
@ -325,6 +339,7 @@ private:
nsISVGValue* mSVGValue; nsISVGValue* mSVGValue;
#endif #endif
float mFloatValue; float mFloatValue;
nsIntMargin* mIntMargin;
}; };
}; };
@ -442,6 +457,17 @@ nsAttrValue::GetFloatValue() const
return GetMiscContainer()->mFloatValue; return GetMiscContainer()->mFloatValue;
} }
inline PRBool
nsAttrValue::GetIntMarginValue(nsIntMargin& aMargin) const
{
NS_PRECONDITION(Type() == eIntMarginValue, "wrong type");
nsIntMargin* m = GetMiscContainer()->mIntMargin;
if (!m)
return PR_FALSE;
aMargin = *m;
return PR_TRUE;
}
inline nsAttrValue::ValueBaseType inline nsAttrValue::ValueBaseType
nsAttrValue::BaseType() const nsAttrValue::BaseType() const
{ {

View File

@ -924,6 +924,53 @@ nsContentUtils::IsHTMLWhitespace(PRUnichar aChar)
aChar == PRUnichar(0x0020); aChar == PRUnichar(0x0020);
} }
/* static */
PRBool
nsContentUtils::ParseIntMarginValue(const nsAString& aString, nsIntMargin& result)
{
nsAutoString marginStr(aString);
marginStr.CompressWhitespace(PR_TRUE, PR_TRUE);
if (marginStr.IsEmpty()) {
return PR_FALSE;
}
PRInt32 start = 0, end = 0;
for (int count = 0; count < 4; count++) {
if (end >= marginStr.Length())
return PR_FALSE;
// top, right, bottom, left
if (count < 3)
end = Substring(marginStr, start).FindChar(',');
else
end = Substring(marginStr, start).Length();
if (end <= 0)
return PR_FALSE;
PRInt32 ec, val =
nsString(Substring(marginStr, start, end)).ToInteger(&ec);
if (NS_FAILED(ec))
return PR_FALSE;
switch(count) {
case 0:
result.top = val;
break;
case 1:
result.right = val;
break;
case 2:
result.bottom = val;
break;
case 3:
result.left = val;
break;
}
start += end + 1;
}
return PR_TRUE;
}
/* static */ /* static */
void void
@ -6115,6 +6162,12 @@ nsIContentUtils::IsSafeToRunScript()
return nsContentUtils::IsSafeToRunScript(); return nsContentUtils::IsSafeToRunScript();
} }
PRBool
nsIContentUtils::ParseIntMarginValue(const nsAString& aString, nsIntMargin& result)
{
return nsContentUtils::ParseIntMarginValue(aString, result);
}
already_AddRefed<nsIDocumentLoaderFactory> already_AddRefed<nsIDocumentLoaderFactory>
nsIContentUtils::FindInternalContentViewer(const char* aType, nsIContentUtils::FindInternalContentViewer(const char* aType,
ContentViewerType* aLoaderType) ContentViewerType* aLoaderType)