PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, bool lockHistory, FormSubmissionTrigger trigger) { ASSERT(form); Document* document = form->document(); KURL actionURL = document->completeURL(attributes.action().isEmpty() ? document->url().string() : attributes.action()); bool isMailtoForm = actionURL.protocolIs("mailto"); bool isMultiPartForm = false; String encodingType = attributes.encodingType(); if (attributes.method() == PostMethod) { isMultiPartForm = attributes.isMultiPartForm(); if (isMultiPartForm && isMailtoForm) { encodingType = "application/x-www-form-urlencoded"; isMultiPartForm = false; } } TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataBuilder::encodingFromAcceptCharset(attributes.acceptCharset(), document); RefPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission()); Vector<pair<String, String> > formValues; for (unsigned i = 0; i < form->associatedElements().size(); ++i) { HTMLFormControlElement* control = form->associatedElements()[i]; if (!control->disabled()) control->appendFormData(*domFormData, isMultiPartForm); if (control->hasLocalName(inputTag)) { HTMLInputElement* input = static_cast<HTMLInputElement*>(control); if (input->isTextField()) { formValues.append(pair<String, String>(input->name(), input->value())); if (input->isSearchField()) input->addSearchResult(); } } } RefPtr<FormData> formData; String boundary; if (isMultiPartForm) { formData = FormData::createMultiPart(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), document); boundary = formData->boundary().data(); } else { formData = FormData::create(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding()); if (attributes.method() == PostMethod && isMailtoForm) { // Convert the form data into a string that we put into the URL. appendMailtoPostFormDataToURL(actionURL, *formData, encodingType); formData = FormData::create(); } } formData->setIdentifier(generateFormDataIdentifier()); String targetOrBaseTarget = attributes.target().isEmpty() ? document->baseTarget() : attributes.target(); RefPtr<FormState> formState = FormState::create(form, formValues, document->frame(), trigger); return adoptRef(new FormSubmission(attributes.method(), actionURL, targetOrBaseTarget, encodingType, formState.release(), formData.release(), boundary, lockHistory, event)); }
// Constructs a new URL given a base URL and a possibly relative input URL. // Any query portion of the relative URL will be encoded in the given encoding. KURL::KURL(const KURL& base, const String& relative, const TextEncoding& encoding) { m_url.init(base, relative, &encoding.encodingForFormSubmission()); }
PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, bool lockHistory, FormSubmissionTrigger trigger) { ASSERT(form); HTMLFormControlElement* submitButton = 0; if (event && event->target()) { for (Node* node = event->target()->toNode(); node; node = node->parentNode()) { if (node->isElementNode() && toElement(node)->isFormControlElement()) { submitButton = static_cast<HTMLFormControlElement*>(node); break; } } } FormSubmission::Attributes copiedAttributes; copiedAttributes.copyFrom(attributes); if (submitButton) { String attributeValue; if (!(attributeValue = submitButton->getAttribute(formactionAttr)).isNull()) copiedAttributes.parseAction(attributeValue); if (!(attributeValue = submitButton->getAttribute(formenctypeAttr)).isNull()) copiedAttributes.updateEncodingType(attributeValue); if (!(attributeValue = submitButton->getAttribute(formmethodAttr)).isNull()) copiedAttributes.updateMethodType(attributeValue); if (!(attributeValue = submitButton->getAttribute(formtargetAttr)).isNull()) copiedAttributes.setTarget(attributeValue); } Document* document = form->document(); KURL actionURL = document->completeURL(copiedAttributes.action().isEmpty() ? document->url().string() : copiedAttributes.action()); bool isMailtoForm = actionURL.protocolIs("mailto"); bool isMultiPartForm = false; String encodingType = copiedAttributes.encodingType(); if (copiedAttributes.method() == PostMethod) { isMultiPartForm = copiedAttributes.isMultiPartForm(); if (isMultiPartForm && isMailtoForm) { encodingType = "application/x-www-form-urlencoded"; isMultiPartForm = false; } } TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataBuilder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document); RefPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission()); Vector<pair<String, String> > formValues; bool containsPasswordData = false; for (unsigned i = 0; i < form->associatedElements().size(); ++i) { FormAssociatedElement* control = form->associatedElements()[i]; HTMLElement* element = toHTMLElement(control); if (!element->isDisabledFormControl()) control->appendFormData(*domFormData, isMultiPartForm); if (element->hasLocalName(inputTag)) { HTMLInputElement* input = static_cast<HTMLInputElement*>(control); if (input->isTextField()) { formValues.append(pair<String, String>(input->name().string(), input->value())); input->addSearchResult(); } if (input->isPasswordField() && !input->value().isEmpty()) containsPasswordData = true; } } RefPtr<FormData> formData; String boundary; if (isMultiPartForm) { formData = FormData::createMultiPart(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), document); boundary = formData->boundary().data(); } else { formData = FormData::create(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), attributes.method() == GetMethod ? FormData::FormURLEncoded : FormData::parseEncodingType(encodingType)); if (copiedAttributes.method() == PostMethod && isMailtoForm) { // Convert the form data into a string that we put into the URL. appendMailtoPostFormDataToURL(actionURL, *formData, encodingType); formData = FormData::create(); } } formData->setIdentifier(generateFormDataIdentifier()); formData->setContainsPasswordData(containsPasswordData); String targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document->baseTarget() : copiedAttributes.target(); RefPtr<FormState> formState = FormState::create(form, formValues, document, trigger); return adoptRef(new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, formState.release(), formData.release(), boundary, lockHistory, event)); }
Ref<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, LockHistory lockHistory, FormSubmissionTrigger trigger) { ASSERT(form); HTMLFormControlElement* submitButton = nullptr; if (event && event->target()) { for (Node* node = event->target()->toNode(); node; node = node->parentNode()) { if (is<HTMLFormControlElement>(*node)) { submitButton = downcast<HTMLFormControlElement>(node); break; } } } FormSubmission::Attributes copiedAttributes; copiedAttributes.copyFrom(attributes); if (submitButton) { AtomicString attributeValue; if (!(attributeValue = submitButton->attributeWithoutSynchronization(formactionAttr)).isNull()) copiedAttributes.parseAction(attributeValue); if (!(attributeValue = submitButton->attributeWithoutSynchronization(formenctypeAttr)).isNull()) copiedAttributes.updateEncodingType(attributeValue); if (!(attributeValue = submitButton->attributeWithoutSynchronization(formmethodAttr)).isNull()) copiedAttributes.updateMethodType(attributeValue); if (!(attributeValue = submitButton->attributeWithoutSynchronization(formtargetAttr)).isNull()) copiedAttributes.setTarget(attributeValue); } Document& document = form->document(); URL actionURL = document.completeURL(copiedAttributes.action().isEmpty() ? document.url().string() : copiedAttributes.action()); bool isMailtoForm = actionURL.protocolIs("mailto"); bool isMultiPartForm = false; String encodingType = copiedAttributes.encodingType(); document.contentSecurityPolicy()->upgradeInsecureRequestIfNeeded(actionURL, ContentSecurityPolicy::InsecureRequestType::FormSubmission); if (copiedAttributes.method() == PostMethod) { isMultiPartForm = copiedAttributes.isMultiPartForm(); if (isMultiPartForm && isMailtoForm) { encodingType = "application/x-www-form-urlencoded"; isMultiPartForm = false; } } TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document); RefPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission()); Vector<std::pair<String, String>> formValues; bool containsPasswordData = false; for (auto& control : form->associatedElements()) { HTMLElement& element = control->asHTMLElement(); if (!element.isDisabledFormControl()) control->appendFormData(*domFormData, isMultiPartForm); if (is<HTMLInputElement>(element)) { HTMLInputElement& input = downcast<HTMLInputElement>(element); if (input.isTextField()) { formValues.append(std::pair<String, String>(input.name().string(), input.value())); input.addSearchResult(); } if (input.isPasswordField() && !input.value().isEmpty()) containsPasswordData = true; } } RefPtr<FormData> formData; String boundary; if (isMultiPartForm) { formData = FormData::createMultiPart(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), &document); boundary = formData->boundary().data(); } else { formData = FormData::create(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), attributes.method() == GetMethod ? FormData::FormURLEncoded : FormData::parseEncodingType(encodingType)); if (copiedAttributes.method() == PostMethod && isMailtoForm) { // Convert the form data into a string that we put into the URL. appendMailtoPostFormDataToURL(actionURL, *formData, encodingType); formData = FormData::create(); } } formData->setIdentifier(generateFormDataIdentifier()); formData->setContainsPasswordData(containsPasswordData); String targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document.baseTarget() : copiedAttributes.target(); auto formState = FormState::create(form, formValues, &document, trigger); return adoptRef(*new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, WTFMove(formState), WTFMove(formData), boundary, lockHistory, event)); }