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
Родитель 51f395c646
Коммит c4ca2d639c
5 изменённых файлов: 150 добавлений и 3 удалений

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

@ -401,6 +401,16 @@ public:
*/
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();
/**

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

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

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

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

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

@ -49,6 +49,7 @@
#include "nsStringBuffer.h"
#include "nsColor.h"
#include "nsCaseTreatment.h"
#include "nsMargin.h"
typedef PRUptrdiff PtrBits;
class nsAString;
@ -98,6 +99,7 @@ public:
#ifdef MOZ_SVG
explicit nsAttrValue(nsISVGValue* aValue);
#endif
explicit nsAttrValue(const nsIntMargin& aValue);
~nsAttrValue();
static nsresult Init();
@ -120,6 +122,7 @@ public:
,eSVGValue = 0x12
#endif
,eFloatValue = 0x13
,eIntMarginValue = 0x14
};
ValueType Type() const;
@ -133,6 +136,7 @@ public:
#ifdef MOZ_SVG
void SetTo(nsISVGValue* aValue);
#endif
void SetTo(const nsIntMargin& aValue);
void SwapValueWith(nsAttrValue& aOther);
@ -153,6 +157,7 @@ public:
inline nsISVGValue* GetSVGValue() const;
#endif
inline float GetFloatValue() const;
PRBool GetIntMarginValue(nsIntMargin& aMargin) const;
/**
* Returns the string corresponding to the stored enum value.
@ -297,6 +302,15 @@ public:
*/
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:
// These have to be the same as in ValueType
enum ValueBaseType {
@ -325,6 +339,7 @@ private:
nsISVGValue* mSVGValue;
#endif
float mFloatValue;
nsIntMargin* mIntMargin;
};
};
@ -442,6 +457,17 @@ nsAttrValue::GetFloatValue() const
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
nsAttrValue::BaseType() const
{

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

@ -924,6 +924,53 @@ nsContentUtils::IsHTMLWhitespace(PRUnichar aChar)
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 */
void
@ -6115,6 +6162,12 @@ nsIContentUtils::IsSafeToRunScript()
return nsContentUtils::IsSafeToRunScript();
}
PRBool
nsIContentUtils::ParseIntMarginValue(const nsAString& aString, nsIntMargin& result)
{
return nsContentUtils::ParseIntMarginValue(aString, result);
}
already_AddRefed<nsIDocumentLoaderFactory>
nsIContentUtils::FindInternalContentViewer(const char* aType,
ContentViewerType* aLoaderType)