mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 03:32:45 +00:00 
			
		
		
		
	LibWeb: Update HTMLFormElement to use navigables
This commit is contained in:
		
							parent
							
								
									4a6ac18cd4
								
							
						
					
					
						commit
						857537f90c
					
				
					 2 changed files with 41 additions and 68 deletions
				
			
		|  | @ -69,10 +69,6 @@ WebIDL::ExceptionOr<void> HTMLFormElement::submit_form(JS::NonnullGCPtr<HTMLElem | ||||||
|     // 3. Let form document be form's node document.
 |     // 3. Let form document be form's node document.
 | ||||||
|     JS::NonnullGCPtr<DOM::Document> form_document = this->document(); |     JS::NonnullGCPtr<DOM::Document> form_document = this->document(); | ||||||
| 
 | 
 | ||||||
|     // FIXME: This is not in the navigable version.
 |  | ||||||
|     // Let form browsing context be the browsing context of form document.
 |  | ||||||
|     auto* form_browsing_context = form_document->browsing_context(); |  | ||||||
| 
 |  | ||||||
|     // 4. If form document's active sandboxing flag set has its sandboxed forms browsing context flag set, then return.
 |     // 4. If form document's active sandboxing flag set has its sandboxed forms browsing context flag set, then return.
 | ||||||
|     if (has_flag(form_document->active_sandboxing_flag_set(), HTML::SandboxingFlagSet::SandboxedForms)) |     if (has_flag(form_document->active_sandboxing_flag_set(), HTML::SandboxingFlagSet::SandboxedForms)) | ||||||
|         return {}; |         return {}; | ||||||
|  | @ -192,9 +188,8 @@ WebIDL::ExceptionOr<void> HTMLFormElement::submit_form(JS::NonnullGCPtr<HTMLElem | ||||||
|     // 19. Let noopener be the result of getting an element's noopener with form and target.
 |     // 19. Let noopener be the result of getting an element's noopener with form and target.
 | ||||||
|     auto no_opener = get_an_elements_noopener(target); |     auto no_opener = get_an_elements_noopener(target); | ||||||
| 
 | 
 | ||||||
|     // FIXME: Update these steps for navigables.
 |  | ||||||
|     // 20. Let targetNavigable be the first return value of applying the rules for choosing a navigable given target, form's node navigable, and noopener.
 |     // 20. Let targetNavigable be the first return value of applying the rules for choosing a navigable given target, form's node navigable, and noopener.
 | ||||||
|     auto target_navigable = form_browsing_context->choose_a_browsing_context(target, no_opener).browsing_context; |     auto target_navigable = form_document->navigable()->choose_a_navigable(target, no_opener).navigable; | ||||||
| 
 | 
 | ||||||
|     // 21. If targetNavigable is null, then return.
 |     // 21. If targetNavigable is null, then return.
 | ||||||
|     if (!target_navigable) { |     if (!target_navigable) { | ||||||
|  | @ -608,7 +603,7 @@ static ErrorOr<String> plain_text_encode(Vector<URL::QueryParam> const& pairs) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-mutate-action
 | // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-mutate-action
 | ||||||
| ErrorOr<void> HTMLFormElement::mutate_action_url(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, String encoding, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, HistoryHandlingBehavior history_handling) | ErrorOr<void> HTMLFormElement::mutate_action_url(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, String encoding, JS::NonnullGCPtr<Navigable> target_navigable, HistoryHandlingBehavior history_handling) | ||||||
| { | { | ||||||
|     // 1. Let pairs be the result of converting to a list of name-value pairs with entry list.
 |     // 1. Let pairs be the result of converting to a list of name-value pairs with entry list.
 | ||||||
|     auto pairs = TRY(convert_to_list_of_name_value_pairs(entry_list)); |     auto pairs = TRY(convert_to_list_of_name_value_pairs(entry_list)); | ||||||
|  | @ -620,16 +615,16 @@ ErrorOr<void> HTMLFormElement::mutate_action_url(AK::URL parsed_action, Vector<X | ||||||
|     parsed_action.set_query(query); |     parsed_action.set_query(query); | ||||||
| 
 | 
 | ||||||
|     // 4. Plan to navigate to parsed action.
 |     // 4. Plan to navigate to parsed action.
 | ||||||
|     plan_to_navigate_to(move(parsed_action), target_navigable, history_handling); |     plan_to_navigate_to(move(parsed_action), Empty {}, target_navigable, history_handling); | ||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-body
 | // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-body
 | ||||||
| ErrorOr<void> HTMLFormElement::submit_as_entity_body(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, [[maybe_unused]] String encoding, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, HistoryHandlingBehavior history_handling) | ErrorOr<void> HTMLFormElement::submit_as_entity_body(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, [[maybe_unused]] String encoding, JS::NonnullGCPtr<Navigable> target_navigable, HistoryHandlingBehavior history_handling) | ||||||
| { | { | ||||||
|     // 1. Assert: method is POST.
 |     // 1. Assert: method is POST.
 | ||||||
| 
 | 
 | ||||||
|     ByteBuffer mime_type; |     POSTResource::RequestContentType mime_type {}; | ||||||
|     ByteBuffer body; |     ByteBuffer body; | ||||||
| 
 | 
 | ||||||
|     // 2. Switch on enctype:
 |     // 2. Switch on enctype:
 | ||||||
|  | @ -646,7 +641,7 @@ ErrorOr<void> HTMLFormElement::submit_as_entity_body(AK::URL parsed_action, Vect | ||||||
|         // NOTE: `encoding` refers to `UTF-8 encode`, which body already is encoded as because it uses AK::String.
 |         // NOTE: `encoding` refers to `UTF-8 encode`, which body already is encoded as because it uses AK::String.
 | ||||||
| 
 | 
 | ||||||
|         // 4. Let mimeType be `application/x-www-form-urlencoded`.
 |         // 4. Let mimeType be `application/x-www-form-urlencoded`.
 | ||||||
|         mime_type = TRY(ByteBuffer::copy("application/x-www-form-urlencoded"sv.bytes())); |         mime_type = POSTResource::RequestContentType::ApplicationXWWWFormUrlencoded; | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     case EncodingTypeAttributeState::FormData: { |     case EncodingTypeAttributeState::FormData: { | ||||||
|  | @ -657,7 +652,7 @@ ErrorOr<void> HTMLFormElement::submit_as_entity_body(AK::URL parsed_action, Vect | ||||||
| 
 | 
 | ||||||
|         // 2. Let mimeType be the isomorphic encoding of the concatenation of "multipart/form-data; boundary=" and the multipart/form-data
 |         // 2. Let mimeType be the isomorphic encoding of the concatenation of "multipart/form-data; boundary=" and the multipart/form-data
 | ||||||
|         //    boundary string generated by the multipart/form-data encoding algorithm.
 |         //    boundary string generated by the multipart/form-data encoding algorithm.
 | ||||||
|         mime_type = TRY(ByteBuffer::copy(TRY(String::formatted("multipart/form-data; boundary={}", body_and_mime_type.boundary)).bytes())); |         mime_type = POSTResource::RequestContentType::MultipartFormData; | ||||||
|         return {}; |         return {}; | ||||||
|     } |     } | ||||||
|     case EncodingTypeAttributeState::PlainText: { |     case EncodingTypeAttributeState::PlainText: { | ||||||
|  | @ -671,40 +666,28 @@ ErrorOr<void> HTMLFormElement::submit_as_entity_body(AK::URL parsed_action, Vect | ||||||
|         // FIXME: 3. Set body to the result of encoding body using encoding.
 |         // FIXME: 3. Set body to the result of encoding body using encoding.
 | ||||||
| 
 | 
 | ||||||
|         // 4. Let mimeType be `text/plain`.
 |         // 4. Let mimeType be `text/plain`.
 | ||||||
|         mime_type = TRY(ByteBuffer::copy("text/plain"sv.bytes())); |         mime_type = POSTResource::RequestContentType::TextPlain; | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     default: |     default: | ||||||
|         VERIFY_NOT_REACHED(); |         VERIFY_NOT_REACHED(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // FIXME: Update this to the navigable version.
 |     // 3. Plan to navigate to parsed action given a POST resource whose request body is body and request content-type is mimeType.
 | ||||||
|     // 3. Plan to navigate to a new request whose url is parsed action, method is method, header list consists of `Content-Type`/MIME type,
 |     plan_to_navigate_to(parsed_action, POSTResource { .request_body = move(body), .request_content_type = mime_type }, target_navigable, history_handling); | ||||||
|     //    and body is body.
 |  | ||||||
|     auto request = Fetch::Infrastructure::Request::create(vm()); |  | ||||||
|     request->set_url(move(parsed_action)); |  | ||||||
|     request->set_method(TRY(ByteBuffer::copy("POST"sv.bytes()))); |  | ||||||
|     request->set_body(move(body)); |  | ||||||
| 
 |  | ||||||
|     auto temp_header = Fetch::Infrastructure::Header { |  | ||||||
|         .name = TRY(ByteBuffer::copy("Content-Type"sv.bytes())), |  | ||||||
|         .value = move(mime_type), |  | ||||||
|     }; |  | ||||||
|     TRY(request->header_list()->append(move(temp_header))); |  | ||||||
|     plan_to_navigate_to(request, target_navigable, history_handling); |  | ||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-get-action
 | // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-get-action
 | ||||||
| void HTMLFormElement::get_action_url(AK::URL parsed_action, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, Web::HTML::HistoryHandlingBehavior history_handling) | void HTMLFormElement::get_action_url(AK::URL parsed_action, JS::NonnullGCPtr<Navigable> target_navigable, Web::HTML::HistoryHandlingBehavior history_handling) | ||||||
| { | { | ||||||
|     // 1. Plan to navigate to parsed action.
 |     // 1. Plan to navigate to parsed action.
 | ||||||
|     // Spec Note: entry list is discarded.
 |     // Spec Note: entry list is discarded.
 | ||||||
|     plan_to_navigate_to(move(parsed_action), target_navigable, history_handling); |     plan_to_navigate_to(move(parsed_action), Empty {}, target_navigable, history_handling); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-mailto-headers
 | // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-mailto-headers
 | ||||||
| ErrorOr<void> HTMLFormElement::mail_with_headers(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, [[maybe_unused]] String encoding, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, HistoryHandlingBehavior history_handling) | ErrorOr<void> HTMLFormElement::mail_with_headers(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, [[maybe_unused]] String encoding, JS::NonnullGCPtr<Navigable> target_navigable, HistoryHandlingBehavior history_handling) | ||||||
| { | { | ||||||
|     // 1. Let pairs be the result of converting to a list of name-value pairs with entry list.
 |     // 1. Let pairs be the result of converting to a list of name-value pairs with entry list.
 | ||||||
|     auto pairs = TRY(convert_to_list_of_name_value_pairs(entry_list)); |     auto pairs = TRY(convert_to_list_of_name_value_pairs(entry_list)); | ||||||
|  | @ -719,11 +702,11 @@ ErrorOr<void> HTMLFormElement::mail_with_headers(AK::URL parsed_action, Vector<X | ||||||
|     parsed_action.set_query(headers); |     parsed_action.set_query(headers); | ||||||
| 
 | 
 | ||||||
|     // 5. Plan to navigate to parsed action.
 |     // 5. Plan to navigate to parsed action.
 | ||||||
|     plan_to_navigate_to(move(parsed_action), target_navigable, history_handling); |     plan_to_navigate_to(move(parsed_action), Empty {}, target_navigable, history_handling); | ||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ErrorOr<void> HTMLFormElement::mail_as_body(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, [[maybe_unused]] String encoding, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, HistoryHandlingBehavior history_handling) | ErrorOr<void> HTMLFormElement::mail_as_body(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, [[maybe_unused]] String encoding, JS::NonnullGCPtr<Navigable> target_navigable, HistoryHandlingBehavior history_handling) | ||||||
| { | { | ||||||
|     // 1. Let pairs be the result of converting to a list of name-value pairs with entry list.
 |     // 1. Let pairs be the result of converting to a list of name-value pairs with entry list.
 | ||||||
|     auto pairs = TRY(convert_to_list_of_name_value_pairs(entry_list)); |     auto pairs = TRY(convert_to_list_of_name_value_pairs(entry_list)); | ||||||
|  | @ -772,17 +755,28 @@ ErrorOr<void> HTMLFormElement::mail_as_body(AK::URL parsed_action, Vector<XHR::F | ||||||
|     parsed_action.set_query(MUST(query_builder.to_string())); |     parsed_action.set_query(MUST(query_builder.to_string())); | ||||||
| 
 | 
 | ||||||
|     // 7. Plan to navigate to parsed action.
 |     // 7. Plan to navigate to parsed action.
 | ||||||
|     plan_to_navigate_to(move(parsed_action), target_navigable, history_handling); |     plan_to_navigate_to(move(parsed_action), Empty {}, target_navigable, history_handling); | ||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plan-to-navigate
 | // FIXME:
 | ||||||
| void HTMLFormElement::plan_to_navigate_to(Variant<AK::URL, JS::NonnullGCPtr<Fetch::Infrastructure::Request>> resource, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, HistoryHandlingBehavior history_handling) | static Bindings::NavigationHistoryBehavior to_navigation_history_behavior(HistoryHandlingBehavior b) | ||||||
| { | { | ||||||
|     // FIXME: Update this to the navigable version.
 |     switch (b) { | ||||||
|  |     case HistoryHandlingBehavior::Push: | ||||||
|  |         return Bindings::NavigationHistoryBehavior::Push; | ||||||
|  |     case HistoryHandlingBehavior::Replace: | ||||||
|  |         return Bindings::NavigationHistoryBehavior::Replace; | ||||||
|  |     default: | ||||||
|  |         return Bindings::NavigationHistoryBehavior::Auto; | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|  | // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plan-to-navigate
 | ||||||
|  | void HTMLFormElement::plan_to_navigate_to(AK::URL url, Variant<Empty, String, POSTResource> post_resource, JS::NonnullGCPtr<Navigable> target_navigable, HistoryHandlingBehavior history_handling) | ||||||
|  | { | ||||||
|     // 1. Let referrerPolicy be the empty string.
 |     // 1. Let referrerPolicy be the empty string.
 | ||||||
|     Optional<ReferrerPolicy::ReferrerPolicy> referrer_policy; |     ReferrerPolicy::ReferrerPolicy referrer_policy = ReferrerPolicy::ReferrerPolicy::EmptyString; | ||||||
| 
 | 
 | ||||||
|     // 2. If the form element's link types include the noreferrer keyword, then set referrerPolicy to "no-referrer".
 |     // 2. If the form element's link types include the noreferrer keyword, then set referrerPolicy to "no-referrer".
 | ||||||
|     auto rel = deprecated_attribute(HTML::AttributeNames::rel).to_lowercase(); |     auto rel = deprecated_attribute(HTML::AttributeNames::rel).to_lowercase(); | ||||||
|  | @ -797,36 +791,15 @@ void HTMLFormElement::plan_to_navigate_to(Variant<AK::URL, JS::NonnullGCPtr<Fetc | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto actual_resource = resource.visit( |  | ||||||
|         [this](AK::URL url) { |  | ||||||
|             // NOTE: BrowsingContext::navigate is supposed to do this for us, however it currently doesn't.
 |  | ||||||
|             //       This will eventually be replaced with URL + POST-resource when updated to the navigable version however,
 |  | ||||||
|             //       so it's not worth changing BrowsingContext::navigate.
 |  | ||||||
|             auto request = Fetch::Infrastructure::Request::create(vm()); |  | ||||||
|             request->set_url(url); |  | ||||||
|             return request; |  | ||||||
|         }, |  | ||||||
|         [](JS::NonnullGCPtr<Fetch::Infrastructure::Request> request) { |  | ||||||
|             return request; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     actual_resource->set_referrer_policy(move(referrer_policy)); |  | ||||||
| 
 |  | ||||||
|     // 4. Queue an element task on the DOM manipulation task source given the form element and the following steps:
 |     // 4. Queue an element task on the DOM manipulation task source given the form element and the following steps:
 | ||||||
|     // NOTE: `this`, `actual_resource` and `target_navigable` are protected by JS::SafeFunction.
 |     // NOTE: `this`, `actual_resource` and `target_navigable` are protected by JS::SafeFunction.
 | ||||||
|     queue_an_element_task(Task::Source::DOMManipulation, [this, actual_resource, target_navigable, history_handling]() { |     queue_an_element_task(Task::Source::DOMManipulation, [this, url, post_resource, target_navigable, history_handling, referrer_policy]() { | ||||||
|         // 1. Set the form's planned navigation to null.
 |         // 1. Set the form's planned navigation to null.
 | ||||||
|         m_planned_navigation = nullptr; |         m_planned_navigation = nullptr; | ||||||
| 
 | 
 | ||||||
|         // FIXME: 2. Navigate targetNavigable to url using the form element's node document, with historyHandling set to historyHandling,
 |         // 2. Navigate targetNavigable to url using the form element's node document, with historyHandling set to historyHandling,
 | ||||||
|         //    referrerPolicy set to referrerPolicy, documentResource set to postResource, and cspNavigationType set to "form-submission".
 |         //    referrerPolicy set to referrerPolicy, documentResource set to postResource, and cspNavigationType set to "form-submission".
 | ||||||
|         // Browsing Context version:
 |         MUST(target_navigable->navigate(url, this->document(), post_resource, nullptr, false, to_navigation_history_behavior(history_handling), {}, {}, referrer_policy)); | ||||||
|         // Navigate target browsing context to destination. If replace is true, then target browsing context must be navigated with
 |  | ||||||
|         // replacement enabled.
 |  | ||||||
|         // NOTE: This uses the current node document's browsing context, as the submission events or any code run after planning the navigation
 |  | ||||||
|         //       could have adopted the node to a different document.
 |  | ||||||
|         VERIFY(document().browsing_context()); |  | ||||||
|         MUST(target_navigable->navigate(actual_resource, *document().browsing_context(), false, history_handling)); |  | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     // 5. Set the form's planned navigation to the just-queued task.
 |     // 5. Set the form's planned navigation to the just-queued task.
 | ||||||
|  |  | ||||||
|  | @ -96,12 +96,12 @@ private: | ||||||
| 
 | 
 | ||||||
|     ErrorOr<String> pick_an_encoding() const; |     ErrorOr<String> pick_an_encoding() const; | ||||||
| 
 | 
 | ||||||
|     ErrorOr<void> mutate_action_url(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, String encoding, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, HistoryHandlingBehavior history_handling); |     ErrorOr<void> mutate_action_url(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, String encoding, JS::NonnullGCPtr<Navigable> target_navigable, HistoryHandlingBehavior history_handling); | ||||||
|     ErrorOr<void> submit_as_entity_body(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, String encoding, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, HistoryHandlingBehavior history_handling); |     ErrorOr<void> submit_as_entity_body(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, String encoding, JS::NonnullGCPtr<Navigable> target_navigable, HistoryHandlingBehavior history_handling); | ||||||
|     void get_action_url(AK::URL parsed_action, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, HistoryHandlingBehavior history_handling); |     void get_action_url(AK::URL parsed_action, JS::NonnullGCPtr<Navigable> target_navigable, HistoryHandlingBehavior history_handling); | ||||||
|     ErrorOr<void> mail_with_headers(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, String encoding, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, HistoryHandlingBehavior history_handling); |     ErrorOr<void> mail_with_headers(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, String encoding, JS::NonnullGCPtr<Navigable> target_navigable, HistoryHandlingBehavior history_handling); | ||||||
|     ErrorOr<void> mail_as_body(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, String encoding, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, HistoryHandlingBehavior history_handling); |     ErrorOr<void> mail_as_body(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, String encoding, JS::NonnullGCPtr<Navigable> target_navigable, HistoryHandlingBehavior history_handling); | ||||||
|     void plan_to_navigate_to(Variant<AK::URL, JS::NonnullGCPtr<Fetch::Infrastructure::Request>> resource, JS::NonnullGCPtr<AbstractBrowsingContext> target_navigable, HistoryHandlingBehavior history_handling); |     void plan_to_navigate_to(AK::URL url, Variant<Empty, String, POSTResource> post_resource, JS::NonnullGCPtr<Navigable> target_navigable, HistoryHandlingBehavior history_handling); | ||||||
| 
 | 
 | ||||||
|     bool m_firing_submission_events { false }; |     bool m_firing_submission_events { false }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Aliaksandr Kalenik
						Aliaksandr Kalenik