Bug 943249 - Make <[i]frame scrolling> compatible with IE/Chrome; that is scrolling="no" (and synonyms) suppress scrollbars (as before), anything else has no effect. r=bz

This commit is contained in:
Mats Palmgren 2014-01-12 04:05:49 +00:00
parent ca5667544b
commit 17490e8b74
8 changed files with 84 additions and 110 deletions

View File

@ -80,31 +80,6 @@ HTMLFrameElement::ParseAttribute(int32_t aNamespaceID,
aValue, aResult);
}
void
HTMLFrameElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
nsRuleData* aData)
{
nsGenericHTMLElement::MapScrollingAttributeInto(aAttributes, aData);
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
}
NS_IMETHODIMP_(bool)
HTMLFrameElement::IsAttributeMapped(const nsIAtom* aAttribute) const
{
static const MappedAttributeEntry* const map[] = {
sScrollingAttributeMap,
sCommonAttributeMap,
};
return FindAttributeDependence(aAttribute, map);
}
nsMapRuleToAttributesFunc
HTMLFrameElement::GetAttributeMappingFunction() const
{
return &MapAttributesIntoRule;
}
JSObject*
HTMLFrameElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
{

View File

@ -37,8 +37,6 @@ public:
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult) MOZ_OVERRIDE;
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
// WebIDL API

View File

@ -158,7 +158,6 @@ HTMLIFrameElement::MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
}
}
nsGenericHTMLElement::MapScrollingAttributeInto(aAttributes, aData);
nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aData);
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
}
@ -175,7 +174,6 @@ HTMLIFrameElement::IsAttributeMapped(const nsIAtom* aAttribute) const
static const MappedAttributeEntry* const map[] = {
attributes,
sScrollingAttributeMap,
sImageAlignAttributeMap,
sCommonAttributeMap,
};
@ -220,8 +218,8 @@ HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
// alreay been updated.
mFrameLoader->ApplySandboxFlags(GetSandboxFlags());
}
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
aNotify);
return nsGenericHTMLFrameElement::AfterSetAttr(aNameSpaceID, aName, aValue,
aNotify);
}
nsresult

View File

@ -1431,12 +1431,6 @@ nsGenericHTMLElement::sBackgroundColorAttributeMap[] = {
{ nullptr }
};
/* static */ const Element::MappedAttributeEntry
nsGenericHTMLElement::sScrollingAttributeMap[] = {
{ &nsGkAtoms::scrolling },
{ nullptr }
};
void
nsGenericHTMLElement::MapImageAlignAttributeInto(const nsMappedAttributes* aAttributes,
nsRuleData* aRuleData)
@ -1675,51 +1669,6 @@ nsGenericHTMLElement::MapBackgroundAttributesInto(const nsMappedAttributes* aAtt
MapBGColorInto(aAttributes, aData);
}
void
nsGenericHTMLElement::MapScrollingAttributeInto(const nsMappedAttributes* aAttributes,
nsRuleData* aData)
{
if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Display)))
return;
// scrolling
nsCSSValue* overflowValues[2] = {
aData->ValueForOverflowX(),
aData->ValueForOverflowY(),
};
for (uint32_t i = 0; i < ArrayLength(overflowValues); ++i) {
if (overflowValues[i]->GetUnit() == eCSSUnit_Null) {
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::scrolling);
if (value && value->Type() == nsAttrValue::eEnum) {
int32_t mappedValue;
switch (value->GetEnumValue()) {
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_HIDDEN;
break;
case NS_STYLE_FRAME_AUTO:
mappedValue = NS_STYLE_OVERFLOW_AUTO;
break;
default:
NS_NOTREACHED("unexpected value");
mappedValue = NS_STYLE_OVERFLOW_AUTO;
break;
}
overflowValues[i]->SetIntValue(mappedValue, eCSSUnit_Enumerated);
}
}
}
}
//----------------------------------------------------------------------
nsresult

View File

@ -753,7 +753,6 @@ public:
static const MappedAttributeEntry sDivAlignAttributeMap[];
static const MappedAttributeEntry sBackgroundAttributeMap[];
static const MappedAttributeEntry sBackgroundColorAttributeMap[];
static const MappedAttributeEntry sScrollingAttributeMap[];
/**
* Helper to map the align attribute into a style struct.

View File

@ -7,16 +7,22 @@
#include "nsGenericHTMLFrameElement.h"
#include "nsIDOMDocument.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsContentUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/ErrorResult.h"
#include "nsIAppsService.h"
#include "nsServiceManagerUtils.h"
#include "mozIApplication.h"
#include "nsIPermissionManager.h"
#include "GeckoProfiler.h"
#include "mozIApplication.h"
#include "nsAttrValueInlines.h"
#include "nsContentUtils.h"
#include "nsIAppsService.h"
#include "nsIDocShell.h"
#include "nsIDOMDocument.h"
#include "nsIFrame.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIPermissionManager.h"
#include "nsIPresShell.h"
#include "nsIScrollable.h"
#include "nsPresContext.h"
#include "nsServiceManagerUtils.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -275,6 +281,55 @@ nsGenericHTMLFrameElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
return NS_OK;
}
/* static */ int32_t
nsGenericHTMLFrameElement::MapScrollingAttribute(const nsAttrValue* aValue)
{
int32_t mappedValue = nsIScrollable::Scrollbar_Auto;
if (aValue && aValue->Type() == nsAttrValue::eEnum) {
switch (aValue->GetEnumValue()) {
case NS_STYLE_FRAME_OFF:
case NS_STYLE_FRAME_NOSCROLL:
case NS_STYLE_FRAME_NO:
mappedValue = nsIScrollable::Scrollbar_Never;
break;
}
}
return mappedValue;
}
/* virtual */ nsresult
nsGenericHTMLFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue,
bool aNotify)
{
if (aName == nsGkAtoms::scrolling && aNameSpaceID == kNameSpaceID_None) {
if (mFrameLoader) {
nsIDocShell* docshell = mFrameLoader->GetExistingDocShell();
nsCOMPtr<nsIScrollable> scrollable = do_QueryInterface(docshell);
if (scrollable) {
int32_t cur;
scrollable->GetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, &cur);
int32_t val = MapScrollingAttribute(aValue);
if (cur != val) {
scrollable->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X, val);
scrollable->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y, val);
nsRefPtr<nsPresContext> presContext;
docshell->GetPresContext(getter_AddRefs(presContext));
nsIPresShell* shell = presContext ? presContext->GetPresShell() : nullptr;
nsIFrame* rootScroll = shell ? shell->GetRootScrollFrame() : nullptr;
if (rootScroll) {
shell->FrameNeedsReflow(rootScroll, nsIPresShell::eStyleChange,
NS_FRAME_IS_DIRTY);
}
}
}
}
}
return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
aNotify);
}
void
nsGenericHTMLFrameElement::DestroyContent()
{

View File

@ -61,6 +61,9 @@ public:
bool aNotify) MOZ_OVERRIDE;
virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
bool aNotify) MOZ_OVERRIDE;
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue,
bool aNotify) MOZ_OVERRIDE;
virtual void DestroyContent() MOZ_OVERRIDE;
nsresult CopyInnerTo(mozilla::dom::Element* aDest);
@ -73,6 +76,17 @@ public:
void SwapFrameLoaders(nsXULElement& aOtherOwner, mozilla::ErrorResult& aError);
static bool BrowserFramesEnabled();
/**
* Helper method to map a HTML 'scrolling' attribute value to a nsIScrollable
* enum value. scrolling="no" (and its synonyms) maps to
* nsIScrollable::Scrollbar_Never, and anything else (including nullptr) maps
* to nsIScrollable::Scrollbar_Auto.
* @param aValue the attribute value to map or nullptr
* @return nsIScrollable::Scrollbar_Never or nsIScrollable::Scrollbar_Auto
*/
static int32_t MapScrollingAttribute(const nsAttrValue* aValue);
protected:
// This doesn't really ensure a frame loade in all cases, only when
// it makes sense.

View File

@ -14,6 +14,7 @@
#include "nsCOMPtr.h"
#include "nsGenericHTMLElement.h"
#include "nsGenericHTMLFrameElement.h"
#include "nsAttrValueInlines.h"
#include "nsIDocShell.h"
#include "nsIContentViewer.h"
@ -148,22 +149,6 @@ nsSubDocumentFrame::Init(nsIContent* aContent,
nsContentUtils::AddScriptRunner(new AsyncFrameInit(this));
}
inline int32_t ConvertOverflow(uint8_t aOverflow)
{
switch (aOverflow) {
case NS_STYLE_OVERFLOW_VISIBLE:
case NS_STYLE_OVERFLOW_AUTO:
return nsIScrollable::Scrollbar_Auto;
case NS_STYLE_OVERFLOW_HIDDEN:
case NS_STYLE_OVERFLOW_CLIP:
return nsIScrollable::Scrollbar_Never;
case NS_STYLE_OVERFLOW_SCROLL:
return nsIScrollable::Scrollbar_Always;
}
NS_NOTREACHED("invalid overflow value passed to ConvertOverflow");
return nsIScrollable::Scrollbar_Auto;
}
void
nsSubDocumentFrame::ShowViewer()
{
@ -179,14 +164,15 @@ nsSubDocumentFrame::ShowViewer()
nsRefPtr<nsFrameLoader> frameloader = FrameLoader();
if (frameloader) {
nsIntSize margin = GetMarginAttributes();
const nsStyleDisplay* disp = StyleDisplay();
nsWeakFrame weakThis(this);
mCallingShow = true;
const nsAttrValue* attrValue =
GetContent()->AsElement()->GetParsedAttr(nsGkAtoms::scrolling);
int32_t scrolling =
nsGenericHTMLFrameElement::MapScrollingAttribute(attrValue);
bool didCreateDoc =
frameloader->Show(margin.width, margin.height,
ConvertOverflow(disp->mOverflowX),
ConvertOverflow(disp->mOverflowY),
this);
scrolling, scrolling, this);
if (!weakThis.IsAlive()) {
return;
}