LCOV - app.info - layout/forms/nsHTMLButtonControlFrame.cpp

LCOV - code coverage report
| Current view: | directory - layout/forms - nsHTMLButtonControlFrame.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 145 | 0 | 0.0 %
| Date: | 2012-06-02 | Functions: | 26 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
           2                 : /* ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is mozilla.org code.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is
          18                 :  * Netscape Communications Corporation.
          19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
          20                 :  * the Initial Developer. All Rights Reserved.
          21                 :  *
          22                 :  * Contributor(s):
          23                 :  *
          24                 :  * Alternatively, the contents of this file may be used under the terms of
          25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          28                 :  * of those above. If you wish to allow use of your version of this file only
          29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          30                 :  * use your version of this file under the terms of the MPL, indicate your
          31                 :  * decision by deleting the provisions above and replace them with the notice
          32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          33                 :  * the provisions above, a recipient may use your version of this file under
          34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          35                 :  *
          36                 :  * ***** END LICENSE BLOCK ***** */
          37                 :
          38                 : #include "nsHTMLButtonControlFrame.h"
          39                 :
          40                 : #include "nsCOMPtr.h"
          41                 : #include "nsContainerFrame.h"
          42                 : #include "nsIFormControlFrame.h"
          43                 : #include "nsHTMLParts.h"
          44                 : #include "nsIFormControl.h"
          45                 :
          46                 : #include "nsPresContext.h"
          47                 : #include "nsIPresShell.h"
          48                 : #include "nsStyleContext.h"
          49                 : #include "nsLeafFrame.h"
          50                 : #include "nsCSSRendering.h"
          51                 : #include "nsISupports.h"
          52                 : #include "nsGkAtoms.h"
          53                 : #include "nsCSSAnonBoxes.h"
          54                 : #include "nsStyleConsts.h"
          55                 : #include "nsIComponentManager.h"
          56                 : #include "nsIDocument.h"
          57                 : #include "nsButtonFrameRenderer.h"
          58                 : #include "nsFormControlFrame.h"
          59                 : #include "nsFrameManager.h"
          60                 : #include "nsINameSpaceManager.h"
          61                 : #include "nsIServiceManager.h"
          62                 : #include "nsIDOMHTMLButtonElement.h"
          63                 : #include "nsIDOMHTMLInputElement.h"
          64                 : #include "nsStyleSet.h"
          65                 : #ifdef ACCESSIBILITY
          66                 : #include "nsAccessibilityService.h"
          67                 : #endif
          68                 : #include "nsDisplayList.h"
          69                 :
          70                 : nsIFrame*
          71               0 : NS_NewHTMLButtonControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
          72                 : {
          73               0 :   return new (aPresShell) nsHTMLButtonControlFrame(aContext);
          74                 : }
          75                 :
          76               0 : NS_IMPL_FRAMEARENA_HELPERS(nsHTMLButtonControlFrame)
          77                 :
          78               0 : nsHTMLButtonControlFrame::nsHTMLButtonControlFrame(nsStyleContext* aContext)
          79               0 :   : nsContainerFrame(aContext)
          80                 : {
          81               0 : }
          82                 :
          83               0 : nsHTMLButtonControlFrame::~nsHTMLButtonControlFrame()
          84                 : {
          85               0 : }
          86                 :
          87                 : void
          88               0 : nsHTMLButtonControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
          89                 : {
          90               0 :   nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
          91               0 :   DestroyAbsoluteFrames(aDestructRoot);
          92               0 :   nsContainerFrame::DestroyFrom(aDestructRoot);
          93               0 : }
          94                 :
          95                 : NS_IMETHODIMP
          96               0 : nsHTMLButtonControlFrame::Init(
          97                 :               nsIContent*      aContent,
          98                 :               nsIFrame*        aParent,
          99                 :               nsIFrame*        aPrevInFlow)
         100                 : {
         101               0 :   nsresult  rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
         102               0 :   if (NS_SUCCEEDED(rv)) {
         103               0 :     mRenderer.SetFrame(this, PresContext());
         104                 :   }
         105               0 :   return rv;
         106                 : }
         107                 :
         108               0 : NS_QUERYFRAME_HEAD(nsHTMLButtonControlFrame)
         109               0 :   NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
         110               0 : NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
         111                 :
         112                 : #ifdef ACCESSIBILITY
         113                 : already_AddRefed<nsAccessible>
         114               0 : nsHTMLButtonControlFrame::CreateAccessible()
         115                 : {
         116               0 :   nsAccessibilityService* accService = nsIPresShell::AccService();
         117               0 :   if (accService) {
         118                 :     return accService->CreateHTMLButtonAccessible(mContent,
         119               0 :                                                   PresContext()->PresShell());
         120                 :   }
         121                 :
         122               0 :   return nsnull;
         123                 : }
         124                 : #endif
         125                 :
         126                 : nsIAtom*
         127               0 : nsHTMLButtonControlFrame::GetType() const
         128                 : {
         129               0 :   return nsGkAtoms::HTMLButtonControlFrame;
         130                 : }
         131                 :
         132                 : void
         133               0 : nsHTMLButtonControlFrame::SetFocus(bool aOn, bool aRepaint)
         134                 : {
         135               0 : }
         136                 :
         137                 : NS_IMETHODIMP
         138               0 : nsHTMLButtonControlFrame::HandleEvent(nsPresContext* aPresContext,
         139                 :                                       nsGUIEvent*     aEvent,
         140                 :                                       nsEventStatus*  aEventStatus)
         141                 : {
         142                 :   // if disabled do nothing
         143               0 :   if (mRenderer.isDisabled()) {
         144               0 :     return NS_OK;
         145                 :   }
         146                 :
         147                 :   // mouse clicks are handled by content
         148                 :   // we don't want our children to get any events. So just pass it to frame.
         149               0 :   return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
         150                 : }
         151                 :
         152                 :
         153                 : NS_IMETHODIMP
         154               0 : nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
         155                 :                                            const nsRect&           aDirtyRect,
         156                 :                                            const nsDisplayListSet& aLists)
         157                 : {
         158               0 :   nsDisplayList onTop;
         159               0 :   if (IsVisibleForPainting(aBuilder)) {
         160               0 :     nsresult rv = mRenderer.DisplayButton(aBuilder, aLists.BorderBackground(), &onTop);
         161               0 :     NS_ENSURE_SUCCESS(rv, rv);
         162                 :   }
         163                 :
         164               0 :   nsDisplayListCollection set;
         165                 :   // Do not allow the child subtree to receive events.
         166               0 :   if (!aBuilder->IsForEventDelivery()) {
         167                 :     nsresult rv =
         168                 :       BuildDisplayListForChild(aBuilder, mFrames.FirstChild(), aDirtyRect, set,
         169               0 :                                DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT);
         170               0 :     NS_ENSURE_SUCCESS(rv, rv);
         171                 :     // That should put the display items in set.Content()
         172                 :   }
         173                 :
         174                 :   // Put the foreground outline and focus rects on top of the children
         175               0 :   set.Content()->AppendToTop(&onTop);
         176                 :
         177                 :   // clips to our padding box for <input>s but not <button>s, unless
         178                 :   // they have non-visible overflow..
         179               0 :   if (IsInput() || GetStyleDisplay()->mOverflowX != NS_STYLE_OVERFLOW_VISIBLE) {
         180               0 :     nsMargin border = GetStyleBorder()->GetActualBorder();
         181               0 :     nsRect rect(aBuilder->ToReferenceFrame(this), GetSize());
         182               0 :     rect.Deflate(border);
         183                 :     nscoord radii[8];
         184               0 :     GetPaddingBoxBorderRadii(radii);
         185                 :
         186               0 :     nsresult rv = OverflowClip(aBuilder, set, aLists, rect, radii);
         187               0 :     NS_ENSURE_SUCCESS(rv, rv);
         188                 :   } else {
         189               0 :     set.MoveTo(aLists);
         190                 :   }
         191                 :
         192               0 :   nsresult rv = DisplayOutline(aBuilder, aLists);
         193               0 :   NS_ENSURE_SUCCESS(rv, rv);
         194                 :
         195                 :   // to draw border when selected in editor
         196               0 :   return DisplaySelectionOverlay(aBuilder, aLists.Content());
         197                 : }
         198                 :
         199                 : nscoord
         200               0 : nsHTMLButtonControlFrame::GetMinWidth(nsRenderingContext* aRenderingContext)
         201                 : {
         202                 :   nscoord result;
         203               0 :   DISPLAY_MIN_WIDTH(this, result);
         204                 :
         205               0 :   nsIFrame* kid = mFrames.FirstChild();
         206                 :   result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext,
         207                 :                                                 kid,
         208               0 :                                                 nsLayoutUtils::MIN_WIDTH);
         209                 :
         210               0 :   result += mRenderer.GetAddedButtonBorderAndPadding().LeftRight();
         211                 :
         212               0 :   return result;
         213                 : }
         214                 :
         215                 : nscoord
         216               0 : nsHTMLButtonControlFrame::GetPrefWidth(nsRenderingContext* aRenderingContext)
         217                 : {
         218                 :   nscoord result;
         219               0 :   DISPLAY_PREF_WIDTH(this, result);
         220                 :
         221               0 :   nsIFrame* kid = mFrames.FirstChild();
         222                 :   result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext,
         223                 :                                                 kid,
         224               0 :                                                 nsLayoutUtils::PREF_WIDTH);
         225               0 :   result += mRenderer.GetAddedButtonBorderAndPadding().LeftRight();
         226               0 :   return result;
         227                 : }
         228                 :
         229                 : NS_IMETHODIMP
         230               0 : nsHTMLButtonControlFrame::Reflow(nsPresContext* aPresContext,
         231                 :                                nsHTMLReflowMetrics& aDesiredSize,
         232                 :                                const nsHTMLReflowState& aReflowState,
         233                 :                                nsReflowStatus& aStatus)
         234                 : {
         235               0 :   DO_GLOBAL_REFLOW_COUNT("nsHTMLButtonControlFrame");
         236               0 :   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
         237                 :
         238               0 :   NS_PRECONDITION(aReflowState.ComputedWidth() != NS_INTRINSICSIZE,
         239                 :                   "Should have real computed width by now");
         240                 :
         241               0 :   if (mState & NS_FRAME_FIRST_REFLOW) {
         242               0 :     nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), true);
         243                 :   }
         244                 :
         245                 :   // Reflow the child
         246               0 :   nsIFrame* firstKid = mFrames.FirstChild();
         247                 :
         248                 :   // XXXbz Eventually we may want to check-and-bail if
         249                 :   // !aReflowState.ShouldReflowAllKids() &&
         250                 :   // !NS_SUBTREE_DIRTY(firstKid).
         251                 :   // We'd need to cache our ascent for that, of course.
         252                 :
         253               0 :   nsMargin focusPadding = mRenderer.GetAddedButtonBorderAndPadding();
         254                 :
         255                 :   // Reflow the contents of the button.
         256                 :   ReflowButtonContents(aPresContext, aDesiredSize, aReflowState, firstKid,
         257               0 :                        focusPadding, aStatus);
         258                 :
         259               0 :   aDesiredSize.width = aReflowState.ComputedWidth();
         260                 :
         261                 :   // If computed use the computed value.
         262               0 :   if (aReflowState.ComputedHeight() != NS_INTRINSICSIZE)
         263               0 :     aDesiredSize.height = aReflowState.ComputedHeight();
         264                 :   else
         265               0 :     aDesiredSize.height += focusPadding.TopBottom();
         266                 :
         267               0 :   aDesiredSize.width += aReflowState.mComputedBorderPadding.LeftRight();
         268               0 :   aDesiredSize.height += aReflowState.mComputedBorderPadding.TopBottom();
         269                 :
         270                 :   // Make sure we obey min/max-height.  Note that we do this after adjusting
         271                 :   // for borderpadding, since buttons have border-box sizing...
         272                 :
         273                 :   // XXXbz unless someone overrides that, of course!  We should really consider
         274                 :   // exposing nsHTMLReflowState::AdjustComputed* or something.
         275                 :   aDesiredSize.height = NS_CSS_MINMAX(aDesiredSize.height,
         276                 :                                       aReflowState.mComputedMinHeight,
         277               0 :                                       aReflowState.mComputedMaxHeight);
         278                 :
         279                 :   aDesiredSize.ascent +=
         280               0 :     aReflowState.mComputedBorderPadding.top + focusPadding.top;
         281                 :
         282               0 :   aDesiredSize.SetOverflowAreasToDesiredBounds();
         283               0 :   ConsiderChildOverflow(aDesiredSize.mOverflowAreas, firstKid);
         284               0 :   FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
         285                 :
         286               0 :   aStatus = NS_FRAME_COMPLETE;
         287                 :
         288               0 :   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
         289               0 :   return NS_OK;
         290                 : }
         291                 :
         292                 : void
         293               0 : nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext,
         294                 :                                                nsHTMLReflowMetrics& aDesiredSize,
         295                 :                                                const nsHTMLReflowState& aReflowState,
         296                 :                                                nsIFrame* aFirstKid,
         297                 :                                                nsMargin aFocusPadding,
         298                 :                                                nsReflowStatus& aStatus)
         299                 : {
         300               0 :   nsSize availSize(aReflowState.ComputedWidth(), NS_INTRINSICSIZE);
         301                 :
         302                 :   // Indent the child inside us by the focus border. We must do this separate
         303                 :   // from the regular border.
         304               0 :   availSize.width -= aFocusPadding.LeftRight();
         305                 :
         306                 :   // See whether out availSize's width is big enough.  If it's smaller than our
         307                 :   // intrinsic min width, that means that the kid wouldn't really fit; for a
         308                 :   // better look in such cases we adjust the available width and our left
         309                 :   // offset to allow the kid to spill left into our padding.
         310               0 :   nscoord xoffset = aFocusPadding.left + aReflowState.mComputedBorderPadding.left;
         311               0 :   nscoord extrawidth = GetMinWidth(aReflowState.rendContext) -
         312               0 :     aReflowState.ComputedWidth();
         313               0 :   if (extrawidth > 0) {
         314               0 :     nscoord extraleft = extrawidth / 2;
         315               0 :     nscoord extraright = extrawidth - extraleft;
         316               0 :     NS_ASSERTION(extraright >=0, "How'd that happen?");
         317                 :
         318                 :     // Do not allow the extras to be bigger than the relevant padding
         319               0 :     extraleft = NS_MIN(extraleft, aReflowState.mComputedPadding.left);
         320               0 :     extraright = NS_MIN(extraright, aReflowState.mComputedPadding.right);
         321               0 :     xoffset -= extraleft;
         322               0 :     availSize.width += extraleft + extraright;
         323                 :   }
         324               0 :   availSize.width = NS_MAX(availSize.width,0);
         325                 :
         326                 :   nsHTMLReflowState reflowState(aPresContext, aReflowState, aFirstKid,
         327               0 :                                 availSize);
         328                 :
         329                 :   ReflowChild(aFirstKid, aPresContext, aDesiredSize, reflowState,
         330                 :               xoffset,
         331                 :               aFocusPadding.top + aReflowState.mComputedBorderPadding.top,
         332               0 :               0, aStatus);
         333                 :
         334                 :   // calculate the min internal height so the contents gets centered correctly.
         335                 :   // XXXbz this assumes border-box sizing.
         336                 :   nscoord minInternalHeight = aReflowState.mComputedMinHeight -
         337               0 :     aReflowState.mComputedBorderPadding.TopBottom();
         338               0 :   minInternalHeight = NS_MAX(minInternalHeight, 0);
         339                 :
         340                 :   // center child vertically
         341               0 :   nscoord yoff = 0;
         342               0 :   if (aReflowState.ComputedHeight() != NS_INTRINSICSIZE) {
         343               0 :     yoff = (aReflowState.ComputedHeight() - aDesiredSize.height)/2;
         344               0 :     if (yoff < 0) {
         345               0 :       yoff = 0;
         346                 :     }
         347               0 :   } else if (aDesiredSize.height < minInternalHeight) {
         348               0 :     yoff = (minInternalHeight - aDesiredSize.height) / 2;
         349                 :   }
         350                 :
         351                 :   // Place the child
         352                 :   FinishReflowChild(aFirstKid, aPresContext, &reflowState, aDesiredSize,
         353                 :                     xoffset,
         354               0 :                     yoff + aFocusPadding.top + aReflowState.mComputedBorderPadding.top, 0);
         355                 :
         356               0 :   if (aDesiredSize.ascent == nsHTMLReflowMetrics::ASK_FOR_BASELINE)
         357               0 :     aDesiredSize.ascent = aFirstKid->GetBaseline();
         358                 :
         359                 :   // Adjust the baseline by our offset (since we moved the child's
         360                 :   // baseline by that much).
         361               0 :   aDesiredSize.ascent += yoff;
         362               0 : }
         363                 :
         364                 : PRIntn
         365               0 : nsHTMLButtonControlFrame::GetSkipSides() const
         366                 : {
         367               0 :   return 0;
         368                 : }
         369                 :
         370               0 : nsresult nsHTMLButtonControlFrame::SetFormProperty(nsIAtom* aName, const nsAString& aValue)
         371                 : {
         372               0 :   if (nsGkAtoms::value == aName) {
         373                 :     return mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::value,
         374               0 :                              aValue, true);
         375                 :   }
         376               0 :   return NS_OK;
         377                 : }
         378                 :
         379               0 : nsresult nsHTMLButtonControlFrame::GetFormProperty(nsIAtom* aName, nsAString& aValue) const
         380                 : {
         381               0 :   if (nsGkAtoms::value == aName)
         382               0 :     mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aValue);
         383                 :
         384               0 :   return NS_OK;
         385                 : }
         386                 :
         387                 : nsStyleContext*
         388               0 : nsHTMLButtonControlFrame::GetAdditionalStyleContext(PRInt32 aIndex) const
         389                 : {
         390               0 :   return mRenderer.GetStyleContext(aIndex);
         391                 : }
         392                 :
         393                 : void
         394               0 : nsHTMLButtonControlFrame::SetAdditionalStyleContext(PRInt32 aIndex,
         395                 :                                                     nsStyleContext* aStyleContext)
         396                 : {
         397               0 :   mRenderer.SetStyleContext(aIndex, aStyleContext);
         398               0 : }
         399                 :
         400                 : NS_IMETHODIMP
         401               0 : nsHTMLButtonControlFrame::AppendFrames(ChildListID     aListID,
         402                 :                                        nsFrameList&    aFrameList)
         403                 : {
         404               0 :   NS_NOTREACHED("unsupported operation");
         405               0 :   return NS_ERROR_UNEXPECTED;
         406                 : }
         407                 :
         408                 : NS_IMETHODIMP
         409               0 : nsHTMLButtonControlFrame::InsertFrames(ChildListID     aListID,
         410                 :                                        nsIFrame*       aPrevFrame,
         411                 :                                        nsFrameList&    aFrameList)
         412                 : {
         413               0 :   NS_NOTREACHED("unsupported operation");
         414               0 :   return NS_ERROR_UNEXPECTED;
         415                 : }
         416                 :
         417                 : NS_IMETHODIMP
         418               0 : nsHTMLButtonControlFrame::RemoveFrame(ChildListID     aListID,
         419                 :                                       nsIFrame*       aOldFrame)
         420                 : {
         421               0 :   NS_NOTREACHED("unsupported operation");
         422               0 :   return NS_ERROR_UNEXPECTED;
         423                 : }

Generated by: LCOV version 1.7