void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event) const { ASSERT(event); ASSERT(renderer()); int signedMaxLength = maxLength(); if (signedMaxLength < 0) return; unsigned unsignedMaxLength = static_cast<unsigned>(signedMaxLength); unsigned currentLength = numGraphemeClusters(toRenderTextControl(renderer())->text()); unsigned selectionLength = numGraphemeClusters(plainText(document()->frame()->selection()->selection().toNormalizedRange().get())); ASSERT(currentLength >= selectionLength); unsigned baseLength = currentLength - selectionLength; unsigned appendableLength = unsignedMaxLength > baseLength ? unsignedMaxLength - baseLength : 0; event->setText(sanitizeUserInputValue(event->text(), appendableLength)); }
bool HTMLTextAreaElement::tooLong() const { // Return false for the default value even if it is longer than maxLength. if (!m_isDirty) return false; int max = maxLength(); if (max < 0) return false; return numGraphemeClusters(value()) > static_cast<unsigned>(max); }
bool HTMLTextAreaElement::tooLong(const String& value, NeedsToCheckDirtyFlag check) const { // Return false for the default value even if it is longer than maxLength. if (check == CheckDirtyFlag && !m_isDirty) return false; int max = maxLength(); if (max < 0) return false; return numGraphemeClusters(value) > static_cast<unsigned>(max); }
static AtomicString makeVisibleEmptyValue(const Vector<String>& symbols) { unsigned maximumLength = 0; for (unsigned index = 0; index < symbols.size(); ++index) maximumLength = std::max(maximumLength, numGraphemeClusters(symbols[index])); StringBuilder builder; builder.reserveCapacity(maximumLength); for (unsigned length = 0; length < maximumLength; ++length) builder.append('-'); return builder.toAtomicString(); }
void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event) const { ASSERT(event); ASSERT(renderer()); int signedMaxLength = maxLength(); if (signedMaxLength < 0) return; unsigned unsignedMaxLength = static_cast<unsigned>(signedMaxLength); unsigned currentLength = numGraphemeClusters(toRenderTextControl(renderer())->text()); // selectionLength represents the selection length of this text field to be // removed by this insertion. // If the text field has no focus, we don't need to take account of the // selection length. The selection is the source of text drag-and-drop in // that case, and nothing in the text field will be removed. unsigned selectionLength = focused() ? numGraphemeClusters(plainText(document()->frame()->selection()->selection().toNormalizedRange().get())) : 0; ASSERT(currentLength >= selectionLength); unsigned baseLength = currentLength - selectionLength; unsigned appendableLength = unsignedMaxLength > baseLength ? unsignedMaxLength - baseLength : 0; event->setText(sanitizeUserInputValue(event->text(), appendableLength)); }
String InputType::validationMessage() const { String value = element().value(); // The order of the following checks is meaningful. e.g. We'd like to show the // badInput message even if the control has other validation errors. if (hasBadInput()) return badInputText(); if (valueMissing(value)) return valueMissingText(); if (typeMismatch()) return typeMismatchText(); if (patternMismatch(value)) return validationMessagePatternMismatchText(); if (element().tooLong()) return validationMessageTooLongText(numGraphemeClusters(value), element().maxLength()); if (!isSteppable()) return emptyString(); const Decimal numericValue = parseToNumberOrNaN(value); if (!numericValue.isFinite()) return emptyString(); StepRange stepRange(createStepRange(RejectAny)); if (numericValue < stepRange.minimum()) return validationMessageRangeUnderflowText(serialize(stepRange.minimum())); if (numericValue > stepRange.maximum()) return validationMessageRangeOverflowText(serialize(stepRange.maximum())); if (stepRange.stepMismatch(numericValue)) { const String stepString = stepRange.hasStep() ? serializeForNumberType(stepRange.step() / stepRange.stepScaleFactor()) : emptyString(); return validationMessageStepMismatchText(serialize(stepRange.stepBase()), stepString); } return emptyString(); }
static inline unsigned computeLengthForSubmission(const String& text) { return numGraphemeClusters(text) + numberOfLineBreaks(text); }