layout/forms/nsGfxButtonControlFrame.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial