double HTMLProgressElement::max() const { double max; bool ok = parseToDoubleForNumberType(getAttribute(maxAttr), &max); if (!ok || max <= 0) return 1; return max; }
double HTMLProgressElement::value() const { double value; bool ok = parseToDoubleForNumberType(fastGetAttribute(valueAttr), &value); if (!ok || value < 0) return 0; return (value > max()) ? max() : value; }
double HTMLProgressElement::value() const { const AtomicString& valueString = getAttribute(valueAttr); double value; bool ok = parseToDoubleForNumberType(valueString, &value); if (!ok || value < 0) return valueString.isNull() ? 1 : 0; return (value > max()) ? max() : value; }
bool ValidityState::typeMismatch() const { if (!m_control->hasTagName(inputTag)) return false; HTMLInputElement* input = static_cast<HTMLInputElement*>(m_control); String value = input->value(); if (value.isEmpty()) return false; switch (input->inputType()) { case HTMLInputElement::COLOR: return !isValidColorString(value); case HTMLInputElement::NUMBER: return !parseToDoubleForNumberType(value, 0); case HTMLInputElement::URL: return !KURL(KURL(), value).isValid(); case HTMLInputElement::EMAIL: { if (!input->multiple()) return !isValidEmailAddress(value); Vector<String> addresses; value.split(',', addresses); for (unsigned i = 0; i < addresses.size(); ++i) { if (!isValidEmailAddress(addresses[i])) return true; } return false; } case HTMLInputElement::DATE: case HTMLInputElement::DATETIME: case HTMLInputElement::DATETIMELOCAL: case HTMLInputElement::MONTH: case HTMLInputElement::TIME: case HTMLInputElement::WEEK: return !HTMLInputElement::parseToDateComponents(input->inputType(), value, 0); case HTMLInputElement::BUTTON: case HTMLInputElement::CHECKBOX: case HTMLInputElement::FILE: case HTMLInputElement::HIDDEN: case HTMLInputElement::IMAGE: case HTMLInputElement::ISINDEX: case HTMLInputElement::PASSWORD: case HTMLInputElement::RADIO: case HTMLInputElement::RANGE: case HTMLInputElement::RESET: case HTMLInputElement::SEARCH: case HTMLInputElement::SUBMIT: case HTMLInputElement::TELEPHONE: // FIXME: Is there validation for <input type=telephone>? case HTMLInputElement::TEXT: return false; } ASSERT_NOT_REACHED(); return false; }
double parseToDoubleForNumberType(const String& string) { return parseToDoubleForNumberType(string, std::numeric_limits<double>::quiet_NaN()); }
bool parseToDoubleForNumberTypeWithDecimalPlaces(const String& string, double *result, unsigned *decimalPlaces) { if (decimalPlaces) *decimalPlaces = 0; if (!parseToDoubleForNumberType(string, result)) return false; if (!decimalPlaces) return true; size_t dotIndex = string.find('.'); size_t eIndex = string.find('e'); if (eIndex == notFound) eIndex = string.find('E'); unsigned baseDecimalPlaces = 0; if (dotIndex != notFound) { if (eIndex == notFound) baseDecimalPlaces = string.length() - dotIndex - 1; else baseDecimalPlaces = eIndex - dotIndex - 1; } int exponent = 0; if (eIndex != notFound) { unsigned cursor = eIndex + 1, cursorSaved; int digit, exponentSign; int32_t exponent32; size_t length = string.length(); // Not using String.toInt() in order to perform the same computation as dtoa() does. exponentSign = 0; switch (digit = string[cursor]) { case '-': exponentSign = 1; case '+': digit = string[++cursor]; } if (digit >= '0' && digit <= '9') { while (cursor < length && digit == '0') digit = string[++cursor]; if (digit > '0' && digit <= '9') { exponent32 = digit - '0'; cursorSaved = cursor; while (cursor < length && (digit = string[++cursor]) >= '0' && digit <= '9') exponent32 = (10 * exponent32) + digit - '0'; if (cursor - cursorSaved > 8 || exponent32 > 19999) /* Avoid confusion from exponents * so large that e might overflow. */ exponent = 19999; /* safe for 16 bit ints */ else exponent = static_cast<int>(exponent32); if (exponentSign) exponent = -exponent; } else exponent = 0; } } int intDecimalPlaces = baseDecimalPlaces - exponent; if (intDecimalPlaces < 0) *decimalPlaces = 0; else if (intDecimalPlaces > 19999) *decimalPlaces = 19999; else *decimalPlaces = static_cast<unsigned>(intDecimalPlaces); return true; }
double HTMLMeterElement::min() const { double min = 0; parseToDoubleForNumberType(getAttribute(minAttr), &min); return min; }
double HTMLMeterElement::optimum() const { double optimum = (max() + min()) / 2; parseToDoubleForNumberType(getAttribute(optimumAttr), &optimum); return std::min(std::max(optimum, min()), max()); }
String NumberInputType::sanitizeValue(const String& proposedValue) const { if (proposedValue.isEmpty()) return proposedValue; return std::isfinite(parseToDoubleForNumberType(proposedValue)) ? proposedValue : emptyString(); }
double NumberInputType::valueAsDouble() const { return parseToDoubleForNumberType(element()->value()); }
double HTMLMeterElement::max() const { double max = std::max(1.0, min()); parseToDoubleForNumberType(getAttribute(maxAttr), &max); return std::max(max, min()); }
double RangeInputType::valueAsDouble() const { return parseToDoubleForNumberType(element().value()); }
bool NumberInputType::isAcceptableValue(const String& proposedValue) { String standardValue = convertFromVisibleValue(proposedValue); return standardValue.isEmpty() || isfinite(parseToDoubleForNumberType(standardValue)); }
double Element::getFloatingPointAttribute(const QualifiedName& attributeName, double fallbackValue) const { return parseToDoubleForNumberType(getAttribute(attributeName), fallbackValue); }
double HTMLMeterElement::value() const { double value = 0; parseToDoubleForNumberType(getAttribute(valueAttr), &value); return std::min(std::max(value, min()), max()); }
void RenderTheme::paintSliderTicks(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect) { Node* node = o->node(); if (!node) return; HTMLInputElement* input = node->toInputElement(); if (!input) return; HTMLDataListElement* dataList = static_cast<HTMLDataListElement*>(input->list()); if (!dataList) return; double min = input->minimum(); double max = input->maximum(); ControlPart part = o->style()->appearance(); // We don't support ticks on alternate sliders like MediaVolumeSliders. if (part != SliderHorizontalPart && part != SliderVerticalPart) return; bool isHorizontal = part == SliderHorizontalPart; IntSize thumbSize; RenderObject* thumbRenderer = input->sliderThumbElement()->renderer(); if (thumbRenderer) { RenderStyle* thumbStyle = thumbRenderer->style(); int thumbWidth = thumbStyle->width().intValue(); int thumbHeight = thumbStyle->height().intValue(); thumbSize.setWidth(isHorizontal ? thumbWidth : thumbHeight); thumbSize.setHeight(isHorizontal ? thumbHeight : thumbWidth); } IntSize tickSize = sliderTickSize(); float zoomFactor = o->style()->effectiveZoom(); FloatRect tickRect; int tickRegionSideMargin = 0; int tickRegionWidth = 0; IntRect trackBounds; RenderObject* trackRenderer = input->sliderTrackElement()->renderer(); // We can ignoring transforms because transform is handled by the graphics context. if (trackRenderer) trackBounds = trackRenderer->absoluteBoundingBoxRectIgnoringTransforms(); IntRect sliderBounds = o->absoluteBoundingBoxRectIgnoringTransforms(); // Make position relative to the transformed ancestor element. trackBounds.setX(trackBounds.x() - sliderBounds.x() + rect.x()); trackBounds.setY(trackBounds.y() - sliderBounds.y() + rect.y()); if (isHorizontal) { tickRect.setWidth(floor(tickSize.width() * zoomFactor)); tickRect.setHeight(floor(tickSize.height() * zoomFactor)); tickRect.setY(floor(rect.y() + rect.height() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor)); tickRegionSideMargin = trackBounds.x() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0; tickRegionWidth = trackBounds.width() - thumbSize.width(); } else { tickRect.setWidth(floor(tickSize.height() * zoomFactor)); tickRect.setHeight(floor(tickSize.width() * zoomFactor)); tickRect.setX(floor(rect.x() + rect.width() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor)); tickRegionSideMargin = trackBounds.y() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0; tickRegionWidth = trackBounds.height() - thumbSize.width(); } RefPtr<HTMLCollection> options = dataList->options(); GraphicsContextStateSaver stateSaver(*paintInfo.context); paintInfo.context->setFillColor(o->style()->visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB); for (unsigned i = 0; Node* node = options->item(i); i++) { ASSERT(node->hasTagName(optionTag)); HTMLOptionElement* optionElement = toHTMLOptionElement(node); String value = optionElement->value(); if (!input->isValidValue(value)) continue; double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value)); double tickFraction = (parsedValue - min) / (max - min); double tickRatio = isHorizontal && o->style()->isLeftToRightDirection() ? tickFraction : 1.0 - tickFraction; double tickPosition = round(tickRegionSideMargin + tickRegionWidth * tickRatio); if (isHorizontal) tickRect.setX(tickPosition); else tickRect.setY(tickPosition); paintInfo.context->fillRect(tickRect); } }
double HTMLMeterElement::low() const { double low = min(); parseToDoubleForNumberType(getAttribute(lowAttr), &low); return std::min(std::max(low, min()), max()); }
bool NumberInputType::typeMismatchFor(const String& value) const { return !value.isEmpty() && !std::isfinite(parseToDoubleForNumberType(value)); }
double HTMLMeterElement::high() const { double high = max(); parseToDoubleForNumberType(getAttribute(highAttr), &high); return std::min(std::max(high, low()), max()); }
bool NumberInputType::hasBadInput() const { String standardValue = convertFromVisibleValue(element()->innerTextValue()); return !standardValue.isEmpty() && !std::isfinite(parseToDoubleForNumberType(standardValue)); }
double NumberInputType::parseToNumber(const String& src, double defaultValue) const { return parseToDoubleForNumberType(src, defaultValue); }