| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2021-03-08 13:40:53 +01:00
										 |  |  |  * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2021-02-21 18:44:17 +02:00
										 |  |  |  * Copyright (c) 2021, the SerenityOS developers. | 
					
						
							| 
									
										
										
										
											2021-11-18 19:22:59 +00:00
										 |  |  |  * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org> | 
					
						
							| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-14 22:29:06 +01:00
										 |  |  | #include <AK/ByteBuffer.h>
 | 
					
						
							| 
									
										
										
										
											2021-11-18 19:22:59 +00:00
										 |  |  | #include <AK/Debug.h>
 | 
					
						
							| 
									
										
										
										
											2019-10-07 19:06:47 +02:00
										 |  |  | #include <AK/URL.h>
 | 
					
						
							| 
									
										
										
										
											2021-07-30 19:31:46 +01:00
										 |  |  | #include <LibWeb/CSS/Parser/Parser.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-07 10:32:51 +01:00
										 |  |  | #include <LibWeb/DOM/Document.h>
 | 
					
						
							| 
									
										
										
										
											2020-07-26 15:08:16 +02:00
										 |  |  | #include <LibWeb/HTML/HTMLLinkElement.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-01 20:42:50 +02:00
										 |  |  | #include <LibWeb/Loader/ResourceLoader.h>
 | 
					
						
							| 
									
										
										
										
											2019-10-07 19:06:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-28 18:20:36 +02:00
										 |  |  | namespace Web::HTML { | 
					
						
							| 
									
										
										
										
											2020-03-07 10:27:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-18 21:00:52 +01:00
										 |  |  | HTMLLinkElement::HTMLLinkElement(DOM::Document& document, DOM::QualifiedName qualified_name) | 
					
						
							| 
									
										
										
										
											2021-02-07 11:20:15 +01:00
										 |  |  |     : HTMLElement(document, move(qualified_name)) | 
					
						
							| 
									
										
										
										
											2019-10-07 19:06:47 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | HTMLLinkElement::~HTMLLinkElement() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-06 17:58:20 +01:00
										 |  |  | void HTMLLinkElement::inserted() | 
					
						
							| 
									
										
										
										
											2020-06-02 12:53:29 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-04-06 17:58:20 +01:00
										 |  |  |     HTMLElement::inserted(); | 
					
						
							| 
									
										
										
										
											2020-06-02 12:53:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 18:44:17 +02:00
										 |  |  |     if (m_relationship & Relationship::Stylesheet && !(m_relationship & Relationship::Alternate)) { | 
					
						
							| 
									
										
										
										
											2021-11-18 19:22:59 +00:00
										 |  |  |         auto url = document().parse_url(href()); | 
					
						
							|  |  |  |         dbgln_if(CSS_LOADER_DEBUG, "HTMLLinkElement: Loading import URL: {}", url); | 
					
						
							|  |  |  |         auto request = LoadRequest::create_for_url_on_page(url, document().page()); | 
					
						
							| 
									
										
										
										
											2022-02-15 14:11:51 +01:00
										 |  |  |         // NOTE: Mark this element as delaying the document load event *before* calling set_resource()
 | 
					
						
							|  |  |  |         //       as it may trigger a synchronous resource_did_load() callback.
 | 
					
						
							| 
									
										
										
										
											2021-11-18 19:22:59 +00:00
										 |  |  |         m_document_load_event_delayer.emplace(document()); | 
					
						
							| 
									
										
										
										
											2022-02-15 14:11:51 +01:00
										 |  |  |         set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, request)); | 
					
						
							| 
									
										
										
										
											2019-10-07 19:06:47 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-27 02:06:37 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (m_relationship & Relationship::Preload) { | 
					
						
							|  |  |  |         // FIXME: Respect the "as" attribute.
 | 
					
						
							|  |  |  |         LoadRequest request; | 
					
						
							| 
									
										
										
										
											2021-09-28 23:50:10 +03:30
										 |  |  |         request.set_url(document().parse_url(attribute(HTML::AttributeNames::href))); | 
					
						
							| 
									
										
										
										
											2021-09-27 02:06:37 +02:00
										 |  |  |         m_preload_resource = ResourceLoader::the().load_resource(Resource::Type::Generic, request); | 
					
						
							| 
									
										
										
										
											2021-09-28 00:08:29 +03:30
										 |  |  |     } else if (m_relationship & Relationship::DNSPrefetch) { | 
					
						
							|  |  |  |         ResourceLoader::the().prefetch_dns(document().parse_url(attribute(HTML::AttributeNames::href))); | 
					
						
							|  |  |  |     } else if (m_relationship & Relationship::Preconnect) { | 
					
						
							|  |  |  |         ResourceLoader::the().preconnect(document().parse_url(attribute(HTML::AttributeNames::href))); | 
					
						
							| 
									
										
										
										
											2021-09-27 02:06:37 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-07 19:06:47 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-07 10:27:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-15 20:25:25 +02:00
										 |  |  | void HTMLLinkElement::parse_attribute(const FlyString& name, const String& value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (name == HTML::AttributeNames::rel) { | 
					
						
							|  |  |  |         m_relationship = 0; | 
					
						
							|  |  |  |         auto parts = value.split_view(' '); | 
					
						
							|  |  |  |         for (auto& part : parts) { | 
					
						
							| 
									
										
										
										
											2021-09-28 00:08:29 +03:30
										 |  |  |             if (part == "stylesheet"sv) | 
					
						
							| 
									
										
										
										
											2020-06-15 20:25:25 +02:00
										 |  |  |                 m_relationship |= Relationship::Stylesheet; | 
					
						
							| 
									
										
										
										
											2021-09-28 00:08:29 +03:30
										 |  |  |             else if (part == "alternate"sv) | 
					
						
							| 
									
										
										
										
											2020-06-15 20:25:25 +02:00
										 |  |  |                 m_relationship |= Relationship::Alternate; | 
					
						
							| 
									
										
										
										
											2021-09-28 00:08:29 +03:30
										 |  |  |             else if (part == "preload"sv) | 
					
						
							| 
									
										
										
										
											2021-09-27 02:06:37 +02:00
										 |  |  |                 m_relationship |= Relationship::Preload; | 
					
						
							| 
									
										
										
										
											2021-09-28 00:08:29 +03:30
										 |  |  |             else if (part == "dns-prefetch"sv) | 
					
						
							|  |  |  |                 m_relationship |= Relationship::DNSPrefetch; | 
					
						
							|  |  |  |             else if (part == "preconnect"sv) | 
					
						
							|  |  |  |                 m_relationship |= Relationship::Preconnect; | 
					
						
							| 
									
										
										
										
											2020-06-15 20:25:25 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-18 19:22:59 +00:00
										 |  |  | void HTMLLinkElement::resource_did_fail() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     dbgln_if(CSS_LOADER_DEBUG, "HTMLLinkElement: Resource did fail. URL: {}", resource()->url()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_document_load_event_delayer.clear(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void HTMLLinkElement::resource_did_load() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     VERIFY(resource()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_document_load_event_delayer.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!resource()->has_encoded_data()) { | 
					
						
							|  |  |  |         dbgln_if(CSS_LOADER_DEBUG, "HTMLLinkElement: Resource did load, no encoded data. URL: {}", resource()->url()); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         dbgln_if(CSS_LOADER_DEBUG, "HTMLLinkElement: Resource did load, has encoded data. URL: {}", resource()->url()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 21:09:55 +01:00
										 |  |  |     auto sheet = parse_css(CSS::ParsingContext(document(), resource()->url()), resource()->encoded_data()); | 
					
						
							| 
									
										
										
										
											2021-11-18 19:22:59 +00:00
										 |  |  |     if (!sheet) { | 
					
						
							|  |  |  |         dbgln_if(CSS_LOADER_DEBUG, "HTMLLinkElement: Failed to parse stylesheet: {}", resource()->url()); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sheet->set_owner_node(this); | 
					
						
							|  |  |  |     document().style_sheets().add_sheet(sheet.release_nonnull()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 10:27:02 +01:00
										 |  |  | } |