diff options
| author | Jim Porter | 2024-02-17 20:49:15 -0800 |
|---|---|---|
| committer | Jim Porter | 2024-03-06 14:36:23 -0800 |
| commit | 59e470dd5de6e75c4d3bb91c876c8540faf33fdb (patch) | |
| tree | 5dce2d1ef354996c9e7cb2d79bc19f87b126883a | |
| parent | b12059e4c320f374735a9c00975ef12cb964043f (diff) | |
| download | emacs-59e470dd5de6e75c4d3bb91c876c8540faf33fdb.tar.gz emacs-59e470dd5de6e75c4d3bb91c876c8540faf33fdb.zip | |
When navigating through history in EWW, don't keep adding to 'eww-history'
This resolves an issue where navigating back and then forward kept
adding new history entries so you could never hit the "end" (bug#69232).
* lisp/net/eww.el (eww-before-browse-history-function): New option.
(eww-history-position): Add docstring.
(eww-mode-map, eww-context-menu): Use correct predicates for when to
enable back/forward.
(eww-save-history): Save history entry in its original place when
viewing a historical page.
(eww--before-browse): New function...
(eww, eww-follow-link, eww-readable): ... call it.
(eww-render): Don't set 'eww-history-position' here...
(eww--before-browse): ... instead, set it here.
(eww-back-url): Set 'eww-history-position' based on the result of
'eww-save-history'.
(eww-forward-url): Set 'eww-history-position' directly, since
'eww-save-history' no longer adds a new entry in this case.
(eww-delete-future-history, eww-clone-previous-history): New functions.
* test/lisp/net/eww-tests.el: New file.
* etc/NEWS: Announce this change.
| -rw-r--r-- | doc/misc/eww.texi | 9 | ||||
| -rw-r--r-- | etc/NEWS | 13 | ||||
| -rw-r--r-- | lisp/net/eww.el | 123 | ||||
| -rw-r--r-- | test/lisp/net/eww-tests.el | 179 |
4 files changed, 312 insertions, 12 deletions
diff --git a/doc/misc/eww.texi b/doc/misc/eww.texi index 5e69b11d347..d31fcf1802b 100644 --- a/doc/misc/eww.texi +++ b/doc/misc/eww.texi | |||
| @@ -192,6 +192,15 @@ history press @kbd{H} (@code{eww-list-histories}) to open the history | |||
| 192 | buffer @file{*eww history*}. The history is lost when EWW is quit. | 192 | buffer @file{*eww history*}. The history is lost when EWW is quit. |
| 193 | If you want to remember websites you can use bookmarks. | 193 | If you want to remember websites you can use bookmarks. |
| 194 | 194 | ||
| 195 | @vindex eww-before-browse-history-function | ||
| 196 | By default, when browsing to a new page from a ``historical'' one | ||
| 197 | (i.e.@: a page loaded by navigating back via @code{eww-back-url}), EWW | ||
| 198 | will first delete any history entries newer than the current page. This | ||
| 199 | is the same behavior as most other web browsers. You can change this by | ||
| 200 | customizing @code{eww-before-browse-history-function} to another value. | ||
| 201 | For example, setting it to @code{ignore} will preserve the existing | ||
| 202 | history entries and simply prepend the new page to the history list. | ||
| 203 | |||
| 195 | @vindex eww-history-limit | 204 | @vindex eww-history-limit |
| 196 | Along with the URLs visited, EWW also remembers both the rendered | 205 | Along with the URLs visited, EWW also remembers both the rendered |
| 197 | page (as it appears in the buffer) and its source. This can take a | 206 | page (as it appears in the buffer) and its source. This can take a |
| @@ -1018,6 +1018,19 @@ When invoked with the prefix argument ('C-u'), | |||
| 1018 | This is useful for continuing reading the URL in the current buffer | 1018 | This is useful for continuing reading the URL in the current buffer |
| 1019 | when the new URL is fetched. | 1019 | when the new URL is fetched. |
| 1020 | 1020 | ||
| 1021 | --- | ||
| 1022 | *** History navigation in EWW now works like other browsers. | ||
| 1023 | Previously, when navigating back and forward through page history, EWW | ||
| 1024 | would add a duplicate entry to the end of the history list each time. | ||
| 1025 | This made it impossible to navigate to the "end" of the history list. | ||
| 1026 | Now, navigating through history in EWW simply changes your position in | ||
| 1027 | the history list, allowing you to reach the end as expected. In | ||
| 1028 | addition, when browsing to a new page from a "historical" one (i.e. a | ||
| 1029 | page loaded by navigating back through history), EWW deletes the history | ||
| 1030 | entries newer than the current page. To change the behavior when | ||
| 1031 | browsing from "historical" pages, you can customize | ||
| 1032 | 'eww-before-browse-history-function'. | ||
| 1033 | |||
| 1021 | ** go-ts-mode | 1034 | ** go-ts-mode |
| 1022 | 1035 | ||
| 1023 | +++ | 1036 | +++ |
diff --git a/lisp/net/eww.el b/lisp/net/eww.el index 5a25eef9e3c..2936bc8f099 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el | |||
| @@ -182,6 +182,33 @@ the tab bar is enabled." | |||
| 182 | (const :tag "Open new tab when tab bar is enabled" tab-bar) | 182 | (const :tag "Open new tab when tab bar is enabled" tab-bar) |
| 183 | (const :tag "Never open URL in new tab" nil))) | 183 | (const :tag "Never open URL in new tab" nil))) |
| 184 | 184 | ||
| 185 | (defcustom eww-before-browse-history-function #'eww-delete-future-history | ||
| 186 | "A function to call to update history before browsing to a new page. | ||
| 187 | EWW provides the following values for this option: | ||
| 188 | |||
| 189 | * `eww-delete-future-history': Delete any history entries after the | ||
| 190 | currently-shown one. This is the default behavior, and works the same | ||
| 191 | as in most other web browsers. | ||
| 192 | |||
| 193 | * `eww-clone-previous-history': Clone and prepend any history entries up | ||
| 194 | to the currently-shown one. This is like `eww-delete-future-history', | ||
| 195 | except that it preserves the previous contents of the history list at | ||
| 196 | the end. | ||
| 197 | |||
| 198 | * `ignore': Preserve the current history unchanged. This will result in | ||
| 199 | the new page simply being prepended to the existing history list. | ||
| 200 | |||
| 201 | You can also set this to any other function you wish." | ||
| 202 | :version "30.1" | ||
| 203 | :group 'eww | ||
| 204 | :type '(choice (function-item :tag "Delete future history" | ||
| 205 | eww-delete-future-history) | ||
| 206 | (function-item :tag "Clone previous history" | ||
| 207 | eww-clone-previous-history) | ||
| 208 | (function-item :tag "Preserve history" | ||
| 209 | ignore) | ||
| 210 | (function :tag "Custom function"))) | ||
| 211 | |||
| 185 | (defcustom eww-after-render-hook nil | 212 | (defcustom eww-after-render-hook nil |
| 186 | "A hook called after eww has finished rendering the buffer." | 213 | "A hook called after eww has finished rendering the buffer." |
| 187 | :version "25.1" | 214 | :version "25.1" |
| @@ -312,7 +339,10 @@ parameter, and should return the (possibly) transformed URL." | |||
| 312 | 339 | ||
| 313 | (defvar eww-data nil) | 340 | (defvar eww-data nil) |
| 314 | (defvar eww-history nil) | 341 | (defvar eww-history nil) |
| 315 | (defvar eww-history-position 0) | 342 | (defvar eww-history-position 0 |
| 343 | "The 1-indexed position in `eww-history'. | ||
| 344 | If zero, EWW is at the newest page, which isn't yet present in | ||
| 345 | `eww-history'.") | ||
| 316 | (defvar eww-prompt-history nil) | 346 | (defvar eww-prompt-history nil) |
| 317 | 347 | ||
| 318 | (defvar eww-local-regex "localhost" | 348 | (defvar eww-local-regex "localhost" |
| @@ -402,6 +432,7 @@ For more information, see Info node `(eww) Top'." | |||
| 402 | (t | 432 | (t |
| 403 | (get-buffer-create "*eww*")))) | 433 | (get-buffer-create "*eww*")))) |
| 404 | (eww-setup-buffer) | 434 | (eww-setup-buffer) |
| 435 | (eww--before-browse) | ||
| 405 | ;; Check whether the domain only uses "Highly Restricted" Unicode | 436 | ;; Check whether the domain only uses "Highly Restricted" Unicode |
| 406 | ;; IDNA characters. If not, transform to punycode to indicate that | 437 | ;; IDNA characters. If not, transform to punycode to indicate that |
| 407 | ;; there may be funny business going on. | 438 | ;; there may be funny business going on. |
| @@ -654,7 +685,6 @@ The renaming scheme is performed in accordance with | |||
| 654 | (with-current-buffer buffer | 685 | (with-current-buffer buffer |
| 655 | (plist-put eww-data :url url) | 686 | (plist-put eww-data :url url) |
| 656 | (eww--after-page-change) | 687 | (eww--after-page-change) |
| 657 | (setq eww-history-position 0) | ||
| 658 | (and last-coding-system-used | 688 | (and last-coding-system-used |
| 659 | (set-buffer-file-coding-system last-coding-system-used)) | 689 | (set-buffer-file-coding-system last-coding-system-used)) |
| 660 | (unless shr-fill-text | 690 | (unless shr-fill-text |
| @@ -905,6 +935,11 @@ The renaming scheme is performed in accordance with | |||
| 905 | `((?u . ,(or url "")) | 935 | `((?u . ,(or url "")) |
| 906 | (?t . ,title)))))))) | 936 | (?t . ,title)))))))) |
| 907 | 937 | ||
| 938 | (defun eww--before-browse () | ||
| 939 | (funcall eww-before-browse-history-function) | ||
| 940 | (setq eww-history-position 0 | ||
| 941 | eww-data (list :title ""))) | ||
| 942 | |||
| 908 | (defun eww--after-page-change () | 943 | (defun eww--after-page-change () |
| 909 | (eww-update-header-line-format) | 944 | (eww-update-header-line-format) |
| 910 | (eww--rename-buffer)) | 945 | (eww--rename-buffer)) |
| @@ -1037,6 +1072,7 @@ the like." | |||
| 1037 | (base (plist-get eww-data :url))) | 1072 | (base (plist-get eww-data :url))) |
| 1038 | (eww-score-readability dom) | 1073 | (eww-score-readability dom) |
| 1039 | (eww-save-history) | 1074 | (eww-save-history) |
| 1075 | (eww--before-browse) | ||
| 1040 | (eww-display-html nil nil | 1076 | (eww-display-html nil nil |
| 1041 | (list 'base (list (cons 'href base)) | 1077 | (list 'base (list (cons 'href base)) |
| 1042 | (eww-highest-readability dom)) | 1078 | (eww-highest-readability dom)) |
| @@ -1129,9 +1165,9 @@ the like." | |||
| 1129 | ["Reload" eww-reload t] | 1165 | ["Reload" eww-reload t] |
| 1130 | ["Follow URL in new buffer" eww-open-in-new-buffer] | 1166 | ["Follow URL in new buffer" eww-open-in-new-buffer] |
| 1131 | ["Back to previous page" eww-back-url | 1167 | ["Back to previous page" eww-back-url |
| 1132 | :active (not (zerop (length eww-history)))] | 1168 | :active (< eww-history-position (length eww-history))] |
| 1133 | ["Forward to next page" eww-forward-url | 1169 | ["Forward to next page" eww-forward-url |
| 1134 | :active (not (zerop eww-history-position))] | 1170 | :active (> eww-history-position 1)] |
| 1135 | ["Browse with external browser" eww-browse-with-external-browser t] | 1171 | ["Browse with external browser" eww-browse-with-external-browser t] |
| 1136 | ["Download" eww-download t] | 1172 | ["Download" eww-download t] |
| 1137 | ["View page source" eww-view-source] | 1173 | ["View page source" eww-view-source] |
| @@ -1155,9 +1191,9 @@ the like." | |||
| 1155 | (easy-menu-define nil easy-menu nil | 1191 | (easy-menu-define nil easy-menu nil |
| 1156 | '("Eww" | 1192 | '("Eww" |
| 1157 | ["Back to previous page" eww-back-url | 1193 | ["Back to previous page" eww-back-url |
| 1158 | :visible (not (zerop (length eww-history)))] | 1194 | :active (< eww-history-position (length eww-history))] |
| 1159 | ["Forward to next page" eww-forward-url | 1195 | ["Forward to next page" eww-forward-url |
| 1160 | :visible (not (zerop eww-history-position))] | 1196 | :active (> eww-history-position 1)] |
| 1161 | ["Reload" eww-reload t])) | 1197 | ["Reload" eww-reload t])) |
| 1162 | (dolist (item (reverse (lookup-key easy-menu [menu-bar eww]))) | 1198 | (dolist (item (reverse (lookup-key easy-menu [menu-bar eww]))) |
| 1163 | (when (consp item) | 1199 | (when (consp item) |
| @@ -1280,16 +1316,20 @@ instead of `browse-url-new-window-flag'." | |||
| 1280 | (interactive nil eww-mode) | 1316 | (interactive nil eww-mode) |
| 1281 | (when (>= eww-history-position (length eww-history)) | 1317 | (when (>= eww-history-position (length eww-history)) |
| 1282 | (user-error "No previous page")) | 1318 | (user-error "No previous page")) |
| 1283 | (eww-save-history) | 1319 | (if (eww-save-history) |
| 1284 | (setq eww-history-position (+ eww-history-position 2)) | 1320 | ;; We were at the latest page (which was just added to the |
| 1321 | ;; history), so go back two entries. | ||
| 1322 | (setq eww-history-position 2) | ||
| 1323 | (setq eww-history-position (1+ eww-history-position))) | ||
| 1285 | (eww-restore-history (elt eww-history (1- eww-history-position)))) | 1324 | (eww-restore-history (elt eww-history (1- eww-history-position)))) |
| 1286 | 1325 | ||
| 1287 | (defun eww-forward-url () | 1326 | (defun eww-forward-url () |
| 1288 | "Go to the next displayed page." | 1327 | "Go to the next displayed page." |
| 1289 | (interactive nil eww-mode) | 1328 | (interactive nil eww-mode) |
| 1290 | (when (zerop eww-history-position) | 1329 | (when (<= eww-history-position 1) |
| 1291 | (user-error "No next page")) | 1330 | (user-error "No next page")) |
| 1292 | (eww-save-history) | 1331 | (eww-save-history) |
| 1332 | (setq eww-history-position (1- eww-history-position)) | ||
| 1293 | (eww-restore-history (elt eww-history (1- eww-history-position)))) | 1333 | (eww-restore-history (elt eww-history (1- eww-history-position)))) |
| 1294 | 1334 | ||
| 1295 | (defun eww-restore-history (elem) | 1335 | (defun eww-restore-history (elem) |
| @@ -1959,6 +1999,7 @@ If EXTERNAL is double prefix, browse in new buffer." | |||
| 1959 | (eww-same-page-p url (plist-get eww-data :url))) | 1999 | (eww-same-page-p url (plist-get eww-data :url))) |
| 1960 | (let ((point (point))) | 2000 | (let ((point (point))) |
| 1961 | (eww-save-history) | 2001 | (eww-save-history) |
| 2002 | (eww--before-browse) | ||
| 1962 | (plist-put eww-data :url url) | 2003 | (plist-put eww-data :url url) |
| 1963 | (goto-char (point-min)) | 2004 | (goto-char (point-min)) |
| 1964 | (if-let ((match (text-property-search-forward 'shr-target-id target #'member))) | 2005 | (if-let ((match (text-property-search-forward 'shr-target-id target #'member))) |
| @@ -2289,11 +2330,69 @@ If ERROR-OUT, signal user-error if there are no bookmarks." | |||
| 2289 | ;;; History code | 2330 | ;;; History code |
| 2290 | 2331 | ||
| 2291 | (defun eww-save-history () | 2332 | (defun eww-save-history () |
| 2333 | "Save the current page's data to the history. | ||
| 2334 | If the current page is a historial one loaded from | ||
| 2335 | `eww-history' (e.g. by calling `eww-back-url'), this will update the | ||
| 2336 | page's entry in `eww-history' and return nil. Otherwise, add a new | ||
| 2337 | entry to `eww-history' and return t." | ||
| 2292 | (plist-put eww-data :point (point)) | 2338 | (plist-put eww-data :point (point)) |
| 2293 | (plist-put eww-data :text (buffer-string)) | 2339 | (plist-put eww-data :text (buffer-string)) |
| 2294 | (let ((history-delete-duplicates nil)) | 2340 | (if (zerop eww-history-position) |
| 2295 | (add-to-history 'eww-history eww-data eww-history-limit t)) | 2341 | (let ((history-delete-duplicates nil)) |
| 2296 | (setq eww-data (list :title ""))) | 2342 | (add-to-history 'eww-history eww-data eww-history-limit t) |
| 2343 | (setq eww-history-position 1) | ||
| 2344 | t) | ||
| 2345 | (setf (elt eww-history (1- eww-history-position)) eww-data) | ||
| 2346 | nil)) | ||
| 2347 | |||
| 2348 | (defun eww-delete-future-history () | ||
| 2349 | "Remove any entries in `eww-history' after the currently-shown one. | ||
| 2350 | This is useful for `eww-before-browse-history-function' to make EWW's | ||
| 2351 | navigation to a new page from a historical one work like other web | ||
| 2352 | browsers: it will delete any \"future\" history elements before adding | ||
| 2353 | the new page to the end of the history. | ||
| 2354 | |||
| 2355 | For example, if `eww-history' looks like this (going from newest to | ||
| 2356 | oldest, with \"*\" marking the current page): | ||
| 2357 | |||
| 2358 | E D C* B A | ||
| 2359 | |||
| 2360 | then calling this function updates `eww-history' to: | ||
| 2361 | |||
| 2362 | C* B A" | ||
| 2363 | (when (> eww-history-position 1) | ||
| 2364 | (setq eww-history (nthcdr (1- eww-history-position) eww-history) | ||
| 2365 | ;; We don't really need to set this since `eww--before-browse' | ||
| 2366 | ;; sets it too, but this ensures that other callers can use | ||
| 2367 | ;; this function and get the expected results. | ||
| 2368 | eww-history-position 1))) | ||
| 2369 | |||
| 2370 | (defun eww-clone-previous-history () | ||
| 2371 | "Clone and prepend entries in `eww-history' up to the currently-shown one. | ||
| 2372 | These cloned entries get added to the beginning of `eww-history' so that | ||
| 2373 | it's possible to navigate back to the very first page for this EWW | ||
| 2374 | without deleting any history entries. | ||
| 2375 | |||
| 2376 | For example, if `eww-history' looks like this (going from newest to | ||
| 2377 | oldest, with \"*\" marking the current page): | ||
| 2378 | |||
| 2379 | E D C* B A | ||
| 2380 | |||
| 2381 | then calling this function updates `eww-history' to: | ||
| 2382 | |||
| 2383 | C* B A E D C B A | ||
| 2384 | |||
| 2385 | This is useful for setting `eww-before-browse-history-function' (which | ||
| 2386 | see)." | ||
| 2387 | (when (> eww-history-position 1) | ||
| 2388 | (setq eww-history (take eww-history-limit | ||
| 2389 | (append (nthcdr (1- eww-history-position) | ||
| 2390 | eww-history) | ||
| 2391 | eww-history)) | ||
| 2392 | ;; As with `eww-delete-future-history', we don't really need | ||
| 2393 | ;; to set this since `eww--before-browse' sets it too, but | ||
| 2394 | ;; let's be thorough. | ||
| 2395 | eww-history-position 1))) | ||
| 2297 | 2396 | ||
| 2298 | (defvar eww-current-buffer) | 2397 | (defvar eww-current-buffer) |
| 2299 | 2398 | ||
diff --git a/test/lisp/net/eww-tests.el b/test/lisp/net/eww-tests.el new file mode 100644 index 00000000000..ced84322e3a --- /dev/null +++ b/test/lisp/net/eww-tests.el | |||
| @@ -0,0 +1,179 @@ | |||
| 1 | ;;; eww-tests.el --- tests for eww.el -*- lexical-binding: t; -*- | ||
| 2 | |||
| 3 | ;; Copyright (C) 2024 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | ;; it under the terms of the GNU General Public License as published by | ||
| 9 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 10 | ;; (at your option) any later version. | ||
| 11 | |||
| 12 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | ;; GNU General Public License for more details. | ||
| 16 | |||
| 17 | ;; You should have received a copy of the GNU General Public License | ||
| 18 | ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. | ||
| 19 | |||
| 20 | ;;; Commentary: | ||
| 21 | |||
| 22 | ;;; Code: | ||
| 23 | |||
| 24 | (require 'ert) | ||
| 25 | (require 'eww) | ||
| 26 | |||
| 27 | (defvar eww-test--response-function (lambda (url) (concat "\n" url)) | ||
| 28 | "A function for returning a mock response for URL. | ||
| 29 | The default just returns an empty list of headers URL as the body.") | ||
| 30 | |||
| 31 | (defmacro eww-test--with-mock-retrieve (&rest body) | ||
| 32 | "Evaluate BODY with a mock implementation of `eww-retrieve'. | ||
| 33 | This avoids network requests during our tests. Additionally, prepare a | ||
| 34 | temporary EWW buffer for our tests." | ||
| 35 | (declare (indent 1)) | ||
| 36 | `(cl-letf (((symbol-function 'eww-retrieve) | ||
| 37 | (lambda (url callback args) | ||
| 38 | (with-temp-buffer | ||
| 39 | (insert (funcall eww-test--response-function url)) | ||
| 40 | (apply callback nil args))))) | ||
| 41 | (with-temp-buffer | ||
| 42 | (eww-mode) | ||
| 43 | ,@body))) | ||
| 44 | |||
| 45 | (defun eww-test--history-urls () | ||
| 46 | (mapcar (lambda (elem) (plist-get elem :url)) eww-history)) | ||
| 47 | |||
| 48 | ;;; Tests: | ||
| 49 | |||
| 50 | (ert-deftest eww-test/history/new-page () | ||
| 51 | "Test that when visiting a new page, the previous one goes into the history." | ||
| 52 | (eww-test--with-mock-retrieve | ||
| 53 | (eww "one.invalid") | ||
| 54 | (eww "two.invalid") | ||
| 55 | (should (equal (eww-test--history-urls) | ||
| 56 | '("http://one.invalid/"))) | ||
| 57 | (eww "three.invalid") | ||
| 58 | (should (equal (eww-test--history-urls) | ||
| 59 | '("http://two.invalid/" | ||
| 60 | "http://one.invalid/"))))) | ||
| 61 | |||
| 62 | (ert-deftest eww-test/history/back-forward () | ||
| 63 | "Test that navigating through history just changes our history position. | ||
| 64 | See bug#69232." | ||
| 65 | (eww-test--with-mock-retrieve | ||
| 66 | (eww "one.invalid") | ||
| 67 | (eww "two.invalid") | ||
| 68 | (eww "three.invalid") | ||
| 69 | (let ((url-history '("http://three.invalid/" | ||
| 70 | "http://two.invalid/" | ||
| 71 | "http://one.invalid/"))) | ||
| 72 | ;; Go back one page. This should add "three.invalid" to the | ||
| 73 | ;; history, making our position in the list 2. | ||
| 74 | (eww-back-url) | ||
| 75 | (should (equal (eww-test--history-urls) url-history)) | ||
| 76 | (should (= eww-history-position 2)) | ||
| 77 | ;; Go back again. | ||
| 78 | (eww-back-url) | ||
| 79 | (should (equal (eww-test--history-urls) url-history)) | ||
| 80 | (should (= eww-history-position 3)) | ||
| 81 | ;; At the beginning of the history, so trying to go back should | ||
| 82 | ;; signal an error. | ||
| 83 | (should-error (eww-back-url)) | ||
| 84 | ;; Go forward once. | ||
| 85 | (eww-forward-url) | ||
| 86 | (should (equal (eww-test--history-urls) url-history)) | ||
| 87 | (should (= eww-history-position 2)) | ||
| 88 | ;; Go forward again. | ||
| 89 | (eww-forward-url) | ||
| 90 | (should (equal (eww-test--history-urls) url-history)) | ||
| 91 | (should (= eww-history-position 1)) | ||
| 92 | ;; At the end of the history, so trying to go forward should | ||
| 93 | ;; signal an error. | ||
| 94 | (should-error (eww-forward-url))))) | ||
| 95 | |||
| 96 | (ert-deftest eww-test/history/reload-in-place () | ||
| 97 | "Test that reloading historical pages updates their history entry in-place. | ||
| 98 | See bug#69232." | ||
| 99 | (eww-test--with-mock-retrieve | ||
| 100 | (eww "one.invalid") | ||
| 101 | (eww "two.invalid") | ||
| 102 | (eww "three.invalid") | ||
| 103 | (eww-back-url) | ||
| 104 | ;; Make sure our history has the original page text. | ||
| 105 | (should (equal (plist-get (nth 1 eww-history) :text) | ||
| 106 | "http://two.invalid/")) | ||
| 107 | (should (= eww-history-position 2)) | ||
| 108 | ;; Reload the page. | ||
| 109 | (let ((eww-test--response-function | ||
| 110 | (lambda (url) (concat "\nreloaded " url)))) | ||
| 111 | (eww-reload) | ||
| 112 | (should (= eww-history-position 2))) | ||
| 113 | ;; Go to another page, and make sure the history is correct, | ||
| 114 | ;; including the reloaded page text. | ||
| 115 | (eww "four.invalid") | ||
| 116 | (should (equal (eww-test--history-urls) '("http://two.invalid/" | ||
| 117 | "http://one.invalid/"))) | ||
| 118 | (should (equal (plist-get (nth 0 eww-history) :text) | ||
| 119 | "reloaded http://two.invalid/")) | ||
| 120 | (should (= eww-history-position 0)))) | ||
| 121 | |||
| 122 | (ert-deftest eww-test/history/before-navigate/delete-future-history () | ||
| 123 | "Test that going to a new page from a historical one deletes future history. | ||
| 124 | See bug#69232." | ||
| 125 | (eww-test--with-mock-retrieve | ||
| 126 | (eww "one.invalid") | ||
| 127 | (eww "two.invalid") | ||
| 128 | (eww "three.invalid") | ||
| 129 | (eww-back-url) | ||
| 130 | (eww "four.invalid") | ||
| 131 | (eww "five.invalid") | ||
| 132 | (should (equal (eww-test--history-urls) '("http://four.invalid/" | ||
| 133 | "http://two.invalid/" | ||
| 134 | "http://one.invalid/"))) | ||
| 135 | (should (= eww-history-position 0)))) | ||
| 136 | |||
| 137 | (ert-deftest eww-test/history/before-navigate/ignore-history () | ||
| 138 | "Test that going to a new page from a historical one preserves history. | ||
| 139 | This sets `eww-before-browse-history-function' to `ignore' to preserve | ||
| 140 | history. See bug#69232." | ||
| 141 | (let ((eww-before-browse-history-function #'ignore)) | ||
| 142 | (eww-test--with-mock-retrieve | ||
| 143 | (eww "one.invalid") | ||
| 144 | (eww "two.invalid") | ||
| 145 | (eww "three.invalid") | ||
| 146 | (eww-back-url) | ||
| 147 | (eww "four.invalid") | ||
| 148 | (eww "five.invalid") | ||
| 149 | (should (equal (eww-test--history-urls) '("http://four.invalid/" | ||
| 150 | "http://three.invalid/" | ||
| 151 | "http://two.invalid/" | ||
| 152 | "http://one.invalid/"))) | ||
| 153 | (should (= eww-history-position 0))))) | ||
| 154 | |||
| 155 | (ert-deftest eww-test/history/before-navigate/clone-previous () | ||
| 156 | "Test that going to a new page from a historical one clones prior history. | ||
| 157 | This sets `eww-before-browse-history-function' to | ||
| 158 | `eww-clone-previous-history' to clone the history. See bug#69232." | ||
| 159 | (let ((eww-before-browse-history-function #'eww-clone-previous-history)) | ||
| 160 | (eww-test--with-mock-retrieve | ||
| 161 | (eww "one.invalid") | ||
| 162 | (eww "two.invalid") | ||
| 163 | (eww "three.invalid") | ||
| 164 | (eww-back-url) | ||
| 165 | (eww "four.invalid") | ||
| 166 | (eww "five.invalid") | ||
| 167 | (should (equal (eww-test--history-urls) | ||
| 168 | '(;; New page and cloned history. | ||
| 169 | "http://four.invalid/" | ||
| 170 | "http://two.invalid/" | ||
| 171 | "http://one.invalid/" | ||
| 172 | ;; Original history. | ||
| 173 | "http://three.invalid/" | ||
| 174 | "http://two.invalid/" | ||
| 175 | "http://one.invalid/"))) | ||
| 176 | (should (= eww-history-position 0))))) | ||
| 177 | |||
| 178 | (provide 'eww-tests) | ||
| 179 | ;; eww-tests.el ends here | ||