Browse Source

LibGUI: Add highlighting to `UrlBox`

Cameron Youell 2 years ago
parent
commit
cb96c892cc
2 changed files with 62 additions and 0 deletions
  1. 59 0
      Userland/Libraries/LibGUI/TextBox.cpp
  2. 3 0
      Userland/Libraries/LibGUI/TextBox.h

+ 59 - 0
Userland/Libraries/LibGUI/TextBox.cpp

@@ -1,13 +1,17 @@
 /*
  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  * Copyright (c) 2022, the SerenityOS developers.
+ * Copyright (c) 2023, Cameron Youell <cameronyouell@gmail.com>
  *
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <AK/URL.h>
+#include <AK/Vector.h>
 #include <LibGUI/Painter.h>
 #include <LibGUI/TextBox.h>
 #include <LibGfx/Palette.h>
+#include <LibGfx/TextAttributes.h>
 
 REGISTER_WIDGET(GUI, TextBox)
 REGISTER_WIDGET(GUI, PasswordBox)
@@ -132,15 +136,25 @@ UrlBox::UrlBox()
     : TextBox()
 {
     set_auto_focusable(false);
+    on_change = [this] {
+        highlight_url();
+    };
 }
 
 void UrlBox::focusout_event(GUI::FocusEvent& event)
 {
     set_focus_transition(true);
 
+    highlight_url();
     TextBox::focusout_event(event);
 }
 
+void UrlBox::focusin_event(GUI::FocusEvent& event)
+{
+    highlight_url();
+    TextBox::focusin_event(event);
+}
+
 void UrlBox::mousedown_event(GUI::MouseEvent& event)
 {
     if (is_displayonly())
@@ -158,4 +172,49 @@ void UrlBox::mousedown_event(GUI::MouseEvent& event)
     }
 }
 
+void UrlBox::highlight_url()
+{
+    auto url = AK::URL::create_with_url_or_path(text());
+    Vector<GUI::TextDocumentSpan> spans;
+
+    if (url.is_valid() && !is_focused()) {
+        if (url.scheme() == "http" || url.scheme() == "https" || url.scheme() == "gemini") {
+            auto host_start = url.scheme().length() + 3;
+            auto host_length = url.host().length();
+
+            // FIXME: Maybe add a generator to use https://publicsuffix.org/list/public_suffix_list.dat
+            //        for now just highlight the whole host
+
+            Gfx::TextAttributes default_format;
+            default_format.color = palette().color(Gfx::ColorRole::PlaceholderText);
+            spans.append({
+                { { 0, 0 }, { 0, host_start } },
+                default_format,
+            });
+
+            Gfx::TextAttributes host_format;
+            host_format.color = palette().color(Gfx::ColorRole::BaseText);
+            spans.append({
+                { { 0, host_start }, { 0, host_start + host_length } },
+                host_format,
+            });
+
+            spans.append({
+                { { 0, host_start + host_length }, { 0, text().length() } },
+                default_format,
+            });
+        } else if (url.scheme() == "file") {
+            Gfx::TextAttributes scheme_format;
+            scheme_format.color = palette().color(Gfx::ColorRole::PlaceholderText);
+            spans.append({
+                { { 0, 0 }, { 0, url.scheme().length() + 3 } },
+                scheme_format,
+            });
+        }
+    }
+
+    document().set_spans(0, move(spans));
+    update();
+}
+
 }

+ 3 - 0
Userland/Libraries/LibGUI/TextBox.h

@@ -72,8 +72,11 @@ public:
 private:
     UrlBox();
 
+    void highlight_url();
+
     virtual void mousedown_event(GUI::MouseEvent&) override;
     virtual void focusout_event(GUI::FocusEvent&) override;
+    virtual void focusin_event(GUI::FocusEvent&) override;
 
     bool m_focus_transition { true };
 };