mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 12:19:54 +00:00
LibWeb: Port Document encoding_parse_url and parse_url to Optional<URL>
This ports two more APIs away from URL::is_valid.
This commit is contained in:
parent
cfe9b7a82b
commit
22a7cd9700
Notes:
github-actions[bot]
2025-01-27 00:04:07 +00:00
Author: https://github.com/shannonbooth
Commit: 22a7cd9700
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3362
Reviewed-by: https://github.com/tcl3 ✅
26 changed files with 135 additions and 107 deletions
|
@ -466,10 +466,15 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla
|
|||
if (!matches_link_pseudo_class(element))
|
||||
return false;
|
||||
auto document_url = element.document().url();
|
||||
URL::URL target_url = element.document().encoding_parse_url(element.attribute(HTML::AttributeNames::href).value_or({}));
|
||||
if (target_url.fragment().has_value())
|
||||
return document_url.equals(target_url, URL::ExcludeFragment::No);
|
||||
return document_url.equals(target_url, URL::ExcludeFragment::Yes);
|
||||
auto maybe_href = element.attribute(HTML::AttributeNames::href);
|
||||
if (!maybe_href.has_value())
|
||||
return false;
|
||||
auto target_url = element.document().encoding_parse_url(*maybe_href);
|
||||
if (!target_url.has_value())
|
||||
return false;
|
||||
if (target_url->fragment().has_value())
|
||||
return document_url.equals(*target_url, URL::ExcludeFragment::No);
|
||||
return document_url.equals(*target_url, URL::ExcludeFragment::Yes);
|
||||
}
|
||||
case CSS::PseudoClass::Visited:
|
||||
// FIXME: Maybe match this selector sometimes?
|
||||
|
|
|
@ -2923,7 +2923,7 @@ Optional<FontLoader&> StyleComputer::load_font_face(ParsedFontFace const& font_f
|
|||
for (auto const& source : font_face.sources()) {
|
||||
// FIXME: These should be loaded relative to the stylesheet URL instead of the document URL.
|
||||
if (source.local_or_url.has<URL::URL>())
|
||||
urls.append(m_document->encoding_parse_url(source.local_or_url.get<URL::URL>().to_string()));
|
||||
urls.append(*m_document->encoding_parse_url(source.local_or_url.get<URL::URL>().to_string()));
|
||||
// FIXME: Handle local()
|
||||
}
|
||||
|
||||
|
|
|
@ -1122,17 +1122,17 @@ URL::URL Document::base_url() const
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#parse-a-url
|
||||
URL::URL Document::parse_url(StringView url) const
|
||||
Optional<URL::URL> Document::parse_url(StringView url) const
|
||||
{
|
||||
// 1. Let baseURL be environment's base URL, if environment is a Document object; otherwise environment's API base URL.
|
||||
auto base_url = this->base_url();
|
||||
|
||||
// 2. Return the result of applying the URL parser to url, with baseURL.
|
||||
return DOMURL::parse(url, base_url).value_or(URL::URL {});
|
||||
return DOMURL::parse(url, base_url);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#encoding-parsing-a-url
|
||||
URL::URL Document::encoding_parse_url(StringView url) const
|
||||
Optional<URL::URL> Document::encoding_parse_url(StringView url) const
|
||||
{
|
||||
// 1. Let encoding be UTF-8.
|
||||
// 2. If environment is a Document object, then set encoding to environment's character encoding.
|
||||
|
@ -1145,7 +1145,7 @@ URL::URL Document::encoding_parse_url(StringView url) const
|
|||
auto base_url = this->base_url();
|
||||
|
||||
// 5. Return the result of applying the URL parser to url, with baseURL and encoding.
|
||||
return DOMURL::parse(url, base_url, encoding).value_or(URL::URL {});
|
||||
return DOMURL::parse(url, base_url, encoding);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#encoding-parsing-and-serializing-a-url
|
||||
|
@ -1155,11 +1155,11 @@ Optional<String> Document::encoding_parse_and_serialize_url(StringView url) cons
|
|||
auto parsed_url = encoding_parse_url(url);
|
||||
|
||||
// 2. If url is failure, then return failure.
|
||||
if (!parsed_url.is_valid())
|
||||
if (!parsed_url.has_value())
|
||||
return {};
|
||||
|
||||
// 3. Return the result of applying the URL serializer to url.
|
||||
return parsed_url.serialize();
|
||||
return parsed_url->serialize();
|
||||
}
|
||||
|
||||
void Document::set_needs_layout()
|
||||
|
@ -4752,10 +4752,10 @@ void Document::shared_declarative_refresh_steps(StringView input, GC::Ptr<HTML::
|
|||
// 11. Parse: Parse urlString relative to document. If that fails, return. Otherwise, set urlRecord to the
|
||||
// resulting URL record.
|
||||
auto maybe_url_record = parse_url(url_string);
|
||||
if (!maybe_url_record.is_valid())
|
||||
if (!maybe_url_record.has_value())
|
||||
return;
|
||||
|
||||
url_record = maybe_url_record;
|
||||
url_record = maybe_url_record.release_value();
|
||||
}
|
||||
|
||||
// 12. Set document's will declaratively refresh to true.
|
||||
|
|
|
@ -162,8 +162,8 @@ public:
|
|||
HTML::OpenerPolicy const& opener_policy() const { return m_opener_policy; }
|
||||
void set_opener_policy(HTML::OpenerPolicy policy) { m_opener_policy = move(policy); }
|
||||
|
||||
URL::URL parse_url(StringView) const;
|
||||
URL::URL encoding_parse_url(StringView) const;
|
||||
Optional<URL::URL> parse_url(StringView) const;
|
||||
Optional<URL::URL> encoding_parse_url(StringView) const;
|
||||
Optional<String> encoding_parse_and_serialize_url(StringView) const;
|
||||
|
||||
CSS::StyleComputer& style_computer() { return *m_style_computer; }
|
||||
|
|
|
@ -125,12 +125,13 @@ void HTMLBodyElement::attribute_changed(FlyString const& name, Optional<String>
|
|||
document().set_visited_link_color(color.value());
|
||||
} else if (name.equals_ignoring_ascii_case("background"sv)) {
|
||||
// https://html.spec.whatwg.org/multipage/rendering.html#the-page:attr-background
|
||||
m_background_style_value = CSS::ImageStyleValue::create(document().encoding_parse_url(value.value_or(String {})));
|
||||
m_background_style_value->on_animate = [this] {
|
||||
if (paintable()) {
|
||||
paintable()->set_needs_display();
|
||||
}
|
||||
};
|
||||
if (auto maybe_background_url = document().encoding_parse_url(value.value_or(String {})); maybe_background_url.has_value()) {
|
||||
m_background_style_value = CSS::ImageStyleValue::create(maybe_background_url.value());
|
||||
m_background_style_value->on_animate = [this] {
|
||||
if (paintable())
|
||||
paintable()->set_needs_display();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#undef __ENUMERATE
|
||||
|
|
|
@ -223,13 +223,13 @@ WebIDL::ExceptionOr<void> HTMLFormElement::submit_form(GC::Ref<HTMLElement> subm
|
|||
// 14. Parse a URL given action, relative to the submitter element's node document. If this fails, return.
|
||||
// 15. Let parsed action be the resulting URL record.
|
||||
auto parsed_action = submitter->document().parse_url(action);
|
||||
if (!parsed_action.is_valid()) {
|
||||
if (!parsed_action.has_value()) {
|
||||
dbgln("Failed to submit form: Invalid URL: {}", action);
|
||||
return {};
|
||||
}
|
||||
|
||||
// 16. Let scheme be the scheme of parsed action.
|
||||
auto const& scheme = parsed_action.scheme();
|
||||
auto const& scheme = parsed_action->scheme();
|
||||
|
||||
// 17. Let enctype be the submitter element's enctype.
|
||||
auto encoding_type = encoding_type_state_from_form_element(submitter);
|
||||
|
@ -282,21 +282,21 @@ WebIDL::ExceptionOr<void> HTMLFormElement::submit_form(GC::Ref<HTMLElement> subm
|
|||
|
||||
if (scheme.is_one_of("http"sv, "https"sv)) {
|
||||
if (method == MethodAttributeState::GET)
|
||||
TRY_OR_THROW_OOM(vm, mutate_action_url(move(parsed_action), move(entry_list), move(encoding), *target_navigable, history_handling, options.user_involvement));
|
||||
TRY_OR_THROW_OOM(vm, mutate_action_url(parsed_action.release_value(), move(entry_list), move(encoding), *target_navigable, history_handling, options.user_involvement));
|
||||
else
|
||||
TRY_OR_THROW_OOM(vm, submit_as_entity_body(move(parsed_action), move(entry_list), encoding_type, move(encoding), *target_navigable, history_handling, options.user_involvement));
|
||||
TRY_OR_THROW_OOM(vm, submit_as_entity_body(parsed_action.release_value(), move(entry_list), encoding_type, move(encoding), *target_navigable, history_handling, options.user_involvement));
|
||||
} else if (scheme.is_one_of("ftp"sv, "javascript"sv)) {
|
||||
get_action_url(move(parsed_action), *target_navigable, history_handling, options.user_involvement);
|
||||
get_action_url(parsed_action.release_value(), *target_navigable, history_handling, options.user_involvement);
|
||||
} else if (scheme.is_one_of("data"sv, "file"sv)) {
|
||||
if (method == MethodAttributeState::GET)
|
||||
TRY_OR_THROW_OOM(vm, mutate_action_url(move(parsed_action), move(entry_list), move(encoding), *target_navigable, history_handling, options.user_involvement));
|
||||
TRY_OR_THROW_OOM(vm, mutate_action_url(parsed_action.release_value(), move(entry_list), move(encoding), *target_navigable, history_handling, options.user_involvement));
|
||||
else
|
||||
get_action_url(move(parsed_action), *target_navigable, history_handling, options.user_involvement);
|
||||
get_action_url(parsed_action.release_value(), *target_navigable, history_handling, options.user_involvement);
|
||||
} else if (scheme == "mailto"sv) {
|
||||
if (method == MethodAttributeState::GET)
|
||||
TRY_OR_THROW_OOM(vm, mail_with_headers(move(parsed_action), move(entry_list), move(encoding), *target_navigable, history_handling, options.user_involvement));
|
||||
TRY_OR_THROW_OOM(vm, mail_with_headers(parsed_action.release_value(), move(entry_list), move(encoding), *target_navigable, history_handling, options.user_involvement));
|
||||
else
|
||||
TRY_OR_THROW_OOM(vm, mail_as_body(move(parsed_action), move(entry_list), encoding_type, move(encoding), *target_navigable, history_handling, options.user_involvement));
|
||||
TRY_OR_THROW_OOM(vm, mail_as_body(parsed_action.release_value(), move(entry_list), encoding_type, move(encoding), *target_navigable, history_handling, options.user_involvement));
|
||||
} else {
|
||||
dbgln("Failed to submit form: Unknown scheme: {}", scheme);
|
||||
return {};
|
||||
|
|
|
@ -47,8 +47,8 @@ void HTMLHyperlinkElementUtils::set_the_url()
|
|||
auto url = hyperlink_element_utils_document().encoding_parse_url(*href_content_attribute);
|
||||
|
||||
// 4. If url is not failure, then set this element's url to url.
|
||||
if (url.is_valid())
|
||||
m_url = move(url);
|
||||
if (url.has_value())
|
||||
m_url = url.release_value();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/links.html#dom-hyperlink-origin
|
||||
|
|
|
@ -522,13 +522,13 @@ ErrorOr<void> HTMLImageElement::update_the_image_data(bool restart_animations, b
|
|||
// If that is not successful, then abort this inner set of steps.
|
||||
// Otherwise, let urlString be the resulting URL string.
|
||||
auto url_string = document().parse_url(selected_source.value());
|
||||
if (!url_string.is_valid())
|
||||
if (!url_string.has_value())
|
||||
goto after_step_7;
|
||||
|
||||
// 2. Let key be a tuple consisting of urlString, the img element's crossorigin attribute's mode,
|
||||
// and, if that mode is not No CORS, the node document's origin.
|
||||
ListOfAvailableImages::Key key;
|
||||
key.url = url_string;
|
||||
key.url = url_string.value();
|
||||
key.mode = m_cors_setting;
|
||||
key.origin = document().origin();
|
||||
|
||||
|
@ -564,7 +564,7 @@ ErrorOr<void> HTMLImageElement::update_the_image_data(bool restart_animations, b
|
|||
restart_the_animation();
|
||||
|
||||
// 2. Set current request's current URL to urlString.
|
||||
m_current_request->set_current_url(realm(), url_string);
|
||||
m_current_request->set_current_url(realm(), *url_string);
|
||||
|
||||
// 3. If maybe omit events is not set or previousURL is not equal to urlString, then fire an event named load at the img element.
|
||||
if (!maybe_omit_events || previous_url != url_string)
|
||||
|
@ -622,7 +622,7 @@ after_step_7:
|
|||
// 12. Parse selected source, relative to the element's node document, and let urlString be the resulting URL string.
|
||||
auto url_string = document().parse_url(selected_source.value().url.to_byte_string());
|
||||
// If that is not successful, then:
|
||||
if (!url_string.is_valid()) {
|
||||
if (!url_string.has_value()) {
|
||||
// 1. Abort the image request for the current request and the pending request.
|
||||
abort_the_image_request(realm(), m_current_request);
|
||||
abort_the_image_request(realm(), m_pending_request);
|
||||
|
@ -673,7 +673,7 @@ after_step_7:
|
|||
|
||||
// 16. Set image request to a new image request whose current URL is urlString.
|
||||
auto image_request = ImageRequest::create(realm(), document().page());
|
||||
image_request->set_current_url(realm(), url_string);
|
||||
image_request->set_current_url(realm(), *url_string);
|
||||
|
||||
// 17. If current request's state is unavailable or broken, then set the current request to image request.
|
||||
// Otherwise, set the pending request to image request.
|
||||
|
@ -690,7 +690,7 @@ after_step_7:
|
|||
if (delay_load_event)
|
||||
m_load_event_delayer.emplace(document());
|
||||
|
||||
add_callbacks_to_image_request(*image_request, maybe_omit_events, url_string, previous_url);
|
||||
add_callbacks_to_image_request(*image_request, maybe_omit_events, *url_string, previous_url);
|
||||
|
||||
// AD-HOC: If the image request is already available or fetching, no need to start another fetch.
|
||||
if (image_request->is_available() || image_request->is_fetching())
|
||||
|
@ -698,7 +698,7 @@ after_step_7:
|
|||
|
||||
// 18. Let request be the result of creating a potential-CORS request given urlString, "image",
|
||||
// and the current state of the element's crossorigin content attribute.
|
||||
auto request = create_potential_CORS_request(vm(), url_string, Fetch::Infrastructure::Request::Destination::Image, m_cors_setting);
|
||||
auto request = create_potential_CORS_request(vm(), *url_string, Fetch::Infrastructure::Request::Destination::Image, m_cors_setting);
|
||||
|
||||
// 19. Set request's client to the element's node document's relevant settings object.
|
||||
request->set_client(&document().relevant_settings_object());
|
||||
|
@ -848,7 +848,7 @@ void HTMLImageElement::react_to_changes_in_the_environment()
|
|||
// 6. ⌛ Parse selected source, relative to the element's node document,
|
||||
// and let urlString be the resulting URL string. If that is not successful, then return.
|
||||
auto url_string = document().parse_url(selected_source.value());
|
||||
if (!url_string.is_valid())
|
||||
if (!url_string.has_value())
|
||||
return;
|
||||
|
||||
// 7. ⌛ Let corsAttributeState be the state of the element's crossorigin content attribute.
|
||||
|
@ -862,14 +862,14 @@ void HTMLImageElement::react_to_changes_in_the_environment()
|
|||
|
||||
// 10. ⌛ Let key be a tuple consisting of urlString, corsAttributeState, and, if corsAttributeState is not No CORS, origin.
|
||||
ListOfAvailableImages::Key key;
|
||||
key.url = url_string;
|
||||
key.url = *url_string;
|
||||
key.mode = m_cors_setting;
|
||||
if (cors_attribute_state != CORSSettingAttribute::NoCORS)
|
||||
key.origin = document().origin();
|
||||
|
||||
// 11. ⌛ Let image request be a new image request whose current URL is urlString
|
||||
auto image_request = ImageRequest::create(realm(), document().page());
|
||||
image_request->set_current_url(realm(), url_string);
|
||||
image_request->set_current_url(realm(), *url_string);
|
||||
|
||||
// 12. ⌛ Let the element's pending request be image request.
|
||||
m_pending_request = image_request;
|
||||
|
@ -917,7 +917,7 @@ void HTMLImageElement::react_to_changes_in_the_environment()
|
|||
// Otherwise:
|
||||
else {
|
||||
// 1. Let request be the result of creating a potential-CORS request given urlString, "image", and corsAttributeState.
|
||||
auto request = create_potential_CORS_request(vm(), url_string, Fetch::Infrastructure::Request::Destination::Image, m_cors_setting);
|
||||
auto request = create_potential_CORS_request(vm(), *url_string, Fetch::Infrastructure::Request::Destination::Image, m_cors_setting);
|
||||
|
||||
// 2. Set request's client to client, initiator to "imageset", and set request's synchronous flag.
|
||||
request->set_client(&client);
|
||||
|
|
|
@ -1385,14 +1385,14 @@ WebIDL::ExceptionOr<void> HTMLInputElement::handle_src_attribute(String const& v
|
|||
auto url = document().encoding_parse_url(value);
|
||||
|
||||
// 2. If url is failure, then return.
|
||||
if (!url.is_valid())
|
||||
if (!url.has_value())
|
||||
return {};
|
||||
|
||||
// 3. Let request be a new request whose URL is url, client is the element's node document's relevant settings
|
||||
// object, destination is "image", initiator type is "input", credentials mode is "include", and whose
|
||||
// use-URL-credentials flag is set.
|
||||
auto request = Fetch::Infrastructure::Request::create(vm);
|
||||
request->set_url(move(url));
|
||||
request->set_url(url.release_value());
|
||||
request->set_client(&document().relevant_settings_object());
|
||||
request->set_destination(Fetch::Infrastructure::Request::Destination::Image);
|
||||
request->set_initiator_type(Fetch::Infrastructure::Request::InitiatorType::Input);
|
||||
|
|
|
@ -77,18 +77,25 @@ void HTMLLinkElement::inserted()
|
|||
|
||||
// FIXME: Follow spec for fetching and processing these attributes as well
|
||||
if (m_relationship & Relationship::Preload) {
|
||||
// FIXME: Respect the "as" attribute.
|
||||
LoadRequest request;
|
||||
request.set_url(document().encoding_parse_url(get_attribute_value(HTML::AttributeNames::href)));
|
||||
set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, request));
|
||||
if (auto maybe_href = document().encoding_parse_url(get_attribute_value(HTML::AttributeNames::href)); maybe_href.has_value()) {
|
||||
// FIXME: Respect the "as" attribute.
|
||||
LoadRequest request;
|
||||
request.set_url(maybe_href.value());
|
||||
set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, request));
|
||||
}
|
||||
} else if (m_relationship & Relationship::DNSPrefetch) {
|
||||
ResourceLoader::the().prefetch_dns(document().encoding_parse_url(get_attribute_value(HTML::AttributeNames::href)));
|
||||
if (auto dns_prefetch_url = document().encoding_parse_url(get_attribute_value(HTML::AttributeNames::href)); dns_prefetch_url.has_value()) {
|
||||
ResourceLoader::the().prefetch_dns(dns_prefetch_url.value());
|
||||
}
|
||||
} else if (m_relationship & Relationship::Preconnect) {
|
||||
ResourceLoader::the().preconnect(document().encoding_parse_url(get_attribute_value(HTML::AttributeNames::href)));
|
||||
if (auto maybe_href = document().encoding_parse_url(get_attribute_value(HTML::AttributeNames::href)); maybe_href.has_value()) {
|
||||
ResourceLoader::the().preconnect(maybe_href.value());
|
||||
}
|
||||
} else if (m_relationship & Relationship::Icon) {
|
||||
auto favicon_url = document().encoding_parse_url(href());
|
||||
auto favicon_request = LoadRequest::create_for_url_on_page(favicon_url, &document().page());
|
||||
set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, favicon_request));
|
||||
if (auto favicon_url = document().encoding_parse_url(href()); favicon_url.has_value()) {
|
||||
auto favicon_request = LoadRequest::create_for_url_on_page(favicon_url.value(), &document().page());
|
||||
set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, favicon_request));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,7 +579,7 @@ WebIDL::ExceptionOr<void> HTMLLinkElement::load_fallback_favicon_if_needed(GC::R
|
|||
// synchronous flag is set, credentials mode is "include", and whose use-URL-credentials flag is set.
|
||||
// NOTE: Fetch requests no longer have a synchronous flag, see https://github.com/whatwg/fetch/pull/1165
|
||||
auto request = Fetch::Infrastructure::Request::create(vm);
|
||||
request->set_url(document->parse_url("/favicon.ico"sv));
|
||||
request->set_url(*document->parse_url("/favicon.ico"sv));
|
||||
request->set_client(&document->relevant_settings_object());
|
||||
request->set_destination(Fetch::Infrastructure::Request::Destination::Image);
|
||||
request->set_credentials_mode(Fetch::Infrastructure::Request::CredentialsMode::Include);
|
||||
|
|
|
@ -625,14 +625,14 @@ public:
|
|||
// would have resulted from parsing the URL specified by candidate's src attribute's value relative to the
|
||||
// candidate's node document when the src attribute was last changed.
|
||||
auto url_record = m_candidate->document().parse_url(candiate_src);
|
||||
auto url_string = url_record.to_string();
|
||||
|
||||
// 4. ⌛ If urlString was not obtained successfully, then end the synchronous section, and jump down to the failed
|
||||
// with elements step below.
|
||||
if (!url_record.is_valid()) {
|
||||
if (!url_record.has_value()) {
|
||||
TRY(failed_with_elements());
|
||||
return {};
|
||||
}
|
||||
auto url_string = url_record->to_string();
|
||||
|
||||
// FIXME: 5. ⌛ If candidate has a type attribute whose value, when parsed as a MIME type (including any codecs described
|
||||
// by the codecs parameter, for types that define that parameter), represents a type that the user agent knows
|
||||
|
@ -645,7 +645,7 @@ public:
|
|||
|
||||
// 8. Run the resource fetch algorithm with urlRecord. If that algorithm returns without aborting this one, then
|
||||
// the load failed.
|
||||
TRY(m_media_element->fetch_resource(url_record, [this](auto) {
|
||||
TRY(m_media_element->fetch_resource(*url_record, [this](auto) {
|
||||
failed_with_elements().release_value_but_fixme_should_propagate_errors();
|
||||
}));
|
||||
|
||||
|
@ -871,15 +871,15 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::select_resource()
|
|||
auto url_record = document().parse_url(source);
|
||||
|
||||
// 3. ⌛ If urlString was obtained successfully, set the currentSrc attribute to urlString.
|
||||
if (url_record.is_valid())
|
||||
m_current_src = url_record.to_string();
|
||||
if (url_record.has_value())
|
||||
m_current_src = url_record->to_string();
|
||||
|
||||
// 4. End the synchronous section, continuing the remaining steps in parallel.
|
||||
|
||||
// 5. If urlRecord was obtained successfully, run the resource fetch algorithm with urlRecord. If that algorithm returns without aborting this one,
|
||||
// then the load failed.
|
||||
if (url_record.is_valid()) {
|
||||
TRY(fetch_resource(url_record, move(failed_with_attribute)));
|
||||
if (url_record.has_value()) {
|
||||
TRY(fetch_resource(*url_record, move(failed_with_attribute)));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -169,7 +169,11 @@ String HTMLObjectElement::data() const
|
|||
if (!data.has_value())
|
||||
return {};
|
||||
|
||||
return document().encoding_parse_url(*data).to_string();
|
||||
auto maybe_url = document().encoding_parse_url(*data);
|
||||
if (!maybe_url.has_value())
|
||||
return {};
|
||||
|
||||
return maybe_url->to_string();
|
||||
}
|
||||
|
||||
GC::Ptr<Layout::Node> HTMLObjectElement::create_layout_node(GC::Ref<CSS::ComputedProperties> style)
|
||||
|
@ -257,7 +261,7 @@ void HTMLObjectElement::queue_element_task_to_run_object_representation_steps()
|
|||
auto url = document().encoding_parse_url(*data);
|
||||
|
||||
// 3. If url is failure, then fire an event named error at the element and jump to the step below labeled fallback.
|
||||
if (!url.is_valid()) {
|
||||
if (!url.has_value()) {
|
||||
dispatch_event(DOM::Event::create(realm, HTML::EventNames::error));
|
||||
run_object_representation_fallback_steps();
|
||||
return;
|
||||
|
@ -267,7 +271,7 @@ void HTMLObjectElement::queue_element_task_to_run_object_representation_steps()
|
|||
// object, destination is "object", credentials mode is "include", mode is "navigate", initiator type is
|
||||
// "object", and whose use-URL-credentials flag is set.
|
||||
auto request = Fetch::Infrastructure::Request::create(vm);
|
||||
request->set_url(move(url));
|
||||
request->set_url(url.release_value());
|
||||
request->set_client(&document().relevant_settings_object());
|
||||
request->set_destination(Fetch::Infrastructure::Request::Destination::Object);
|
||||
request->set_credentials_mode(Fetch::Infrastructure::Request::CredentialsMode::Include);
|
||||
|
@ -512,7 +516,13 @@ void HTMLObjectElement::load_image()
|
|||
// FIXME: This currently reloads the image instead of reusing the resource we've already downloaded.
|
||||
auto data = get_attribute_value(HTML::AttributeNames::data);
|
||||
auto url = document().encoding_parse_url(data);
|
||||
m_resource_request = HTML::SharedResourceRequest::get_or_create(realm(), document().page(), url);
|
||||
|
||||
if (!url.has_value()) {
|
||||
run_object_representation_fallback_steps();
|
||||
return;
|
||||
}
|
||||
|
||||
m_resource_request = HTML::SharedResourceRequest::get_or_create(realm(), document().page(), *url);
|
||||
m_resource_request->add_callbacks(
|
||||
[this] {
|
||||
run_object_representation_completed_steps(Representation::Image);
|
||||
|
@ -522,7 +532,7 @@ void HTMLObjectElement::load_image()
|
|||
});
|
||||
|
||||
if (m_resource_request->needs_fetching()) {
|
||||
auto request = HTML::create_potential_CORS_request(vm(), url, Fetch::Infrastructure::Request::Destination::Image, HTML::CORSSettingAttribute::NoCORS);
|
||||
auto request = HTML::create_potential_CORS_request(vm(), *url, Fetch::Infrastructure::Request::Destination::Image, HTML::CORSSettingAttribute::NoCORS);
|
||||
request->set_client(&document().relevant_settings_object());
|
||||
m_resource_request->fetch_resource(realm(), request);
|
||||
}
|
||||
|
|
|
@ -385,7 +385,7 @@ void HTMLScriptElement::prepare_script()
|
|||
auto url = document().parse_url(src);
|
||||
|
||||
// 6. If the previous step failed, then queue an element task on the DOM manipulation task source given el to fire an event named error at el, and return. Otherwise, let url be the resulting URL record.
|
||||
if (!url.is_valid()) {
|
||||
if (!url.has_value()) {
|
||||
dbgln("HTMLScriptElement: Refusing to run script because the src URL '{}' is invalid.", url);
|
||||
queue_an_element_task(HTML::Task::Source::DOMManipulation, [this] {
|
||||
dispatch_event(DOM::Event::create(realm(), HTML::EventNames::error));
|
||||
|
@ -413,16 +413,16 @@ void HTMLScriptElement::prepare_script()
|
|||
// -> "classic"
|
||||
if (m_script_type == ScriptType::Classic) {
|
||||
// Fetch a classic script given url, settings object, options, classic script CORS setting, encoding, and onComplete.
|
||||
fetch_classic_script(*this, url, settings_object, move(options), classic_script_cors_setting, encoding.release_value(), on_complete).release_value_but_fixme_should_propagate_errors();
|
||||
fetch_classic_script(*this, *url, settings_object, move(options), classic_script_cors_setting, encoding.release_value(), on_complete).release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
// -> "module"
|
||||
else if (m_script_type == ScriptType::Module) {
|
||||
// If el does not have an integrity attribute, then set options's integrity metadata to the result of resolving a module integrity metadata with url and settings object.
|
||||
if (!has_attribute(HTML::AttributeNames::integrity))
|
||||
options.integrity_metadata = resolve_a_module_integrity_metadata(url, settings_object);
|
||||
options.integrity_metadata = resolve_a_module_integrity_metadata(*url, settings_object);
|
||||
|
||||
// Fetch an external module script graph given url, settings object, options, and onComplete.
|
||||
fetch_external_module_script_graph(realm(), url, settings_object, options, on_complete);
|
||||
fetch_external_module_script_graph(realm(), *url, settings_object, options, on_complete);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,8 +89,8 @@ void HTMLTableCellElement::apply_presentational_hints(GC::Ref<CSS::CascadedPrope
|
|||
return;
|
||||
} else if (name == HTML::AttributeNames::background) {
|
||||
// https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url
|
||||
if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid())
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value));
|
||||
if (auto parsed_value = document().encoding_parse_url(value); parsed_value.has_value())
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(*parsed_value));
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -91,8 +91,8 @@ void HTMLTableElement::apply_presentational_hints(GC::Ref<CSS::CascadedPropertie
|
|||
}
|
||||
if (name == HTML::AttributeNames::background) {
|
||||
// https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url
|
||||
if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid())
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value));
|
||||
if (auto parsed_value = document().encoding_parse_url(value); parsed_value.has_value())
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(*parsed_value));
|
||||
return;
|
||||
}
|
||||
if (name == HTML::AttributeNames::bgcolor) {
|
||||
|
|
|
@ -62,8 +62,8 @@ void HTMLTableRowElement::apply_presentational_hints(GC::Ref<CSS::CascadedProper
|
|||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value()));
|
||||
} else if (name == HTML::AttributeNames::background) {
|
||||
// https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url
|
||||
if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid())
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value));
|
||||
if (auto parsed_value = document().encoding_parse_url(value); parsed_value.has_value())
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(*parsed_value));
|
||||
} else if (name == HTML::AttributeNames::height) {
|
||||
if (auto parsed_value = parse_dimension_value(value))
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, *parsed_value);
|
||||
|
|
|
@ -115,8 +115,8 @@ void HTMLTableSectionElement::apply_presentational_hints(GC::Ref<CSS::CascadedPr
|
|||
for_each_attribute([&](auto& name, auto& value) {
|
||||
// https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url
|
||||
if (name == HTML::AttributeNames::background) {
|
||||
if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid())
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value));
|
||||
if (auto parsed_value = document().encoding_parse_url(value); parsed_value.has_value())
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(*parsed_value));
|
||||
}
|
||||
// https://html.spec.whatwg.org/multipage/rendering.html#tables-2:rules-for-parsing-a-legacy-colour-value
|
||||
else if (name == HTML::AttributeNames::bgcolor) {
|
||||
|
|
|
@ -164,14 +164,14 @@ WebIDL::ExceptionOr<void> HTMLVideoElement::determine_element_poster_frame(Optio
|
|||
// 3. Parse the poster attribute's value relative to the element's node document. If this fails, then there is no
|
||||
// poster frame; return.
|
||||
auto url_record = document().parse_url(*poster);
|
||||
if (!url_record.is_valid())
|
||||
if (!url_record.has_value())
|
||||
return {};
|
||||
|
||||
// 4. Let request be a new request whose URL is the resulting URL record, client is the element's node document's
|
||||
// relevant settings object, destination is "image", initiator type is "video", credentials mode is "include",
|
||||
// and whose use-URL-credentials flag is set.
|
||||
auto request = Fetch::Infrastructure::Request::create(vm);
|
||||
request->set_url(move(url_record));
|
||||
request->set_url(url_record.release_value());
|
||||
request->set_client(&document().relevant_settings_object());
|
||||
request->set_destination(Fetch::Infrastructure::Request::Destination::Image);
|
||||
request->set_initiator_type(Fetch::Infrastructure::Request::InitiatorType::Video);
|
||||
|
|
|
@ -208,8 +208,8 @@ Optional<URL::URL> NavigableContainer::shared_attribute_processing_steps_for_ifr
|
|||
auto src_attribute_value = get_attribute_value(HTML::AttributeNames::src);
|
||||
if (!src_attribute_value.is_empty()) {
|
||||
auto parsed_src = document().parse_url(src_attribute_value);
|
||||
if (parsed_src.is_valid())
|
||||
url = parsed_src;
|
||||
if (parsed_src.has_value())
|
||||
url = parsed_src.release_value();
|
||||
}
|
||||
|
||||
// 3. If the inclusive ancestor navigables of element's node navigable contains a navigable
|
||||
|
|
|
@ -202,7 +202,7 @@ WebIDL::ExceptionOr<Window::OpenedWindow> Window::window_open_steps_internal(Str
|
|||
url_record = source_document.encoding_parse_url(url);
|
||||
|
||||
// 2. If urlRecord is failure, then throw a "SyntaxError" DOMException.
|
||||
if (!url_record->is_valid())
|
||||
if (!url_record.has_value())
|
||||
return WebIDL::SyntaxError::create(realm(), MUST(String::formatted("Invalid URL '{}'", url)));
|
||||
}
|
||||
|
||||
|
|
|
@ -497,28 +497,31 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
|
|||
GC::Ref<DOM::Document> document = *m_navigable->active_document();
|
||||
auto href = link->href();
|
||||
auto url = document->encoding_parse_url(href);
|
||||
|
||||
if (button == UIEvents::MouseButton::Primary && (modifiers & UIEvents::Mod_PlatformCtrl) != 0) {
|
||||
m_navigable->page().client().page_did_click_link(url, link->target().to_byte_string(), modifiers);
|
||||
} else if (button == UIEvents::MouseButton::Middle) {
|
||||
m_navigable->page().client().page_did_middle_click_link(url, link->target().to_byte_string(), modifiers);
|
||||
} else if (button == UIEvents::MouseButton::Secondary) {
|
||||
m_navigable->page().client().page_did_request_link_context_menu(top_level_viewport_position, url, link->target().to_byte_string(), modifiers);
|
||||
if (url.has_value()) {
|
||||
if (button == UIEvents::MouseButton::Primary && (modifiers & UIEvents::Mod_PlatformCtrl) != 0) {
|
||||
m_navigable->page().client().page_did_click_link(*url, link->target().to_byte_string(), modifiers);
|
||||
} else if (button == UIEvents::MouseButton::Middle) {
|
||||
m_navigable->page().client().page_did_middle_click_link(*url, link->target().to_byte_string(), modifiers);
|
||||
} else if (button == UIEvents::MouseButton::Secondary) {
|
||||
m_navigable->page().client().page_did_request_link_context_menu(top_level_viewport_position, *url, link->target().to_byte_string(), modifiers);
|
||||
}
|
||||
}
|
||||
} else if (button == UIEvents::MouseButton::Secondary) {
|
||||
if (is<HTML::HTMLImageElement>(*node)) {
|
||||
auto& image_element = as<HTML::HTMLImageElement>(*node);
|
||||
auto image_url = image_element.document().encoding_parse_url(image_element.src());
|
||||
Optional<Gfx::Bitmap const*> bitmap;
|
||||
if (image_element.immutable_bitmap())
|
||||
bitmap = image_element.immutable_bitmap()->bitmap();
|
||||
if (image_url.has_value()) {
|
||||
Optional<Gfx::Bitmap const*> bitmap;
|
||||
if (image_element.immutable_bitmap())
|
||||
bitmap = image_element.immutable_bitmap()->bitmap();
|
||||
|
||||
m_navigable->page().client().page_did_request_image_context_menu(top_level_viewport_position, image_url, "", modifiers, bitmap);
|
||||
m_navigable->page().client().page_did_request_image_context_menu(top_level_viewport_position, *image_url, "", modifiers, bitmap);
|
||||
}
|
||||
} else if (is<HTML::HTMLMediaElement>(*node)) {
|
||||
auto& media_element = as<HTML::HTMLMediaElement>(*node);
|
||||
|
||||
Page::MediaContextMenu menu {
|
||||
.media_url = media_element.document().encoding_parse_url(media_element.current_src()),
|
||||
.media_url = *media_element.document().encoding_parse_url(media_element.current_src()),
|
||||
.is_video = is<HTML::HTMLVideoElement>(*node),
|
||||
.is_playing = media_element.potentially_playing(),
|
||||
.is_muted = media_element.muted(),
|
||||
|
@ -811,7 +814,7 @@ EventResult EventHandler::handle_mousemove(CSSPixelPoint viewport_position, CSSP
|
|||
|
||||
if (is_hovering_link) {
|
||||
page.set_is_hovering_link(true);
|
||||
page.client().page_did_hover_link(document.encoding_parse_url(hovered_link_element->href()));
|
||||
page.client().page_did_hover_link(*document.encoding_parse_url(hovered_link_element->href()));
|
||||
} else if (page.is_hovering_link()) {
|
||||
page.set_is_hovering_link(false);
|
||||
page.client().page_did_unhover_link();
|
||||
|
|
|
@ -129,7 +129,9 @@ GC::Ptr<SVGGradientElement const> SVGGradientElement::linked_gradient(HashTable<
|
|||
auto link = has_attribute(AttributeNames::href) ? get_attribute(AttributeNames::href) : get_attribute("xlink:href"_fly_string);
|
||||
if (auto href = link; href.has_value() && !link->is_empty()) {
|
||||
auto url = document().encoding_parse_url(*href);
|
||||
auto id = url.fragment();
|
||||
if (!url.has_value())
|
||||
return {};
|
||||
auto id = url->fragment();
|
||||
if (!id.has_value() || id->is_empty())
|
||||
return {};
|
||||
auto element = document().get_element_by_id(id.value());
|
||||
|
|
|
@ -146,11 +146,10 @@ void SVGImageElement::process_the_url(Optional<String> const& href)
|
|||
}
|
||||
|
||||
m_href = document().parse_url(*href);
|
||||
|
||||
if (!m_href.is_valid())
|
||||
if (!m_href.has_value())
|
||||
return;
|
||||
|
||||
fetch_the_document(m_href);
|
||||
fetch_the_document(*m_href);
|
||||
}
|
||||
|
||||
// https://svgwg.org/svg2-draft/linking.html#processingURL-fetch
|
||||
|
|
|
@ -60,7 +60,7 @@ private:
|
|||
size_t m_current_frame_index { 0 };
|
||||
size_t m_loops_completed { 0 };
|
||||
|
||||
URL::URL m_href;
|
||||
Optional<URL::URL> m_href;
|
||||
|
||||
GC::Ptr<HTML::SharedResourceRequest> m_resource_request;
|
||||
Optional<DOM::DocumentLoadEventDelayer> m_load_event_delayer;
|
||||
|
|
|
@ -53,11 +53,12 @@ void SVGScriptElement::process_the_script_element()
|
|||
if (has_attribute(SVG::AttributeNames::href) || has_attribute_ns(Namespace::XLink.to_string(), SVG::AttributeNames::href)) {
|
||||
auto href_value = href()->base_val();
|
||||
|
||||
script_url = document().parse_url(href_value);
|
||||
if (!script_url.is_valid()) {
|
||||
auto maybe_script_url = document().parse_url(href_value);
|
||||
if (!maybe_script_url.has_value()) {
|
||||
dbgln("Invalid script URL: {}", href_value);
|
||||
return;
|
||||
}
|
||||
script_url = maybe_script_url.release_value();
|
||||
|
||||
auto& vm = realm().vm();
|
||||
auto request = Fetch::Infrastructure::Request::create(vm);
|
||||
|
|
|
@ -433,14 +433,14 @@ void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request,
|
|||
} else {
|
||||
auto link = maybe_link.release_value();
|
||||
auto url = document->encoding_parse_url(link->get_attribute_value(Web::HTML::AttributeNames::href));
|
||||
if (url.query().has_value() && !url.query()->is_empty()) {
|
||||
if (url->query().has_value() && !url->query()->is_empty()) {
|
||||
load_html(page_id, "<h1>Invalid ref test link - query string must be empty</h1>");
|
||||
return;
|
||||
}
|
||||
if (has_mismatch_selector)
|
||||
url.set_query("mismatch"_string);
|
||||
url->set_query("mismatch"_string);
|
||||
|
||||
load_url(page_id, url);
|
||||
load_url(page_id, *url);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue