Explorar el Código

LibHTML: Start adding support for <link rel="stylesheet">

This patch adds basic support for external stylesheets. It currently
only works with file:// URLs.

We do a synchronous full relayout after loading a stylesheet, which is
definitely on the aggressive side, but it gives us something to work
on improving. :^)
Andreas Kling hace 5 años
padre
commit
71e8ddcd1c

+ 8 - 0
Base/home/anon/www/link.css

@@ -0,0 +1,8 @@
+#foo {
+    background-color: teal;
+    color: white;
+    padding-left: 20;
+    padding-top: 20;
+    padding-right: 20;
+    padding-bottom: 20;
+}

+ 9 - 0
Base/home/anon/www/link.html

@@ -0,0 +1,9 @@
+<html>
+<head>
+<title>Link element test</title>
+<link rel="stylesheet" href="link.css">
+</head>
+<body>
+<div id="foo">I should be styled!</div>
+</body>
+</html>

+ 1 - 0
Base/home/anon/www/welcome.html

@@ -22,6 +22,7 @@ h1 {
         <li><a href="phint.html">presentational hints</a></li>
         <li><a href="images.html">images</a></li>
         <li><a href="selectors.html">selectors</a></li>
+        <li><a href="link.html">link element</a></li>
     </ul>
 </body>
 </html>

+ 41 - 0
Libraries/LibHTML/DOM/HTMLLinkElement.cpp

@@ -0,0 +1,41 @@
+#include <AK/URL.h>
+#include <LibCore/CFile.h>
+#include <LibHTML/DOM/Document.h>
+#include <LibHTML/DOM/HTMLLinkElement.h>
+#include <LibHTML/Parser/CSSParser.h>
+
+HTMLLinkElement::HTMLLinkElement(Document& document, const String& tag_name)
+    : HTMLElement(document, tag_name)
+{
+}
+
+HTMLLinkElement::~HTMLLinkElement()
+{
+}
+
+void HTMLLinkElement::inserted_into(Node&)
+{
+    if (rel() == "stylesheet") {
+        URL url = document().complete_url(href());
+        if (url.protocol() != "file") {
+            ASSERT_NOT_REACHED();
+        }
+        auto file = CFile::construct(url.path());
+        if (!file->open(CIODevice::ReadOnly)) {
+            dbg() << "Failed to open " << url.to_string();
+            ASSERT_NOT_REACHED();
+            return;
+        }
+        auto data = file->read_all();
+        auto sheet = parse_css(String::copy(data));
+
+        if (!sheet) {
+            dbg() << "Failed to parse " << url.to_string();
+            ASSERT_NOT_REACHED();
+            return;
+        }
+
+        document().add_sheet(*sheet);
+        document().invalidate_layout();
+    }
+}

+ 21 - 0
Libraries/LibHTML/DOM/HTMLLinkElement.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include <LibHTML/DOM/HTMLElement.h>
+
+class HTMLLinkElement final : public HTMLElement {
+public:
+    HTMLLinkElement(Document&, const String& tag_name);
+    virtual ~HTMLLinkElement() override;
+
+    virtual void inserted_into(Node&) override;
+
+    String rel() const { return attribute("rel"); }
+    String type() const { return attribute("type"); }
+    String href() const { return attribute("href"); }
+};
+
+template<>
+inline bool is<HTMLLinkElement>(const Node& node)
+{
+    return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "link";
+}

+ 5 - 1
Libraries/LibHTML/HtmlView.cpp

@@ -36,7 +36,11 @@ void HtmlView::set_document(Document* document)
         m_document->on_invalidate_layout = nullptr;
 
     m_document = document;
-    m_document->on_invalidate_layout = [this]() { layout_and_sync_size(); };
+    m_document->on_invalidate_layout = [this]() {
+        m_layout_root = m_document->create_layout_tree(m_document->style_resolver(), nullptr);
+        layout_and_sync_size();
+        update();
+    };
 
     main_frame().set_document(document);
 

+ 1 - 0
Libraries/LibHTML/Makefile.shared

@@ -13,6 +13,7 @@ LIBHTML_OBJS = \
     DOM/HTMLBodyElement.o \
     DOM/HTMLFontElement.o \
     DOM/HTMLImageElement.o \
+    DOM/HTMLLinkElement.o \
     DOM/Document.o \
     DOM/Text.o \
     CSS/Selector.o \

+ 3 - 0
Libraries/LibHTML/Parser/HTMLParser.cpp

@@ -12,6 +12,7 @@
 #include <LibHTML/DOM/HTMLImageElement.h>
 #include <LibHTML/DOM/HTMLStyleElement.h>
 #include <LibHTML/DOM/HTMLTitleElement.h>
+#include <LibHTML/DOM/HTMLLinkElement.h>
 #include <LibHTML/DOM/Text.h>
 #include <LibHTML/Parser/HTMLParser.h>
 #include <ctype.h>
@@ -36,6 +37,8 @@ static NonnullRefPtr<Element> create_element(Document& document, const String& t
         return adopt(*new HTMLStyleElement(document, tag_name));
     if (lowercase_tag_name == "title")
         return adopt(*new HTMLTitleElement(document, tag_name));
+    if (lowercase_tag_name == "link")
+        return adopt(*new HTMLLinkElement(document, tag_name));
     if (lowercase_tag_name == "img")
         return adopt(*new HTMLImageElement(document, tag_name));
     if (lowercase_tag_name == "h1"