Line data Source code
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/. */
5 : #include "nsButtonFrameRenderer.h"
6 : #include "nsCSSRendering.h"
7 : #include "nsPresContext.h"
8 : #include "nsGkAtoms.h"
9 : #include "nsCSSPseudoElements.h"
10 : #include "nsNameSpaceManager.h"
11 : #include "mozilla/StyleSetHandle.h"
12 : #include "mozilla/StyleSetHandleInlines.h"
13 : #include "nsDisplayList.h"
14 : #include "nsITheme.h"
15 : #include "nsFrame.h"
16 : #include "mozilla/EventStates.h"
17 : #include "mozilla/dom/Element.h"
18 : #include "Layers.h"
19 : #include "gfxPrefs.h"
20 : #include "gfxUtils.h"
21 : #include "mozilla/layers/WebRenderDisplayItemLayer.h"
22 :
23 : #define ACTIVE "active"
24 : #define HOVER "hover"
25 : #define FOCUS "focus"
26 :
27 : using namespace mozilla;
28 : using namespace mozilla::image;
29 : using namespace mozilla::layers;
30 :
31 0 : nsButtonFrameRenderer::nsButtonFrameRenderer()
32 : {
33 0 : MOZ_COUNT_CTOR(nsButtonFrameRenderer);
34 0 : }
35 :
36 0 : nsButtonFrameRenderer::~nsButtonFrameRenderer()
37 : {
38 0 : MOZ_COUNT_DTOR(nsButtonFrameRenderer);
39 :
40 : #ifdef DEBUG
41 0 : if (mInnerFocusStyle) {
42 0 : mInnerFocusStyle->FrameRelease();
43 : }
44 : #endif
45 0 : }
46 :
47 : void
48 0 : nsButtonFrameRenderer::SetFrame(nsFrame* aFrame, nsPresContext* aPresContext)
49 : {
50 0 : mFrame = aFrame;
51 0 : ReResolveStyles(aPresContext);
52 0 : }
53 :
54 : nsIFrame*
55 0 : nsButtonFrameRenderer::GetFrame()
56 : {
57 0 : return mFrame;
58 : }
59 :
60 : void
61 0 : nsButtonFrameRenderer::SetDisabled(bool aDisabled, bool notify)
62 : {
63 0 : if (aDisabled)
64 0 : mFrame->GetContent()->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled, EmptyString(),
65 0 : notify);
66 : else
67 0 : mFrame->GetContent()->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, notify);
68 0 : }
69 :
70 : bool
71 0 : nsButtonFrameRenderer::isDisabled()
72 : {
73 0 : return mFrame->GetContent()->AsElement()->
74 0 : State().HasState(NS_EVENT_STATE_DISABLED);
75 : }
76 :
77 : class nsDisplayButtonBoxShadowOuter : public nsDisplayItem {
78 : public:
79 0 : nsDisplayButtonBoxShadowOuter(nsDisplayListBuilder* aBuilder,
80 : nsButtonFrameRenderer* aRenderer)
81 0 : : nsDisplayItem(aBuilder, aRenderer->GetFrame()) {
82 0 : MOZ_COUNT_CTOR(nsDisplayButtonBoxShadowOuter);
83 0 : }
84 : #ifdef NS_BUILD_REFCNT_LOGGING
85 0 : virtual ~nsDisplayButtonBoxShadowOuter() {
86 0 : MOZ_COUNT_DTOR(nsDisplayButtonBoxShadowOuter);
87 0 : }
88 : #endif
89 :
90 : virtual void Paint(nsDisplayListBuilder* aBuilder,
91 : gfxContext* aCtx) override;
92 : virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
93 : bool* aSnap) override;
94 0 : NS_DISPLAY_DECL_NAME("ButtonBoxShadowOuter", TYPE_BUTTON_BOX_SHADOW_OUTER)
95 : };
96 :
97 : nsRect
98 0 : nsDisplayButtonBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
99 0 : *aSnap = false;
100 0 : return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
101 : }
102 :
103 : void
104 0 : nsDisplayButtonBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder,
105 : gfxContext* aCtx) {
106 0 : nsRect frameRect = nsRect(ToReferenceFrame(), mFrame->GetSize());
107 :
108 0 : nsCSSRendering::PaintBoxShadowOuter(mFrame->PresContext(), *aCtx, mFrame,
109 0 : frameRect, mVisibleRect);
110 0 : }
111 :
112 : class nsDisplayButtonBorder : public nsDisplayItem {
113 : public:
114 0 : nsDisplayButtonBorder(nsDisplayListBuilder* aBuilder,
115 : nsButtonFrameRenderer* aRenderer)
116 0 : : nsDisplayItem(aBuilder, aRenderer->GetFrame()), mBFR(aRenderer) {
117 0 : MOZ_COUNT_CTOR(nsDisplayButtonBorder);
118 0 : }
119 : #ifdef NS_BUILD_REFCNT_LOGGING
120 0 : virtual ~nsDisplayButtonBorder() {
121 0 : MOZ_COUNT_DTOR(nsDisplayButtonBorder);
122 0 : }
123 : #endif
124 0 : virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
125 : HitTestState* aState,
126 : nsTArray<nsIFrame*> *aOutFrames) override {
127 0 : aOutFrames->AppendElement(mFrame);
128 0 : }
129 : virtual void Paint(nsDisplayListBuilder* aBuilder,
130 : gfxContext* aCtx) override;
131 : virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
132 : bool* aSnap) override;
133 : virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
134 : virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
135 : const nsDisplayItemGeometry* aGeometry,
136 : nsRegion *aInvalidRegion) override;
137 : virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
138 : LayerManager* aManager,
139 : const ContainerLayerParameters& aParameters) override;
140 : virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
141 : LayerManager* aManager,
142 : const ContainerLayerParameters& aContainerParameters) override;
143 : virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
144 : const StackingContextHelper& aSc,
145 : nsTArray<WebRenderParentCommand>& aParentCommands,
146 : mozilla::layers::WebRenderLayerManager* aManager,
147 : nsDisplayListBuilder* aDisplayListBuilder) override;
148 0 : NS_DISPLAY_DECL_NAME("ButtonBorderBackground", TYPE_BUTTON_BORDER_BACKGROUND)
149 : private:
150 : nsButtonFrameRenderer* mBFR;
151 : Maybe<nsCSSBorderRenderer> mBorderRenderer;
152 : };
153 :
154 : nsDisplayItemGeometry*
155 0 : nsDisplayButtonBorder::AllocateGeometry(nsDisplayListBuilder* aBuilder)
156 : {
157 0 : return new nsDisplayItemGenericImageGeometry(this, aBuilder);
158 : }
159 :
160 : LayerState
161 0 : nsDisplayButtonBorder::GetLayerState(nsDisplayListBuilder* aBuilder,
162 : LayerManager* aManager,
163 : const ContainerLayerParameters& aParameters)
164 : {
165 0 : if (ShouldUseAdvancedLayer(aManager, gfxPrefs::LayersAllowDisplayButtonBorder)) {
166 : // TODO: Figure out what to do with sync decode images
167 0 : if (aBuilder->ShouldSyncDecodeImages()) {
168 0 : return LAYER_NONE;
169 : }
170 :
171 0 : nsPoint offset = ToReferenceFrame();
172 0 : if (!nsDisplayBoxShadowInner::CanCreateWebRenderCommands(aBuilder,
173 : mFrame,
174 : offset)) {
175 0 : return LAYER_NONE;
176 : }
177 :
178 : Maybe<nsCSSBorderRenderer> br =
179 0 : nsCSSRendering::CreateBorderRenderer(mFrame->PresContext(),
180 : nullptr,
181 : mFrame,
182 0 : nsRect(),
183 0 : nsRect(offset, mFrame->GetSize()),
184 0 : mFrame->StyleContext(),
185 0 : mFrame->GetSkipSides());
186 0 : if (!br) {
187 0 : return LAYER_NONE;
188 : }
189 :
190 0 : if (!br->CanCreateWebRenderCommands()) {
191 0 : return LAYER_NONE;
192 : }
193 :
194 0 : mBorderRenderer = br;
195 0 : return LAYER_ACTIVE;
196 : }
197 :
198 0 : return LAYER_NONE;
199 : }
200 :
201 : already_AddRefed<Layer>
202 0 : nsDisplayButtonBorder::BuildLayer(nsDisplayListBuilder* aBuilder,
203 : LayerManager* aManager,
204 : const ContainerLayerParameters& aContainerParameters)
205 : {
206 0 : return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
207 : }
208 :
209 : bool
210 0 : nsDisplayButtonBorder::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
211 : const StackingContextHelper& aSc,
212 : nsTArray<WebRenderParentCommand>& aParentCommands,
213 : mozilla::layers::WebRenderLayerManager* aManager,
214 : nsDisplayListBuilder* aDisplayListBuilder)
215 : {
216 0 : if (aManager->IsLayersFreeTransaction()) {
217 0 : ContainerLayerParameters parameter;
218 0 : if (GetLayerState(aDisplayListBuilder, aManager, parameter) != LAYER_ACTIVE) {
219 0 : return false;
220 : }
221 : }
222 :
223 0 : MOZ_ASSERT(mBorderRenderer);
224 :
225 : // This is really a combination of paint box shadow inner +
226 : // paint border.
227 0 : nsRect buttonRect = nsRect(ToReferenceFrame(), mFrame->GetSize());
228 : bool snap;
229 0 : nsRegion visible = GetBounds(aDisplayListBuilder, &snap);
230 0 : nsDisplayBoxShadowInner::CreateInsetBoxShadowWebRenderCommands(aBuilder,
231 : aSc,
232 : visible,
233 : mFrame,
234 0 : buttonRect);
235 0 : mBorderRenderer->CreateWebRenderCommands(aBuilder, aSc);
236 :
237 0 : return true;
238 : }
239 :
240 : void
241 0 : nsDisplayButtonBorder::ComputeInvalidationRegion(
242 : nsDisplayListBuilder* aBuilder,
243 : const nsDisplayItemGeometry* aGeometry,
244 : nsRegion *aInvalidRegion)
245 : {
246 : auto geometry =
247 0 : static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
248 :
249 0 : if (aBuilder->ShouldSyncDecodeImages() &&
250 0 : geometry->ShouldInvalidateToSyncDecodeImages()) {
251 : bool snap;
252 0 : aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
253 : }
254 :
255 0 : nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
256 0 : }
257 :
258 : void
259 0 : nsDisplayButtonBorder::Paint(nsDisplayListBuilder* aBuilder,
260 : gfxContext* aCtx)
261 : {
262 0 : NS_ASSERTION(mFrame, "No frame?");
263 0 : nsPresContext* pc = mFrame->PresContext();
264 0 : nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize());
265 :
266 : // draw the border and background inside the focus and outline borders
267 : DrawResult result =
268 0 : mBFR->PaintBorder(aBuilder, pc, *aCtx, mVisibleRect, r);
269 :
270 0 : nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
271 0 : }
272 :
273 : nsRect
274 0 : nsDisplayButtonBorder::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
275 0 : *aSnap = false;
276 0 : return aBuilder->IsForEventDelivery() ? nsRect(ToReferenceFrame(), mFrame->GetSize())
277 0 : : mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
278 : }
279 :
280 : class nsDisplayButtonForeground : public nsDisplayItem {
281 : public:
282 0 : nsDisplayButtonForeground(nsDisplayListBuilder* aBuilder,
283 : nsButtonFrameRenderer* aRenderer)
284 0 : : nsDisplayItem(aBuilder, aRenderer->GetFrame()), mBFR(aRenderer) {
285 0 : MOZ_COUNT_CTOR(nsDisplayButtonForeground);
286 0 : }
287 : #ifdef NS_BUILD_REFCNT_LOGGING
288 0 : virtual ~nsDisplayButtonForeground() {
289 0 : MOZ_COUNT_DTOR(nsDisplayButtonForeground);
290 0 : }
291 : #endif
292 :
293 : nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
294 : void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
295 : const nsDisplayItemGeometry* aGeometry,
296 : nsRegion *aInvalidRegion) override;
297 : virtual void Paint(nsDisplayListBuilder* aBuilder,
298 : gfxContext* aCtx) override;
299 : virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
300 : LayerManager* aManager,
301 : const ContainerLayerParameters& aParameters) override;
302 : virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
303 : LayerManager* aManager,
304 : const ContainerLayerParameters& aContainerParameters) override;
305 : virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
306 : const StackingContextHelper& aSc,
307 : nsTArray<WebRenderParentCommand>& aParentCommands,
308 : mozilla::layers::WebRenderLayerManager* aManager,
309 : nsDisplayListBuilder* aDisplayListBuilder) override;
310 0 : NS_DISPLAY_DECL_NAME("ButtonForeground", TYPE_BUTTON_FOREGROUND)
311 : private:
312 : nsButtonFrameRenderer* mBFR;
313 : Maybe<nsCSSBorderRenderer> mBorderRenderer;
314 : };
315 :
316 : nsDisplayItemGeometry*
317 0 : nsDisplayButtonForeground::AllocateGeometry(nsDisplayListBuilder* aBuilder)
318 : {
319 0 : return new nsDisplayItemGenericImageGeometry(this, aBuilder);
320 : }
321 :
322 : void
323 0 : nsDisplayButtonForeground::ComputeInvalidationRegion(
324 : nsDisplayListBuilder* aBuilder,
325 : const nsDisplayItemGeometry* aGeometry,
326 : nsRegion* aInvalidRegion)
327 : {
328 : auto geometry =
329 0 : static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
330 :
331 0 : if (aBuilder->ShouldSyncDecodeImages() &&
332 0 : geometry->ShouldInvalidateToSyncDecodeImages()) {
333 : bool snap;
334 0 : aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
335 : }
336 :
337 0 : nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
338 0 : }
339 :
340 0 : void nsDisplayButtonForeground::Paint(nsDisplayListBuilder* aBuilder,
341 : gfxContext* aCtx)
342 : {
343 0 : nsPresContext *presContext = mFrame->PresContext();
344 0 : const nsStyleDisplay *disp = mFrame->StyleDisplay();
345 0 : if (!mFrame->IsThemed(disp) ||
346 0 : !presContext->GetTheme()->ThemeDrawsFocusForWidget(disp->mAppearance)) {
347 0 : nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize());
348 :
349 : // Draw the -moz-focus-inner border
350 : DrawResult result =
351 0 : mBFR->PaintInnerFocusBorder(aBuilder, presContext, *aCtx, mVisibleRect, r);
352 :
353 0 : nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
354 : }
355 0 : }
356 :
357 : LayerState
358 0 : nsDisplayButtonForeground::GetLayerState(nsDisplayListBuilder* aBuilder,
359 : LayerManager* aManager,
360 : const ContainerLayerParameters& aParameters)
361 : {
362 0 : Maybe<nsCSSBorderRenderer> br;
363 :
364 0 : if (ShouldUseAdvancedLayer(aManager, gfxPrefs::LayersAllowButtonForegroundLayers)) {
365 0 : nsPresContext *presContext = mFrame->PresContext();
366 0 : const nsStyleDisplay *disp = mFrame->StyleDisplay();
367 0 : if (!mFrame->IsThemed(disp) ||
368 0 : !presContext->GetTheme()->ThemeDrawsFocusForWidget(disp->mAppearance)) {
369 0 : nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize());
370 0 : br = mBFR->CreateInnerFocusBorderRenderer(aBuilder, presContext, nullptr, mVisibleRect, r);
371 : }
372 : }
373 :
374 0 : if (!br || !br->CanCreateWebRenderCommands()) {
375 0 : return LAYER_NONE;
376 : }
377 :
378 0 : mBorderRenderer = br;
379 :
380 0 : return LAYER_ACTIVE;
381 : }
382 :
383 : already_AddRefed<mozilla::layers::Layer>
384 0 : nsDisplayButtonForeground::BuildLayer(nsDisplayListBuilder* aBuilder,
385 : LayerManager* aManager,
386 : const ContainerLayerParameters& aContainerParameters)
387 : {
388 0 : return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
389 : }
390 :
391 : bool
392 0 : nsDisplayButtonForeground::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
393 : const StackingContextHelper& aSc,
394 : nsTArray<WebRenderParentCommand>& aParentCommands,
395 : mozilla::layers::WebRenderLayerManager* aManager,
396 : nsDisplayListBuilder* aDisplayListBuilder)
397 : {
398 0 : if (aManager->IsLayersFreeTransaction()) {
399 0 : ContainerLayerParameters parameter;
400 0 : if (GetLayerState(aDisplayListBuilder, aManager, parameter) != LAYER_ACTIVE) {
401 0 : return false;
402 : }
403 : }
404 :
405 0 : mBorderRenderer->CreateWebRenderCommands(aBuilder, aSc);
406 0 : return true;
407 : }
408 :
409 : nsresult
410 0 : nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder,
411 : nsDisplayList* aBackground,
412 : nsDisplayList* aForeground)
413 : {
414 0 : if (mFrame->StyleEffects()->mBoxShadow) {
415 : aBackground->AppendNewToTop(new (aBuilder)
416 0 : nsDisplayButtonBoxShadowOuter(aBuilder, this));
417 : }
418 :
419 0 : nsRect buttonRect = mFrame->GetRectRelativeToSelf();
420 :
421 0 : nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
422 0 : aBuilder, mFrame, buttonRect, aBackground);
423 :
424 : aBackground->AppendNewToTop(new (aBuilder)
425 0 : nsDisplayButtonBorder(aBuilder, this));
426 :
427 : // Only display focus rings if we actually have them. Since at most one
428 : // button would normally display a focus ring, most buttons won't have them.
429 0 : if (mInnerFocusStyle && mInnerFocusStyle->StyleBorder()->HasBorder()) {
430 : aForeground->AppendNewToTop(new (aBuilder)
431 0 : nsDisplayButtonForeground(aBuilder, this));
432 : }
433 0 : return NS_OK;
434 : }
435 :
436 : void
437 0 : nsButtonFrameRenderer::GetButtonInnerFocusRect(const nsRect& aRect, nsRect& aResult)
438 : {
439 0 : aResult = aRect;
440 0 : aResult.Deflate(mFrame->GetUsedBorderAndPadding());
441 :
442 0 : nsMargin innerFocusPadding(0,0,0,0);
443 0 : if (mInnerFocusStyle) {
444 0 : mInnerFocusStyle->StylePadding()->GetPadding(innerFocusPadding);
445 : }
446 0 : aResult.Inflate(innerFocusPadding);
447 0 : }
448 :
449 : DrawResult
450 0 : nsButtonFrameRenderer::PaintInnerFocusBorder(
451 : nsDisplayListBuilder* aBuilder,
452 : nsPresContext* aPresContext,
453 : gfxContext& aRenderingContext,
454 : const nsRect& aDirtyRect,
455 : const nsRect& aRect)
456 : {
457 : // we draw the -moz-focus-inner border just inside the button's
458 : // normal border and padding, to match Windows themes.
459 :
460 0 : nsRect rect;
461 :
462 0 : PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages()
463 0 : ? PaintBorderFlags::SYNC_DECODE_IMAGES
464 0 : : PaintBorderFlags();
465 :
466 0 : DrawResult result = DrawResult::SUCCESS;
467 :
468 0 : if (mInnerFocusStyle) {
469 0 : GetButtonInnerFocusRect(aRect, rect);
470 :
471 : result &=
472 0 : nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
473 0 : aDirtyRect, rect, mInnerFocusStyle, flags);
474 : }
475 :
476 0 : return result;
477 : }
478 :
479 : Maybe<nsCSSBorderRenderer>
480 0 : nsButtonFrameRenderer::CreateInnerFocusBorderRenderer(
481 : nsDisplayListBuilder* aBuilder,
482 : nsPresContext* aPresContext,
483 : gfxContext* aRenderingContext,
484 : const nsRect& aDirtyRect,
485 : const nsRect& aRect)
486 : {
487 0 : if (mInnerFocusStyle) {
488 0 : nsRect rect;
489 0 : GetButtonInnerFocusRect(aRect, rect);
490 :
491 0 : gfx::DrawTarget* dt = aRenderingContext ? aRenderingContext->GetDrawTarget() : nullptr;
492 : return nsCSSRendering::CreateBorderRenderer(aPresContext,
493 : dt,
494 0 : mFrame,
495 : aDirtyRect,
496 : rect,
497 0 : mInnerFocusStyle);
498 : }
499 :
500 0 : return Nothing();
501 : }
502 :
503 : DrawResult
504 0 : nsButtonFrameRenderer::PaintBorder(
505 : nsDisplayListBuilder* aBuilder,
506 : nsPresContext* aPresContext,
507 : gfxContext& aRenderingContext,
508 : const nsRect& aDirtyRect,
509 : const nsRect& aRect)
510 : {
511 : // get the button rect this is inside the focus and outline rects
512 0 : nsRect buttonRect = aRect;
513 0 : nsStyleContext* context = mFrame->StyleContext();
514 :
515 0 : PaintBorderFlags borderFlags = aBuilder->ShouldSyncDecodeImages()
516 0 : ? PaintBorderFlags::SYNC_DECODE_IMAGES
517 0 : : PaintBorderFlags();
518 :
519 : nsCSSRendering::PaintBoxShadowInner(aPresContext, aRenderingContext,
520 0 : mFrame, buttonRect);
521 :
522 : DrawResult result =
523 0 : nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
524 0 : aDirtyRect, buttonRect, context, borderFlags);
525 :
526 0 : return result;
527 : }
528 :
529 : /**
530 : * Call this when styles change
531 : */
532 : void
533 0 : nsButtonFrameRenderer::ReResolveStyles(nsPresContext* aPresContext)
534 : {
535 : // get all the styles
536 0 : nsStyleContext* context = mFrame->StyleContext();
537 0 : StyleSetHandle styleSet = aPresContext->StyleSet();
538 :
539 : #ifdef DEBUG
540 0 : if (mInnerFocusStyle) {
541 0 : mInnerFocusStyle->FrameRelease();
542 : }
543 : #endif
544 :
545 : // get styles assigned to -moz-inner-focus (ie dotted border on Windows)
546 : mInnerFocusStyle =
547 0 : styleSet->ProbePseudoElementStyle(mFrame->GetContent()->AsElement(),
548 : CSSPseudoElementType::mozFocusInner,
549 0 : context);
550 :
551 : #ifdef DEBUG
552 0 : if (mInnerFocusStyle) {
553 0 : mInnerFocusStyle->FrameAddRef();
554 : }
555 : #endif
556 0 : }
557 :
558 : nsStyleContext*
559 0 : nsButtonFrameRenderer::GetStyleContext(int32_t aIndex) const
560 : {
561 0 : switch (aIndex) {
562 : case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX:
563 0 : return mInnerFocusStyle;
564 : default:
565 0 : return nullptr;
566 : }
567 : }
568 :
569 : void
570 0 : nsButtonFrameRenderer::SetStyleContext(int32_t aIndex, nsStyleContext* aStyleContext)
571 : {
572 0 : switch (aIndex) {
573 : case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX:
574 : #ifdef DEBUG
575 0 : if (mInnerFocusStyle) {
576 0 : mInnerFocusStyle->FrameRelease();
577 : }
578 : #endif
579 0 : mInnerFocusStyle = aStyleContext;
580 0 : break;
581 : }
582 : #ifdef DEBUG
583 0 : aStyleContext->FrameAddRef();
584 : #endif
585 0 : }
|