OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. |
6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
7 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) | 7 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) |
8 * Copyright (C) 2009, 2010, 2011, 2012 Google Inc. All rights reserved. | 8 * Copyright (C) 2009, 2010, 2011, 2012 Google Inc. All rights reserved. |
9 * Copyright (C) 2012 Samsung Electronics. All rights reserved. | 9 * Copyright (C) 2012 Samsung Electronics. All rights reserved. |
10 * | 10 * |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 #include "core/rendering/RenderTheme.h" | 67 #include "core/rendering/RenderTheme.h" |
68 #include "platform/text/PlatformLocale.h" | 68 #include "platform/text/PlatformLocale.h" |
69 #include "platform/text/TextBreakIterator.h" | 69 #include "platform/text/TextBreakIterator.h" |
70 | 70 |
71 namespace WebCore { | 71 namespace WebCore { |
72 | 72 |
73 using WebKit::WebLocalizedString; | 73 using WebKit::WebLocalizedString; |
74 using namespace HTMLNames; | 74 using namespace HTMLNames; |
75 using namespace std; | 75 using namespace std; |
76 | 76 |
77 typedef PassRefPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement*); | 77 typedef PassRefPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement&); |
78 typedef HashMap<AtomicString, InputTypeFactoryFunction, CaseFoldingHash> InputTy
peFactoryMap; | 78 typedef HashMap<AtomicString, InputTypeFactoryFunction, CaseFoldingHash> InputTy
peFactoryMap; |
79 | 79 |
80 static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap() | 80 static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap() |
81 { | 81 { |
82 OwnPtr<InputTypeFactoryMap> map = adoptPtr(new InputTypeFactoryMap); | 82 OwnPtr<InputTypeFactoryMap> map = adoptPtr(new InputTypeFactoryMap); |
83 map->add(InputTypeNames::button(), ButtonInputType::create); | 83 map->add(InputTypeNames::button(), ButtonInputType::create); |
84 map->add(InputTypeNames::checkbox(), CheckboxInputType::create); | 84 map->add(InputTypeNames::checkbox(), CheckboxInputType::create); |
85 if (RuntimeEnabledFeatures::inputTypeColorEnabled()) | 85 if (RuntimeEnabledFeatures::inputTypeColorEnabled()) |
86 map->add(InputTypeNames::color(), ColorInputType::create); | 86 map->add(InputTypeNames::color(), ColorInputType::create); |
87 map->add(InputTypeNames::date(), DateInputType::create); | 87 map->add(InputTypeNames::date(), DateInputType::create); |
(...skipping 18 matching lines...) Expand all Loading... |
106 // No need to register "text" because it is the default type. | 106 // No need to register "text" because it is the default type. |
107 return map.release(); | 107 return map.release(); |
108 } | 108 } |
109 | 109 |
110 static const InputTypeFactoryMap* factoryMap() | 110 static const InputTypeFactoryMap* factoryMap() |
111 { | 111 { |
112 static const InputTypeFactoryMap* factoryMap = createInputTypeFactoryMap().l
eakPtr(); | 112 static const InputTypeFactoryMap* factoryMap = createInputTypeFactoryMap().l
eakPtr(); |
113 return factoryMap; | 113 return factoryMap; |
114 } | 114 } |
115 | 115 |
116 PassRefPtr<InputType> InputType::create(HTMLInputElement* element, const AtomicS
tring& typeName) | 116 PassRefPtr<InputType> InputType::create(HTMLInputElement& element, const AtomicS
tring& typeName) |
117 { | 117 { |
118 InputTypeFactoryFunction factory = typeName.isEmpty() ? 0 : factoryMap()->ge
t(typeName); | 118 InputTypeFactoryFunction factory = typeName.isEmpty() ? 0 : factoryMap()->ge
t(typeName); |
119 if (!factory) | 119 if (!factory) |
120 factory = TextInputType::create; | 120 factory = TextInputType::create; |
121 return factory(element); | 121 return factory(element); |
122 } | 122 } |
123 | 123 |
124 PassRefPtr<InputType> InputType::createText(HTMLInputElement* element) | 124 PassRefPtr<InputType> InputType::createText(HTMLInputElement& element) |
125 { | 125 { |
126 return TextInputType::create(element); | 126 return TextInputType::create(element); |
127 } | 127 } |
128 | 128 |
129 const AtomicString& InputType::normalizeTypeName(const AtomicString& typeName) | 129 const AtomicString& InputType::normalizeTypeName(const AtomicString& typeName) |
130 { | 130 { |
131 if (typeName.isEmpty()) | 131 if (typeName.isEmpty()) |
132 return InputTypeNames::text(); | 132 return InputTypeNames::text(); |
133 InputTypeFactoryMap::const_iterator it = factoryMap()->find(typeName); | 133 InputTypeFactoryMap::const_iterator it = factoryMap()->find(typeName); |
134 return it == factoryMap()->end() ? InputTypeNames::text() : it->key; | 134 return it == factoryMap()->end() ? InputTypeNames::text() : it->key; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 return false; | 168 return false; |
169 } | 169 } |
170 | 170 |
171 bool InputType::shouldSaveAndRestoreFormControlState() const | 171 bool InputType::shouldSaveAndRestoreFormControlState() const |
172 { | 172 { |
173 return true; | 173 return true; |
174 } | 174 } |
175 | 175 |
176 FormControlState InputType::saveFormControlState() const | 176 FormControlState InputType::saveFormControlState() const |
177 { | 177 { |
178 String currentValue = element()->value(); | 178 String currentValue = element().value(); |
179 if (currentValue == element()->defaultValue()) | 179 if (currentValue == element().defaultValue()) |
180 return FormControlState(); | 180 return FormControlState(); |
181 return FormControlState(currentValue); | 181 return FormControlState(currentValue); |
182 } | 182 } |
183 | 183 |
184 void InputType::restoreFormControlState(const FormControlState& state) | 184 void InputType::restoreFormControlState(const FormControlState& state) |
185 { | 185 { |
186 element()->setValue(state[0]); | 186 element().setValue(state[0]); |
187 } | 187 } |
188 | 188 |
189 bool InputType::isFormDataAppendable() const | 189 bool InputType::isFormDataAppendable() const |
190 { | 190 { |
191 // There is no form data unless there's a name for non-image types. | 191 // There is no form data unless there's a name for non-image types. |
192 return !element()->name().isEmpty(); | 192 return !element().name().isEmpty(); |
193 } | 193 } |
194 | 194 |
195 bool InputType::appendFormData(FormDataList& encoding, bool) const | 195 bool InputType::appendFormData(FormDataList& encoding, bool) const |
196 { | 196 { |
197 // Always successful. | 197 // Always successful. |
198 encoding.appendData(element()->name(), element()->value()); | 198 encoding.appendData(element().name(), element().value()); |
199 return true; | 199 return true; |
200 } | 200 } |
201 | 201 |
202 double InputType::valueAsDate() const | 202 double InputType::valueAsDate() const |
203 { | 203 { |
204 return DateComponents::invalidMilliseconds(); | 204 return DateComponents::invalidMilliseconds(); |
205 } | 205 } |
206 | 206 |
207 void InputType::setValueAsDate(double, ExceptionState& es) const | 207 void InputType::setValueAsDate(double, ExceptionState& es) const |
208 { | 208 { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 return locale().queryString(WebLocalizedString::ValidationTypeMismatch); | 360 return locale().queryString(WebLocalizedString::ValidationTypeMismatch); |
361 } | 361 } |
362 | 362 |
363 String InputType::valueMissingText() const | 363 String InputType::valueMissingText() const |
364 { | 364 { |
365 return locale().queryString(WebLocalizedString::ValidationValueMissing); | 365 return locale().queryString(WebLocalizedString::ValidationValueMissing); |
366 } | 366 } |
367 | 367 |
368 String InputType::validationMessage() const | 368 String InputType::validationMessage() const |
369 { | 369 { |
370 const String value = element()->value(); | 370 const String value = element().value(); |
371 | 371 |
372 // The order of the following checks is meaningful. e.g. We'd like to show t
he | 372 // The order of the following checks is meaningful. e.g. We'd like to show t
he |
373 // badInput message even if the control has other validation errors. | 373 // badInput message even if the control has other validation errors. |
374 if (hasBadInput()) | 374 if (hasBadInput()) |
375 return badInputText(); | 375 return badInputText(); |
376 | 376 |
377 if (valueMissing(value)) | 377 if (valueMissing(value)) |
378 return valueMissingText(); | 378 return valueMissingText(); |
379 | 379 |
380 if (typeMismatch()) | 380 if (typeMismatch()) |
381 return typeMismatchText(); | 381 return typeMismatchText(); |
382 | 382 |
383 if (patternMismatch(value)) | 383 if (patternMismatch(value)) |
384 return locale().queryString(WebLocalizedString::ValidationPatternMismatc
h); | 384 return locale().queryString(WebLocalizedString::ValidationPatternMismatc
h); |
385 | 385 |
386 if (element()->tooLong()) | 386 if (element().tooLong()) |
387 return locale().validationMessageTooLongText(value.length(), element()->
maxLength()); | 387 return locale().validationMessageTooLongText(value.length(), element().m
axLength()); |
388 | 388 |
389 if (!isSteppable()) | 389 if (!isSteppable()) |
390 return emptyString(); | 390 return emptyString(); |
391 | 391 |
392 const Decimal numericValue = parseToNumberOrNaN(value); | 392 const Decimal numericValue = parseToNumberOrNaN(value); |
393 if (!numericValue.isFinite()) | 393 if (!numericValue.isFinite()) |
394 return emptyString(); | 394 return emptyString(); |
395 | 395 |
396 StepRange stepRange(createStepRange(RejectAny)); | 396 StepRange stepRange(createStepRange(RejectAny)); |
397 | 397 |
(...skipping 23 matching lines...) Expand all Loading... |
421 { | 421 { |
422 return event->isKeyboardEvent() && event->type() == EventTypeNames::keypress
&& toKeyboardEvent(event)->charCode() == '\r'; | 422 return event->isKeyboardEvent() && event->type() == EventTypeNames::keypress
&& toKeyboardEvent(event)->charCode() == '\r'; |
423 } | 423 } |
424 | 424 |
425 void InputType::createShadowSubtree() | 425 void InputType::createShadowSubtree() |
426 { | 426 { |
427 } | 427 } |
428 | 428 |
429 void InputType::destroyShadowSubtree() | 429 void InputType::destroyShadowSubtree() |
430 { | 430 { |
431 if (ShadowRoot* root = element()->userAgentShadowRoot()) | 431 if (ShadowRoot* root = element().userAgentShadowRoot()) |
432 root->removeChildren(); | 432 root->removeChildren(); |
433 } | 433 } |
434 | 434 |
435 Decimal InputType::parseToNumber(const String&, const Decimal& defaultValue) con
st | 435 Decimal InputType::parseToNumber(const String&, const Decimal& defaultValue) con
st |
436 { | 436 { |
437 ASSERT_NOT_REACHED(); | 437 ASSERT_NOT_REACHED(); |
438 return defaultValue; | 438 return defaultValue; |
439 } | 439 } |
440 | 440 |
441 Decimal InputType::parseToNumberOrNaN(const String& string) const | 441 Decimal InputType::parseToNumberOrNaN(const String& string) const |
442 { | 442 { |
443 return parseToNumber(string, Decimal::nan()); | 443 return parseToNumber(string, Decimal::nan()); |
444 } | 444 } |
445 | 445 |
446 bool InputType::parseToDateComponents(const String&, DateComponents*) const | 446 bool InputType::parseToDateComponents(const String&, DateComponents*) const |
447 { | 447 { |
448 ASSERT_NOT_REACHED(); | 448 ASSERT_NOT_REACHED(); |
449 return false; | 449 return false; |
450 } | 450 } |
451 | 451 |
452 String InputType::serialize(const Decimal&) const | 452 String InputType::serialize(const Decimal&) const |
453 { | 453 { |
454 ASSERT_NOT_REACHED(); | 454 ASSERT_NOT_REACHED(); |
455 return String(); | 455 return String(); |
456 } | 456 } |
457 | 457 |
458 void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const | 458 void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const |
459 { | 459 { |
460 if (element()->active()) | 460 if (element().active()) |
461 element()->dispatchSimulatedClick(event); | 461 element().dispatchSimulatedClick(event); |
462 event->setDefaultHandled(); | 462 event->setDefaultHandled(); |
463 } | 463 } |
464 | 464 |
465 Chrome* InputType::chrome() const | 465 Chrome* InputType::chrome() const |
466 { | 466 { |
467 if (Page* page = element()->document().page()) | 467 if (Page* page = element().document().page()) |
468 return &page->chrome(); | 468 return &page->chrome(); |
469 return 0; | 469 return 0; |
470 } | 470 } |
471 | 471 |
472 Locale& InputType::locale() const | 472 Locale& InputType::locale() const |
473 { | 473 { |
474 return element()->locale(); | 474 return element().locale(); |
475 } | 475 } |
476 | 476 |
477 bool InputType::canSetStringValue() const | 477 bool InputType::canSetStringValue() const |
478 { | 478 { |
479 return true; | 479 return true; |
480 } | 480 } |
481 | 481 |
482 bool InputType::hasCustomFocusLogic() const | 482 bool InputType::hasCustomFocusLogic() const |
483 { | 483 { |
484 return true; | 484 return true; |
485 } | 485 } |
486 | 486 |
487 bool InputType::isKeyboardFocusable() const | 487 bool InputType::isKeyboardFocusable() const |
488 { | 488 { |
489 return element()->isFocusable(); | 489 return element().isFocusable(); |
490 } | 490 } |
491 | 491 |
492 bool InputType::shouldShowFocusRingOnMouseFocus() const | 492 bool InputType::shouldShowFocusRingOnMouseFocus() const |
493 { | 493 { |
494 return false; | 494 return false; |
495 } | 495 } |
496 | 496 |
497 bool InputType::shouldUseInputMethod() const | 497 bool InputType::shouldUseInputMethod() const |
498 { | 498 { |
499 return false; | 499 return false; |
500 } | 500 } |
501 | 501 |
502 void InputType::enableSecureTextInput() | 502 void InputType::enableSecureTextInput() |
503 { | 503 { |
504 } | 504 } |
505 | 505 |
506 void InputType::disableSecureTextInput() | 506 void InputType::disableSecureTextInput() |
507 { | 507 { |
508 } | 508 } |
509 | 509 |
510 void InputType::accessKeyAction(bool) | 510 void InputType::accessKeyAction(bool) |
511 { | 511 { |
512 element()->focus(false); | 512 element().focus(false); |
513 } | 513 } |
514 | 514 |
515 void InputType::detach() | 515 void InputType::detach() |
516 { | 516 { |
517 } | 517 } |
518 | 518 |
519 void InputType::countUsage() | 519 void InputType::countUsage() |
520 { | 520 { |
521 } | 521 } |
522 | 522 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 return true; | 573 return true; |
574 } | 574 } |
575 | 575 |
576 bool InputType::storesValueSeparateFromAttribute() | 576 bool InputType::storesValueSeparateFromAttribute() |
577 { | 577 { |
578 return true; | 578 return true; |
579 } | 579 } |
580 | 580 |
581 void InputType::setValue(const String& sanitizedValue, bool valueChanged, TextFi
eldEventBehavior eventBehavior) | 581 void InputType::setValue(const String& sanitizedValue, bool valueChanged, TextFi
eldEventBehavior eventBehavior) |
582 { | 582 { |
583 element()->setValueInternal(sanitizedValue, eventBehavior); | 583 element().setValueInternal(sanitizedValue, eventBehavior); |
584 element()->setNeedsStyleRecalc(); | 584 element().setNeedsStyleRecalc(); |
585 if (!valueChanged) | 585 if (!valueChanged) |
586 return; | 586 return; |
587 switch (eventBehavior) { | 587 switch (eventBehavior) { |
588 case DispatchChangeEvent: | 588 case DispatchChangeEvent: |
589 element()->dispatchFormControlChangeEvent(); | 589 element().dispatchFormControlChangeEvent(); |
590 break; | 590 break; |
591 case DispatchInputAndChangeEvent: | 591 case DispatchInputAndChangeEvent: |
592 element()->dispatchFormControlInputEvent(); | 592 element().dispatchFormControlInputEvent(); |
593 element()->dispatchFormControlChangeEvent(); | 593 element().dispatchFormControlChangeEvent(); |
594 break; | 594 break; |
595 case DispatchNoEvent: | 595 case DispatchNoEvent: |
596 break; | 596 break; |
597 } | 597 } |
598 } | 598 } |
599 | 599 |
600 bool InputType::canSetValue(const String&) | 600 bool InputType::canSetValue(const String&) |
601 { | 601 { |
602 return true; | 602 return true; |
603 } | 603 } |
604 | 604 |
605 String InputType::localizeValue(const String& proposedValue) const | 605 String InputType::localizeValue(const String& proposedValue) const |
606 { | 606 { |
607 return proposedValue; | 607 return proposedValue; |
608 } | 608 } |
609 | 609 |
610 String InputType::visibleValue() const | 610 String InputType::visibleValue() const |
611 { | 611 { |
612 return element()->value(); | 612 return element().value(); |
613 } | 613 } |
614 | 614 |
615 String InputType::sanitizeValue(const String& proposedValue) const | 615 String InputType::sanitizeValue(const String& proposedValue) const |
616 { | 616 { |
617 return proposedValue; | 617 return proposedValue; |
618 } | 618 } |
619 | 619 |
620 bool InputType::receiveDroppedFiles(const DragData*) | 620 bool InputType::receiveDroppedFiles(const DragData*) |
621 { | 621 { |
622 ASSERT_NOT_REACHED(); | 622 ASSERT_NOT_REACHED(); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 } | 819 } |
820 | 820 |
821 void InputType::applyStep(int count, AnyStepHandling anyStepHandling, TextFieldE
ventBehavior eventBehavior, ExceptionState& es) | 821 void InputType::applyStep(int count, AnyStepHandling anyStepHandling, TextFieldE
ventBehavior eventBehavior, ExceptionState& es) |
822 { | 822 { |
823 StepRange stepRange(createStepRange(anyStepHandling)); | 823 StepRange stepRange(createStepRange(anyStepHandling)); |
824 if (!stepRange.hasStep()) { | 824 if (!stepRange.hasStep()) { |
825 es.throwUninformativeAndGenericDOMException(InvalidStateError); | 825 es.throwUninformativeAndGenericDOMException(InvalidStateError); |
826 return; | 826 return; |
827 } | 827 } |
828 | 828 |
829 const Decimal current = parseToNumberOrNaN(element()->value()); | 829 const Decimal current = parseToNumberOrNaN(element().value()); |
830 if (!current.isFinite()) { | 830 if (!current.isFinite()) { |
831 es.throwUninformativeAndGenericDOMException(InvalidStateError); | 831 es.throwUninformativeAndGenericDOMException(InvalidStateError); |
832 return; | 832 return; |
833 } | 833 } |
834 Decimal newValue = current + stepRange.step() * count; | 834 Decimal newValue = current + stepRange.step() * count; |
835 if (!newValue.isFinite()) { | 835 if (!newValue.isFinite()) { |
836 es.throwUninformativeAndGenericDOMException(InvalidStateError); | 836 es.throwUninformativeAndGenericDOMException(InvalidStateError); |
837 return; | 837 return; |
838 } | 838 } |
839 | 839 |
840 const Decimal acceptableErrorValue = stepRange.acceptableError(); | 840 const Decimal acceptableErrorValue = stepRange.acceptableError(); |
841 if (newValue - stepRange.minimum() < -acceptableErrorValue) { | 841 if (newValue - stepRange.minimum() < -acceptableErrorValue) { |
842 es.throwUninformativeAndGenericDOMException(InvalidStateError); | 842 es.throwUninformativeAndGenericDOMException(InvalidStateError); |
843 return; | 843 return; |
844 } | 844 } |
845 if (newValue < stepRange.minimum()) | 845 if (newValue < stepRange.minimum()) |
846 newValue = stepRange.minimum(); | 846 newValue = stepRange.minimum(); |
847 | 847 |
848 const AtomicString& stepString = element()->fastGetAttribute(stepAttr); | 848 const AtomicString& stepString = element().fastGetAttribute(stepAttr); |
849 if (!equalIgnoringCase(stepString, "any")) | 849 if (!equalIgnoringCase(stepString, "any")) |
850 newValue = stepRange.alignValueForStep(current, newValue); | 850 newValue = stepRange.alignValueForStep(current, newValue); |
851 | 851 |
852 if (newValue - stepRange.maximum() > acceptableErrorValue) { | 852 if (newValue - stepRange.maximum() > acceptableErrorValue) { |
853 es.throwUninformativeAndGenericDOMException(InvalidStateError); | 853 es.throwUninformativeAndGenericDOMException(InvalidStateError); |
854 return; | 854 return; |
855 } | 855 } |
856 if (newValue > stepRange.maximum()) | 856 if (newValue > stepRange.maximum()) |
857 newValue = stepRange.maximum(); | 857 newValue = stepRange.maximum(); |
858 | 858 |
859 setValueAsDecimal(newValue, eventBehavior, es); | 859 setValueAsDecimal(newValue, eventBehavior, es); |
860 | 860 |
861 if (AXObjectCache* cache = element()->document().existingAXObjectCache()) | 861 if (AXObjectCache* cache = element().document().existingAXObjectCache()) |
862 cache->postNotification(element(), AXObjectCache::AXValueChanged, true); | 862 cache->postNotification(&element(), AXObjectCache::AXValueChanged, true)
; |
863 } | 863 } |
864 | 864 |
865 bool InputType::getAllowedValueStep(Decimal* step) const | 865 bool InputType::getAllowedValueStep(Decimal* step) const |
866 { | 866 { |
867 StepRange stepRange(createStepRange(RejectAny)); | 867 StepRange stepRange(createStepRange(RejectAny)); |
868 *step = stepRange.step(); | 868 *step = stepRange.step(); |
869 return stepRange.hasStep(); | 869 return stepRange.hasStep(); |
870 } | 870 } |
871 | 871 |
872 StepRange InputType::createStepRange(AnyStepHandling) const | 872 StepRange InputType::createStepRange(AnyStepHandling) const |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
939 const Decimal step = stepRange.step(); | 939 const Decimal step = stepRange.step(); |
940 | 940 |
941 int sign; | 941 int sign; |
942 if (step > 0) | 942 if (step > 0) |
943 sign = n; | 943 sign = n; |
944 else if (step < 0) | 944 else if (step < 0) |
945 sign = -n; | 945 sign = -n; |
946 else | 946 else |
947 sign = 0; | 947 sign = 0; |
948 | 948 |
949 String currentStringValue = element()->value(); | 949 String currentStringValue = element().value(); |
950 Decimal current = parseToNumberOrNaN(currentStringValue); | 950 Decimal current = parseToNumberOrNaN(currentStringValue); |
951 if (!current.isFinite()) { | 951 if (!current.isFinite()) { |
952 current = defaultValueForStepUp(); | 952 current = defaultValueForStepUp(); |
953 const Decimal nextDiff = step * n; | 953 const Decimal nextDiff = step * n; |
954 if (current < stepRange.minimum() - nextDiff) | 954 if (current < stepRange.minimum() - nextDiff) |
955 current = stepRange.minimum() - nextDiff; | 955 current = stepRange.minimum() - nextDiff; |
956 if (current > stepRange.maximum() - nextDiff) | 956 if (current > stepRange.maximum() - nextDiff) |
957 current = stepRange.maximum() - nextDiff; | 957 current = stepRange.maximum() - nextDiff; |
958 setValueAsDecimal(current, DispatchNoEvent, IGNORE_EXCEPTION); | 958 setValueAsDecimal(current, DispatchNoEvent, IGNORE_EXCEPTION); |
959 } | 959 } |
960 if ((sign > 0 && current < stepRange.minimum()) || (sign < 0 && current > st
epRange.maximum())) { | 960 if ((sign > 0 && current < stepRange.minimum()) || (sign < 0 && current > st
epRange.maximum())) { |
961 setValueAsDecimal(sign > 0 ? stepRange.minimum() : stepRange.maximum(),
DispatchInputAndChangeEvent, IGNORE_EXCEPTION); | 961 setValueAsDecimal(sign > 0 ? stepRange.minimum() : stepRange.maximum(),
DispatchInputAndChangeEvent, IGNORE_EXCEPTION); |
962 } else { | 962 } else { |
963 if (stepMismatch(element()->value())) { | 963 if (stepMismatch(element().value())) { |
964 ASSERT(!step.isZero()); | 964 ASSERT(!step.isZero()); |
965 const Decimal base = stepRange.stepBase(); | 965 const Decimal base = stepRange.stepBase(); |
966 Decimal newValue; | 966 Decimal newValue; |
967 if (sign < 0) | 967 if (sign < 0) |
968 newValue = base + ((current - base) / step).floor() * step; | 968 newValue = base + ((current - base) / step).floor() * step; |
969 else if (sign > 0) | 969 else if (sign > 0) |
970 newValue = base + ((current - base) / step).ceiling() * step; | 970 newValue = base + ((current - base) / step).ceiling() * step; |
971 else | 971 else |
972 newValue = current; | 972 newValue = current; |
973 | 973 |
974 if (newValue < stepRange.minimum()) | 974 if (newValue < stepRange.minimum()) |
975 newValue = stepRange.minimum(); | 975 newValue = stepRange.minimum(); |
976 if (newValue > stepRange.maximum()) | 976 if (newValue > stepRange.maximum()) |
977 newValue = stepRange.maximum(); | 977 newValue = stepRange.maximum(); |
978 | 978 |
979 setValueAsDecimal(newValue, n == 1 || n == -1 ? DispatchInputAndChan
geEvent : DispatchNoEvent, IGNORE_EXCEPTION); | 979 setValueAsDecimal(newValue, n == 1 || n == -1 ? DispatchInputAndChan
geEvent : DispatchNoEvent, IGNORE_EXCEPTION); |
980 if (n > 1) | 980 if (n > 1) |
981 applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent,
IGNORE_EXCEPTION); | 981 applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent,
IGNORE_EXCEPTION); |
982 else if (n < -1) | 982 else if (n < -1) |
983 applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent,
IGNORE_EXCEPTION); | 983 applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent,
IGNORE_EXCEPTION); |
984 } else { | 984 } else { |
985 applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent, IGNORE_E
XCEPTION); | 985 applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent, IGNORE_E
XCEPTION); |
986 } | 986 } |
987 } | 987 } |
988 } | 988 } |
989 | 989 |
990 void InputType::observeFeatureIfVisible(UseCounter::Feature feature) const | 990 void InputType::observeFeatureIfVisible(UseCounter::Feature feature) const |
991 { | 991 { |
992 if (RenderStyle* style = element()->renderStyle()) { | 992 if (RenderStyle* style = element().renderStyle()) { |
993 if (style->visibility() != HIDDEN) | 993 if (style->visibility() != HIDDEN) |
994 UseCounter::count(element()->document(), feature); | 994 UseCounter::count(element().document(), feature); |
995 } | 995 } |
996 } | 996 } |
997 | 997 |
998 } // namespace WebCore | 998 } // namespace WebCore |
OLD | NEW |