Bug 1590884 - Move XUL accesskey handling to DOM and remove nsXULLabelFrame. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D106233
This commit is contained in:
Tim Nguyen 2021-02-24 14:46:28 +00:00
parent f4cf90f115
commit 159428759d
15 changed files with 77 additions and 320 deletions

View File

@ -680,6 +680,8 @@ nsresult nsXULElement::BindToTree(BindContext& aContext, nsINode& aParent) {
XULKeySetGlobalKeyListener::AttachKeyHandler(this);
}
RegUnRegAccessKey(true);
if (NeedTooltipSupport(*this)) {
AddTooltipSupport();
}
@ -699,6 +701,8 @@ void nsXULElement::UnbindFromTree(bool aNullParent) {
XULKeySetGlobalKeyListener::DetachKeyHandler(this);
}
RegUnRegAccessKey(false);
if (NeedTooltipSupport(*this)) {
RemoveTooltipSupport();
}
@ -739,27 +743,57 @@ void nsXULElement::DoneAddingChildren(bool aHaveNotified) {
}
}
void nsXULElement::UnregisterAccessKey(const nsAString& aOldValue) {
// If someone changes the accesskey, unregister the old one
//
Document* doc = GetComposedDoc();
if (doc && !aOldValue.IsEmpty()) {
if (PresShell* presShell = doc->GetPresShell()) {
presShell->GetPresContext()->EventStateManager()->UnregisterAccessKey(
this, aOldValue.First());
// XXX(ntim): Unify with nsGenericHTMLElement.cpp
void nsXULElement::RegUnRegAccessKey(bool aDoReg) {
// Don't try to register for unsupported elements
if (!SupportsAccessKey()) {
return;
}
// first check to see if we have an access key
nsAutoString accessKey;
GetAttr(nsGkAtoms::accesskey, accessKey);
if (accessKey.IsEmpty()) {
return;
}
// We have an access key, so get the ESM from the pres context.
if (nsPresContext* presContext = GetPresContext(eForUncomposedDoc)) {
EventStateManager* esm = presContext->EventStateManager();
// Register or unregister as appropriate.
if (aDoReg) {
esm->RegisterAccessKey(this, (uint32_t)accessKey.First());
} else {
esm->UnregisterAccessKey(this, (uint32_t)accessKey.First());
}
}
}
bool nsXULElement::SupportsAccessKey() const {
if (NodeInfo()->Equals(nsGkAtoms::label) && HasAttr(nsGkAtoms::control)) {
return true;
}
// XXX(ntim): check if description[value] or description[accesskey] are
// actually used, remove `value` from {Before/After}SetAttr if not the case
if (NodeInfo()->Equals(nsGkAtoms::description) && HasAttr(nsGkAtoms::value) &&
HasAttr(nsGkAtoms::control)) {
return true;
}
return IsAnyOfXULElements(nsGkAtoms::button, nsGkAtoms::toolbarbutton,
nsGkAtoms::checkbox, nsGkAtoms::tab,
nsGkAtoms::radio);
}
nsresult nsXULElement::BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
const nsAttrValueOrString* aValue,
bool aNotify) {
if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::accesskey &&
IsInUncomposedDoc()) {
nsAutoString oldValue;
if (GetAttr(aNamespaceID, aName, oldValue)) {
UnregisterAccessKey(oldValue);
}
if (aNamespaceID == kNameSpaceID_None &&
(aName == nsGkAtoms::accesskey || aName == nsGkAtoms::control ||
aName == nsGkAtoms::value)) {
RegUnRegAccessKey(false);
} else if (aNamespaceID == kNameSpaceID_None &&
(aName == nsGkAtoms::command || aName == nsGkAtoms::observes) &&
IsInUncomposedDoc()) {
@ -810,7 +844,10 @@ nsresult nsXULElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
AddListenerForAttributeIfNeeded(aName);
}
if (aName == nsGkAtoms::tooltip || aName == nsGkAtoms::tooltiptext) {
if (aName == nsGkAtoms::accesskey || aName == nsGkAtoms::control ||
aName == nsGkAtoms::value) {
RegUnRegAccessKey(true);
} else if (aName == nsGkAtoms::tooltip || aName == nsGkAtoms::tooltiptext) {
if (!!aValue != !!aOldValue && IsInComposedDoc() &&
!NodeInfo()->Equals(nsGkAtoms::treechildren)) {
if (aValue) {

View File

@ -558,7 +558,8 @@ class nsXULElement : public nsStyledElement {
return slots ? slots->mControllers.get() : nullptr;
}
void UnregisterAccessKey(const nsAString& aOldValue);
bool SupportsAccessKey() const;
void RegUnRegAccessKey(bool aDoReg);
bool BoolAttrIsTrue(nsAtom* aName) const;
friend nsXULElement* NS_NewBasicXULElement(

View File

@ -211,7 +211,6 @@ static FrameCtorDebugFlags gFlags[] = {
# include "nsMenuFrame.h"
# include "nsPopupSetFrame.h"
# include "nsTreeColFrame.h"
# include "nsXULLabelFrame.h"
//------------------------------------------------------------------
@ -3969,9 +3968,10 @@ nsCSSFrameConstructor::FindXULTagData(const Element& aElement,
SIMPLE_XUL_CREATE(treecol, NS_NewTreeColFrame),
SIMPLE_TAG_CHAIN(button, nsCSSFrameConstructor::FindXULButtonData),
SIMPLE_TAG_CHAIN(toolbarbutton, nsCSSFrameConstructor::FindXULButtonData),
SIMPLE_TAG_CHAIN(label, nsCSSFrameConstructor::FindXULLabelData),
SIMPLE_TAG_CHAIN(label,
nsCSSFrameConstructor::FindXULLabelOrDescriptionData),
SIMPLE_TAG_CHAIN(description,
nsCSSFrameConstructor::FindXULDescriptionData),
nsCSSFrameConstructor::FindXULLabelOrDescriptionData),
SIMPLE_XUL_CREATE(menu, NS_NewMenuFrame),
SIMPLE_XUL_CREATE(menulist, NS_NewMenuFrame),
SIMPLE_XUL_CREATE(menuitem, NS_NewMenuItemFrame),
@ -4007,11 +4007,6 @@ nsCSSFrameConstructor::FindPopupGroupData(const Element& aElement,
return &sPopupSetData;
}
/* static */
const nsCSSFrameConstructor::FrameConstructionData
nsCSSFrameConstructor::sXULTextBoxData =
SIMPLE_XUL_FCDATA(NS_NewTextBoxFrame);
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindXULButtonData(const Element& aElement,
@ -4034,38 +4029,18 @@ nsCSSFrameConstructor::FindXULButtonData(const Element& aElement,
SCROLLABLE_XUL_FCDATA(NS_NewButtonBoxFrame);
return &sXULButtonData;
}
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindXULLabelData(const Element& aElement,
ComputedStyle&) {
if (aElement.HasAttr(kNameSpaceID_None, nsGkAtoms::value)) {
return &sXULTextBoxData;
nsCSSFrameConstructor::FindXULLabelOrDescriptionData(const Element& aElement,
ComputedStyle&) {
// Follow CSS display value if no value attribute
if (!aElement.HasAttr(nsGkAtoms::value)) {
return nullptr;
}
static const FrameConstructionData sLabelData =
SIMPLE_XUL_FCDATA(NS_NewXULLabelFrame);
return &sLabelData;
}
static nsIFrame* NS_NewXULDescriptionFrame(PresShell* aPresShell,
ComputedStyle* aContext) {
// XXXbz do we really need to set up the block formatting context root? If the
// parent is not a block we'll get it anyway, and if it is, do we want it?
return NS_NewBlockFormattingContext(aPresShell, aContext);
}
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindXULDescriptionData(const Element& aElement,
ComputedStyle&) {
if (aElement.HasAttr(kNameSpaceID_None, nsGkAtoms::value)) {
return &sXULTextBoxData;
}
static const FrameConstructionData sDescriptionData =
SIMPLE_XUL_FCDATA(NS_NewXULDescriptionFrame);
return &sDescriptionData;
static const FrameConstructionData sXULTextBoxData =
SIMPLE_XUL_FCDATA(NS_NewTextBoxFrame);
return &sXULTextBoxData;
}
# ifdef XP_MACOSX
@ -7863,11 +7838,6 @@ nsIFrame* nsCSSFrameConstructor::CreateContinuingFrame(
"no support for fragmenting table captions yet");
newFrame = NS_NewBlockFrame(mPresShell, computedStyle);
newFrame->Init(content, aParentFrame, aFrame);
#ifdef MOZ_XUL
} else if (LayoutFrameType::XULLabel == frameType) {
newFrame = NS_NewXULLabelFrame(mPresShell, computedStyle);
newFrame->Init(content, aParentFrame, aFrame);
#endif
} else if (LayoutFrameType::ColumnSetWrapper == frameType) {
newFrame =
NS_NewColumnSetWrapperFrame(mPresShell, computedStyle, nsFrameState(0));

View File

@ -1451,14 +1451,10 @@ class nsCSSFrameConstructor final : public nsFrameManager {
#ifdef MOZ_XUL
static const FrameConstructionData* FindPopupGroupData(const Element&,
ComputedStyle&);
// sXULTextBoxData used for both labels and descriptions
static const FrameConstructionData sXULTextBoxData;
static const FrameConstructionData* FindXULButtonData(const Element&,
ComputedStyle&);
static const FrameConstructionData* FindXULLabelData(const Element&,
ComputedStyle&);
static const FrameConstructionData* FindXULDescriptionData(const Element&,
ComputedStyle&);
static const FrameConstructionData* FindXULLabelOrDescriptionData(
const Element&, ComputedStyle&);
# ifdef XP_MACOSX
static const FrameConstructionData* FindXULMenubarData(const Element&,
ComputedStyle&);

View File

@ -140,7 +140,6 @@ FRAME_CLASSES = [
Frame("nsTreeBodyFrame", "LeafBox", LEAF),
Frame("nsTreeColFrame", "Box", NOT_LEAF),
Frame("nsVideoFrame", "HTMLVideo", NOT_LEAF),
Frame("nsXULLabelFrame", "XULLabel", NOT_LEAF),
Frame("nsXULScrollFrame", "Scroll", NOT_LEAF),
Frame("ViewportFrame", "Viewport", NOT_LEAF),
Frame("WBRFrame", "Wbr", LEAF),

View File

@ -474,9 +474,6 @@ void ReflowInput::InitCBReflowInput() {
static bool IsQuirkContainingBlockHeight(const ReflowInput* rs,
LayoutFrameType aFrameType) {
if (LayoutFrameType::Block == aFrameType ||
#ifdef MOZ_XUL
LayoutFrameType::XULLabel == aFrameType ||
#endif
LayoutFrameType::Scroll == aFrameType) {
// Note: This next condition could change due to a style change,
// but that would cause a style reflow anyway, which means we're ok.
@ -1904,11 +1901,7 @@ static nscoord CalcQuirkContainingBlockHeight(
// if the ancestor is auto height then skip it and continue up if it
// is the first block frame and possibly the body/html
if (LayoutFrameType::Block == frameType ||
#ifdef MOZ_XUL
LayoutFrameType::XULLabel == frameType ||
#endif
LayoutFrameType::Scroll == frameType) {
secondAncestorRI = firstAncestorRI;
firstAncestorRI = ri;

View File

@ -11952,7 +11952,6 @@ void DR_State::InitFrameTypeTable() {
AddFrameTypeInfo(LayoutFrameType::Text, "text", "text");
AddFrameTypeInfo(LayoutFrameType::Viewport, "VP", "viewport");
# ifdef MOZ_XUL
AddFrameTypeInfo(LayoutFrameType::XULLabel, "XULLabel", "XULLabel");
AddFrameTypeInfo(LayoutFrameType::Box, "Box", "Box");
AddFrameTypeInfo(LayoutFrameType::Slider, "Slider", "Slider");
AddFrameTypeInfo(LayoutFrameType::PopupSet, "PopupSet", "PopupSet");

View File

@ -53,7 +53,6 @@ if CONFIG["MOZ_XUL"]:
"nsSplitterFrame.cpp",
"nsTextBoxFrame.cpp",
"nsTitleBarFrame.cpp",
"nsXULLabelFrame.cpp",
"nsXULPopupManager.cpp",
]

View File

@ -162,9 +162,6 @@ void nsBoxFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
MarkIntrinsicISizesDirty();
CacheAttributes();
// register access key
RegUnregAccessKey(true);
}
void nsBoxFrame::CacheAttributes() {
@ -719,9 +716,6 @@ nsBoxFrame::DoXULLayout(nsBoxLayoutState& aState) {
void nsBoxFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
// unregister access key
RegUnregAccessKey(false);
// clean up the container box's layout manager and child boxes
SetXULLayoutManager(nullptr);
@ -874,11 +868,6 @@ nsresult nsBoxFrame::AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
PresShell()->FrameNeedsReflow(this, IntrinsicDirty::StyleChange,
NS_FRAME_IS_DIRTY);
}
// If the accesskey changed, register for the new value
// The old value has been unregistered in nsXULElement::SetAttr
else if (aAttribute == nsGkAtoms::accesskey) {
RegUnregAccessKey(true);
} else if (aAttribute == nsGkAtoms::rows &&
mContent->IsXULElement(nsGkAtoms::tree)) {
// Reflow ourselves and all our children if "rows" changes, since
@ -970,35 +959,6 @@ nsresult nsBoxFrame::GetFrameName(nsAString& aResult) const {
}
#endif
// If you make changes to this function, check its counterparts
// in nsTextBoxFrame and nsXULLabelFrame
void nsBoxFrame::RegUnregAccessKey(bool aDoReg) {
MOZ_ASSERT(mContent);
// only support accesskeys for the following elements
if (!mContent->IsAnyOfXULElements(nsGkAtoms::button, nsGkAtoms::toolbarbutton,
nsGkAtoms::checkbox, nsGkAtoms::tab,
nsGkAtoms::radio)) {
return;
}
nsAutoString accessKey;
mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey,
accessKey);
if (accessKey.IsEmpty()) return;
// With a valid PresContext we can get the ESM
// and register the access key
EventStateManager* esm = PresContext()->EventStateManager();
uint32_t key = accessKey.First();
if (aDoReg)
esm->RegisterAccessKey(mContent->AsElement(), key);
else
esm->UnregisterAccessKey(mContent->AsElement(), key);
}
void nsBoxFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) {
if (HasAnyStateBits(NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK)) {
aResult.AppendElement(OwnedAnonBox(PrincipalChildList().FirstChild()));

View File

@ -187,9 +187,6 @@ class nsBoxFrame : public nsContainerFrame {
bool GetEventPoint(mozilla::WidgetGUIEvent* aEvent,
mozilla::LayoutDeviceIntPoint& aPoint);
protected:
void RegUnregAccessKey(bool aDoReg);
private:
void CacheAttributes();

View File

@ -85,11 +85,6 @@ nsresult nsTextBoxFrame::AttributeChanged(int32_t aNameSpaceID,
XULRedraw(state);
}
// If the accesskey changed, register for the new value
// The old value has been unregistered in nsXULElement::SetAttr
if (aAttribute == nsGkAtoms::accesskey || aAttribute == nsGkAtoms::control)
RegUnregAccessKey(true);
return NS_OK;
}
@ -112,16 +107,6 @@ void nsTextBoxFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
bool aResize;
bool aRedraw;
UpdateAttributes(nullptr, aResize, aRedraw); /* update all */
// register access key
RegUnregAccessKey(true);
}
void nsTextBoxFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
// unregister access key
RegUnregAccessKey(false);
nsLeafBoxFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
}
bool nsTextBoxFrame::AlwaysAppendAccessKey() {
@ -1108,40 +1093,3 @@ nsresult nsTextBoxFrame::GetFrameName(nsAString& aResult) const {
return NS_OK;
}
#endif
// If you make changes to this function, check its counterparts
// in nsBoxFrame and nsXULLabelFrame
nsresult nsTextBoxFrame::RegUnregAccessKey(bool aDoReg) {
// if we have no content, we can't do anything
if (!mContent) return NS_ERROR_FAILURE;
// check if we have a |control| attribute
// do this check first because few elements have control attributes, and we
// can weed out most of the elements quickly.
// XXXjag a side-effect is that we filter out anonymous <label>s
// in e.g. <menu>, <menuitem>, <button>. These <label>s inherit
// |accesskey| and would otherwise register themselves, overwriting
// the content we really meant to be registered.
if (!mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::control))
return NS_OK;
// see if we even have an access key
nsAutoString accessKey;
mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey,
accessKey);
if (accessKey.IsEmpty()) return NS_OK;
// With a valid PresContext we can get the ESM
// and (un)register the access key
EventStateManager* esm = PresContext()->EventStateManager();
uint32_t key = accessKey.First();
if (aDoReg)
esm->RegisterAccessKey(mContent->AsElement(), key);
else
esm->UnregisterAccessKey(mContent->AsElement(), key);
return NS_OK;
}

View File

@ -36,9 +36,6 @@ class nsTextBoxFrame final : public nsLeafBoxFrame {
virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* asPrevInFlow) override;
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
int32_t aModType) override;
@ -94,8 +91,6 @@ class nsTextBoxFrame final : public nsLeafBoxFrame {
void GetTextSize(gfxContext& aRenderingContext, const nsString& aString,
nsSize& aSize, nscoord& aAscent);
nsresult RegUnregAccessKey(bool aDoReg);
private:
bool AlwaysAppendAccessKey();
bool InsertSeparatorBeforeAccessKey();

View File

@ -1,96 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* derived class of nsBlockFrame used for xul:label elements */
#include "nsXULLabelFrame.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/PresShell.h"
#include "nsHTMLParts.h"
#include "nsNameSpaceManager.h"
using namespace mozilla;
nsIFrame* NS_NewXULLabelFrame(PresShell* aPresShell, ComputedStyle* aStyle) {
nsXULLabelFrame* it =
new (aPresShell) nsXULLabelFrame(aStyle, aPresShell->GetPresContext());
it->AddStateBits(NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS);
return it;
}
NS_IMPL_FRAMEARENA_HELPERS(nsXULLabelFrame)
// If you make changes to this function, check its counterparts
// in nsBoxFrame and nsTextBoxFrame
nsresult nsXULLabelFrame::RegUnregAccessKey(bool aDoReg) {
// To filter out <label>s without a control attribute.
// XXXjag a side-effect is that we filter out anonymous <label>s
// in e.g. <menu>, <menuitem>, <button>. These <label>s inherit
// |accesskey| and would otherwise register themselves, overwriting
// the content we really meant to be registered.
if (!mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::control))
return NS_OK;
nsAutoString accessKey;
mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey,
accessKey);
if (accessKey.IsEmpty()) return NS_OK;
// With a valid PresContext we can get the ESM
// and register the access key
EventStateManager* esm = PresContext()->EventStateManager();
uint32_t key = accessKey.First();
if (aDoReg)
esm->RegisterAccessKey(mContent->AsElement(), key);
else
esm->UnregisterAccessKey(mContent->AsElement(), key);
return NS_OK;
}
/////////////////////////////////////////////////////////////////////////////
// nsIFrame
void nsXULLabelFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) {
nsBlockFrame::Init(aContent, aParent, aPrevInFlow);
// register access key
RegUnregAccessKey(true);
}
void nsXULLabelFrame::DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) {
// unregister access key
RegUnregAccessKey(false);
nsBlockFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
}
nsresult nsXULLabelFrame::AttributeChanged(int32_t aNameSpaceID,
nsAtom* aAttribute,
int32_t aModType) {
nsresult rv =
nsBlockFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
// If the accesskey changed, register for the new value
// The old value has been unregistered in nsXULElement::SetAttr
if (aAttribute == nsGkAtoms::accesskey || aAttribute == nsGkAtoms::control)
RegUnregAccessKey(true);
return rv;
}
/////////////////////////////////////////////////////////////////////////////
// Diagnostics
#ifdef DEBUG_FRAME_DUMP
nsresult nsXULLabelFrame::GetFrameName(nsAString& aResult) const {
return MakeFrameName(u"XULLabel"_ns, aResult);
}
#endif

View File

@ -1,50 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* derived class of nsBlockFrame used for xul:label elements */
#ifndef nsXULLabelFrame_h_
#define nsXULLabelFrame_h_
#include "mozilla/Attributes.h"
#include "nsBlockFrame.h"
namespace mozilla {
class PresShell;
} // namespace mozilla
class nsXULLabelFrame final : public nsBlockFrame {
public:
NS_DECL_FRAMEARENA_HELPERS(nsXULLabelFrame)
friend nsIFrame* NS_NewXULLabelFrame(mozilla::PresShell* aPresShell,
ComputedStyle* aStyle);
// nsIFrame
virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
virtual void DestroyFrom(nsIFrame* aDestructRoot,
PostDestroyData& aPostDestroyData) override;
virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
int32_t aModType) override;
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif
protected:
explicit nsXULLabelFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
: nsBlockFrame(aStyle, aPresContext, kClassID) {}
nsresult RegUnregAccessKey(bool aDoReg);
};
nsIFrame* NS_NewXULLabelFrame(mozilla::PresShell* aPresShell,
mozilla::ComputedStyle* aStyle);
#endif /* !defined(nsXULLabelFrame_h_) */

View File

@ -111,6 +111,15 @@ vbox {
}
/********** label **********/
label {
display: inline-block;
}
description {
display: flow-root;
}
label.text-link, label[onclick] {
-moz-user-focus: normal;
}
@ -588,7 +597,7 @@ findbar {
}
/* Some elements that in HTML blocks should be inline-level by default */
label, button, image {
button, image {
display: -moz-inline-box;
}