diff --git a/mozilla/layout/doc/adding-style-props.html b/mozilla/layout/doc/adding-style-props.html new file mode 100644 index 00000000000..6488685dcdf --- /dev/null +++ b/mozilla/layout/doc/adding-style-props.html @@ -0,0 +1,218 @@ +
+ +++Document history:
++
+- 03/21/2001: Marc Attinasi (attinasi@netscape.com) created document +/ implementing -moz-force-broken-image-icon for bug +58646 +
+
+
CSS_PROP(-moz-force-broken-image-iconst, force_broken_image_icons, FRAMECHANGE) // bug 58646+The first value is the formal property name, in other words the property +name as it is seen by the CSS parser.
// nsCSSUserInterface+The GetValue method must be similarly modified +:
case eCSSProperty_user_input:
case eCSSProperty_user_modify:
case eCSSProperty_user_select:
case eCSSProperty_key_equivalent:
case eCSSProperty_user_focus:
case eCSSProperty_resizer:
case eCSSProperty_cursor:
case eCSSProperty_force_broken_image_icons: {
CSS_ENSURE(UserInterface) {
switch (aProperty) {
case eCSSProperty_user_input: theUserInterface->mUserInput = aValue; break;
case eCSSProperty_user_modify: theUserInterface->mUserModify = aValue; break;
case eCSSProperty_user_select: theUserInterface->mUserSelect = aValue; break;
case eCSSProperty_key_equivalent:
CSS_ENSURE_DATA(theUserInterface->mKeyEquivalent, nsCSSValueList) {
theUserInterface->mKeyEquivalent->mValue = aValue;
CSS_IF_DELETE(theUserInterface->mKeyEquivalent->mNext);
}
break;
case eCSSProperty_user_focus: theUserInterface->mUserFocus = aValue; break;
case eCSSProperty_resizer: theUserInterface->mResizer = aValue; break;
case eCSSProperty_cursor:
CSS_ENSURE_DATA(theUserInterface->mCursor, nsCSSValueList) {
theUserInterface->mCursor->mValue = aValue;
CSS_IF_DELETE(theUserInterface->mCursor->mNext);
}
break;
case eCSSProperty_force_broken_image_icons: theUserInterface->mForceBrokenImageIcon = aValue; break;
CSS_BOGUS_DEFAULT; // make compiler happy
}
}
break;
}
// nsCSSUserInterface+Finally modify +the 'List' method to output the property value.
case eCSSProperty_user_input:
case eCSSProperty_user_modify:
case eCSSProperty_user_select:
case eCSSProperty_key_equivalent:
case eCSSProperty_user_focus:
case eCSSProperty_resizer:
case eCSSProperty_cursor:
case eCSSProperty_force_broken_image_icons: {
CSS_VARONSTACK_GET(UserInterface);
if (nsnull != theUserInterface) {
switch (aProperty) {
case eCSSProperty_user_input: aValue = theUserInterface->mUserInput; break;
case eCSSProperty_user_modify: aValue = theUserInterface->mUserModify; break;
case eCSSProperty_user_select: aValue = theUserInterface->mUserSelect; break;
case eCSSProperty_key_equivalent:
if (nsnull != theUserInterface->mKeyEquivalent) {
aValue = theUserInterface->mKeyEquivalent->mValue;
}
break;
case eCSSProperty_user_focus: aValue = theUserInterface->mUserFocus; break;
case eCSSProperty_resizer: aValue = theUserInterface->mResizer; break;
case eCSSProperty_cursor:
if (nsnull != theUserInterface->mCursor) {
aValue = theUserInterface->mCursor->mValue;
}
break;
case eCSSProperty_force_broken_image_icons: aValue = theUserInterface->mForceBrokenImageIcons; break;
CSS_BOGUS_DEFAULT; // make compiler happy
}
}
else {
aValue.Reset();
}
break;
}
void nsCSSUserInterface::List(FILE* out, PRInt32 aIndent) const+ +
{
for (PRInt32 index = aIndent; --index >= 0; ) fputs(" ", out);
nsAutoString buffer;
mUserInput.AppendToString(buffer, eCSSProperty_user_input);
mUserModify.AppendToString(buffer, eCSSProperty_user_modify);
mUserSelect.AppendToString(buffer, eCSSProperty_user_select);
nsCSSValueList* keyEquiv = mKeyEquivalent;
while (nsnull != keyEquiv) {
keyEquiv->mValue.AppendToString(buffer, eCSSProperty_key_equivalent);
keyEquiv= keyEquiv->mNext;
}
mUserFocus.AppendToString(buffer, eCSSProperty_user_focus);
mResizer.AppendToString(buffer, eCSSProperty_resizer);
nsCSSValueList* cursor = mCursor;
while (nsnull != cursor) {
cursor->mValue.AppendToString(buffer, eCSSProperty_cursor);
cursor = cursor->mNext;
}
mForceBrokenImageIcon.AppendToString(buffer,eCSSProperty_force_broken_image_icons);
fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out);
}
case eCSSProperty_force_broken_image_icons:+
return ParsePositiveVariant(aErrorCode, aValue, VARIANT_INTEGER, nsnull);+This will parse the value as a positive integer value, which is what we want.
struct nsStyleUIReset: public nsStyleStruct {
nsStyleUIReset(void);
nsStyleUIReset(const nsStyleUIReset& aOther);
~nsStyleUIReset(void);
NS_DEFINE_STATIC_STYLESTRUCTID_ACCESSOR(eStyleStruct_UIReset)
void* operator new(size_t sz, nsIPresContext* aContext) {
void* result = nsnull;
aContext->AllocateFromShell(sz, &result);
return result;
}
void Destroy(nsIPresContext* aContext) {
this->~nsStyleUIReset();
aContext->FreeToShell(sizeof(nsStyleUIReset), this);
};
PRInt32 CalcDifference(const nsStyleUIReset& aOther) const;
PRUint8 mUserSelect; // [reset] (selection-style)
PRUnichar mKeyEquivalent; // [reset] XXX what type should this be?
PRUint8 mResizer; // [reset]
PRUint8 mForceBrokenImageIcon; // [reset] (0 if not forcing, otherwise forcing)
};
+In the implementation file
+nsStyleContext.cpp
+add the new data member to the constructors of the style struct and the CalcDifference
+method, which must return the correct style-change hint when a change to
+your new property is detected. The constructor changes are obvious, but here
+is the CalcDifference change for our example:PRInt32 nsStyleUIReset::CalcDifference(const nsStyleUIReset& aOther) const+
{
if (mForceBrokenImageIcon == aOther.mForceBrokenImageIcon) {
if (mResizer == aOther.mResizer) {
if (mUserSelect == aOther.mUserSelect) {
if (mKeyEquivalent == aOther.mKeyEquivalent) {
return NS_STYLE_HINT_NONE;
}
return NS_STYLE_HINT_CONTENT;
}
return NS_STYLE_HINT_VISUAL;
}
return NS_STYLE_HINT_VISUAL;
}
return NS_STYLE_HINT_FRAMECHANGE;
}
static nsresult+
MapUIForDeclaration(nsCSSDeclaration* aDecl, const nsStyleStructID& aID, nsCSSUserInterface& aUI)
{
if (!aDecl)
return NS_OK; // The rule must have a declaration.
nsCSSUserInterface* ourUI = (nsCSSUserInterface*)aDecl->GetData(kCSSUserInterfaceSID);
if (!ourUI)
return NS_OK; // We don't have any rules for UI.
if (aID == eStyleStruct_UserInterface) {
if (aUI.mUserFocus.GetUnit() == eCSSUnit_Null && ourUI->mUserFocus.GetUnit() != eCSSUnit_Null)
aUI.mUserFocus = ourUI->mUserFocus;
if (aUI.mUserInput.GetUnit() == eCSSUnit_Null && ourUI->mUserInput.GetUnit() != eCSSUnit_Null)
aUI.mUserInput = ourUI->mUserInput;
if (aUI.mUserModify.GetUnit() == eCSSUnit_Null && ourUI->mUserModify.GetUnit() != eCSSUnit_Null)
aUI.mUserModify = ourUI->mUserModify;
if (!aUI.mCursor && ourUI->mCursor)
aUI.mCursor = ourUI->mCursor;
}
else if (aID == eStyleStruct_UIReset) {
if (aUI.mUserSelect.GetUnit() == eCSSUnit_Null && ourUI->mUserSelect.GetUnit() != eCSSUnit_Null)
aUI.mUserSelect = ourUI->mUserSelect;
if (!aUI.mKeyEquivalent && ourUI->mKeyEquivalent)
aUI.mKeyEquivalent = ourUI->mKeyEquivalent;
if (aUI.mResizer.GetUnit() == eCSSUnit_Null && ourUI->mResizer.GetUnit() != eCSSUnit_Null)
aUI.mResizer = ourUI->mResizer;
if (aUI.mForceBrokenImageIcon.GetUnit() == eCSSUnit_Null && ourUI->mForceBrokenImageIcon.GetUnit() == eCSSUnit_Integer)
aUI.mForceBrokenImageIcon = ourUI->mForceBrokenImageIcon;
}
return NS_OK;
}
static const PropertyCheckData UIResetCheckProperties[] = {
CHECKDATA_PROP(nsCSSUserInterface, mUserSelect, CHECKDATA_VALUE, PR_FALSE),
CHECKDATA_PROP(nsCSSUserInterface, mResizer, CHECKDATA_VALUE, PR_FALSE),
CHECKDATA_PROP(nsCSSUserInterface, mKeyEquivalent, CHECKDATA_VALUELIST, PR_FALSE)
CHECKDATA_PROP(nsCSSUserInterface, mForceBrokenImageIcon, CHECKDATA_VALUE, PR_FALSE)
};
+The first two arguments correspond to the structure and data member from
+teh CSSDeclaration, the third is the data type, the fourth indicates if it
+is a coord value or not....+
// resizer: auto, none, enum, inherit
if (eCSSUnit_Enumerated == uiData.mResizer.GetUnit()) {
ui->mResizer = uiData.mResizer.GetIntValue();
}
else if (eCSSUnit_Auto == uiData.mResizer.GetUnit()) {
ui->mResizer = NS_STYLE_RESIZER_AUTO;
}
else if (eCSSUnit_None == uiData.mResizer.GetUnit()) {
ui->mResizer = NS_STYLE_RESIZER_NONE;
}
else if (eCSSUnit_Inherit == uiData.mResizer.GetUnit()) {
inherited = PR_TRUE;
ui->mResizer = parentUI->mResizer;
}
// force-broken-image-icons: integer
if (eCSSUnit_Integer == uiData.mForceBrokenImageIcons.GetUnit()) {
ui->mForceBrokenImageIcons = uiData.mForceBrokenImageIcons.GetIntValue();
}
if (inherited)
// We inherited, and therefore can't be cached in the rule node. We have to be put right on the
// style context.
aContext->SetStyle(eStyleStruct_UIReset, *ui);
else {
// We were fully specified and can therefore be cached right on the rule node.
if (!aHighestNode->mStyleData.mResetData)
aHighestNode->mStyleData.mResetData = new (mPresContext) nsResetStyleData;
aHighestNode->mStyleData.mResetData->mUIData = ui;
// Propagate the bit down.
PropagateDependentBit(NS_STYLE_INHERIT_UI_RESET, aHighestNode);
}
...
PRBool forceIcon = PR_FALSE;+Create some testcases with style rules that use the new property, make sure +it is being parsed correctly. Test it in an external stylesheet and in inline +style. Test that it is inherited correctly, or not inherited as appropriate +to your property. Update this document with any further details, or correcting +any errors.
const nsStyleUIReset* styleData;
GetStyleData(eStyleStruct_UIReset, (const nsStyleStruct*&) styleData);
if (styleData->mForceBrokenImageIcon) {
forceIcon = PR_TRUE;
}