mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 01:57:00 +00:00
Bug 849524 - Avoid reflowing when <input type=range>'s thumb position needs to be updated due to its value changing. r=dholbert
This commit is contained in:
parent
d976ddfc04
commit
f0406a7abb
@ -2599,11 +2599,9 @@ nsHTMLInputElement::SetValueOfRangeForUserEvent(double aValue)
|
||||
nsAutoString val;
|
||||
ConvertNumberToString(aValue, val);
|
||||
SetValueInternal(val, true, true);
|
||||
nsIFrame* frame = GetPrimaryFrame();
|
||||
nsRangeFrame* frame = do_QueryFrame(GetPrimaryFrame());
|
||||
if (frame) {
|
||||
// Trigger reflow to update the position of the thumb:
|
||||
frame->PresContext()->GetPresShell()->
|
||||
FrameNeedsReflow(frame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
|
||||
frame->UpdateThumbPositionForValueChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,6 +378,34 @@ nsRangeFrame::GetValueAtEventPoint(nsGUIEvent* aEvent)
|
||||
return minimum + (double(contentPoint.x) / double(contentRect.width)) * range;
|
||||
}
|
||||
|
||||
void
|
||||
nsRangeFrame::UpdateThumbPositionForValueChange()
|
||||
{
|
||||
if (NS_SUBTREE_DIRTY(this)) {
|
||||
return; // we're going to be updated when we reflow
|
||||
}
|
||||
nsIFrame* thumbFrame = mThumbDiv->GetPrimaryFrame();
|
||||
if (!thumbFrame) {
|
||||
return; // diplay:none?
|
||||
}
|
||||
// TODO in bug 842179 - factor out duplication here and in Reflow.
|
||||
double fraction = GetValueAsFractionOfRange();
|
||||
nsRect contentRect = GetContentRectRelativeToSelf();
|
||||
nsMargin borderAndPadding = GetUsedBorderAndPadding();
|
||||
nsSize thumbSize = thumbFrame->GetSize();
|
||||
nsPoint newPosition(borderAndPadding.left, borderAndPadding.top);
|
||||
if (IsHorizontal()) {
|
||||
newPosition += nsPoint(NSToCoordRound(fraction * contentRect.width) -
|
||||
thumbSize.width/2,
|
||||
(contentRect.height - thumbSize.height)/2);
|
||||
} else {
|
||||
newPosition += nsPoint((contentRect.width - thumbSize.width)/2,
|
||||
NSToCoordRound(fraction * contentRect.height) -
|
||||
thumbSize.height/2);
|
||||
}
|
||||
thumbFrame->SetPosition(newPosition);
|
||||
SchedulePaint();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRangeFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
@ -392,18 +420,22 @@ nsRangeFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
aAttribute == nsGkAtoms::min ||
|
||||
aAttribute == nsGkAtoms::max ||
|
||||
aAttribute == nsGkAtoms::step)) {
|
||||
nsIFrame* trackFrame = mTrackDiv->GetPrimaryFrame();
|
||||
if (trackFrame) { // diplay:none?
|
||||
PresContext()->PresShell()->FrameNeedsReflow(trackFrame,
|
||||
nsIPresShell::eResize,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
|
||||
nsIFrame* thumbFrame = mThumbDiv->GetPrimaryFrame();
|
||||
if (thumbFrame) { // diplay:none?
|
||||
PresContext()->PresShell()->FrameNeedsReflow(thumbFrame,
|
||||
nsIPresShell::eResize,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
// We want to update the position of the thumb, except in one special case:
|
||||
// If the value attribute is being set, it is possible that we are in the
|
||||
// middle of a type change away from type=range, under the
|
||||
// SetAttr(..., nsGkAtoms::value, ...) call in nsHTMLInputElement::
|
||||
// HandleTypeChange. In that case the nsHTMLInputElement's type will
|
||||
// already have changed, and if we call UpdateThumbPositionForValueChange()
|
||||
// we'll fail the asserts under that call that check the type of our
|
||||
// nsHTMLInputElement. Given that we're changing away from being a range
|
||||
// and this frame will shortly be destroyed, there's no point in calling
|
||||
// UpdateThumbPositionForValueChange() anyway.
|
||||
MOZ_ASSERT(mContent->IsHTML(nsGkAtoms::input), "bad cast");
|
||||
bool typeIsRange = static_cast<nsHTMLInputElement*>(mContent)->GetType() ==
|
||||
NS_FORM_INPUT_RANGE;
|
||||
MOZ_ASSERT(typeIsRange || aAttribute == nsGkAtoms::value, "why?");
|
||||
if (typeIsRange) {
|
||||
UpdateThumbPositionForValueChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,6 +92,13 @@ public:
|
||||
|
||||
double GetValueAtEventPoint(nsGUIEvent* aEvent);
|
||||
|
||||
/**
|
||||
* Helper to reposition the thumb and schedule a repaint when the value of
|
||||
* the range changes. (This does not reflow, since the position and size of
|
||||
* the thumb do not affect the position or size of any other frames.)
|
||||
*/
|
||||
void UpdateThumbPositionForValueChange();
|
||||
|
||||
private:
|
||||
|
||||
// Helper function which reflows the anonymous div frames.
|
||||
|
Loading…
x
Reference in New Issue
Block a user