From e69b4303fdd904f41357da16863dbd3b03853d2c Mon Sep 17 00:00:00 2001 From: Robin Linden Date: Sat, 21 Oct 2023 22:03:59 +0200 Subject: [PATCH] browser/gui: Display favicons if available --- browser/gui/app.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/browser/gui/app.cpp b/browser/gui/app.cpp index 2db9c1a73..548368921 100644 --- a/browser/gui/app.cpp +++ b/browser/gui/app.cpp @@ -11,6 +11,7 @@ #include "render/render.h" #include "uri/uri.h" +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -327,6 +329,7 @@ int App::run() { } void App::navigate() { + // TODO(robinlinden): Unset favicon. May require us to have a Hastur icon. page_loaded_ = false; auto uri = uri::Uri::parse(url_buf_, engine_.uri()); browse_history_.push(uri); @@ -395,6 +398,27 @@ void App::on_page_loaded() { window_.setTitle(browser_title_); } + // TODO(robinlinden): Non-blocking load of favicon. + // https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel#icon + auto is_favicon_link = [](dom::Element const *v) { + auto rel = v->attributes.find("rel"); + return rel != end(v->attributes) && rel->second == "icon" && v->attributes.contains("href"); + }; + + for (auto const &link : dom::nodes_by_xpath(engine_.dom().html(), "/html/head/link") + | std::views::filter(is_favicon_link) | std::views::reverse) { + auto uri = uri::Uri::parse(link->attributes.at("href"), engine_.uri()); + auto icon = engine_.load(uri).response; + sf::Image favicon; + if (icon.err != protocol::Error::Ok || !favicon.loadFromMemory(icon.body.data(), icon.body.size())) { + spdlog::warn("Error loading favicon from '{}': {}", uri.uri, to_string(icon.err)); + continue; + } + + window_.setIcon(favicon.getSize().x, favicon.getSize().y, favicon.getPixelsPtr()); + break; + } + update_status_line(); response_headers_str_ = engine_.response().headers.to_string(); dom_str_ = dom::to_string(engine_.dom());