📄 htmlinputelement.cpp
字号:
} } else if (charCode == ' ') { switch (inputType()) { case BUTTON: case CHECKBOX: case FILE: case IMAGE: case RESET: case SUBMIT: case RADIO: // Prevent scrolling down the page. evt->setDefaultHandled(); return; default: break; } } if (clickElement) { dispatchSimulatedClick(evt); evt->setDefaultHandled(); return; } } if (evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent()) { String key = static_cast<KeyboardEvent*>(evt)->keyIdentifier(); if (key == "U+0020") { switch (inputType()) { case BUTTON: case CHECKBOX: case FILE: case IMAGE: case RESET: case SUBMIT: case RADIO: setActive(true, true); // No setDefaultHandled() - IE dispatches a keypress in this case. return; default: break; } } if (inputType() == RADIO && (key == "Up" || key == "Down" || key == "Left" || key == "Right")) { // Left and up mean "previous radio button". // Right and down mean "next radio button". // Tested in WinIE, and even for RTL, left still means previous radio button (and so moves // to the right). Seems strange, but we'll match it. bool forward = (key == "Down" || key == "Right"); // We can only stay within the form's children if the form hasn't been demoted to a leaf because // of malformed HTML. Node* n = this; while ((n = (forward ? n->traverseNextNode() : n->traversePreviousNode()))) { // Once we encounter a form element, we know we're through. if (n->hasTagName(formTag)) break; // Look for more radio buttons. if (n->hasTagName(inputTag)) { HTMLInputElement* elt = static_cast<HTMLInputElement*>(n); if (elt->form() != form()) break; if (n->hasTagName(inputTag)) { HTMLInputElement* inputElt = static_cast<HTMLInputElement*>(n); if (inputElt->inputType() == RADIO && inputElt->name() == name() && inputElt->isFocusable()) { inputElt->setChecked(true); document()->setFocusedNode(inputElt); inputElt->dispatchSimulatedClick(evt, false, false); evt->setDefaultHandled(); break; } } } } } } if (evt->type() == eventNames().keyupEvent && evt->isKeyboardEvent()) { bool clickElement = false; String key = static_cast<KeyboardEvent*>(evt)->keyIdentifier(); if (key == "U+0020") { switch (inputType()) { case BUTTON: case CHECKBOX: case FILE: case IMAGE: case RESET: case SUBMIT: // Simulate mouse click for spacebar for these types of elements. // The AppKit already does this for some, but not all, of them. clickElement = true; break; case RADIO: // If an unselected radio is tabbed into (because the entire group has nothing // checked, or because of some explicit .focus() call), then allow space to check it. if (!checked()) clickElement = true; break; case HIDDEN: case ISINDEX: case PASSWORD: case RANGE: case SEARCH: case TEXT: break; } } if (clickElement) { if (active()) dispatchSimulatedClick(evt); evt->setDefaultHandled(); return; } } if (clickDefaultFormButton) { if (isSearchField()) { addSearchResult(); onSearch(); } // Fire onChange for text fields. RenderObject* r = renderer(); if (r && r->isTextField() && toRenderTextControl(r)->isEdited()) { onChange(); // Refetch the renderer since arbitrary JS code run during onchange can do anything, including destroying it. r = renderer(); if (r && r->isTextField()) toRenderTextControl(r)->setEdited(false); } // Form may never have been present, or may have been destroyed by the change event. if (form()) form()->submitClick(evt); evt->setDefaultHandled(); return; } if (evt->isBeforeTextInsertedEvent()) InputElement::handleBeforeTextInsertedEvent(m_data, document(), evt); if (isTextField() && renderer() && (evt->isMouseEvent() || evt->isDragEvent() || evt->isWheelEvent() || evt->type() == eventNames().blurEvent || evt->type() == eventNames().focusEvent)) static_cast<RenderTextControlSingleLine*>(renderer())->forwardEvent(evt); if (inputType() == RANGE && renderer()) { RenderSlider* slider = static_cast<RenderSlider*>(renderer()); if (evt->isMouseEvent() && evt->type() == eventNames().mousedownEvent && static_cast<MouseEvent*>(evt)->button() == LeftButton) { MouseEvent* mEvt = static_cast<MouseEvent*>(evt); if (!slider->mouseEventIsInThumb(mEvt)) { IntPoint eventOffset(mEvt->offsetX(), mEvt->offsetY()); if (mEvt->target() != this) // Does this ever happen now? Was added for <video> controls eventOffset = roundedIntPoint(renderer()->absoluteToLocal(FloatPoint(mEvt->pageX(), mEvt->pageY()), false, true)); slider->setValueForPosition(slider->positionForOffset(eventOffset)); } } if (evt->isMouseEvent() || evt->isDragEvent() || evt->isWheelEvent()) slider->forwardEvent(evt); }}bool HTMLInputElement::isURLAttribute(Attribute *attr) const{ return (attr->name() == srcAttr);}String HTMLInputElement::defaultValue() const{ return getAttribute(valueAttr);}void HTMLInputElement::setDefaultValue(const String &value){ setAttribute(valueAttr, value);}bool HTMLInputElement::defaultChecked() const{ return !getAttribute(checkedAttr).isNull();}void HTMLInputElement::setDefaultChecked(bool defaultChecked){ setAttribute(checkedAttr, defaultChecked ? "" : 0);}void HTMLInputElement::setDefaultName(const AtomicString& name){ m_data.setName(name);}String HTMLInputElement::accept() const{ return getAttribute(acceptAttr);}void HTMLInputElement::setAccept(const String &value){ setAttribute(acceptAttr, value);}String HTMLInputElement::accessKey() const{ return getAttribute(accesskeyAttr);}void HTMLInputElement::setAccessKey(const String &value){ setAttribute(accesskeyAttr, value);}String HTMLInputElement::align() const{ return getAttribute(alignAttr);}void HTMLInputElement::setAlign(const String &value){ setAttribute(alignAttr, value);}String HTMLInputElement::alt() const{ return getAttribute(altAttr);}void HTMLInputElement::setAlt(const String &value){ setAttribute(altAttr, value);}int HTMLInputElement::maxLength() const{ return m_data.maxLength();}void HTMLInputElement::setMaxLength(int _maxLength){ setAttribute(maxlengthAttr, String::number(_maxLength));}bool HTMLInputElement::multiple() const{ return !getAttribute(multipleAttr).isNull();}void HTMLInputElement::setMultiple(bool multiple){ setAttribute(multipleAttr, multiple ? "" : 0);} void HTMLInputElement::setSize(unsigned _size){ setAttribute(sizeAttr, String::number(_size));}KURL HTMLInputElement::src() const{ return document()->completeURL(getAttribute(srcAttr));}void HTMLInputElement::setSrc(const String &value){ setAttribute(srcAttr, value);}String HTMLInputElement::useMap() const{ return getAttribute(usemapAttr);}void HTMLInputElement::setUseMap(const String &value){ setAttribute(usemapAttr, value);}void HTMLInputElement::setAutofilled(bool b){ if (b == m_autofilled) return; m_autofilled = b; setChanged();}FileList* HTMLInputElement::files(){ if (inputType() != FILE) return 0; return m_fileList.get();}String HTMLInputElement::constrainValue(const String& proposedValue) const{ return InputElement::constrainValue(m_data, proposedValue, m_data.maxLength());}bool HTMLInputElement::needsActivationCallback(){ return inputType() == PASSWORD || m_autocomplete == Off;}void HTMLInputElement::registerForActivationCallbackIfNeeded(){ if (needsActivationCallback()) document()->registerForDocumentActivationCallbacks(this);}void HTMLInputElement::unregisterForActivationCallbackIfNeeded(){ if (!needsActivationCallback()) document()->unregisterForDocumentActivationCallbacks(this);}void HTMLInputElement::cacheSelection(int start, int end){ m_data.setCachedSelectionStart(start); m_data.setCachedSelectionEnd(end);}void HTMLInputElement::addSearchResult(){ ASSERT(isSearchField()); if (renderer()) static_cast<RenderTextControlSingleLine*>(renderer())->addSearchResult();}void HTMLInputElement::onSearch(){ ASSERT(isSearchField()); if (renderer()) static_cast<RenderTextControlSingleLine*>(renderer())->stopSearchEventTimer(); dispatchEventForType(eventNames().searchEvent, true, false);}VisibleSelection HTMLInputElement::selection() const{ if (!renderer() || !isTextField() || m_data.cachedSelectionStart() == -1 || m_data.cachedSelectionEnd() == -1) return VisibleSelection(); return toRenderTextControl(renderer())->selection(m_data.cachedSelectionStart(), m_data.cachedSelectionEnd());}void HTMLInputElement::documentDidBecomeActive(){ ASSERT(needsActivationCallback()); reset();}void HTMLInputElement::willMoveToNewOwnerDocument(){ // Always unregister for cache callbacks when leaving a document, even if we would otherwise like to be registered if (needsActivationCallback()) document()->unregisterForDocumentActivationCallbacks(this); document()->checkedRadioButtons().removeButton(this); HTMLFormControlElementWithState::willMoveToNewOwnerDocument();}void HTMLInputElement::didMoveToNewOwnerDocument(){ registerForActivationCallbackIfNeeded(); HTMLFormControlElementWithState::didMoveToNewOwnerDocument();} void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const{ HTMLFormControlElementWithState::addSubresourceAttributeURLs(urls); addSubresourceURL(urls, src());}bool HTMLInputElement::willValidate() const{ // FIXME: This shall check for new WF2 input types too return HTMLFormControlElementWithState::willValidate() && inputType() != HIDDEN && inputType() != BUTTON && inputType() != RESET;}bool HTMLInputElement::placeholderShouldBeVisible() const{ return m_data.placeholderShouldBeVisible();}} // namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -