Fix regression of scrolling attribute and overflow property on frame and iframe elements. Make the two interact correctly according to CSS cascading rules. b=220195 r+sr=bzbarsky

This commit is contained in:
dbaron%dbaron.org 2003-09-25 03:55:04 +00:00
parent 24ea48e040
commit 7861160d62
6 changed files with 136 additions and 92 deletions

View File

@ -3238,6 +3238,12 @@ nsGenericHTMLElement::sBackgroundAttributeMap[] = {
{ nsnull }
};
/* static */ const nsGenericHTMLElement::AttributeDependenceEntry
nsGenericHTMLElement::sScrollingAttributeMap[] = {
{ &nsHTMLAtoms::scrolling },
{ nsnull }
};
PRBool
nsGenericHTMLElement::FindAttributeDependence(const nsIAtom* aAttribute,
const AttributeDependenceEntry* const aMaps[],
@ -3482,6 +3488,47 @@ nsGenericHTMLElement::MapBackgroundAttributesInto(const nsIHTMLMappedAttributes*
}
}
void
nsGenericHTMLElement::MapScrollingAttributeInto(const nsIHTMLMappedAttributes* aAttributes,
nsRuleData* aData)
{
if (aData->mSID != eStyleStruct_Display)
return;
// scrolling
if (aData->mDisplayData->mOverflow.GetUnit() == eCSSUnit_Null) {
nsHTMLValue value;
aAttributes->GetAttribute(nsHTMLAtoms::scrolling, value);
if (eHTMLUnit_Enumerated == value.GetUnit()) {
PRInt32 mappedValue;
switch (value.GetIntValue()) {
case NS_STYLE_FRAME_ON:
case NS_STYLE_FRAME_SCROLL:
case NS_STYLE_FRAME_YES:
mappedValue = NS_STYLE_OVERFLOW_SCROLL;
break;
case NS_STYLE_FRAME_OFF:
case NS_STYLE_FRAME_NOSCROLL:
case NS_STYLE_FRAME_NO:
mappedValue = NS_STYLE_OVERFLOW_SCROLLBARS_NONE;
break;
case NS_STYLE_FRAME_AUTO:
mappedValue = NS_STYLE_OVERFLOW_AUTO;
break;
default:
NS_NOTREACHED("unexpected value");
mappedValue = NS_STYLE_OVERFLOW_AUTO;
break;
}
aData->mDisplayData->mOverflow.SetIntValue(mappedValue,
eCSSUnit_Enumerated);
}
}
}
//----------------------------------------------------------------------
nsGenericHTMLLeafElement::nsGenericHTMLLeafElement()

View File

@ -502,6 +502,7 @@ public:
static const AttributeDependenceEntry sImageAlignAttributeMap[];
static const AttributeDependenceEntry sDivAlignAttributeMap[];
static const AttributeDependenceEntry sBackgroundAttributeMap[];
static const AttributeDependenceEntry sScrollingAttributeMap[];
/**
* A common method where you can just pass in a list of maps to check
@ -571,6 +572,16 @@ public:
*/
static void MapBackgroundAttributesInto(const nsIHTMLMappedAttributes* aAttributes,
nsRuleData* aData);
/**
* Helper to map the scrolling attribute on FRAME and IFRAME
* into a style struct.
*
* @param aAttributes the list of attributes to map
* @param aData the returned rule data [INOUT]
* @see GetAttributeMappingFunction
*/
static void MapScrollingAttributeInto(const nsIHTMLMappedAttributes* aAttributes,
nsRuleData* aData);
/**
* Get the primary frame for a piece of content.
*

View File

@ -88,6 +88,8 @@ public:
NS_IMETHOD AttributeToString(nsIAtom* aAttribute,
const nsHTMLValue& aValue,
nsAString& aResult) const;
NS_IMETHOD_(PRBool) HasAttributeDependentStyle(const nsIAtom* aAttribute) const;
NS_IMETHOD GetAttributeMappingFunction(nsMapRuleToAttributesFunc& aMapRuleFunc) const;
};
nsresult
@ -285,6 +287,32 @@ nsHTMLFrameElement::AttributeToString(nsIAtom* aAttribute,
aResult);
}
static void
MapAttributesIntoRule(const nsIHTMLMappedAttributes* aAttributes,
nsRuleData* aData)
{
nsGenericHTMLElement::MapScrollingAttributeInto(aAttributes, aData);
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
}
NS_IMETHODIMP_(PRBool)
nsHTMLFrameElement::HasAttributeDependentStyle(const nsIAtom* aAttribute) const
{
static const AttributeDependenceEntry* const map[] = {
sScrollingAttributeMap,
sCommonAttributeMap,
};
return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map));
}
NS_IMETHODIMP
nsHTMLFrameElement::GetAttributeMappingFunction(nsMapRuleToAttributesFunc& aMapRuleFunc) const
{
aMapRuleFunc = &MapAttributesIntoRule;
return NS_OK;
}
//*****************************************************************************
// nsHTMLFrameElement::nsIChromeEventHandler

View File

@ -481,6 +481,7 @@ MapAttributesIntoRule(const nsIHTMLMappedAttributes* aAttributes,
}
}
nsGenericHTMLElement::MapScrollingAttributeInto(aAttributes, aData);
nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aData);
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
}
@ -497,6 +498,7 @@ nsHTMLIFrameElement::HasAttributeDependentStyle(const nsIAtom* aAttribute) const
static const AttributeDependenceEntry* const map[] = {
attributes,
sScrollingAttributeMap,
sImageAlignAttributeMap,
sCommonAttributeMap,
};

View File

@ -254,7 +254,6 @@ public:
PRBool GetURL(nsIContent* aContent, nsString& aResult);
PRBool GetName(nsIContent* aContent, nsString& aResult);
PRInt32 GetScrolling(nsIContent* aContent);
nsFrameborder GetFrameBorder();
PRInt32 GetMarginWidth(nsIContent* aContent);
PRInt32 GetMarginHeight(nsIContent* aContent);
@ -783,48 +782,6 @@ PRBool nsHTMLFrameInnerFrame::GetName(nsIContent* aContent, nsString& aResult)
return PR_FALSE;
}
PRInt32 nsHTMLFrameInnerFrame::GetScrolling(nsIContent* aContent)
{
PRInt32 returnValue = -1;
nsresult rv = NS_OK;
nsCOMPtr<nsIHTMLContent> content = do_QueryInterface(mContent, &rv);
if (NS_SUCCEEDED(rv) && content) {
nsHTMLValue value;
// XXXldb This code belongs in the attribute mapping code for the
// content node -- otherwise it doesn't follow the CSS cascading
// rules correctly.
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetHTMLAttribute(nsHTMLAtoms::scrolling, value)) {
if (eHTMLUnit_Enumerated == value.GetUnit()) {
switch (value.GetIntValue()) {
case NS_STYLE_FRAME_ON:
case NS_STYLE_FRAME_SCROLL:
case NS_STYLE_FRAME_YES:
returnValue = NS_STYLE_OVERFLOW_SCROLL;
break;
case NS_STYLE_FRAME_OFF:
case NS_STYLE_FRAME_NOSCROLL:
case NS_STYLE_FRAME_NO:
returnValue = NS_STYLE_OVERFLOW_HIDDEN;
break;
case NS_STYLE_FRAME_AUTO:
default:
returnValue = NS_STYLE_OVERFLOW_AUTO;
break;
}
}
}
// Check style for overflow
const nsStyleDisplay* display = GetStyleDisplay();
if (display->mOverflow)
returnValue = display->mOverflow;
}
return returnValue;
}
nsFrameborder nsHTMLFrameInnerFrame::GetFrameBorder()
{
nsFrameborder rv = eFrameborder_Notset;
@ -1062,12 +1019,33 @@ nsHTMLFrameInnerFrame::ShowDocShell(nsIPresContext* aPresContext)
nsCOMPtr<nsIScrollable> sc(do_QueryInterface(docShell));
if (sc) {
PRInt32 scrolling = GetScrolling(content);
PRInt32 scrolling = GetStyleDisplay()->mOverflow;
PRInt32 scrollX, scrollY;
switch (scrolling) {
case NS_STYLE_OVERFLOW_SCROLLBARS_NONE:
scrollX = NS_STYLE_OVERFLOW_HIDDEN;
scrollY = NS_STYLE_OVERFLOW_HIDDEN;
break;
case NS_STYLE_OVERFLOW_SCROLLBARS_HORIZONTAL:
scrollX = NS_STYLE_OVERFLOW_SCROLL;
scrollY = NS_STYLE_OVERFLOW_HIDDEN;
break;
case NS_STYLE_OVERFLOW_SCROLLBARS_VERTICAL:
scrollX = NS_STYLE_OVERFLOW_HIDDEN;
scrollY = NS_STYLE_OVERFLOW_SCROLL;
break;
case NS_STYLE_OVERFLOW_VISIBLE:
scrollX = scrollY = NS_STYLE_OVERFLOW_AUTO;
break;
default:
scrollX = scrollY = scrolling;
break;
}
sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
scrolling);
scrollX);
sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
scrolling);
scrollY);
}
nsCOMPtr<nsIWidget> widget;

View File

@ -254,7 +254,6 @@ public:
PRBool GetURL(nsIContent* aContent, nsString& aResult);
PRBool GetName(nsIContent* aContent, nsString& aResult);
PRInt32 GetScrolling(nsIContent* aContent);
nsFrameborder GetFrameBorder();
PRInt32 GetMarginWidth(nsIContent* aContent);
PRInt32 GetMarginHeight(nsIContent* aContent);
@ -783,48 +782,6 @@ PRBool nsHTMLFrameInnerFrame::GetName(nsIContent* aContent, nsString& aResult)
return PR_FALSE;
}
PRInt32 nsHTMLFrameInnerFrame::GetScrolling(nsIContent* aContent)
{
PRInt32 returnValue = -1;
nsresult rv = NS_OK;
nsCOMPtr<nsIHTMLContent> content = do_QueryInterface(mContent, &rv);
if (NS_SUCCEEDED(rv) && content) {
nsHTMLValue value;
// XXXldb This code belongs in the attribute mapping code for the
// content node -- otherwise it doesn't follow the CSS cascading
// rules correctly.
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetHTMLAttribute(nsHTMLAtoms::scrolling, value)) {
if (eHTMLUnit_Enumerated == value.GetUnit()) {
switch (value.GetIntValue()) {
case NS_STYLE_FRAME_ON:
case NS_STYLE_FRAME_SCROLL:
case NS_STYLE_FRAME_YES:
returnValue = NS_STYLE_OVERFLOW_SCROLL;
break;
case NS_STYLE_FRAME_OFF:
case NS_STYLE_FRAME_NOSCROLL:
case NS_STYLE_FRAME_NO:
returnValue = NS_STYLE_OVERFLOW_HIDDEN;
break;
case NS_STYLE_FRAME_AUTO:
default:
returnValue = NS_STYLE_OVERFLOW_AUTO;
break;
}
}
}
// Check style for overflow
const nsStyleDisplay* display = GetStyleDisplay();
if (display->mOverflow)
returnValue = display->mOverflow;
}
return returnValue;
}
nsFrameborder nsHTMLFrameInnerFrame::GetFrameBorder()
{
nsFrameborder rv = eFrameborder_Notset;
@ -1062,12 +1019,33 @@ nsHTMLFrameInnerFrame::ShowDocShell(nsIPresContext* aPresContext)
nsCOMPtr<nsIScrollable> sc(do_QueryInterface(docShell));
if (sc) {
PRInt32 scrolling = GetScrolling(content);
PRInt32 scrolling = GetStyleDisplay()->mOverflow;
PRInt32 scrollX, scrollY;
switch (scrolling) {
case NS_STYLE_OVERFLOW_SCROLLBARS_NONE:
scrollX = NS_STYLE_OVERFLOW_HIDDEN;
scrollY = NS_STYLE_OVERFLOW_HIDDEN;
break;
case NS_STYLE_OVERFLOW_SCROLLBARS_HORIZONTAL:
scrollX = NS_STYLE_OVERFLOW_SCROLL;
scrollY = NS_STYLE_OVERFLOW_HIDDEN;
break;
case NS_STYLE_OVERFLOW_SCROLLBARS_VERTICAL:
scrollX = NS_STYLE_OVERFLOW_HIDDEN;
scrollY = NS_STYLE_OVERFLOW_SCROLL;
break;
case NS_STYLE_OVERFLOW_VISIBLE:
scrollX = scrollY = NS_STYLE_OVERFLOW_AUTO;
break;
default:
scrollX = scrollY = scrolling;
break;
}
sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
scrolling);
scrollX);
sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
scrolling);
scrollY);
}
nsCOMPtr<nsIWidget> widget;