void InputElement::updateValueIfNeeded(InputElementData& data) { String oldValue = data.value(); String newValue = data.inputElement()->constrainValue(oldValue); if (newValue != oldValue) data.inputElement()->setValue(newValue); }
void InputElement::dispatchFocusEvent(InputElementData& data, Document* document) { if (!data.inputElement()->isTextField()) return; updatePlaceholderVisibility(data, document); if (data.inputElement()->isPasswordField() && document->frame()) document->setUseSecureKeyboardEntryWhenActive(true); }
void InputElement::updateFocusAppearance(InputElementData& data, Document* document, bool restorePreviousSelection) { ASSERT(data.inputElement()->isTextField()); if (!restorePreviousSelection || data.cachedSelectionStart() == -1) data.inputElement()->select(); else // Restore the cached selection. updateSelectionRange(data, data.cachedSelectionStart(), data.cachedSelectionEnd()); if (document && document->frame()) document->frame()->revealSelection(); }
void InputElement::updatePlaceholderVisibility(InputElementData& data, Document* document, bool placeholderValueChanged) { ASSERT(data.inputElement()->isTextField()); bool oldPlaceholderShouldBeVisible = data.placeholderShouldBeVisible(); Element* element = data.element(); data.setPlaceholderShouldBeVisible(data.inputElement()->value().isEmpty() && document->focusedNode() != element && !data.inputElement()->placeholder().isEmpty()); if ((oldPlaceholderShouldBeVisible != data.placeholderShouldBeVisible() || placeholderValueChanged) && element->renderer()) static_cast<RenderTextControlSingleLine*>(element->renderer())->updatePlaceholderVisibility(); }
void InputElement::dispatchBlurEvent(InputElementData& data, Document* document) { if (!data.inputElement()->isTextField()) return; Frame* frame = document->frame(); if (!frame) return; updatePlaceholderVisibility(data, document); if (data.inputElement()->isPasswordField()) document->setUseSecureKeyboardEntryWhenActive(false); frame->textFieldDidEndEditing(data.element()); }
String InputElement::constrainValue(const InputElementData& data, const String& proposedValue, int maxLength) { String string = proposedValue; if (!data.inputElement()->isTextField()) return string; string.replace("\r\n", " "); string.replace('\r', ' '); string.replace('\n', ' '); StringImpl* s = string.impl(); int newLength = numCharactersInGraphemeClusters(s, maxLength); for (int i = 0; i < newLength; ++i) { const UChar& current = (*s)[i]; if (current < ' ' && current != '\t') { newLength = i; break; } } if (newLength < static_cast<int>(string.length())) return string.left(newLength); return string; }
void InputElement::aboutToUnload(InputElementData& data, Document* document) { if (!data.inputElement()->isTextField() || !data.element()->focused() || !document->frame()) return; document->frame()->textFieldDidEndEditing(data.element()); }
void InputElement::updateSelectionRange(InputElementData& data, int start, int end) { if (!data.inputElement()->isTextField()) return; if (RenderTextControl* renderer = toRenderTextControl(data.element()->renderer())) renderer->setSelectionRange(start, end); }
void InputElement::setValueFromRenderer(InputElementData& data, Document* document, const String& value) { // Renderer and our event handler are responsible for constraining values. ASSERT(value == data.inputElement()->constrainValue(value) || data.inputElement()->constrainValue(value).isEmpty()); if (data.inputElement()->isTextField()) updatePlaceholderVisibility(data, document); // Workaround for bug where trailing \n is included in the result of textContent. // The assert macro above may also be simplified to: value == constrainValue(value) // http://bugs.webkit.org/show_bug.cgi?id=9661 if (value == "\n") data.setValue(""); else data.setValue(value); Element* element = data.element(); element->setFormControlValueMatchesRenderer(true); // Fire the "input" DOM event element->dispatchEvent(eventNames().inputEvent, true, false); notifyFormStateChanged(data, document); }
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)); }