From 9741cc2454e1d943dd137c8af053662ef2b42c37 Mon Sep 17 00:00:00 2001 From: Jim Porter Date: Sun, 23 Jun 2024 12:18:57 -0700 Subject: [PATCH] Slice images based on their height in SHR, not their zoom level * lisp/net/shr.el (shr-sliced-image-height): New option... (shr-put-image): ... use it. Compute the number of slices in relation to the image height; this way, each slice is roughly the height of a line of ordinary text. * test/lisp/net/shr-tests.el (shr-test/zoom-image): Update test, since zooming no longer necessarily triggers slicing. * doc/misc/eww.texi (Advanced): Document 'shr-sliced-image-proportion'. * etc/NEWS: Announce this change. (cherry picked from commit 3ce7e4ee3f1f8bf85c2c455ac624bec6c7cd10a8) --- doc/misc/eww.texi | 9 +++++++++ etc/NEWS | 11 +++++++++++ lisp/net/shr.el | 28 +++++++++++++++++++++++++--- test/lisp/net/shr-tests.el | 15 ++++++--------- 4 files changed, 51 insertions(+), 12 deletions(-) diff --git a/doc/misc/eww.texi b/doc/misc/eww.texi index eec6b3c3299..e0c6b7d610b 100644 --- a/doc/misc/eww.texi +++ b/doc/misc/eww.texi @@ -373,6 +373,15 @@ customizing @code{shr-blocked-images}. @code{shr-inhibit-images}. If this variable is @code{nil}, display the ``ALT'' text of images instead. +@vindex shr-sliced-image-height + To make scrolling up/down past images more intuititve, EWW splits +large images into several rows. This way, you can scroll individually +past each slice, instead of jumping past the entire image. EWW slices +images that take up more than @code{shr-sliced-image-height} of the +height of the window they are displayed in. For example, a value of 0.7 +means that images are allowed to take up 70% of the height of the window +before being sliced. + @vindex shr-color-visible-distance-min @vindex shr-color-visible-luminance-min @cindex Contrast diff --git a/etc/NEWS b/etc/NEWS index 2b1534c31eb..3e74d724f48 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -43,6 +43,17 @@ applies, and please also update docstrings as needed. If 'whitespace-style' includes 'missing-newline-at-eof (which is the default), the 'whitespace-cleanup' function will now add the newline. +** SHR + ++++ +*** SHR now slices large images into rows. +Sliced images allow for more intuitive scrolling up/down by letting you +scroll past each slice, instead of jumping past the entire image. +Previously, SHR sliced images when zoomed to their original size, no +matter how large or small that was). Now, SHR slices any images taller +than 'shr-sliced-image-height'. For more information, see the "(eww) +Advanced" node in the EWW manual. + * New Modes and Packages in Emacs 31.1 diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 3dadcb9a09b..fe061adae29 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -58,6 +58,20 @@ fit these criteria." :version "24.1" :type 'float) +(defcustom shr-sliced-image-height 0.9 + "How tall images can be before slicing in relation to the window they're in. +A value of 0.7 means that images are allowed to take up 70% of the +height of the window before being sliced by `insert-sliced-image'. If +nil, never slice images. + +Sliced images allow for more intuitive scrolling up/down by letting you +scroll past each slice, instead of jumping past the entire image. +Alternately, you can use `pixel-scroll-precision-mode' to scroll +pixel-wise past images, in which case you can set this option to nil." + :version "31.1" + :type '(choice (const :tag "Never slice images") + float)) + (defcustom shr-allowed-images nil "If non-nil, only images that match this regexp are displayed. If nil, all URLs are allowed. Also see `shr-blocked-images'." @@ -1157,14 +1171,22 @@ element is the data blob and the second element is the content-type." (when (and (> (current-column) 0) (not inline)) (insert "\n")) - (let ((image-pos (point))) - (if (eq size 'original) + (let ((image-pos (point)) + image-height body-height) + (if (and shr-sliced-image-height + (setq image-height (cdr (image-size image t)) + body-height (window-body-height + (get-buffer-window (current-buffer)) + t)) + (> (/ image-height body-height 1.0) + shr-sliced-image-height)) ;; Normally, we try to keep the buffer text the same ;; by preserving ALT. With a sliced image, we have to ;; repeat the text for each line, so we can't do that. ;; Just use "*" for the string to insert instead. (progn - (insert-sliced-image image "*" nil 20 1) + (insert-sliced-image + image "*" nil (/ image-height (default-line-height)) 1) (let ((overlay (make-overlay start (point)))) ;; Avoid displaying unsightly decorations on the ;; image slices. diff --git a/test/lisp/net/shr-tests.el b/test/lisp/net/shr-tests.el index 815c1a3cf3f..cc258552819 100644 --- a/test/lisp/net/shr-tests.el +++ b/test/lisp/net/shr-tests.el @@ -159,6 +159,7 @@ settings, then once more for each (OPTION . VALUE) pair.") (shr-width 80) (shr-use-fonts nil) (shr-image-animate nil) + (shr-sliced-image-height nil) (inhibit-message t) (dom (libxml-parse-html-region (point-min) (point-max)))) ;; Render the document. @@ -171,19 +172,15 @@ settings, then once more for each (OPTION . VALUE) pair.") (shr-zoom-image) (shr-test-wait-for (lambda () (= put-image-calls 2)) "Timed out waiting to zoom image") - ;; Check that we got a sliced image. - (let ((slice-count 0)) + ;; Check that we have a single image at original size. + (let (image-sizes) (goto-char (point-min)) (while (< (point) (point-max)) - (when-let ((display (get-text-property (point) 'display))) - ;; If this is nil, we found a non-sliced image, but we - ;; should have replaced that! - (should (assq 'slice display)) - (cl-incf slice-count)) + (when (get-text-property (point) 'display) + (push (get-text-property (point) 'image-size) image-sizes)) (goto-char (or (next-single-property-change (point) 'display) (point-max)))) - ;; Make sure we actually saw a slice. - (should (> slice-count 1))))))))) + (should (equal image-sizes '(original)))))))))) (require 'shr) -- 2.39.2