JSValue JSHTMLFormElement::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) { JSHTMLElement* jsForm = static_cast<JSHTMLFormElement*>(asObject(slotBase)); HTMLFormElement* form = static_cast<HTMLFormElement*>(jsForm->impl()); Vector<RefPtr<Node> > namedItems; form->getNamedElements(identifierToAtomicString(propertyName), namedItems); if (namedItems.isEmpty()) return jsUndefined(); if (namedItems.size() == 1) return toJS(exec, jsForm->globalObject(), namedItems[0].get()); // FIXME: HTML5 specifies that this should be a RadioNodeList. return toJS(exec, jsForm->globalObject(), StaticNodeList::adopt(namedItems).get()); }
TEST_F(HTMLSelectElementTest, DefaultToolTip) { document().documentElement()->setInnerHTML( "<select size=4><option value=" ">Placeholder</option><optgroup><option>o2</option></optgroup></select>", ASSERT_NO_EXCEPTION); document().view()->updateAllLifecyclePhases(); HTMLSelectElement* select = toHTMLSelectElement(document().body()->firstChild()); Element* option = toElement(select->firstChild()); Element* optgroup = toElement(option->nextSibling()); EXPECT_EQ(String(), select->defaultToolTip()) << "defaultToolTip for SELECT without FORM and without required " "attribute should return null string."; EXPECT_EQ(select->defaultToolTip(), option->defaultToolTip()); EXPECT_EQ(select->defaultToolTip(), optgroup->defaultToolTip()); select->setBooleanAttribute(HTMLNames::requiredAttr, true); EXPECT_EQ("<<ValidationValueMissingForSelect>>", select->defaultToolTip()) << "defaultToolTip for SELECT without FORM and with required attribute " "should return a valueMissing message."; EXPECT_EQ(select->defaultToolTip(), option->defaultToolTip()); EXPECT_EQ(select->defaultToolTip(), optgroup->defaultToolTip()); HTMLFormElement* form = HTMLFormElement::create(document()); document().body()->appendChild(form); form->appendChild(select); EXPECT_EQ("<<ValidationValueMissingForSelect>>", select->defaultToolTip()) << "defaultToolTip for SELECT with FORM and required attribute should " "return a valueMissing message."; EXPECT_EQ(select->defaultToolTip(), option->defaultToolTip()); EXPECT_EQ(select->defaultToolTip(), optgroup->defaultToolTip()); form->setBooleanAttribute(HTMLNames::novalidateAttr, true); EXPECT_EQ(String(), select->defaultToolTip()) << "defaultToolTip for SELECT with FORM[novalidate] and required " "attribute should return null string."; EXPECT_EQ(select->defaultToolTip(), option->defaultToolTip()); EXPECT_EQ(select->defaultToolTip(), optgroup->defaultToolTip()); option->remove(); optgroup->remove(); EXPECT_EQ(String(), option->defaultToolTip()); EXPECT_EQ(String(), optgroup->defaultToolTip()); }
JSValue* JSHTMLFormElementPrototypeFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args) { if (!thisObj->inherits(&JSHTMLFormElement::info)) return throwError(exec, TypeError); HTMLFormElement* imp = static_cast<HTMLFormElement*>(static_cast<JSHTMLFormElement*>(thisObj)->impl()); switch (id) { case JSHTMLFormElement::SubmitFuncNum: { imp->submit(); return jsUndefined(); } case JSHTMLFormElement::ResetFuncNum: { imp->reset(); return jsUndefined(); } } return 0; }
static inline String formSignature(const HTMLFormElement& form) { URL actionURL = form.getURLAttribute(actionAttr); // Remove the query part because it might contain volatile parameters such // as a session key. actionURL.setQuery(String()); StringBuilder builder; if (!actionURL.isEmpty()) builder.append(actionURL.string()); recordFormStructure(form, builder); return builder.toString(); }
void HTMLImageElement::resetFormOwner() { m_formWasSetByParser = false; HTMLFormElement* nearestForm = findFormAncestor(); if (m_form) { if (nearestForm == m_form.get()) return; m_form->disassociate(*this); } if (nearestForm) { #if ENABLE(OILPAN) m_form = nearestForm; #else m_form = nearestForm->createWeakPtr(); #endif m_form->associate(*this); } else { #if ENABLE(OILPAN) m_form = nullptr; #else m_form = WeakPtr<HTMLFormElement>(); #endif } }
void FormController::restoreControlStateIn(HTMLFormElement& form) { for (auto& element : form.associatedElements()) { if (!element->isFormControlElementWithState()) continue; HTMLFormControlElementWithState* control = static_cast<HTMLFormControlElementWithState*>(element); if (!control->shouldSaveAndRestoreFormControlState()) continue; if (ownerFormForState(*control) != &form) continue; FormControlState state = takeStateForFormElement(*control); if (state.valueSize() > 0) control->restoreFormControlState(state); } }
void FormController::restoreControlStateIn(HTMLFormElement& form) { const Vector<FormAssociatedElement*>& elements = form.associatedElements(); for (size_t i = 0; i < elements.size(); ++i) { if (!elements[i]->isFormControlElementWithState()) continue; HTMLFormControlElementWithState* control = static_cast<HTMLFormControlElementWithState*>(elements[i]); if (!control->shouldSaveAndRestoreFormControlState()) continue; if (ownerFormForState(*control) != &form) continue; FormControlState state = takeStateForFormElement(*control); if (state.valueSize() > 0) control->restoreFormControlState(state); } }
static inline void recordFormStructure(const HTMLFormElement& form, StringBuilder& builder) { // 2 is enough to distinguish forms in webkit.org/b/91209#c0 const size_t namedControlsToBeRecorded = 2; const Vector<FormAssociatedElement*>& controls = form.associatedElements(); builder.appendLiteral(" ["); for (size_t i = 0, namedControls = 0; i < controls.size() && namedControls < namedControlsToBeRecorded; ++i) { if (!controls[i]->isFormControlElementWithState()) continue; HTMLFormControlElementWithState* control = static_cast<HTMLFormControlElementWithState*>(controls[i]); if (!ownerFormForState(*control)) continue; AtomicString name = control->name(); if (name.isEmpty()) continue; namedControls++; builder.append(name); builder.append(' '); } builder.append(']'); }
PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems( ContextMenu* defaultMenu) { // Displaying the context menu in this function is a big hack as we don't // have context, i.e. whether this is being invoked via a script or in // response to user input (Mouse event WM_RBUTTONDOWN, // Keyboard events KeyVK_APPS, Shift+F10). Check if this is being invoked // in response to the above input events before popping up the context menu. if (!m_webView->contextMenuAllowed()) return 0; HitTestResult r = m_webView->page()->contextMenuController()->hitTestResult(); Frame* selectedFrame = r.innerNonSharedNode()->document()->frame(); WebContextMenuData data; data.mousePosition = selectedFrame->view()->contentsToWindow(r.roundedPoint()); // Compute edit flags. data.editFlags = WebContextMenuData::CanDoNone; if (m_webView->focusedWebCoreFrame()->editor()->canUndo()) data.editFlags |= WebContextMenuData::CanUndo; if (m_webView->focusedWebCoreFrame()->editor()->canRedo()) data.editFlags |= WebContextMenuData::CanRedo; if (m_webView->focusedWebCoreFrame()->editor()->canCut()) data.editFlags |= WebContextMenuData::CanCut; if (m_webView->focusedWebCoreFrame()->editor()->canCopy()) data.editFlags |= WebContextMenuData::CanCopy; if (m_webView->focusedWebCoreFrame()->editor()->canPaste()) data.editFlags |= WebContextMenuData::CanPaste; if (m_webView->focusedWebCoreFrame()->editor()->canDelete()) data.editFlags |= WebContextMenuData::CanDelete; // We can always select all... data.editFlags |= WebContextMenuData::CanSelectAll; data.editFlags |= WebContextMenuData::CanTranslate; // Links, Images, Media tags, and Image/Media-Links take preference over // all else. data.linkURL = r.absoluteLinkURL(); if (!r.absoluteImageURL().isEmpty()) { data.srcURL = r.absoluteImageURL(); data.mediaType = WebContextMenuData::MediaTypeImage; } else if (!r.absoluteMediaURL().isEmpty()) { data.srcURL = r.absoluteMediaURL(); // We know that if absoluteMediaURL() is not empty, then this // is a media element. HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(r.innerNonSharedNode()); if (mediaElement->hasTagName(HTMLNames::videoTag)) data.mediaType = WebContextMenuData::MediaTypeVideo; else if (mediaElement->hasTagName(HTMLNames::audioTag)) data.mediaType = WebContextMenuData::MediaTypeAudio; if (mediaElement->error()) data.mediaFlags |= WebContextMenuData::MediaInError; if (mediaElement->paused()) data.mediaFlags |= WebContextMenuData::MediaPaused; if (mediaElement->muted()) data.mediaFlags |= WebContextMenuData::MediaMuted; if (mediaElement->loop()) data.mediaFlags |= WebContextMenuData::MediaLoop; if (mediaElement->supportsSave()) data.mediaFlags |= WebContextMenuData::MediaCanSave; if (mediaElement->hasAudio()) data.mediaFlags |= WebContextMenuData::MediaHasAudio; if (mediaElement->hasVideo()) data.mediaFlags |= WebContextMenuData::MediaHasVideo; if (mediaElement->controls()) data.mediaFlags |= WebContextMenuData::MediaControlRootElement; } else if (r.innerNonSharedNode()->hasTagName(HTMLNames::objectTag) || r.innerNonSharedNode()->hasTagName(HTMLNames::embedTag)) { RenderObject* object = r.innerNonSharedNode()->renderer(); if (object && object->isWidget()) { Widget* widget = toRenderWidget(object)->widget(); if (widget && widget->isPluginContainer()) { data.mediaType = WebContextMenuData::MediaTypePlugin; WebPluginContainerImpl* plugin = static_cast<WebPluginContainerImpl*>(widget); WebString text = plugin->plugin()->selectionAsText(); if (!text.isEmpty()) { data.selectedText = text; data.editFlags |= WebContextMenuData::CanCopy; } data.editFlags &= ~WebContextMenuData::CanTranslate; data.linkURL = plugin->plugin()->linkAtPosition(data.mousePosition); if (plugin->plugin()->supportsPaginatedPrint()) data.mediaFlags |= WebContextMenuData::MediaCanPrint; HTMLPlugInImageElement* pluginElement = static_cast<HTMLPlugInImageElement*>(r.innerNonSharedNode()); data.srcURL = pluginElement->document()->completeURL(pluginElement->url()); data.mediaFlags |= WebContextMenuData::MediaCanSave; // Add context menu commands that are supported by the plugin. if (plugin->plugin()->canRotateView()) data.mediaFlags |= WebContextMenuData::MediaCanRotate; } } } data.isImageBlocked = (data.mediaType == WebContextMenuData::MediaTypeImage) && !r.image(); // If it's not a link, an image, a media element, or an image/media link, // show a selection menu or a more generic page menu. if (selectedFrame->document()->loader()) data.frameEncoding = selectedFrame->document()->encoding(); // Send the frame and page URLs in any case. data.pageURL = urlFromFrame(m_webView->mainFrameImpl()->frame()); if (selectedFrame != m_webView->mainFrameImpl()->frame()) { data.frameURL = urlFromFrame(selectedFrame); RefPtr<HistoryItem> historyItem = selectedFrame->loader()->history()->currentItem(); if (historyItem) data.frameHistoryItem = WebHistoryItem(historyItem); } if (r.isSelected()) { if (!r.innerNonSharedNode()->hasTagName(HTMLNames::inputTag) || !static_cast<HTMLInputElement*>(r.innerNonSharedNode())->isPasswordField()) data.selectedText = selectedFrame->editor()->selectedText().stripWhiteSpace(); } if (r.isContentEditable()) { data.isEditable = true; #if ENABLE(INPUT_SPEECH) if (r.innerNonSharedNode()->hasTagName(HTMLNames::inputTag)) { data.isSpeechInputEnabled = static_cast<HTMLInputElement*>(r.innerNonSharedNode())->isSpeechEnabled(); } #endif // When Chrome enables asynchronous spellchecking, its spellchecker adds spelling markers to misspelled // words and attaches suggestions to these markers in the background. Therefore, when a user right-clicks // a mouse on a word, Chrome just needs to find a spelling marker on the word instread of spellchecking it. if (selectedFrame->settings() && selectedFrame->settings()->asynchronousSpellCheckingEnabled()) { VisibleSelection selection = selectedFrame->selection()->selection(); if (selection.isCaret()) { selection.expandUsingGranularity(WordGranularity); RefPtr<Range> range = selection.toNormalizedRange(); Vector<DocumentMarker*> markers = selectedFrame->document()->markers()->markersInRange(range.get(), DocumentMarker::Spelling | DocumentMarker::Grammar); if (markers.size() == 1) { range->setStart(range->startContainer(), markers[0]->startOffset()); range->setEnd(range->endContainer(), markers[0]->endOffset()); data.misspelledWord = range->text(); if (markers[0]->description().length()) { Vector<String> suggestions; markers[0]->description().split('\n', suggestions); data.dictionarySuggestions = suggestions; } else if (m_webView->spellCheckClient()) { int misspelledOffset, misspelledLength; m_webView->spellCheckClient()->spellCheck(data.misspelledWord, misspelledOffset, misspelledLength, &data.dictionarySuggestions); } selection = VisibleSelection(range.get()); if (selectedFrame->selection()->shouldChangeSelection(selection)) selectedFrame->selection()->setSelection(selection, WordGranularity); } } } else if (m_webView->focusedWebCoreFrame()->editor()->isContinuousSpellCheckingEnabled()) { data.isSpellCheckingEnabled = true; // Spellchecking might be enabled for the field, but could be disabled on the node. if (m_webView->focusedWebCoreFrame()->editor()->isSpellCheckingEnabledInFocusedNode()) { data.misspelledWord = selectMisspelledWord(defaultMenu, selectedFrame); if (m_webView->spellCheckClient()) { int misspelledOffset, misspelledLength; m_webView->spellCheckClient()->spellCheck( data.misspelledWord, misspelledOffset, misspelledLength, &data.dictionarySuggestions); if (!misspelledLength) data.misspelledWord.reset(); } } } HTMLFormElement* form = selectedFrame->selection()->currentForm(); if (form && form->checkValidity() && r.innerNonSharedNode()->hasTagName(HTMLNames::inputTag)) { HTMLInputElement* selectedElement = static_cast<HTMLInputElement*>(r.innerNonSharedNode()); if (selectedElement) { WebSearchableFormData ws = WebSearchableFormData(WebFormElement(form), WebInputElement(selectedElement)); if (ws.url().isValid()) data.keywordURL = ws.url(); } } } #if OS(DARWIN) if (selectedFrame->editor()->selectionHasStyle(CSSPropertyDirection, "ltr") != FalseTriState) data.writingDirectionLeftToRight |= WebContextMenuData::CheckableMenuItemChecked; if (selectedFrame->editor()->selectionHasStyle(CSSPropertyDirection, "rtl") != FalseTriState) data.writingDirectionRightToLeft |= WebContextMenuData::CheckableMenuItemChecked; #endif // OS(DARWIN) // Now retrieve the security info. DocumentLoader* dl = selectedFrame->loader()->documentLoader(); WebDataSource* ds = WebDataSourceImpl::fromDocumentLoader(dl); if (ds) data.securityInfo = ds->response().securityInfo(); data.referrerPolicy = static_cast<WebReferrerPolicy>(selectedFrame->document()->referrerPolicy()); // Filter out custom menu elements and add them into the data. populateCustomMenuItems(defaultMenu, &data); data.node = r.innerNonSharedNode(); WebFrame* selected_web_frame = WebFrameImpl::fromFrame(selectedFrame); if (m_webView->client()) m_webView->client()->showContextMenu(selected_web_frame, data); return 0; }
void JSHTMLFormElement::putValueProperty(ExecState* exec, int token, JSValue* value) { switch (token) { case NameAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); imp->setName(valueToStringWithNullCheck(exec, value)); break; } case AcceptCharsetAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); imp->setAcceptCharset(valueToStringWithNullCheck(exec, value)); break; } case ActionAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); imp->setAction(valueToStringWithNullCheck(exec, value)); break; } case EncodingAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); imp->setEncoding(valueToStringWithNullCheck(exec, value)); break; } case EnctypeAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); imp->setEnctype(valueToStringWithNullCheck(exec, value)); break; } case MethodAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); imp->setMethod(valueToStringWithNullCheck(exec, value)); break; } case TargetAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); imp->setTarget(valueToStringWithNullCheck(exec, value)); break; } } }
JSValue* JSHTMLFormElement::getValueProperty(ExecState* exec, int token) const { switch (token) { case ElementsAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); return toJS(exec, WTF::getPtr(imp->elements())); } case LengthAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); return jsNumber(exec, imp->length()); } case NameAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); return jsString(exec, imp->name()); } case AcceptCharsetAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); return jsString(exec, imp->acceptCharset()); } case ActionAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); return jsString(exec, imp->action()); } case EncodingAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); return jsString(exec, imp->encoding()); } case EnctypeAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); return jsString(exec, imp->enctype()); } case MethodAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); return jsString(exec, imp->method()); } case TargetAttrNum: { HTMLFormElement* imp = static_cast<HTMLFormElement*>(impl()); return jsString(exec, imp->target()); } case ConstructorAttrNum: return getConstructor(exec); } return 0; }
void setJSHTMLFormElementTarget(ExecState* exec, JSObject* thisObject, JSValue value) { JSHTMLFormElement* castedThisObj = static_cast<JSHTMLFormElement*>(thisObject); HTMLFormElement* imp = static_cast<HTMLFormElement*>(castedThisObj->impl()); imp->setTarget(valueToStringWithNullCheck(exec, value)); }
void setJSHTMLFormElementNoValidate(ExecState* exec, JSObject* thisObject, JSValue value) { JSHTMLFormElement* castedThisObj = static_cast<JSHTMLFormElement*>(thisObject); HTMLFormElement* imp = static_cast<HTMLFormElement*>(castedThisObj->impl()); imp->setNoValidate(value.toBoolean(exec)); }
void setJSHTMLFormElementMethod(ExecState* exec, JSObject* thisObject, JSValue value) { HTMLFormElement* imp = static_cast<HTMLFormElement*>(static_cast<JSHTMLFormElement*>(thisObject)->impl()); imp->setMethod(valueToStringWithNullCheck(exec, value)); }