| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2010 Google Inc. All rights reserved. | 3 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 #include "core/rendering/RenderSlider.h" | 47 #include "core/rendering/RenderSlider.h" |
| 48 #include "core/rendering/RenderTheme.h" | 48 #include "core/rendering/RenderTheme.h" |
| 49 #include <wtf/MathExtras.h> | 49 #include <wtf/MathExtras.h> |
| 50 | 50 |
| 51 using namespace std; | 51 using namespace std; |
| 52 | 52 |
| 53 namespace WebCore { | 53 namespace WebCore { |
| 54 | 54 |
| 55 using namespace HTMLNames; | 55 using namespace HTMLNames; |
| 56 | 56 |
| 57 inline static Decimal sliderPosition(HTMLInputElement* element) | 57 inline static Decimal sliderPosition(Handle<HTMLInputElement> element) |
| 58 { | 58 { |
| 59 const StepRange stepRange(element->createStepRange(RejectAny)); | 59 const StepRange stepRange(element->createStepRange(RejectAny)); |
| 60 const Decimal oldValue = parseToDecimalForNumberType(element->value(), stepR
ange.defaultValue()); | 60 const Decimal oldValue = parseToDecimalForNumberType(element->value(), stepR
ange.defaultValue()); |
| 61 return stepRange.proportionFromValue(stepRange.clampValue(oldValue)); | 61 return stepRange.proportionFromValue(stepRange.clampValue(oldValue)); |
| 62 } | 62 } |
| 63 | 63 |
| 64 inline static bool hasVerticalAppearance(HTMLInputElement* input) | 64 inline static bool hasVerticalAppearance(Handle<HTMLInputElement> input) |
| 65 { | 65 { |
| 66 ASSERT(input->renderer()); | 66 ASSERT(input->renderer()); |
| 67 RenderStyle* sliderStyle = input->renderer()->style(); | 67 RenderStyle* sliderStyle = input->renderer()->style(); |
| 68 | 68 |
| 69 if (sliderStyle->appearance() == MediaVolumeSliderPart && input->renderer()-
>theme()->usesVerticalVolumeSlider()) | 69 if (sliderStyle->appearance() == MediaVolumeSliderPart && input->renderer()-
>theme()->usesVerticalVolumeSlider()) |
| 70 return true; | 70 return true; |
| 71 | 71 |
| 72 return sliderStyle->appearance() == SliderVerticalPart; | 72 return sliderStyle->appearance() == SliderVerticalPart; |
| 73 } | 73 } |
| 74 | 74 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 : RenderFlexibleBox(element) { } | 130 : RenderFlexibleBox(element) { } |
| 131 public: | 131 public: |
| 132 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logic
alTop, LogicalExtentComputedValues&) const OVERRIDE; | 132 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logic
alTop, LogicalExtentComputedValues&) const OVERRIDE; |
| 133 | 133 |
| 134 private: | 134 private: |
| 135 virtual void layout() OVERRIDE; | 135 virtual void layout() OVERRIDE; |
| 136 }; | 136 }; |
| 137 | 137 |
| 138 void RenderSliderContainer::computeLogicalHeight(LayoutUnit logicalHeight, Layou
tUnit logicalTop, LogicalExtentComputedValues& computedValues) const | 138 void RenderSliderContainer::computeLogicalHeight(LayoutUnit logicalHeight, Layou
tUnit logicalTop, LogicalExtentComputedValues& computedValues) const |
| 139 { | 139 { |
| 140 HTMLInputElement* input = node()->shadowHost()->toInputElement(); | 140 Handle<HTMLInputElement> input = node()->shadowHost()->toInputElement(); |
| 141 bool isVertical = hasVerticalAppearance(input); | 141 bool isVertical = hasVerticalAppearance(input); |
| 142 | 142 |
| 143 #if ENABLE(DATALIST_ELEMENT) | 143 #if ENABLE(DATALIST_ELEMENT) |
| 144 if (input->renderer()->isSlider() && !isVertical && input->list()) { | 144 if (input->renderer()->isSlider() && !isVertical && input->list()) { |
| 145 int offsetFromCenter = theme()->sliderTickOffsetFromTrackCenter(); | 145 int offsetFromCenter = theme()->sliderTickOffsetFromTrackCenter(); |
| 146 LayoutUnit trackHeight = 0; | 146 LayoutUnit trackHeight = 0; |
| 147 if (offsetFromCenter < 0) | 147 if (offsetFromCenter < 0) |
| 148 trackHeight = -2 * offsetFromCenter; | 148 trackHeight = -2 * offsetFromCenter; |
| 149 else { | 149 else { |
| 150 int tickLength = theme()->sliderTickSize().height(); | 150 int tickLength = theme()->sliderTickSize().height(); |
| 151 trackHeight = 2 * (offsetFromCenter + tickLength); | 151 trackHeight = 2 * (offsetFromCenter + tickLength); |
| 152 } | 152 } |
| 153 float zoomFactor = style()->effectiveZoom(); | 153 float zoomFactor = style()->effectiveZoom(); |
| 154 if (zoomFactor != 1.0) | 154 if (zoomFactor != 1.0) |
| 155 trackHeight *= zoomFactor; | 155 trackHeight *= zoomFactor; |
| 156 | 156 |
| 157 RenderBox::computeLogicalHeight(trackHeight, logicalTop, computedValues)
; | 157 RenderBox::computeLogicalHeight(trackHeight, logicalTop, computedValues)
; |
| 158 return; | 158 return; |
| 159 } | 159 } |
| 160 #endif | 160 #endif |
| 161 if (isVertical) | 161 if (isVertical) |
| 162 logicalHeight = RenderSlider::defaultTrackLength; | 162 logicalHeight = RenderSlider::defaultTrackLength; |
| 163 RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues); | 163 RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues); |
| 164 } | 164 } |
| 165 | 165 |
| 166 void RenderSliderContainer::layout() | 166 void RenderSliderContainer::layout() |
| 167 { | 167 { |
| 168 HTMLInputElement* input = node()->shadowHost()->toInputElement(); | 168 Handle<HTMLInputElement> input = node()->shadowHost()->toInputElement(); |
| 169 bool isVertical = hasVerticalAppearance(input); | 169 bool isVertical = hasVerticalAppearance(input); |
| 170 style()->setFlexDirection(isVertical ? FlowColumn : FlowRow); | 170 style()->setFlexDirection(isVertical ? FlowColumn : FlowRow); |
| 171 TextDirection oldTextDirection = style()->direction(); | 171 TextDirection oldTextDirection = style()->direction(); |
| 172 if (isVertical) { | 172 if (isVertical) { |
| 173 // FIXME: Work around rounding issues in RTL vertical sliders. We want t
hem to | 173 // FIXME: Work around rounding issues in RTL vertical sliders. We want t
hem to |
| 174 // render identically to LTR vertical sliders. We can remove this work a
round when | 174 // render identically to LTR vertical sliders. We can remove this work a
round when |
| 175 // subpixel rendering is enabled on all ports. | 175 // subpixel rendering is enabled on all ports. |
| 176 style()->setDirection(LTR); | 176 style()->setDirection(LTR); |
| 177 } | 177 } |
| 178 | 178 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 return hostInput()->matchesReadOnlyPseudoClass(); | 239 return hostInput()->matchesReadOnlyPseudoClass(); |
| 240 } | 240 } |
| 241 | 241 |
| 242 bool SliderThumbElement::matchesReadWritePseudoClass() const | 242 bool SliderThumbElement::matchesReadWritePseudoClass() const |
| 243 { | 243 { |
| 244 return hostInput()->matchesReadWritePseudoClass(); | 244 return hostInput()->matchesReadWritePseudoClass(); |
| 245 } | 245 } |
| 246 | 246 |
| 247 Node* SliderThumbElement::focusDelegate() | 247 Node* SliderThumbElement::focusDelegate() |
| 248 { | 248 { |
| 249 return hostInput(); | 249 return Handle<HTMLInputElement>(hostInput()).raw(); |
| 250 } | 250 } |
| 251 | 251 |
| 252 void SliderThumbElement::dragFrom(const LayoutPoint& point) | 252 void SliderThumbElement::dragFrom(const LayoutPoint& point) |
| 253 { | 253 { |
| 254 setPositionFromPoint(point); | 254 setPositionFromPoint(point); |
| 255 startDragging(); | 255 startDragging(); |
| 256 } | 256 } |
| 257 | 257 |
| 258 void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point) | 258 void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point) |
| 259 { | 259 { |
| 260 HTMLInputElement* input = hostInput(); | 260 Handle<HTMLInputElement> input = hostInput(); |
| 261 HTMLElement* trackElement = sliderTrackElementOf(input); | 261 HTMLElement* trackElement = sliderTrackElementOf(input.raw()); |
| 262 | 262 |
| 263 if (!input->renderer() || !renderBox() || !trackElement->renderBox()) | 263 if (!input->renderer() || !renderBox() || !trackElement->renderBox()) |
| 264 return; | 264 return; |
| 265 | 265 |
| 266 input->setTextAsOfLastFormControlChangeEvent(input->value()); | 266 input->setTextAsOfLastFormControlChangeEvent(input->value()); |
| 267 LayoutPoint offset = roundedLayoutPoint(input->renderer()->absoluteToLocal(p
oint, UseTransforms)); | 267 LayoutPoint offset = roundedLayoutPoint(input->renderer()->absoluteToLocal(p
oint, UseTransforms)); |
| 268 bool isVertical = hasVerticalAppearance(input); | 268 bool isVertical = hasVerticalAppearance(input); |
| 269 bool isLeftToRightDirection = renderBox()->style()->isLeftToRightDirection()
; | 269 bool isLeftToRightDirection = renderBox()->style()->isLeftToRightDirection()
; |
| 270 LayoutUnit trackSize; | 270 LayoutUnit trackSize; |
| 271 LayoutUnit position; | 271 LayoutUnit position; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 | 340 |
| 341 void SliderThumbElement::defaultEventHandler(Event* event) | 341 void SliderThumbElement::defaultEventHandler(Event* event) |
| 342 { | 342 { |
| 343 if (!event->isMouseEvent()) { | 343 if (!event->isMouseEvent()) { |
| 344 HTMLDivElement::defaultEventHandler(event); | 344 HTMLDivElement::defaultEventHandler(event); |
| 345 return; | 345 return; |
| 346 } | 346 } |
| 347 | 347 |
| 348 // FIXME: Should handle this readonly/disabled check in more general way. | 348 // FIXME: Should handle this readonly/disabled check in more general way. |
| 349 // Missing this kind of check is likely to occur elsewhere if adding it in e
ach shadow element. | 349 // Missing this kind of check is likely to occur elsewhere if adding it in e
ach shadow element. |
| 350 HTMLInputElement* input = hostInput(); | 350 Handle<HTMLInputElement> input = hostInput(); |
| 351 if (!input || input->isDisabledOrReadOnly()) { | 351 if (!input || input->isDisabledOrReadOnly()) { |
| 352 stopDragging(); | 352 stopDragging(); |
| 353 HTMLDivElement::defaultEventHandler(event); | 353 HTMLDivElement::defaultEventHandler(event); |
| 354 return; | 354 return; |
| 355 } | 355 } |
| 356 | 356 |
| 357 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); | 357 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); |
| 358 bool isLeftButton = mouseEvent->button() == LeftButton; | 358 bool isLeftButton = mouseEvent->button() == LeftButton; |
| 359 const AtomicString& eventType = event->type(); | 359 const AtomicString& eventType = event->type(); |
| 360 | 360 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 371 if (m_inDragMode) | 371 if (m_inDragMode) |
| 372 setPositionFromPoint(mouseEvent->absoluteLocation()); | 372 setPositionFromPoint(mouseEvent->absoluteLocation()); |
| 373 return; | 373 return; |
| 374 } | 374 } |
| 375 | 375 |
| 376 HTMLDivElement::defaultEventHandler(event); | 376 HTMLDivElement::defaultEventHandler(event); |
| 377 } | 377 } |
| 378 | 378 |
| 379 bool SliderThumbElement::willRespondToMouseMoveEvents() | 379 bool SliderThumbElement::willRespondToMouseMoveEvents() |
| 380 { | 380 { |
| 381 const HTMLInputElement* input = hostInput(); | 381 Handle<const HTMLInputElement> input = hostInput(); |
| 382 if (input && !input->isDisabledOrReadOnly() && m_inDragMode) | 382 if (input && !input->isDisabledOrReadOnly() && m_inDragMode) |
| 383 return true; | 383 return true; |
| 384 | 384 |
| 385 return HTMLDivElement::willRespondToMouseMoveEvents(); | 385 return HTMLDivElement::willRespondToMouseMoveEvents(); |
| 386 } | 386 } |
| 387 | 387 |
| 388 bool SliderThumbElement::willRespondToMouseClickEvents() | 388 bool SliderThumbElement::willRespondToMouseClickEvents() |
| 389 { | 389 { |
| 390 const HTMLInputElement* input = hostInput(); | 390 Handle<const HTMLInputElement> input = hostInput(); |
| 391 if (input && !input->isDisabledOrReadOnly()) | 391 if (input && !input->isDisabledOrReadOnly()) |
| 392 return true; | 392 return true; |
| 393 | 393 |
| 394 return HTMLDivElement::willRespondToMouseClickEvents(); | 394 return HTMLDivElement::willRespondToMouseClickEvents(); |
| 395 } | 395 } |
| 396 | 396 |
| 397 void SliderThumbElement::detach() | 397 void SliderThumbElement::detach() |
| 398 { | 398 { |
| 399 if (m_inDragMode) { | 399 if (m_inDragMode) { |
| 400 if (Frame* frame = document()->frame()) | 400 if (Frame* frame = document()->frame()) |
| 401 frame->eventHandler()->setCapturingMouseEventsNode(0); | 401 frame->eventHandler()->setCapturingMouseEventsNode(0); |
| 402 } | 402 } |
| 403 HTMLDivElement::detach(); | 403 HTMLDivElement::detach(); |
| 404 } | 404 } |
| 405 | 405 |
| 406 HTMLInputElement* SliderThumbElement::hostInput() const | 406 Result<HTMLInputElement> SliderThumbElement::hostInput() const |
| 407 { | 407 { |
| 408 // Only HTMLInputElement creates SliderThumbElement instances as its shadow
nodes. | 408 // Only HTMLInputElement creates SliderThumbElement instances as its shadow
nodes. |
| 409 // So, shadowHost() must be an HTMLInputElement. | 409 // So, shadowHost() must be an HTMLInputElement. |
| 410 return shadowHost()->toInputElement(); | 410 return shadowHost()->toInputElement(); |
| 411 } | 411 } |
| 412 | 412 |
| 413 static const AtomicString& sliderThumbShadowPseudoId() | 413 static const AtomicString& sliderThumbShadowPseudoId() |
| 414 { | 414 { |
| 415 DEFINE_STATIC_LOCAL(const AtomicString, sliderThumb, ("-webkit-slider-thumb"
, AtomicString::ConstructFromLiteral)); | 415 DEFINE_STATIC_LOCAL(const AtomicString, sliderThumb, ("-webkit-slider-thumb"
, AtomicString::ConstructFromLiteral)); |
| 416 return sliderThumb; | 416 return sliderThumb; |
| 417 } | 417 } |
| 418 | 418 |
| 419 static const AtomicString& mediaSliderThumbShadowPseudoId() | 419 static const AtomicString& mediaSliderThumbShadowPseudoId() |
| 420 { | 420 { |
| 421 DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderThumb, ("-webkit-media-sl
ider-thumb", AtomicString::ConstructFromLiteral)); | 421 DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderThumb, ("-webkit-media-sl
ider-thumb", AtomicString::ConstructFromLiteral)); |
| 422 return mediaSliderThumb; | 422 return mediaSliderThumb; |
| 423 } | 423 } |
| 424 | 424 |
| 425 const AtomicString& SliderThumbElement::shadowPseudoId() const | 425 const AtomicString& SliderThumbElement::shadowPseudoId() const |
| 426 { | 426 { |
| 427 HTMLInputElement* input = hostInput(); | 427 Handle<HTMLInputElement> input = hostInput(); |
| 428 if (!input) | 428 if (!input) |
| 429 return sliderThumbShadowPseudoId(); | 429 return sliderThumbShadowPseudoId(); |
| 430 | 430 |
| 431 RenderStyle* sliderStyle = input->renderer()->style(); | 431 RenderStyle* sliderStyle = input->renderer()->style(); |
| 432 switch (sliderStyle->appearance()) { | 432 switch (sliderStyle->appearance()) { |
| 433 case MediaSliderPart: | 433 case MediaSliderPart: |
| 434 case MediaSliderThumbPart: | 434 case MediaSliderThumbPart: |
| 435 case MediaVolumeSliderPart: | 435 case MediaVolumeSliderPart: |
| 436 case MediaVolumeSliderThumbPart: | 436 case MediaVolumeSliderThumbPart: |
| 437 case MediaFullScreenVolumeSliderPart: | 437 case MediaFullScreenVolumeSliderPart: |
| (...skipping 19 matching lines...) Expand all Loading... |
| 457 RenderObject* SliderContainerElement::createRenderer(RenderArena* arena, RenderS
tyle*) | 457 RenderObject* SliderContainerElement::createRenderer(RenderArena* arena, RenderS
tyle*) |
| 458 { | 458 { |
| 459 return new (arena) RenderSliderContainer(this); | 459 return new (arena) RenderSliderContainer(this); |
| 460 } | 460 } |
| 461 | 461 |
| 462 const AtomicString& SliderContainerElement::shadowPseudoId() const | 462 const AtomicString& SliderContainerElement::shadowPseudoId() const |
| 463 { | 463 { |
| 464 DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-medi
a-slider-container", AtomicString::ConstructFromLiteral)); | 464 DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-medi
a-slider-container", AtomicString::ConstructFromLiteral)); |
| 465 DEFINE_STATIC_LOCAL(const AtomicString, sliderContainer, ("-webkit-slider-co
ntainer", AtomicString::ConstructFromLiteral)); | 465 DEFINE_STATIC_LOCAL(const AtomicString, sliderContainer, ("-webkit-slider-co
ntainer", AtomicString::ConstructFromLiteral)); |
| 466 | 466 |
| 467 HTMLInputElement* input = shadowHost()->toInputElement(); | 467 Handle<HTMLInputElement> input = shadowHost()->toInputElement(); |
| 468 if (!input) | 468 if (!input) |
| 469 return sliderContainer; | 469 return sliderContainer; |
| 470 | 470 |
| 471 RenderStyle* sliderStyle = input->renderer()->style(); | 471 RenderStyle* sliderStyle = input->renderer()->style(); |
| 472 switch (sliderStyle->appearance()) { | 472 switch (sliderStyle->appearance()) { |
| 473 case MediaSliderPart: | 473 case MediaSliderPart: |
| 474 case MediaSliderThumbPart: | 474 case MediaSliderThumbPart: |
| 475 case MediaVolumeSliderPart: | 475 case MediaVolumeSliderPart: |
| 476 case MediaVolumeSliderThumbPart: | 476 case MediaVolumeSliderThumbPart: |
| 477 case MediaFullScreenVolumeSliderPart: | 477 case MediaFullScreenVolumeSliderPart: |
| 478 case MediaFullScreenVolumeSliderThumbPart: | 478 case MediaFullScreenVolumeSliderThumbPart: |
| 479 return mediaSliderContainer; | 479 return mediaSliderContainer; |
| 480 default: | 480 default: |
| 481 return sliderContainer; | 481 return sliderContainer; |
| 482 } | 482 } |
| 483 } | 483 } |
| 484 | 484 |
| 485 } | 485 } |
| OLD | NEW |