/* -*- 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/. */ #include "nsHTMLButtonControlFrame.h" #include "nsContainerFrame.h" #include "nsIFormControlFrame.h" #include "nsIFrameInlines.h" #include "nsPresContext.h" #include "nsGkAtoms.h" #include "nsButtonFrameRenderer.h" #include "nsCSSAnonBoxes.h" #include "nsCheckboxRadioFrame.h" #include "nsNameSpaceManager.h" #include "nsDisplayList.h" #include using namespace mozilla; nsContainerFrame* NS_NewHTMLButtonControlFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle) { return new (aPresShell) nsHTMLButtonControlFrame(aStyle); } NS_IMPL_FRAMEARENA_HELPERS(nsHTMLButtonControlFrame) nsHTMLButtonControlFrame::nsHTMLButtonControlFrame(ComputedStyle* aStyle, nsIFrame::ClassID aID) : nsContainerFrame(aStyle, aID) {} nsHTMLButtonControlFrame::~nsHTMLButtonControlFrame() {} void nsHTMLButtonControlFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) { nsCheckboxRadioFrame::RegUnRegAccessKey(static_cast(this), false); nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData); } void nsHTMLButtonControlFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, nsIFrame* aPrevInFlow) { nsContainerFrame::Init(aContent, aParent, aPrevInFlow); mRenderer.SetFrame(this, PresContext()); } NS_QUERYFRAME_HEAD(nsHTMLButtonControlFrame) NS_QUERYFRAME_ENTRY(nsIFormControlFrame) NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) #ifdef ACCESSIBILITY a11y::AccType nsHTMLButtonControlFrame::AccessibleType() { return a11y::eHTMLButtonType; } #endif void nsHTMLButtonControlFrame::SetFocus(bool aOn, bool aRepaint) {} nsresult nsHTMLButtonControlFrame::HandleEvent(nsPresContext* aPresContext, WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) { // if disabled do nothing if (mRenderer.isDisabled()) { return NS_OK; } // mouse clicks are handled by content // we don't want our children to get any events. So just pass it to frame. return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } bool nsHTMLButtonControlFrame::ShouldClipPaintingToBorderBox() { return IsInput() || StyleDisplay()->mOverflowX != StyleOverflow::Visible; } void nsHTMLButtonControlFrame::BuildDisplayList( nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) { // Clip to our border area for event hit testing. Maybe eventClipState; const bool isForEventDelivery = aBuilder->IsForEventDelivery(); if (isForEventDelivery) { eventClipState.emplace(aBuilder); nsRect rect(aBuilder->ToReferenceFrame(this), GetSize()); nscoord radii[8]; bool hasRadii = GetBorderRadii(radii); eventClipState->ClipContainingBlockDescendants(rect, hasRadii ? radii : nullptr); } nsDisplayList onTop; if (IsVisibleForPainting()) { mRenderer.DisplayButton(aBuilder, aLists.BorderBackground(), &onTop); } nsDisplayListCollection set(aBuilder); // Do not allow the child subtree to receive events, // except in case of