void Chrome::setToolTip(const HitTestResult& result) { // First priority is a potential toolTip representing a spelling or grammar error String toolTip = result.spellingToolTip(); // Next priority is a toolTip from a URL beneath the mouse (if preference is set to show those). if (toolTip.isEmpty() && m_page->settings()->showsURLsInToolTips()) { if (Node* node = result.innerNonSharedNode()) { // Get tooltip representing form action, if relevant if (node->hasTagName(inputTag)) { HTMLInputElement* input = static_cast<HTMLInputElement*>(node); if (input->inputType() == HTMLInputElement::SUBMIT) if (HTMLFormElement* form = input->form()) toolTip = form->action(); } } // Get tooltip representing link's URL if (toolTip.isEmpty()) // FIXME: Need to pass this URL through userVisibleString once that's in WebCore toolTip = result.absoluteLinkURL().string(); } // Lastly we'll consider a tooltip for element with "title" attribute if (toolTip.isEmpty()) toolTip = result.title(); m_client->setToolTip(toolTip); }
void Chrome::setToolTip(const HitTestResult& result) { // First priority is a potential toolTip representing a spelling or grammar error TextDirection toolTipDirection; String toolTip = result.spellingToolTip(toolTipDirection); // Next priority is a toolTip from a URL beneath the mouse (if preference is set to show those). if (toolTip.isEmpty() && m_page.settings().showsURLsInToolTips()) { if (Element* element = result.innerNonSharedElement()) { // Get tooltip representing form action, if relevant if (isHTMLInputElement(element)) { HTMLInputElement* input = toHTMLInputElement(element); if (input->isSubmitButton()) { if (HTMLFormElement* form = input->form()) { toolTip = form->action(); if (form->renderer()) toolTipDirection = form->renderer()->style()->direction(); else toolTipDirection = LTR; } } } } // Get tooltip representing link's URL if (toolTip.isEmpty()) { // FIXME: Need to pass this URL through userVisibleString once that's in WebCore toolTip = result.absoluteLinkURL().string(); // URL always display as LTR. toolTipDirection = LTR; } } // Next we'll consider a tooltip for element with "title" attribute if (toolTip.isEmpty()) toolTip = result.title(toolTipDirection); if (toolTip.isEmpty() && m_page.settings().showsToolTipOverTruncatedText()) toolTip = result.innerTextIfTruncated(toolTipDirection); // Lastly, for <input type="file"> that allow multiple files, we'll consider a tooltip for the selected filenames if (toolTip.isEmpty()) { if (Element* element = result.innerNonSharedElement()) { if (isHTMLInputElement(element)) { toolTip = toHTMLInputElement(element)->defaultToolTip(); // FIXME: We should obtain text direction of tooltip from // ChromeClient or platform. As of October 2011, all client // implementations don't use text direction information for // ChromeClient::setToolTip. We'll work on tooltip text // direction during bidi cleanup in form inputs. toolTipDirection = LTR; } } } m_client.setToolTip(toolTip, toolTipDirection); }
HTMLInputElement* RadioInputType::findNextFocusableRadioButtonInGroup(HTMLInputElement* currentElement, bool forward) { HTMLElement* htmlElement; for (htmlElement = nextElement(*currentElement, element().form(), forward); htmlElement; htmlElement = nextElement(*htmlElement, element().form(), forward)) { if (!isHTMLInputElement(*htmlElement)) continue; HTMLInputElement* inputElement = toHTMLInputElement(htmlElement); if (element().form() == inputElement->form() && inputElement->type() == InputTypeNames::radio && inputElement->name() == element().name() && inputElement->isFocusable()) return inputElement; } return nullptr; }
void Chrome::setToolTip(const HitTestResult& result) { // First priority is a potential toolTip representing a spelling or grammar error String toolTip = result.spellingToolTip(); // Next priority is a toolTip from a URL beneath the mouse (if preference is set to show those). if (toolTip.isEmpty() && m_page->settings()->showsURLsInToolTips()) { if (Node* node = result.innerNonSharedNode()) { // Get tooltip representing form action, if relevant if (node->hasTagName(inputTag)) { HTMLInputElement* input = static_cast<HTMLInputElement*>(node); if (input->inputType() == HTMLInputElement::SUBMIT) if (HTMLFormElement* form = input->form()) toolTip = form->action(); } } // Get tooltip representing link's URL if (toolTip.isEmpty()) // FIXME: Need to pass this URL through userVisibleString once that's in WebCore toolTip = result.absoluteLinkURL().string(); } // Next we'll consider a tooltip for element with "title" attribute if (toolTip.isEmpty()) toolTip = result.title(); // Lastly, for <input type="file"> that allow multiple files, we'll consider a tooltip for the selected filenames if (toolTip.isEmpty()) { if (Node* node = result.innerNonSharedNode()) { if (node->hasTagName(inputTag)) { HTMLInputElement* input = static_cast<HTMLInputElement*>(node); if (input->inputType() == HTMLInputElement::FILE) { FileList* files = input->files(); unsigned listSize = files->length(); if (files && listSize > 1) { Vector<UChar> names; for (size_t i = 0; i < listSize; ++i) { append(names, files->item(i)->fileName()); if (i != listSize - 1) names.append('\n'); } toolTip = String::adopt(names); } } } } } m_client->setToolTip(toolTip); }
HRESULT STDMETHODCALLTYPE DOMHTMLInputElement::form( /* [retval][out] */ IDOMHTMLElement** result) { if (!result) return E_POINTER; *result = 0; ASSERT(m_element && m_element->hasTagName(inputTag)); HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(m_element); COMPtr<IDOMElement> domElement; domElement.adoptRef(DOMHTMLElement::createInstance(inputElement->form())); if (domElement) return domElement->QueryInterface(IID_IDOMHTMLElement, (void**) result); return E_FAIL; }
void RadioInputType::didDispatchClick(Event* event, const ClickHandlingState& state) { if (event->defaultPrevented() || event->defaultHandled()) { // Restore the original selected radio button if possible. // Make sure it is still a radio button and only do the restoration if it still belongs to our group. HTMLInputElement* checkedRadioButton = state.checkedRadioButton.get(); if (checkedRadioButton && checkedRadioButton->isRadioButton() && checkedRadioButton->form() == element()->form() && checkedRadioButton->name() == element()->name()) { checkedRadioButton->setChecked(true); } } // The work we did in willDispatchClick was default handling. event->setDefaultHandled(); }
bool RadioInputType::isKeyboardFocusable() const { // When using Spatial Navigation, every radio button should be focusable. if (isSpatialNavigationEnabled(element()->document()->frame())) return true; // Never allow keyboard tabbing to leave you in the same radio group. Always // skip any other elements in the group. Node* currentFocusedNode = element()->document()->focusedNode(); if (currentFocusedNode && currentFocusedNode->hasTagName(inputTag)) { HTMLInputElement* focusedInput = static_cast<HTMLInputElement*>(currentFocusedNode); if (focusedInput->isRadioButton() && focusedInput->form() == element()->form() && focusedInput->name() == element()->name()) return false; } // Allow keyboard focus if we're checked or if nothing in the group is checked. return element()->checked() || !element()->checkedRadioButtonForGroup(); }
void RadioInputType::handleKeydownEvent(KeyboardEvent* event) { BaseCheckableInputType::handleKeydownEvent(event); if (event->defaultHandled()) return; const String& key = event->keyIdentifier(); if (key != "Up" && key != "Down" && key != "Left" && key != "Right") return; // 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. However, // when using Spatial Navigation, we need to be able to navigate without // changing the selection. Document& document = element().document(); if (isSpatialNavigationEnabled(document.frame())) return; 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* node = &element(); while ((node = (forward ? NodeTraversal::next(*node) : NodeTraversal::previous(*node)))) { // Once we encounter a form element, we know we're through. if (node->hasTagName(formTag)) break; // Look for more radio buttons. if (!node->hasTagName(inputTag)) continue; HTMLInputElement* inputElement = toHTMLInputElement(node); if (inputElement->form() != element().form()) break; if (inputElement->isRadioButton() && inputElement->name() == element().name() && inputElement->isFocusable()) { RefPtr<HTMLInputElement> protector(inputElement); document.setFocusedElement(inputElement); inputElement->dispatchSimulatedClick(event, SendNoEvents); event->setDefaultHandled(); return; } } }
bool RadioInputType::isKeyboardFocusable(KeyboardEvent* event) const { if (!InputType::isKeyboardFocusable(event)) return false; // When using Spatial Navigation, every radio button should be focusable. if (isSpatialNavigationEnabled(element().document().frame())) return true; // Never allow keyboard tabbing to leave you in the same radio group. Always // skip any other elements in the group. Element* currentFocusedNode = element().document().focusedElement(); if (currentFocusedNode && isHTMLInputElement(currentFocusedNode)) { HTMLInputElement* focusedInput = toHTMLInputElement(currentFocusedNode); if (focusedInput->isRadioButton() && focusedInput->form() == element().form() && focusedInput->name() == element().name()) return false; } // Allow keyboard focus if we're checked or if nothing in the group is checked. return element().checked() || !element().checkedRadioButtonForGroup(); }
JSValue* JSHTMLInputElement::getValueProperty(ExecState* exec, int token) const { switch (token) { case DefaultValueAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsString(imp->defaultValue()); } case DefaultCheckedAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsBoolean(imp->defaultChecked()); } case FormAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return toJS(exec, WTF::getPtr(imp->form())); } case AcceptAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsString(imp->accept()); } case AccessKeyAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsString(imp->accessKey()); } case AlignAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsString(imp->align()); } case AltAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsString(imp->alt()); } case CheckedAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsBoolean(imp->checked()); } case DisabledAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsBoolean(imp->disabled()); } case MaxLengthAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsNumber(imp->maxLength()); } case NameAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsString(imp->name()); } case ReadOnlyAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsBoolean(imp->readOnly()); } case SizeAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsNumber(imp->size()); } case SrcAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsString(imp->src()); } case TabIndexAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsNumber(imp->tabIndex()); } case TypeAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsString(imp->type()); } case UseMapAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsString(imp->useMap()); } case ValueAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsString(imp->value()); } case IndeterminateAttrNum: { HTMLInputElement* imp = static_cast<HTMLInputElement*>(impl()); return jsBoolean(imp->indeterminate()); } case ConstructorAttrNum: return getConstructor(exec); } return 0; }