Subject: Re: bug#78948: [PATCH] Retain the <base> tag when making a page in EWW document readable

From: Steven Allen <[email-masked]>
Date: Thu, 03 Jul 2025 08:18:31 -0700

Eli Zaretskii <[email-masked]> writes:

>> Cc: Lars Magne Ingebrigtsen <[email-masked]>,
>>  Jim Porter <[email-masked]>
>> Date: Wed, 02 Jul 2025 14:37:27 -0700
>> From:  Steven Allen via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <[email-masked]>
>>
>> Retain the <base> tag when making a page in EWW document
>> readable. Otherwise, relative links aren't resolved correctly.
>
> Thanks.  Could you please show a recipe for reproducing the problem?

1. Start emacs.
2. M-x eww RET https://stebalien.com/tags/emacs/ RET
3. R (readable mode)
4. Try to follow the top link and get a 404 error code.

> Also, would it make sense to have a test for this?

Good point, see attached.

>From 1db9f024b5767df8bbc61b6d0d43e65e334c4358 Mon Sep 17 00:00:00 2001
From: Steven Allen <[email-masked]>
Date: Wed, 2 Jul 2025 14:32:28 -0700
Subject: [PATCH] Retain the <base> tag when making a page in EWW document
 readable

The base tag is necessary to correctly resolve relative links.

* lisp/net/eww.el (eww-readable-dom): Retain the base tag in addition to
the title/link tags.  (Bug#78948)
* test/lisp/net/eww-tests.el (eww-test--wordy-page): Add a base tag.
(eww-test/readable/default-readable): Test that the base tag is retained.
---
 lisp/net/eww.el            | 2 +-
 test/lisp/net/eww-tests.el | 9 +++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index 2f99234c47d..76dccaec9dd 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -1225,7 +1225,7 @@ eww-readable-dom
          ;; "previous" pages.  NOTE: We could probably filter out
          ;; stylesheet <link> tags here, though it doesn't really matter
          ;; since we don't *do* anything with stylesheets...
-         (when (memq (dom-tag node) '(title link))
+         (when (memq (dom-tag node) '(title link base))
            ;; Copy the node, but not any of its (non-text) children.
            ;; This way, we can ensure that we don't include a node
            ;; directly in our list in addition to as a child of some
diff --git a/test/lisp/net/eww-tests.el b/test/lisp/net/eww-tests.el
index 18cbd272991..e9cfde4243a 100644
--- a/test/lisp/net/eww-tests.el
+++ b/test/lisp/net/eww-tests.el
@@ -39,6 +39,7 @@ eww-test--wordy-page
           "<head>"
           "<title>Welcome to my home page</title>"
           "<link rel=\"home\" href=\"somewhere.invalid\">"
+          "<base href=\"/foo/\">"
           "</head><body>"
           "<a>This is an uninteresting sentence.</a>"
           "<div>" eww-test--lots-of-words "</div>"
@@ -251,9 +252,13 @@ eww-test/readable/default-readable
       (eww "example.invalid")
       ;; Make sure EWW uses "readable" mode.
       (should (plist-get eww-data :readable))
-      ;; Make sure the page include the <title> and <link> nodes.
+      ;; Make sure the page include the <title>, <link>, and <base> nodes.
       (should (equal (plist-get eww-data :title) "Welcome to my home page"))
-      (should (equal (plist-get eww-data :home) "somewhere.invalid")))))
+      (should (equal (plist-get eww-data :home) "somewhere.invalid"))
+      (let* ((html (dom-child-by-tag (plist-get eww-data :dom) 'html))
+             (base-tags (dom-by-tag html 'base)))
+        (should (length= base-tags 1))
+        (should (equal (dom-attr (car base-tags) 'href) "/foo/"))))))
 
 (provide 'eww-tests)
 ;; eww-tests.el ends here
-- 
2.50.0