15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2011 Apple Inc. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 3306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/html/forms/RangeInputType.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionStatePlaceholder.h" 365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h" 375d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/InputTypeNames.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/accessibility/AXObjectCache.h" 3906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/KeyboardEvent.h" 4006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/MouseEvent.h" 4106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/ScopedEventQueue.h" 4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Touch.h" 4306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/TouchEvent.h" 4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/TouchList.h" 45e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/ShadowRoot.h" 4693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "core/html/HTMLDataListElement.h" 479e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)#include "core/html/HTMLDataListOptionsCollection.h" 4853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLDivElement.h" 4953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLInputElement.h" 5093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "core/html/HTMLOptionElement.h" 5106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/html/forms/StepRange.h" 5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/parser/HTMLParserIdioms.h" 53e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/html/shadow/ShadowElementNames.h" 5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/shadow/SliderThumbElement.h" 5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderSlider.h" 561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/PlatformMouseEvent.h" 5793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/MathExtras.h" 5893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/NonCopyingSort.h" 5993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/PassOwnPtr.h" 6006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include <limits> 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames; 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const int rangeDefaultMinimum = 0; 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const int rangeDefaultMaximum = 100; 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const int rangeDefaultStep = 1; 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const int rangeDefaultStepBase = 0; 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const int rangeStepScaleFactor = 1; 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static Decimal ensureMaximum(const Decimal& proposedValue, const Decimal& minimum, const Decimal& fallbackValue) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return proposedValue >= minimum ? proposedValue : std::max(minimum, fallbackValue); 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 77323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)PassRefPtrWillBeRawPtr<InputType> RangeInputType::create(HTMLInputElement& element) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 79323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) return adoptRefWillBeNoop(new RangeInputType(element)); 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 82bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)RangeInputType::RangeInputType(HTMLInputElement& element) 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : InputType(element) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_tickMarkValuesDirty(true) 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 88e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)void RangeInputType::countUsage() 89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 90f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) countUsageIfVisible(UseCounter::InputTypeRange); 91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const AtomicString& RangeInputType::formControlType() const 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 9551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) return InputTypeNames::range; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double RangeInputType::valueAsDouble() const 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 100bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return parseToDoubleForNumberType(element().value()); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void RangeInputType::setValueAsDouble(double newValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) setValueAsDecimal(Decimal::fromDouble(newValue), eventBehavior, exceptionState); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RangeInputType::typeMismatchFor(const String& value) const 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return !value.isEmpty() && !std::isfinite(parseToDoubleForNumberType(value)); 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RangeInputType::supportsRequired() const 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)StepRange RangeInputType::createStepRange(AnyStepHandling anyStepHandling) const 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (rangeDefaultStep, rangeDefaultStepBase, rangeStepScaleFactor)); 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) const Decimal stepBase = findStepBase(rangeDefaultStepBase); 123bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) const Decimal minimum = parseToNumber(element().fastGetAttribute(minAttr), rangeDefaultMinimum); 124bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) const Decimal maximum = ensureMaximum(parseToNumber(element().fastGetAttribute(maxAttr), rangeDefaultMaximum), minimum, rangeDefaultMaximum); 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 126bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) const Decimal step = StepRange::parseStep(anyStepHandling, stepDescription, element().fastGetAttribute(stepAttr)); 12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return StepRange(stepBase, minimum, maximum, step, stepDescription); 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RangeInputType::isSteppable() const 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RangeInputType::handleMouseDownEvent(MouseEvent* event) 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 137bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (element().isDisabledOrReadOnly()) 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Node* targetNode = event->target()->toNode(); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (event->button() != LeftButton || !targetNode) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 143bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ASSERT(element().shadow()); 144bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (targetNode != element() && !targetNode->isDescendantOf(element().userAgentShadowRoot())) 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 146e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) SliderThumbElement* thumb = sliderThumbElement(); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (targetNode == thumb) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) thumb->dragFrom(event->absoluteLocation()); 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RangeInputType::handleTouchEvent(TouchEvent* event) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 154bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (element().isDisabledOrReadOnly()) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (event->type() == EventTypeNames::touchend) { 1586f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch element().dispatchFormControlChangeEvent(); 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) event->setDefaultHandled(); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TouchList* touches = event->targetTouches(); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (touches->length() == 1) { 165e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) sliderThumbElement()->setPositionFromPoint(touches->item(0)->absoluteLocation()); 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) event->setDefaultHandled(); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RangeInputType::hasTouchEventHandler() const 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RangeInputType::handleKeydownEvent(KeyboardEvent* event) 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 177bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (element().isDisabledOrReadOnly()) 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const String& key = event->keyIdentifier(); 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 182bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) const Decimal current = parseToNumberOrNaN(element().value()); 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(current.isFinite()); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StepRange stepRange(createStepRange(RejectAny)); 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: We can't use stepUp() for the step value "any". So, we increase 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // or decrease the value by 1/100 of the value range. Is it reasonable? 190bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) const Decimal step = equalIgnoringCase(element().fastGetAttribute(stepAttr), "any") ? (stepRange.maximum() - stepRange.minimum()) / 100 : stepRange.step(); 1915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) const Decimal bigStep = std::max((stepRange.maximum() - stepRange.minimum()) / 10, step); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isVertical = false; 194bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (element().renderer()) { 195bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ControlPart part = element().renderer()->style()->appearance(); 196d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) isVertical = part == SliderVerticalPart; 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Decimal newValue; 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (key == "Up") 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newValue = current + step; 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (key == "Down") 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newValue = current - step; 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (key == "Left") 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newValue = isVertical ? current + step : current - step; 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (key == "Right") 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newValue = isVertical ? current - step : current + step; 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (key == "PageUp") 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newValue = current + bigStep; 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (key == "PageDown") 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newValue = current - bigStep; 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (key == "Home") 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newValue = isVertical ? stepRange.maximum() : stepRange.minimum(); 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (key == "End") 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newValue = isVertical ? stepRange.minimum() : stepRange.maximum(); 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; // Did not match any key binding. 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newValue = stepRange.clampValue(newValue); 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (newValue != current) { 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EventQueueScope scope; 223d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) TextFieldEventBehavior eventBehavior = DispatchInputAndChangeEvent; 2241fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch setValueAsDecimal(newValue, eventBehavior, IGNORE_EXCEPTION); 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 226bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (AXObjectCache* cache = element().document().existingAXObjectCache()) 227bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) cache->postNotification(&element(), AXObjectCache::AXValueChanged, true); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) event->setDefaultHandled(); 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RangeInputType::createShadowSubtree() 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 235bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ASSERT(element().shadow()); 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 237bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) Document& document = element().document(); 238d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBeRawPtr<HTMLDivElement> track = HTMLDivElement::create(document); 23909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) track->setShadowPseudoId(AtomicString("-webkit-slider-runnable-track", AtomicString::ConstructFromLiteral)); 240e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) track->setAttribute(idAttr, ShadowElementNames::sliderTrack()); 241e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) track->appendChild(SliderThumbElement::create(document)); 242323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) RefPtrWillBeRawPtr<HTMLElement> container = SliderContainerElement::create(document); 243e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) container->appendChild(track.release()); 244bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) element().userAgentShadowRoot()->appendChild(container.release()); 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 247591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochRenderObject* RangeInputType::createRenderer(RenderStyle*) const 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 249bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return new RenderSlider(&element()); 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Decimal RangeInputType::parseToNumber(const String& src, const Decimal& defaultValue) const 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return parseToDecimalForNumberType(src, defaultValue); 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RangeInputType::serialize(const Decimal& value) const 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!value.isFinite()) 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return String(); 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return serializeForNumberType(value); 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: Could share this with BaseClickableWithKeyInputType and BaseCheckableInputType if we had a common base class. 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RangeInputType::accessKeyAction(bool sendMouseEvents) 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InputType::accessKeyAction(sendMouseEvents); 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 269bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) element().dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 272e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)void RangeInputType::sanitizeValueInResponseToMinOrMaxAttributeChange() 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 274bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (element().hasDirtyValue()) 275bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) element().setValue(element().value()); 276521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 277e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) sliderThumbElement()->setPositionFromValue(); 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RangeInputType::setValue(const String& value, bool valueChanged, TextFieldEventBehavior eventBehavior) 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InputType::setValue(value, valueChanged, eventBehavior); 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!valueChanged) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 287e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) sliderThumbElement()->setPositionFromValue(); 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RangeInputType::fallbackValue() const 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return serializeForNumberType(createStepRange(RejectAny).defaultValue()); 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String RangeInputType::sanitizeValue(const String& proposedValue) const 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StepRange stepRange(createStepRange(RejectAny)); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Decimal proposedNumericValue = parseToNumber(proposedValue, stepRange.defaultValue()); 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return serializeForNumberType(stepRange.clampValue(proposedNumericValue)); 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 302a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void RangeInputType::disabledAttributeChanged() 303a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){ 304a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (element().isDisabledFormControl()) 305a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) sliderThumbElement()->stopDragging(); 306a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)} 307a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RangeInputType::shouldRespectListAttribute() 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 310d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return true; 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 313e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)inline SliderThumbElement* RangeInputType::sliderThumbElement() const 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 315bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return toSliderThumbElement(element().userAgentShadowRoot()->getElementById(ShadowElementNames::sliderThumb())); 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 318e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)inline Element* RangeInputType::sliderTrackElement() const 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 320bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return element().userAgentShadowRoot()->getElementById(ShadowElementNames::sliderTrack()); 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RangeInputType::listAttributeTargetChanged() 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_tickMarkValuesDirty = true; 326e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) Element* sliderTrackElement = this->sliderTrackElement(); 327926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (sliderTrackElement->renderer()) 3285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) sliderTrackElement->renderer()->setNeedsLayoutAndFullPaintInvalidation(); 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static bool decimalCompare(const Decimal& a, const Decimal& b) 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return a < b; 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RangeInputType::updateTickMarkValues() 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_tickMarkValuesDirty) 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_tickMarkValues.clear(); 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_tickMarkValuesDirty = false; 342bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) HTMLDataListElement* dataList = element().dataList(); 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!dataList) 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3459e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) RefPtrWillBeRawPtr<HTMLDataListOptionsCollection> options = dataList->options(); 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_tickMarkValues.reserveCapacity(options->length()); 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < options->length(); ++i) { 3489e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) HTMLOptionElement* optionElement = options->item(i); 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) String optionValue = optionElement->value(); 35009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (!this->element().isValidValue(optionValue)) 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_tickMarkValues.append(parseToNumber(optionValue, Decimal::nan())); 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_tickMarkValues.shrinkToFit(); 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) nonCopyingSort(m_tickMarkValues.begin(), m_tickMarkValues.end(), decimalCompare); 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Decimal RangeInputType::findClosestTickMarkValue(const Decimal& value) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateTickMarkValues(); 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_tickMarkValues.size()) 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Decimal::nan(); 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t left = 0; 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t right = m_tickMarkValues.size(); 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t middle; 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (true) { 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(left <= right); 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) middle = left + (right - left) / 2; 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!middle) 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (middle == m_tickMarkValues.size() - 1 && m_tickMarkValues[middle] < value) { 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) middle++; 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_tickMarkValues[middle - 1] <= value && m_tickMarkValues[middle] >= value) 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_tickMarkValues[middle] < value) 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) left = middle; 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) right = middle; 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Decimal closestLeft = middle ? m_tickMarkValues[middle - 1] : Decimal::infinity(Decimal::Negative); 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Decimal closestRight = middle != m_tickMarkValues.size() ? m_tickMarkValues[middle] : Decimal::infinity(Decimal::Positive); 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (closestRight - value < value - closestLeft) 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return closestRight; 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return closestLeft; 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 391c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 392