aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBasil L. Contovounesios2020-05-06 18:02:32 +0100
committerBasil L. Contovounesios2020-05-22 16:28:20 +0100
commit3a7894ecd11c66337e7aea8ade8f47673d290a24 (patch)
treeb3be04e3235bce5c8d408e765390df5d46bae692
parent3f082af536c33ba713561e7ad4b691aaad488701 (diff)
downloademacs-3a7894ecd11c66337e7aea8ade8f47673d290a24.tar.gz
emacs-3a7894ecd11c66337e7aea8ade8f47673d290a24.zip
Improve shr/eww handling of mailto URLs
* lisp/net/eww.el (eww): Use function-put in place of put, as recommended in "(elisp) Symbol Plists". (eww-follow-link): * lisp/net/shr.el (shr-browse-url): Rather than call browse-url-mail directly, call browse-url which respects the user options browse-url-handlers and browse-url-mailto-function. (Bug#41133) (shr--current-link-region): Return nil if there is no link at point. (shr--blink-link): Adapt accordingly. (shr-fill-line, shr-indent, shr-table-body): Refactor to avoid some unnecessary allocations. * etc/NEWS: Announce that eww-follow-link and shr-browse-url support custom URL handlers.
-rw-r--r--etc/NEWS18
-rw-r--r--lisp/net/eww.el30
-rw-r--r--lisp/net/shr.el84
3 files changed, 70 insertions, 62 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 4533dc46c56..eb73bd64e05 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -356,6 +356,24 @@ symbol property to the browsing functions. With a new command
356'browse-url-with-browser-kind', an URL can explicitly be browsed with 356'browse-url-with-browser-kind', an URL can explicitly be browsed with
357either an internal or external browser. 357either an internal or external browser.
358 358
359** SHR
360
361---
362*** The command 'shr-browse-url' now supports custom mailto handlers.
363Clicking on or otherwise following a 'mailto:' link in a HTML buffer
364rendered by SHR previously invoked the command 'browse-url-mailto'.
365This is still the case by default, but if you customize
366'browse-url-mailto-function' or 'browse-url-handlers' to call some
367other function, it will now be called instead of the default.
368
369** EWW
370
371---
372*** The command 'eww-follow-link' now supports custom mailto handlers.
373The function that is invoked when clicking on or otherwise following a
374'mailto:' link in an EWW buffer can now be customized. For more
375information, see the related entry about 'shr-browse-url' above.
376
359** Project 377** Project
360 378
361*** New user option 'project-vc-merge-submodules'. 379*** New user option 'project-vc-merge-submodules'.
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index a6c1abdbb19..2a70560ca7b 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -307,10 +307,10 @@ the default EWW buffer."
307 (insert (format "Loading %s..." url)) 307 (insert (format "Loading %s..." url))
308 (goto-char (point-min))) 308 (goto-char (point-min)))
309 (let ((url-mime-accept-string eww-accept-content-types)) 309 (let ((url-mime-accept-string eww-accept-content-types))
310 (url-retrieve url 'eww-render 310 (url-retrieve url #'eww-render
311 (list url nil (current-buffer))))) 311 (list url nil (current-buffer)))))
312 312
313(put 'eww 'browse-url-browser-kind 'internal) 313(function-put 'eww 'browse-url-browser-kind 'internal)
314 314
315(defun eww--dwim-expand-url (url) 315(defun eww--dwim-expand-url (url)
316 (setq url (string-trim url)) 316 (setq url (string-trim url))
@@ -375,8 +375,8 @@ engine used."
375 (let ((region-string (buffer-substring (region-beginning) (region-end)))) 375 (let ((region-string (buffer-substring (region-beginning) (region-end))))
376 (if (not (string-match-p "\\`[ \n\t\r\v\f]*\\'" region-string)) 376 (if (not (string-match-p "\\`[ \n\t\r\v\f]*\\'" region-string))
377 (eww region-string) 377 (eww region-string)
378 (call-interactively 'eww))) 378 (call-interactively #'eww)))
379 (call-interactively 'eww))) 379 (call-interactively #'eww)))
380 380
381(defun eww-open-in-new-buffer () 381(defun eww-open-in-new-buffer ()
382 "Fetch link at point in a new EWW buffer." 382 "Fetch link at point in a new EWW buffer."
@@ -1013,7 +1013,7 @@ just re-display the HTML already fetched."
1013 (eww-display-html 'utf-8 url (plist-get eww-data :dom) 1013 (eww-display-html 'utf-8 url (plist-get eww-data :dom)
1014 (point) (current-buffer))) 1014 (point) (current-buffer)))
1015 (let ((url-mime-accept-string eww-accept-content-types)) 1015 (let ((url-mime-accept-string eww-accept-content-types))
1016 (url-retrieve url 'eww-render 1016 (url-retrieve url #'eww-render
1017 (list url (point) (current-buffer) encode)))))) 1017 (list url (point) (current-buffer) encode))))))
1018 1018
1019;; Form support. 1019;; Form support.
@@ -1576,8 +1576,10 @@ If EXTERNAL is double prefix, browse in new buffer."
1576 (cond 1576 (cond
1577 ((not url) 1577 ((not url)
1578 (message "No link under point")) 1578 (message "No link under point"))
1579 ((string-match "^mailto:" url) 1579 ((string-match-p "\\`mailto:" url)
1580 (browse-url-mail url)) 1580 ;; This respects the user options `browse-url-handlers'
1581 ;; and `browse-url-mailto-function'.
1582 (browse-url url))
1581 ((and (consp external) (<= (car external) 4)) 1583 ((and (consp external) (<= (car external) 4))
1582 (funcall browse-url-secondary-browser-function url) 1584 (funcall browse-url-secondary-browser-function url)
1583 (shr--blink-link)) 1585 (shr--blink-link))
@@ -1615,7 +1617,7 @@ Use link at point if there is one, else the current page's URL."
1615 (eww-current-url)))) 1617 (eww-current-url))))
1616 (if (not url) 1618 (if (not url)
1617 (message "No URL under point") 1619 (message "No URL under point")
1618 (url-retrieve url 'eww-download-callback (list url))))) 1620 (url-retrieve url #'eww-download-callback (list url)))))
1619 1621
1620(defun eww-download-callback (status url) 1622(defun eww-download-callback (status url)
1621 (unless (plist-get status :error) 1623 (unless (plist-get status :error)
@@ -2128,12 +2130,12 @@ entries (if any) will be removed from the list.
2128Only the properties listed in `eww-desktop-data-save' are included. 2130Only the properties listed in `eww-desktop-data-save' are included.
2129Generally, the list should not include the (usually overly large) 2131Generally, the list should not include the (usually overly large)
2130:dom, :source and :text properties." 2132:dom, :source and :text properties."
2131 (let ((history (mapcar 'eww-desktop-data-1 2133 (let ((history (mapcar #'eww-desktop-data-1
2132 (cons eww-data eww-history)))) 2134 (cons eww-data eww-history))))
2133 (list :history (if eww-desktop-remove-duplicates 2135 (list :history (if eww-desktop-remove-duplicates
2134 (cl-remove-duplicates 2136 (cl-remove-duplicates
2135 history :test 'eww-desktop-history-duplicate) 2137 history :test #'eww-desktop-history-duplicate)
2136 history)))) 2138 history))))
2137 2139
2138(defun eww-restore-desktop (file-name buffer-name misc-data) 2140(defun eww-restore-desktop (file-name buffer-name misc-data)
2139 "Restore an eww buffer from its desktop file record. 2141 "Restore an eww buffer from its desktop file record.
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 1f80ab74db5..03260c9e70a 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -135,7 +135,7 @@ same domain as the main data."
135This is used for cid: URLs, and the function is called with the 135This is used for cid: URLs, and the function is called with the
136cid: URL as the argument.") 136cid: URL as the argument.")
137 137
138(defvar shr-put-image-function 'shr-put-image 138(defvar shr-put-image-function #'shr-put-image
139 "Function called to put image and alt string.") 139 "Function called to put image and alt string.")
140 140
141(defface shr-strike-through '((t :strike-through t)) 141(defface shr-strike-through '((t :strike-through t))
@@ -365,25 +365,20 @@ If the URL is already at the front of the kill ring act like
365 (shr-copy-url url))) 365 (shr-copy-url url)))
366 366
367(defun shr--current-link-region () 367(defun shr--current-link-region ()
368 (let ((current (get-text-property (point) 'shr-url)) 368 "Return the start and end positions of the URL at point, if any.
369 start) 369Value is a pair of positions (START . END) if there is a non-nil
370 (save-excursion 370`shr-url' text property at point; otherwise nil."
371 ;; Go to the beginning. 371 (when (get-text-property (point) 'shr-url)
372 (while (and (not (bobp)) 372 (let* ((end (or (next-single-property-change (point) 'shr-url)
373 (equal (get-text-property (point) 'shr-url) current)) 373 (point-max)))
374 (forward-char -1)) 374 (beg (or (previous-single-property-change end 'shr-url)
375 (unless (equal (get-text-property (point) 'shr-url) current) 375 (point-min))))
376 (forward-char 1)) 376 (cons beg end))))
377 (setq start (point))
378 ;; Go to the end.
379 (while (and (not (eobp))
380 (equal (get-text-property (point) 'shr-url) current))
381 (forward-char 1))
382 (list start (point)))))
383 377
384(defun shr--blink-link () 378(defun shr--blink-link ()
385 (let* ((region (shr--current-link-region)) 379 "Briefly fontify URL at point with the face `shr-selected-link'."
386 (overlay (make-overlay (car region) (cadr region)))) 380 (when-let* ((region (shr--current-link-region))
381 (overlay (make-overlay (car region) (cdr region))))
387 (overlay-put overlay 'face 'shr-selected-link) 382 (overlay-put overlay 'face 'shr-selected-link)
388 (run-at-time 1 nil (lambda () 383 (run-at-time 1 nil (lambda ()
389 (delete-overlay overlay))))) 384 (delete-overlay overlay)))))
@@ -437,7 +432,7 @@ the URL of the image to the kill buffer instead."
437 (if (not url) 432 (if (not url)
438 (message "No image under point") 433 (message "No image under point")
439 (message "Inserting %s..." url) 434 (message "Inserting %s..." url)
440 (url-retrieve url 'shr-image-fetched 435 (url-retrieve url #'shr-image-fetched
441 (list (current-buffer) (1- (point)) (point-marker)) 436 (list (current-buffer) (1- (point)) (point-marker))
442 t)))) 437 t))))
443 438
@@ -463,7 +458,7 @@ size, and full-buffer size."
463 (when (> (- (point) start) 2) 458 (when (> (- (point) start) 2)
464 (delete-region start (1- (point))))) 459 (delete-region start (1- (point)))))
465 (message "Inserting %s..." url) 460 (message "Inserting %s..." url)
466 (url-retrieve url 'shr-image-fetched 461 (url-retrieve url #'shr-image-fetched
467 (list (current-buffer) (1- (point)) (point-marker) 462 (list (current-buffer) (1- (point)) (point-marker)
468 (list (cons 'size 463 (list (cons 'size
469 (cond ((or (eq size 'default) 464 (cond ((or (eq size 'default)
@@ -493,7 +488,7 @@ size, and full-buffer size."
493 ((fboundp function) 488 ((fboundp function)
494 (apply function dom args)) 489 (apply function dom args))
495 (t 490 (t
496 (apply 'shr-generic dom args))))) 491 (apply #'shr-generic dom args)))))
497 492
498(defun shr-descend (dom) 493(defun shr-descend (dom)
499 (let ((function 494 (let ((function
@@ -730,9 +725,10 @@ size, and full-buffer size."
730 (let ((gap-start (point)) 725 (let ((gap-start (point))
731 (face (get-text-property (point) 'face))) 726 (face (get-text-property (point) 'face)))
732 ;; Extend the background to the end of the line. 727 ;; Extend the background to the end of the line.
733 (if face 728 (insert ?\n)
734 (insert (propertize "\n" 'face (shr-face-background face))) 729 (when face
735 (insert "\n")) 730 (put-text-property (1- (point)) (point)
731 'face (shr-face-background face)))
736 (shr-indent) 732 (shr-indent)
737 (when (and (> (1- gap-start) (point-min)) 733 (when (and (> (1- gap-start) (point-min))
738 (get-text-property (point) 'shr-url) 734 (get-text-property (point) 'shr-url)
@@ -935,12 +931,11 @@ size, and full-buffer size."
935 931
936(defun shr-indent () 932(defun shr-indent ()
937 (when (> shr-indentation 0) 933 (when (> shr-indentation 0)
938 (insert 934 (if (not shr-use-fonts)
939 (if (not shr-use-fonts) 935 (insert-char ?\s shr-indentation)
940 (make-string shr-indentation ?\s) 936 (insert ?\s)
941 (propertize " " 937 (put-text-property (1- (point)) (point)
942 'display 938 'display `(space :width (,shr-indentation))))))
943 `(space :width (,shr-indentation)))))))
944 939
945(defun shr-fontize-dom (dom &rest types) 940(defun shr-fontize-dom (dom &rest types)
946 (let ((start (point))) 941 (let ((start (point)))
@@ -987,16 +982,11 @@ the mouse click event."
987 (cond 982 (cond
988 ((not url) 983 ((not url)
989 (message "No link under point")) 984 (message "No link under point"))
990 ((string-match "^mailto:" url) 985 (external
991 (browse-url-mail url)) 986 (funcall browse-url-secondary-browser-function url)
987 (shr--blink-link))
992 (t 988 (t
993 (if external 989 (browse-url url (xor new-window browse-url-new-window-flag))))))
994 (progn
995 (funcall browse-url-secondary-browser-function url)
996 (shr--blink-link))
997 (browse-url url (if new-window
998 (not browse-url-new-window-flag)
999 browse-url-new-window-flag)))))))
1000 990
1001(defun shr-save-contents (directory) 991(defun shr-save-contents (directory)
1002 "Save the contents from URL in a file." 992 "Save the contents from URL in a file."
@@ -1005,7 +995,7 @@ the mouse click event."
1005 (if (not url) 995 (if (not url)
1006 (message "No link under point") 996 (message "No link under point")
1007 (url-retrieve (shr-encode-url url) 997 (url-retrieve (shr-encode-url url)
1008 'shr-store-contents (list url directory))))) 998 #'shr-store-contents (list url directory)))))
1009 999
1010(defun shr-store-contents (status url directory) 1000(defun shr-store-contents (status url directory)
1011 (unless (plist-get status :error) 1001 (unless (plist-get status :error)
@@ -1156,7 +1146,6 @@ width/height instead."
1156 1146
1157;; url-cache-extract autoloads url-cache. 1147;; url-cache-extract autoloads url-cache.
1158(declare-function url-cache-create-filename "url-cache" (url)) 1148(declare-function url-cache-create-filename "url-cache" (url))
1159(autoload 'browse-url-mail "browse-url")
1160 1149
1161(defun shr-get-image-data (url) 1150(defun shr-get-image-data (url)
1162 "Get image data for URL. 1151 "Get image data for URL.
@@ -1230,7 +1219,7 @@ START, and END. Note that START and END should be markers."
1230 (funcall shr-put-image-function 1219 (funcall shr-put-image-function
1231 image (buffer-substring start end)) 1220 image (buffer-substring start end))
1232 (delete-region (point) end)))) 1221 (delete-region (point) end))))
1233 (url-retrieve url 'shr-image-fetched 1222 (url-retrieve url #'shr-image-fetched
1234 (list (current-buffer) start end) 1223 (list (current-buffer) start end)
1235 t t))))) 1224 t t)))))
1236 1225
@@ -1679,7 +1668,7 @@ The preference is a float determined from `shr-prefer-media-type'."
1679 (or alt ""))) 1668 (or alt "")))
1680 (insert " ") 1669 (insert " ")
1681 (url-queue-retrieve 1670 (url-queue-retrieve
1682 (shr-encode-url url) 'shr-image-fetched 1671 (shr-encode-url url) #'shr-image-fetched
1683 (list (current-buffer) start (set-marker (make-marker) (point)) 1672 (list (current-buffer) start (set-marker (make-marker) (point))
1684 (list :width width :height height)) 1673 (list :width width :height height))
1685 t 1674 t
@@ -2006,12 +1995,11 @@ BASE is the URL of the HTML being rendered."
2006 (cond 1995 (cond
2007 ((null tbodies) 1996 ((null tbodies)
2008 dom) 1997 dom)
2009 ((= (length tbodies) 1) 1998 ((null (cdr tbodies))
2010 (car tbodies)) 1999 (car tbodies))
2011 (t 2000 (t
2012 ;; Table with multiple tbodies. Convert into a single tbody. 2001 ;; Table with multiple tbodies. Convert into a single tbody.
2013 `(tbody nil ,@(cl-reduce 'append 2002 `(tbody nil ,@(mapcan #'dom-non-text-children tbodies))))))
2014 (mapcar 'dom-non-text-children tbodies)))))))
2015 2003
2016(defun shr--fix-tbody (tbody) 2004(defun shr--fix-tbody (tbody)
2017 (nconc (list 'tbody (dom-attributes tbody)) 2005 (nconc (list 'tbody (dom-attributes tbody))
@@ -2311,8 +2299,8 @@ flags that control whether to collect or render objects."
2311 (dolist (column row) 2299 (dolist (column row)
2312 (aset natural-widths i (max (aref natural-widths i) column)) 2300 (aset natural-widths i (max (aref natural-widths i) column))
2313 (setq i (1+ i))))) 2301 (setq i (1+ i)))))
2314 (let ((extra (- (apply '+ (append suggested-widths nil)) 2302 (let ((extra (- (apply #'+ (append suggested-widths nil))
2315 (apply '+ (append widths nil)) 2303 (apply #'+ (append widths nil))
2316 (* shr-table-separator-pixel-width (1+ (length widths))))) 2304 (* shr-table-separator-pixel-width (1+ (length widths)))))
2317 (expanded-columns 0)) 2305 (expanded-columns 0))
2318 ;; We have extra, unused space, so divide this space amongst the 2306 ;; We have extra, unused space, so divide this space amongst the