/src/mozilla-central/layout/forms/nsHTMLButtonControlFrame.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #include "nsHTMLButtonControlFrame.h" |
8 | | |
9 | | #include "nsContainerFrame.h" |
10 | | #include "nsIFormControlFrame.h" |
11 | | #include "nsPresContext.h" |
12 | | #include "nsGkAtoms.h" |
13 | | #include "nsButtonFrameRenderer.h" |
14 | | #include "nsCSSAnonBoxes.h" |
15 | | #include "nsCheckboxRadioFrame.h" |
16 | | #include "nsNameSpaceManager.h" |
17 | | #include "nsDisplayList.h" |
18 | | #include <algorithm> |
19 | | |
20 | | using namespace mozilla; |
21 | | |
22 | | nsContainerFrame* |
23 | | NS_NewHTMLButtonControlFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle) |
24 | 0 | { |
25 | 0 | return new (aPresShell) nsHTMLButtonControlFrame(aStyle); |
26 | 0 | } |
27 | | |
28 | | NS_IMPL_FRAMEARENA_HELPERS(nsHTMLButtonControlFrame) |
29 | | |
30 | | nsHTMLButtonControlFrame::nsHTMLButtonControlFrame(ComputedStyle* aStyle, |
31 | | nsIFrame::ClassID aID) |
32 | | : nsContainerFrame(aStyle, aID) |
33 | 0 | { |
34 | 0 | } |
35 | | |
36 | | nsHTMLButtonControlFrame::~nsHTMLButtonControlFrame() |
37 | 0 | { |
38 | 0 | } |
39 | | |
40 | | void |
41 | | nsHTMLButtonControlFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) |
42 | 0 | { |
43 | 0 | nsCheckboxRadioFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false); |
44 | 0 | nsContainerFrame::DestroyFrom(aDestructRoot, aPostDestroyData); |
45 | 0 | } |
46 | | |
47 | | void |
48 | | nsHTMLButtonControlFrame::Init(nsIContent* aContent, |
49 | | nsContainerFrame* aParent, |
50 | | nsIFrame* aPrevInFlow) |
51 | 0 | { |
52 | 0 | nsContainerFrame::Init(aContent, aParent, aPrevInFlow); |
53 | 0 | mRenderer.SetFrame(this, PresContext()); |
54 | 0 | } |
55 | | |
56 | 0 | NS_QUERYFRAME_HEAD(nsHTMLButtonControlFrame) |
57 | 0 | NS_QUERYFRAME_ENTRY(nsIFormControlFrame) |
58 | 0 | NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) |
59 | | |
60 | | #ifdef ACCESSIBILITY |
61 | | a11y::AccType |
62 | | nsHTMLButtonControlFrame::AccessibleType() |
63 | 0 | { |
64 | 0 | return a11y::eHTMLButtonType; |
65 | 0 | } |
66 | | #endif |
67 | | |
68 | | void |
69 | | nsHTMLButtonControlFrame::SetFocus(bool aOn, bool aRepaint) |
70 | 0 | { |
71 | 0 | } |
72 | | |
73 | | nsresult |
74 | | nsHTMLButtonControlFrame::HandleEvent(nsPresContext* aPresContext, |
75 | | WidgetGUIEvent* aEvent, |
76 | | nsEventStatus* aEventStatus) |
77 | 0 | { |
78 | 0 | // if disabled do nothing |
79 | 0 | if (mRenderer.isDisabled()) { |
80 | 0 | return NS_OK; |
81 | 0 | } |
82 | 0 | |
83 | 0 | // mouse clicks are handled by content |
84 | 0 | // we don't want our children to get any events. So just pass it to frame. |
85 | 0 | return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus); |
86 | 0 | } |
87 | | |
88 | | bool |
89 | | nsHTMLButtonControlFrame::ShouldClipPaintingToBorderBox() |
90 | 0 | { |
91 | 0 | return IsInput() || StyleDisplay()->mOverflowX != NS_STYLE_OVERFLOW_VISIBLE; |
92 | 0 | } |
93 | | |
94 | | void |
95 | | nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, |
96 | | const nsDisplayListSet& aLists) |
97 | 0 | { |
98 | 0 | // Clip to our border area for event hit testing. |
99 | 0 | Maybe<DisplayListClipState::AutoSaveRestore> eventClipState; |
100 | 0 | const bool isForEventDelivery = aBuilder->IsForEventDelivery(); |
101 | 0 | if (isForEventDelivery) { |
102 | 0 | eventClipState.emplace(aBuilder); |
103 | 0 | nsRect rect(aBuilder->ToReferenceFrame(this), GetSize()); |
104 | 0 | nscoord radii[8]; |
105 | 0 | bool hasRadii = GetBorderRadii(radii); |
106 | 0 | eventClipState->ClipContainingBlockDescendants(rect, hasRadii ? radii : nullptr); |
107 | 0 | } |
108 | 0 |
|
109 | 0 | nsDisplayList onTop; |
110 | 0 | if (IsVisibleForPainting(aBuilder)) { |
111 | 0 | mRenderer.DisplayButton(aBuilder, aLists.BorderBackground(), &onTop); |
112 | 0 | } |
113 | 0 |
|
114 | 0 | nsDisplayListCollection set(aBuilder); |
115 | 0 |
|
116 | 0 | // Do not allow the child subtree to receive events. |
117 | 0 | if (!isForEventDelivery || aBuilder->HitTestIsForVisibility()) { |
118 | 0 | DisplayListClipState::AutoSaveRestore clipState(aBuilder); |
119 | 0 |
|
120 | 0 | if (ShouldClipPaintingToBorderBox()) { |
121 | 0 | nsMargin border = StyleBorder()->GetComputedBorder(); |
122 | 0 | nsRect rect(aBuilder->ToReferenceFrame(this), GetSize()); |
123 | 0 | rect.Deflate(border); |
124 | 0 | nscoord radii[8]; |
125 | 0 | bool hasRadii = GetPaddingBoxBorderRadii(radii); |
126 | 0 | clipState.ClipContainingBlockDescendants(rect, hasRadii ? radii : nullptr); |
127 | 0 | } |
128 | 0 |
|
129 | 0 | BuildDisplayListForChild(aBuilder, mFrames.FirstChild(), set, |
130 | 0 | DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT); |
131 | 0 | // That should put the display items in set.Content() |
132 | 0 | } |
133 | 0 |
|
134 | 0 | // Put the foreground outline and focus rects on top of the children |
135 | 0 | set.Content()->AppendToTop(&onTop); |
136 | 0 | set.MoveTo(aLists); |
137 | 0 |
|
138 | 0 | DisplayOutline(aBuilder, aLists); |
139 | 0 |
|
140 | 0 | // to draw border when selected in editor |
141 | 0 | DisplaySelectionOverlay(aBuilder, aLists.Content()); |
142 | 0 | } |
143 | | |
144 | | nscoord |
145 | | nsHTMLButtonControlFrame::GetMinISize(gfxContext* aRenderingContext) |
146 | 0 | { |
147 | 0 | nscoord result; |
148 | 0 | DISPLAY_MIN_INLINE_SIZE(this, result); |
149 | 0 | if (StyleDisplay()->IsContainSize()) { |
150 | 0 | result = 0; |
151 | 0 | } else { |
152 | 0 | nsIFrame* kid = mFrames.FirstChild(); |
153 | 0 | result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, |
154 | 0 | kid, |
155 | 0 | nsLayoutUtils::MIN_ISIZE); |
156 | 0 | } |
157 | 0 | return result; |
158 | 0 | } |
159 | | |
160 | | nscoord |
161 | | nsHTMLButtonControlFrame::GetPrefISize(gfxContext* aRenderingContext) |
162 | 0 | { |
163 | 0 | nscoord result; |
164 | 0 | DISPLAY_PREF_INLINE_SIZE(this, result); |
165 | 0 | if (StyleDisplay()->IsContainSize()) { |
166 | 0 | result = 0; |
167 | 0 | } else { |
168 | 0 | nsIFrame* kid = mFrames.FirstChild(); |
169 | 0 | result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext, |
170 | 0 | kid, |
171 | 0 | nsLayoutUtils::PREF_ISIZE); |
172 | 0 | } |
173 | 0 | return result; |
174 | 0 | } |
175 | | |
176 | | void |
177 | | nsHTMLButtonControlFrame::Reflow(nsPresContext* aPresContext, |
178 | | ReflowOutput& aDesiredSize, |
179 | | const ReflowInput& aReflowInput, |
180 | | nsReflowStatus& aStatus) |
181 | 0 | { |
182 | 0 | MarkInReflow(); |
183 | 0 | DO_GLOBAL_REFLOW_COUNT("nsHTMLButtonControlFrame"); |
184 | 0 | DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); |
185 | 0 | MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); |
186 | 0 |
|
187 | 0 | if (mState & NS_FRAME_FIRST_REFLOW) { |
188 | 0 | nsCheckboxRadioFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), true); |
189 | 0 | } |
190 | 0 |
|
191 | 0 | // Reflow the child |
192 | 0 | nsIFrame* firstKid = mFrames.FirstChild(); |
193 | 0 |
|
194 | 0 | MOZ_ASSERT(firstKid, "Button should have a child frame for its contents"); |
195 | 0 | MOZ_ASSERT(!firstKid->GetNextSibling(), |
196 | 0 | "Button should have exactly one child frame"); |
197 | 0 | MOZ_ASSERT(firstKid->Style()->GetPseudo() == |
198 | 0 | nsCSSAnonBoxes::buttonContent(), |
199 | 0 | "Button's child frame has unexpected pseudo type!"); |
200 | 0 |
|
201 | 0 | // XXXbz Eventually we may want to check-and-bail if |
202 | 0 | // !aReflowInput.ShouldReflowAllKids() && |
203 | 0 | // !NS_SUBTREE_DIRTY(firstKid). |
204 | 0 | // We'd need to cache our ascent for that, of course. |
205 | 0 |
|
206 | 0 | // Reflow the contents of the button. |
207 | 0 | // (This populates our aDesiredSize, too.) |
208 | 0 | ReflowButtonContents(aPresContext, aDesiredSize, |
209 | 0 | aReflowInput, firstKid); |
210 | 0 |
|
211 | 0 | if (!ShouldClipPaintingToBorderBox()) { |
212 | 0 | ConsiderChildOverflow(aDesiredSize.mOverflowAreas, firstKid); |
213 | 0 | } |
214 | 0 | // else, we ignore child overflow -- anything that overflows beyond our |
215 | 0 | // own border-box will get clipped when painting. |
216 | 0 |
|
217 | 0 | FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, |
218 | 0 | aReflowInput, aStatus); |
219 | 0 |
|
220 | 0 | // We're always complete and we don't support overflow containers |
221 | 0 | // so we shouldn't have a next-in-flow ever. |
222 | 0 | aStatus.Reset(); |
223 | 0 | MOZ_ASSERT(!GetNextInFlow()); |
224 | 0 |
|
225 | 0 | NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); |
226 | 0 | } |
227 | | |
228 | | void |
229 | | nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext, |
230 | | ReflowOutput& aButtonDesiredSize, |
231 | | const ReflowInput& aButtonReflowInput, |
232 | | nsIFrame* aFirstKid) |
233 | 0 | { |
234 | 0 | WritingMode wm = GetWritingMode(); |
235 | 0 | LogicalSize availSize = aButtonReflowInput.ComputedSize(wm); |
236 | 0 | availSize.BSize(wm) = NS_INTRINSICSIZE; |
237 | 0 |
|
238 | 0 | // shorthand for a value we need to use in a bunch of places |
239 | 0 | const LogicalMargin& clbp = aButtonReflowInput.ComputedLogicalBorderPadding(); |
240 | 0 |
|
241 | 0 | LogicalPoint childPos(wm); |
242 | 0 | childPos.I(wm) = clbp.IStart(wm); |
243 | 0 | availSize.ISize(wm) = std::max(availSize.ISize(wm), 0); |
244 | 0 |
|
245 | 0 | ReflowInput contentsReflowInput(aPresContext, aButtonReflowInput, |
246 | 0 | aFirstKid, availSize); |
247 | 0 |
|
248 | 0 | nsReflowStatus contentsReflowStatus; |
249 | 0 | ReflowOutput contentsDesiredSize(aButtonReflowInput); |
250 | 0 | childPos.B(wm) = 0; // This will be set properly later, after reflowing the |
251 | 0 | // child to determine its size. |
252 | 0 |
|
253 | 0 | const LayoutFrameType frameType = aFirstKid->Type(); |
254 | 0 | if (frameType == LayoutFrameType::FlexContainer || |
255 | 0 | frameType == LayoutFrameType::GridContainer) { |
256 | 0 | contentsReflowInput.ComputedBSize() = aButtonReflowInput.ComputedBSize(); |
257 | 0 | contentsReflowInput.ComputedMinBSize() = |
258 | 0 | aButtonReflowInput.ComputedMinBSize(); |
259 | 0 | contentsReflowInput.ComputedMaxBSize() = |
260 | 0 | aButtonReflowInput.ComputedMaxBSize(); |
261 | 0 | } |
262 | 0 |
|
263 | 0 | // We just pass a dummy containerSize here, as the child will be |
264 | 0 | // repositioned later by FinishReflowChild. |
265 | 0 | nsSize dummyContainerSize; |
266 | 0 | ReflowChild(aFirstKid, aPresContext, |
267 | 0 | contentsDesiredSize, contentsReflowInput, |
268 | 0 | wm, childPos, dummyContainerSize, 0, contentsReflowStatus); |
269 | 0 | MOZ_ASSERT(contentsReflowStatus.IsComplete(), |
270 | 0 | "We gave button-contents frame unconstrained available height, " |
271 | 0 | "so it should be complete"); |
272 | 0 |
|
273 | 0 | // Compute the button's content-box size: |
274 | 0 | LogicalSize buttonContentBox(wm); |
275 | 0 | if (aButtonReflowInput.ComputedBSize() != NS_INTRINSICSIZE) { |
276 | 0 | // Button has a fixed block-size -- that's its content-box bSize. |
277 | 0 | buttonContentBox.BSize(wm) = aButtonReflowInput.ComputedBSize(); |
278 | 0 | } else if (aButtonReflowInput.mStyleDisplay->IsContainSize()) { |
279 | 0 | // Button is intrinsically sized and has size containment. |
280 | 0 | // It should have a BSize that is either zero or the minimum |
281 | 0 | // specified BSize. |
282 | 0 | buttonContentBox.BSize(wm) = aButtonReflowInput.ComputedMinBSize(); |
283 | 0 | } else { |
284 | 0 | // Button is intrinsically sized -- it should shrinkwrap the |
285 | 0 | // button-contents' bSize: |
286 | 0 | buttonContentBox.BSize(wm) = contentsDesiredSize.BSize(wm); |
287 | 0 |
|
288 | 0 | // Make sure we obey min/max-bSize in the case when we're doing intrinsic |
289 | 0 | // sizing (we get it for free when we have a non-intrinsic |
290 | 0 | // aButtonReflowInput.ComputedBSize()). Note that we do this before |
291 | 0 | // adjusting for borderpadding, since mComputedMaxBSize and |
292 | 0 | // mComputedMinBSize are content bSizes. |
293 | 0 | buttonContentBox.BSize(wm) = |
294 | 0 | NS_CSS_MINMAX(buttonContentBox.BSize(wm), |
295 | 0 | aButtonReflowInput.ComputedMinBSize(), |
296 | 0 | aButtonReflowInput.ComputedMaxBSize()); |
297 | 0 | } |
298 | 0 | if (aButtonReflowInput.ComputedISize() != NS_INTRINSICSIZE) { |
299 | 0 | buttonContentBox.ISize(wm) = aButtonReflowInput.ComputedISize(); |
300 | 0 | } else if (aButtonReflowInput.mStyleDisplay->IsContainSize()) { |
301 | 0 | buttonContentBox.ISize(wm) = aButtonReflowInput.ComputedMinISize(); |
302 | 0 | } else { |
303 | 0 | buttonContentBox.ISize(wm) = contentsDesiredSize.ISize(wm); |
304 | 0 | buttonContentBox.ISize(wm) = |
305 | 0 | NS_CSS_MINMAX(buttonContentBox.ISize(wm), |
306 | 0 | aButtonReflowInput.ComputedMinISize(), |
307 | 0 | aButtonReflowInput.ComputedMaxISize()); |
308 | 0 | } |
309 | 0 |
|
310 | 0 | // Center child in the block-direction in the button |
311 | 0 | // (technically, inside of the button's focus-padding area) |
312 | 0 | nscoord extraSpace = buttonContentBox.BSize(wm) - |
313 | 0 | contentsDesiredSize.BSize(wm); |
314 | 0 |
|
315 | 0 | childPos.B(wm) = std::max(0, extraSpace / 2); |
316 | 0 |
|
317 | 0 | // Adjust childPos.B() to be in terms of the button's frame-rect: |
318 | 0 | childPos.B(wm) += clbp.BStart(wm); |
319 | 0 |
|
320 | 0 | nsSize containerSize = |
321 | 0 | (buttonContentBox + clbp.Size(wm)).GetPhysicalSize(wm); |
322 | 0 |
|
323 | 0 | // Place the child |
324 | 0 | FinishReflowChild(aFirstKid, aPresContext, |
325 | 0 | contentsDesiredSize, &contentsReflowInput, |
326 | 0 | wm, childPos, containerSize, 0); |
327 | 0 |
|
328 | 0 | // Make sure we have a useful 'ascent' value for the child |
329 | 0 | if (contentsDesiredSize.BlockStartAscent() == |
330 | 0 | ReflowOutput::ASK_FOR_BASELINE) { |
331 | 0 | WritingMode wm = aButtonReflowInput.GetWritingMode(); |
332 | 0 | contentsDesiredSize.SetBlockStartAscent(aFirstKid->GetLogicalBaseline(wm)); |
333 | 0 | } |
334 | 0 |
|
335 | 0 | // OK, we're done with the child frame. |
336 | 0 | // Use what we learned to populate the button frame's reflow metrics. |
337 | 0 | // * Button's height & width are content-box size + border-box contribution: |
338 | 0 | aButtonDesiredSize.SetSize(wm, |
339 | 0 | LogicalSize(wm, aButtonReflowInput.ComputedISize() + clbp.IStartEnd(wm), |
340 | 0 | buttonContentBox.BSize(wm) + clbp.BStartEnd(wm))); |
341 | 0 |
|
342 | 0 | // * Button's ascent is its child's ascent, plus the child's block-offset |
343 | 0 | // within our frame... unless it's orthogonal, in which case we'll use the |
344 | 0 | // contents inline-size as an approximation for now. |
345 | 0 | // XXX is there a better strategy? should we include border-padding? |
346 | 0 | if (aButtonReflowInput.mStyleDisplay->IsContainSize()) { |
347 | 0 | // If we're size-contained, we should pretend our contents had 0 height |
348 | 0 | // (as they would, if we had no children). This case is identical to the |
349 | 0 | // final else case, but uses only our specified button height for ascent |
350 | 0 | // (ie. it ignores the height returned in contentsDesiredSize). |
351 | 0 | nscoord containAscent = (buttonContentBox.BSize(wm) / 2) + clbp.BStart(wm); |
352 | 0 | aButtonDesiredSize.SetBlockStartAscent(containAscent); |
353 | 0 | } else if (aButtonDesiredSize.GetWritingMode().IsOrthogonalTo(wm)) { |
354 | 0 | aButtonDesiredSize.SetBlockStartAscent(contentsDesiredSize.ISize(wm)); |
355 | 0 | } else { |
356 | 0 | aButtonDesiredSize.SetBlockStartAscent(contentsDesiredSize.BlockStartAscent() + |
357 | 0 | childPos.B(wm)); |
358 | 0 | } |
359 | 0 |
|
360 | 0 | aButtonDesiredSize.SetOverflowAreasToDesiredBounds(); |
361 | 0 | } |
362 | | |
363 | | bool |
364 | | nsHTMLButtonControlFrame::GetVerticalAlignBaseline(mozilla::WritingMode aWM, |
365 | | nscoord* aBaseline) const |
366 | 0 | { |
367 | 0 | nsIFrame* inner = mFrames.FirstChild(); |
368 | 0 | if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM))) { |
369 | 0 | return false; |
370 | 0 | } |
371 | 0 | if (!inner->GetVerticalAlignBaseline(aWM, aBaseline)) { |
372 | 0 | // <input type=color> has an empty block frame as inner frame |
373 | 0 | *aBaseline = inner-> |
374 | 0 | SynthesizeBaselineBOffsetFromBorderBox(aWM, BaselineSharingGroup::eFirst); |
375 | 0 | } |
376 | 0 | nscoord innerBStart = inner->BStart(aWM, GetSize()); |
377 | 0 | *aBaseline += innerBStart; |
378 | 0 | return true; |
379 | 0 | } |
380 | | |
381 | | bool |
382 | | nsHTMLButtonControlFrame::GetNaturalBaselineBOffset(mozilla::WritingMode aWM, |
383 | | BaselineSharingGroup aBaselineGroup, |
384 | | nscoord* aBaseline) const |
385 | 0 | { |
386 | 0 | nsIFrame* inner = mFrames.FirstChild(); |
387 | 0 | if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM))) { |
388 | 0 | return false; |
389 | 0 | } |
390 | 0 | if (!inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aBaseline)) { |
391 | 0 | // <input type=color> has an empty block frame as inner frame |
392 | 0 | *aBaseline = inner-> |
393 | 0 | SynthesizeBaselineBOffsetFromBorderBox(aWM, aBaselineGroup); |
394 | 0 | } |
395 | 0 | nscoord innerBStart = inner->BStart(aWM, GetSize()); |
396 | 0 | if (aBaselineGroup == BaselineSharingGroup::eFirst) { |
397 | 0 | *aBaseline += innerBStart; |
398 | 0 | } else { |
399 | 0 | *aBaseline += BSize(aWM) - (innerBStart + inner->BSize(aWM)); |
400 | 0 | } |
401 | 0 | return true; |
402 | 0 | } |
403 | | |
404 | | nsresult nsHTMLButtonControlFrame::SetFormProperty(nsAtom* aName, const nsAString& aValue) |
405 | 0 | { |
406 | 0 | if (nsGkAtoms::value == aName) { |
407 | 0 | return mContent->AsElement()->SetAttr(kNameSpaceID_None, nsGkAtoms::value, |
408 | 0 | aValue, true); |
409 | 0 | } |
410 | 0 | return NS_OK; |
411 | 0 | } |
412 | | |
413 | | ComputedStyle* |
414 | | nsHTMLButtonControlFrame::GetAdditionalComputedStyle(int32_t aIndex) const |
415 | 0 | { |
416 | 0 | return mRenderer.GetComputedStyle(aIndex); |
417 | 0 | } |
418 | | |
419 | | void |
420 | | nsHTMLButtonControlFrame::SetAdditionalComputedStyle(int32_t aIndex, |
421 | | ComputedStyle* aComputedStyle) |
422 | 0 | { |
423 | 0 | mRenderer.SetComputedStyle(aIndex, aComputedStyle); |
424 | 0 | } |
425 | | |
426 | | void |
427 | | nsHTMLButtonControlFrame::AppendDirectlyOwnedAnonBoxes(nsTArray<OwnedAnonBox>& aResult) |
428 | 0 | { |
429 | 0 | MOZ_ASSERT(mFrames.FirstChild(), "Must have our button-content anon box"); |
430 | 0 | MOZ_ASSERT(!mFrames.FirstChild()->GetNextSibling(), |
431 | 0 | "Must only have our button-content anon box"); |
432 | 0 | aResult.AppendElement(OwnedAnonBox(mFrames.FirstChild())); |
433 | 0 | } |
434 | | |
435 | | #ifdef DEBUG |
436 | | void |
437 | | nsHTMLButtonControlFrame::AppendFrames(ChildListID aListID, |
438 | | nsFrameList& aFrameList) |
439 | | { |
440 | | MOZ_CRASH("unsupported operation"); |
441 | | } |
442 | | |
443 | | void |
444 | | nsHTMLButtonControlFrame::InsertFrames(ChildListID aListID, |
445 | | nsIFrame* aPrevFrame, |
446 | | nsFrameList& aFrameList) |
447 | | { |
448 | | MOZ_CRASH("unsupported operation"); |
449 | | } |
450 | | |
451 | | void |
452 | | nsHTMLButtonControlFrame::RemoveFrame(ChildListID aListID, |
453 | | nsIFrame* aOldFrame) |
454 | | { |
455 | | MOZ_CRASH("unsupported operation"); |
456 | | } |
457 | | #endif |