void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, Document* document, Event* event) { ASSERT(event->isBeforeTextInsertedEvent()); // Make sure that the text to be inserted will not violate the maxLength. int oldLength = numGraphemeClusters(data.inputElement()->value().impl()); ASSERT(oldLength <= data.maxLength()); int selectionLength = numGraphemeClusters(plainText(document->frame()->selection()->selection().toNormalizedRange().get()).impl()); ASSERT(oldLength >= selectionLength); int maxNewLength = data.maxLength() - (oldLength - selectionLength); // Truncate the inserted text to avoid violating the maxLength and other constraints. BeforeTextInsertedEvent* textEvent = static_cast<BeforeTextInsertedEvent*>(event); textEvent->setText(constrainValue(data, textEvent->text(), maxNewLength)); }
void InputElement::parseMaxLengthAttribute(InputElementData& data, InputElement* inputElement, Element* element, Attribute* attribute) { int maxLength = attribute->isNull() ? InputElement::s_maximumLength : attribute->value().toInt(); if (maxLength <= 0 || maxLength > InputElement::s_maximumLength) maxLength = InputElement::s_maximumLength; int oldMaxLength = data.maxLength(); data.setMaxLength(maxLength); if (oldMaxLength != maxLength) updateValueIfNeeded(data, inputElement); element->setNeedsStyleRecalc(); }
void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputElement* inputElement, Element* element, Event* event) { ASSERT(event->isBeforeTextInsertedEvent()); // Make sure that the text to be inserted will not violate the maxLength. // We use RenderTextControlSingleLine::text() instead of InputElement::value() // because they can be mismatched by sanitizeValue() in // RenderTextControlSingleLine::subtreeHasChanged() in some cases. unsigned oldLength = numGraphemeClusters(toRenderTextControlSingleLine(element->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 = element->focused() ? numGraphemeClusters(plainText(element->document()->frame()->selection()->selection().toNormalizedRange().get())) : 0; ASSERT(oldLength >= selectionLength); // Selected characters will be removed by the next text event. unsigned baseLength = oldLength - selectionLength; unsigned maxLength = static_cast<unsigned>(inputElement->supportsMaxLength() ? data.maxLength() : s_maximumLength); // maxLength() can never be negative. unsigned appendableLength = maxLength > baseLength ? maxLength - baseLength : 0; // Truncate the inserted text to avoid violating the maxLength and other constraints. BeforeTextInsertedEvent* textEvent = static_cast<BeforeTextInsertedEvent*>(event); #if ENABLE(WCSS) RefPtr<Range> range = element->document()->frame()->selection()->selection().toNormalizedRange(); String candidateString = toRenderTextControlSingleLine(element->renderer())->text(); if (selectionLength) candidateString.replace(range->startOffset(), range->endOffset(), textEvent->text()); else candidateString.insert(textEvent->text(), range->startOffset()); if (!isConformToInputMask(inputElement->data(), candidateString)) { textEvent->setText(""); return; } #endif textEvent->setText(sanitizeUserInputValue(inputElement, textEvent->text(), appendableLength)); }