Esempio n. 1
0
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());
}
Esempio n. 2
0
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());
}
Esempio n. 3
0
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();
}
Esempio n. 5
0
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);
    }
}
Esempio n. 7
0
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(']');
}
Esempio n. 9
0
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;
}
Esempio n. 10
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;
    }
    }
}
Esempio n. 11
0
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));
}
Esempio n. 14
0
void setJSHTMLFormElementMethod(ExecState* exec, JSObject* thisObject, JSValue value)
{
    HTMLFormElement* imp = static_cast<HTMLFormElement*>(static_cast<JSHTMLFormElement*>(thisObject)->impl());
    imp->setMethod(valueToStringWithNullCheck(exec, value));
}