layout/forms/nsGfxButtonControlFrame.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsGfxButtonControlFrame.h"
     7 #include "nsIFormControl.h"
     8 #include "nsGkAtoms.h"
     9 #include "nsAutoPtr.h"
    10 #include "nsStyleSet.h"
    11 #include "nsContentUtils.h"
    12 // MouseEvent suppression in PP
    13 #include "nsContentList.h"
    15 #include "nsIDOMHTMLInputElement.h"
    16 #include "nsTextNode.h"
    18 using namespace mozilla;
    20 nsGfxButtonControlFrame::nsGfxButtonControlFrame(nsStyleContext* aContext):
    21   nsHTMLButtonControlFrame(aContext)
    22 {
    23 }
    25 nsIFrame*
    26 NS_NewGfxButtonControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
    27 {
    28   return new (aPresShell) nsGfxButtonControlFrame(aContext);
    29 }
    31 NS_IMPL_FRAMEARENA_HELPERS(nsGfxButtonControlFrame)
    33 void nsGfxButtonControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
    34 {
    35   nsContentUtils::DestroyAnonymousContent(&mTextContent);
    36   nsHTMLButtonControlFrame::DestroyFrom(aDestructRoot);
    37 }
    39 nsIAtom*
    40 nsGfxButtonControlFrame::GetType() const
    41 {
    42   return nsGkAtoms::gfxButtonControlFrame;
    43 }
    45 #ifdef DEBUG_FRAME_DUMP
    46 nsresult
    47 nsGfxButtonControlFrame::GetFrameName(nsAString& aResult) const
    48 {
    49   return MakeFrameName(NS_LITERAL_STRING("ButtonControl"), aResult);
    50 }
    51 #endif
    53 // Create the text content used as label for the button.
    54 // The frame will be generated by the frame constructor.
    55 nsresult
    56 nsGfxButtonControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
    57 {
    58   nsXPIDLString label;
    59   GetLabel(label);
    61   // Add a child text content node for the label
    62   mTextContent = new nsTextNode(mContent->NodeInfo()->NodeInfoManager());
    64   // set the value of the text node and add it to the child list
    65   mTextContent->SetText(label, false);
    66   aElements.AppendElement(mTextContent);
    68   return NS_OK;
    69 }
    71 void
    72 nsGfxButtonControlFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
    73                                                   uint32_t aFilter)
    74 {
    75   aElements.MaybeAppendElement(mTextContent);
    76 }
    78 // Create the text content used as label for the button.
    79 // The frame will be generated by the frame constructor.
    80 nsIFrame*
    81 nsGfxButtonControlFrame::CreateFrameFor(nsIContent*      aContent)
    82 {
    83   nsIFrame * newFrame = nullptr;
    85   if (aContent == mTextContent) {
    86     nsIFrame * parentFrame = mFrames.FirstChild();
    88     nsPresContext* presContext = PresContext();
    89     nsRefPtr<nsStyleContext> textStyleContext;
    90     textStyleContext = presContext->StyleSet()->
    91       ResolveStyleForNonElement(mStyleContext);
    93     newFrame = NS_NewTextFrame(presContext->PresShell(), textStyleContext);
    94     // initialize the text frame
    95     newFrame->Init(mTextContent, parentFrame, nullptr);
    96     mTextContent->SetPrimaryFrame(newFrame);
    97   }
    99   return newFrame;
   100 }
   102 NS_QUERYFRAME_HEAD(nsGfxButtonControlFrame)
   103   NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
   104 NS_QUERYFRAME_TAIL_INHERITING(nsHTMLButtonControlFrame)
   106 // Initially we hardcoded the default strings here.
   107 // Next, we used html.css to store the default label for various types
   108 // of buttons. (nsGfxButtonControlFrame::DoNavQuirksReflow rev 1.20)
   109 // However, since html.css is not internationalized, we now grab the default
   110 // label from a string bundle as is done for all other UI strings.
   111 // See bug 16999 for further details.
   112 nsresult
   113 nsGfxButtonControlFrame::GetDefaultLabel(nsXPIDLString& aString) const
   114 {
   115   nsCOMPtr<nsIFormControl> form = do_QueryInterface(mContent);
   116   NS_ENSURE_TRUE(form, NS_ERROR_UNEXPECTED);
   118   int32_t type = form->GetType();
   119   const char *prop;
   120   if (type == NS_FORM_INPUT_RESET) {
   121     prop = "Reset";
   122   }
   123   else if (type == NS_FORM_INPUT_SUBMIT) {
   124     prop = "Submit";
   125   }
   126   else {
   127     aString.Truncate();
   128     return NS_OK;
   129   }
   131   return nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
   132                                             prop, aString);
   133 }
   135 nsresult
   136 nsGfxButtonControlFrame::GetLabel(nsXPIDLString& aLabel)
   137 {
   138   // Get the text from the "value" property on our content if there is
   139   // one; otherwise set it to a default value (localized).
   140   nsresult rv;
   141   nsCOMPtr<nsIDOMHTMLInputElement> elt = do_QueryInterface(mContent);
   142   if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::value) && elt) {
   143     rv = elt->GetValue(aLabel);
   144   } else {
   145     // Generate localized label.
   146     // We can't make any assumption as to what the default would be
   147     // because the value is localized for non-english platforms, thus
   148     // it might not be the string "Reset", "Submit Query", or "Browse..."
   149     rv = GetDefaultLabel(aLabel);
   150   }
   152   NS_ENSURE_SUCCESS(rv, rv);
   154   // Compress whitespace out of label if needed.
   155   if (!StyleText()->WhiteSpaceIsSignificant()) {
   156     aLabel.CompressWhitespace();
   157   } else if (aLabel.Length() > 2 && aLabel.First() == ' ' &&
   158              aLabel.CharAt(aLabel.Length() - 1) == ' ') {
   159     // This is a bit of a hack.  The reason this is here is as follows: we now
   160     // have default padding on our buttons to make them non-ugly.
   161     // Unfortunately, IE-windows does not have such padding, so people will
   162     // stick values like " ok " (with the spaces) in the buttons in an attempt
   163     // to make them look decent.  Unfortunately, if they do this the button
   164     // looks way too big in Mozilla.  Worse yet, if they do this _and_ set a
   165     // fixed width for the button we run into trouble because our focus-rect
   166     // border/padding and outer border take up 10px of the horizontal button
   167     // space or so; the result is that the text is misaligned, even with the
   168     // recentering we do in nsHTMLButtonControlFrame::Reflow.  So to solve
   169     // this, even if the whitespace is significant, single leading and trailing
   170     // _spaces_ (and not other whitespace) are removed.  The proper solution,
   171     // of course, is to not have the focus rect painting taking up 6px of
   172     // horizontal space. We should do that instead (via XBL form controls or
   173     // changing the renderer) and remove this.
   174     aLabel.Cut(0, 1);
   175     aLabel.Truncate(aLabel.Length() - 1);
   176   }
   178   return NS_OK;
   179 }
   181 nsresult
   182 nsGfxButtonControlFrame::AttributeChanged(int32_t         aNameSpaceID,
   183                                           nsIAtom*        aAttribute,
   184                                           int32_t         aModType)
   185 {
   186   nsresult rv = NS_OK;
   188   // If the value attribute is set, update the text of the label
   189   if (nsGkAtoms::value == aAttribute) {
   190     if (mTextContent && mContent) {
   191       nsXPIDLString label;
   192       rv = GetLabel(label);
   193       NS_ENSURE_SUCCESS(rv, rv);
   195       mTextContent->SetText(label, true);
   196     } else {
   197       rv = NS_ERROR_UNEXPECTED;
   198     }
   200   // defer to HTMLButtonControlFrame
   201   } else {
   202     rv = nsHTMLButtonControlFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
   203   }
   204   return rv;
   205 }
   207 bool
   208 nsGfxButtonControlFrame::IsLeaf() const
   209 {
   210   return true;
   211 }
   213 nsIFrame*
   214 nsGfxButtonControlFrame::GetContentInsertionFrame()
   215 {
   216   return this;
   217 }
   219 nsresult
   220 nsGfxButtonControlFrame::HandleEvent(nsPresContext* aPresContext, 
   221                                      WidgetGUIEvent* aEvent,
   222                                      nsEventStatus* aEventStatus)
   223 {
   224   // Override the HandleEvent to prevent the nsFrame::HandleEvent
   225   // from being called. The nsFrame::HandleEvent causes the button label
   226   // to be selected (Drawn with an XOR rectangle over the label)
   228   // do we have user-input style?
   229   const nsStyleUserInterface* uiStyle = StyleUserInterface();
   230   if (uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE || uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED)
   231     return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
   233   return NS_OK;
   234 }

mercurial