aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGnus developers2013-06-16 22:20:55 +0000
committerKatsumi Yamaoka2013-06-16 22:20:55 +0000
commitc74cb3449a0c0e54f79ecec93886a0737326e033 (patch)
tree810b66eda9c360f1d365b145b0caf0284f7b3bf4
parent28237e48e122aa8cbd9b7bea8d3d5d15b8181666 (diff)
downloademacs-c74cb3449a0c0e54f79ecec93886a0737326e033.tar.gz
emacs-c74cb3449a0c0e54f79ecec93886a0737326e033.zip
2013-06-16 Lars Magne Ingebrigtsen <larsi@gnus.org>
* eww.el (eww-display-html): Default to using the entire window width. * shr.el (shr-make-table): Cache the table rendering at the table level, and not the <td> level. This is a bit faster. * eww.el (eww-render): Go to the correct ID when given URLs ending with #id. * shr.el (shr-tag-li): Don't require a new paragraph, since other browsers don't. (shr-expand-url): Respect #anchor links. (shr-parse-base): Chop off the anchor before using. (shr-descend): Respect display: none. (shr-descend): Allow marking elements that have certain IDs. * eww.el (eww-tag-textarea): Use `text' instead of `editable-field'. * shr.el (shr-expand-url): Don't bug out on zero-length links. * eww.el (eww-tag-textarea): Support <textarea>. 2013-06-16 RĂ¼diger Sonderfeld <ruediger@c-plusplus.de> * shr.el (shr-dom-to-xml): Fixed function call. * eww.el (eww): New group. (eww-header-line-format): New custom variable. (eww-current-title): New variable. (eww-display-html): Update header and handle title tag. (eww-update-header-line-format): New function. (eww-tag-title): New function. * shr.el (shr-dom-to-xml): (shr-dom-to-xml): New function. (shr-tag-svg): Add support for the SVG tag. (shr-bullet): New custom variable. (shr-tag-li): Support custom bullet in unordered lists. 2013-06-16 Lars Magne Ingebrigtsen <larsi@gnus.org> * shr.el (shr-expand-url): Respect // URLs. * eww.el (eww-tag-body): Override the shr body rendering so that we can put a background colour onto the entire buffer. (eww-render): When being redirected, use the redirect URL as the new base URL. * shr.el (shr-parse-base): Fix parsing error. * eww.el (eww-submit): Pass the base in to `shr-expand-url'. * shr.el (shr-parse-base): New function. (shr-expand-url): Use it to expand relative URLs reliably.
-rw-r--r--lisp/gnus/ChangeLog55
-rw-r--r--lisp/gnus/eww.el121
-rw-r--r--lisp/gnus/shr.el177
3 files changed, 270 insertions, 83 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 33ae989d15a..58b5ae1a56a 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,58 @@
12013-06-16 Lars Magne Ingebrigtsen <larsi@gnus.org>
2
3 * eww.el (eww-display-html): Default to using the entire window width.
4
5 * shr.el (shr-make-table): Cache the table rendering at the table
6 level, and not the <td> level. This is a bit faster.
7
8 * eww.el (eww-render): Go to the correct ID when given URLs ending with
9 #id.
10
11 * shr.el (shr-tag-li): Don't require a new paragraph, since other
12 browsers don't.
13 (shr-expand-url): Respect #anchor links.
14 (shr-parse-base): Chop off the anchor before using.
15 (shr-descend): Respect display: none.
16 (shr-descend): Allow marking elements that have certain IDs.
17
18 * eww.el (eww-tag-textarea): Use `text' instead of `editable-field'.
19
20 * shr.el (shr-expand-url): Don't bug out on zero-length links.
21
22 * eww.el (eww-tag-textarea): Support <textarea>.
23
242013-06-16 RĂ¼diger Sonderfeld <ruediger@c-plusplus.de>
25
26 * shr.el (shr-dom-to-xml): Fixed function call.
27
28 * eww.el (eww): New group.
29 (eww-header-line-format): New custom variable.
30 (eww-current-title): New variable.
31 (eww-display-html): Update header and handle title tag.
32 (eww-update-header-line-format): New function.
33 (eww-tag-title): New function.
34
35 * shr.el (shr-dom-to-xml): (shr-dom-to-xml): New function.
36 (shr-tag-svg): Add support for the SVG tag.
37 (shr-bullet): New custom variable.
38 (shr-tag-li): Support custom bullet in unordered lists.
39
402013-06-16 Lars Magne Ingebrigtsen <larsi@gnus.org>
41
42 * shr.el (shr-expand-url): Respect // URLs.
43
44 * eww.el (eww-tag-body): Override the shr body rendering so that we can
45 put a background colour onto the entire buffer.
46 (eww-render): When being redirected, use the redirect URL as the new
47 base URL.
48
49 * shr.el (shr-parse-base): Fix parsing error.
50
51 * eww.el (eww-submit): Pass the base in to `shr-expand-url'.
52
53 * shr.el (shr-parse-base): New function.
54 (shr-expand-url): Use it to expand relative URLs reliably.
55
12013-06-15 Teodor Zlatanov <tzz@lifelogs.com> 562013-06-15 Teodor Zlatanov <tzz@lifelogs.com>
2 57
3 * auth-source.el (auth-source-search-collection): Fix docstring. 58 * auth-source.el (auth-source-search-collection): Fix docstring.
diff --git a/lisp/gnus/eww.el b/lisp/gnus/eww.el
index 270c3ee3ed2..b34ec7655cc 100644
--- a/lisp/gnus/eww.el
+++ b/lisp/gnus/eww.el
@@ -29,7 +29,22 @@
29(require 'url) 29(require 'url)
30(require 'mm-url) 30(require 'mm-url)
31 31
32(defgroup eww nil
33 "Emacs Web Wowser"
34 :version "24.4"
35 :group 'hypermedia
36 :prefix "eww-")
37
38(defcustom eww-header-line-format "%t: %u"
39 "Header line format.
40- %t is replaced by the title.
41- %u is replaced by the URL."
42 :group 'eww
43 :type 'string)
44
32(defvar eww-current-url nil) 45(defvar eww-current-url nil)
46(defvar eww-current-title ""
47 "Title of current page.")
33(defvar eww-history nil) 48(defvar eww-history nil)
34 49
35;;;###autoload 50;;;###autoload
@@ -53,7 +68,13 @@
53 (match-string 1))))) 68 (match-string 1)))))
54 69
55(defun eww-render (status url &optional point) 70(defun eww-render (status url &optional point)
71 (let ((redirect (plist-get status :redirect)))
72 (when redirect
73 (setq url redirect)))
56 (let* ((headers (eww-parse-headers)) 74 (let* ((headers (eww-parse-headers))
75 (shr-target-id
76 (and (string-match "#\\(.*\\)" url)
77 (match-string 1 url)))
57 (content-type 78 (content-type
58 (mail-header-parse-content-type 79 (mail-header-parse-content-type
59 (or (cdr (assoc "content-type" headers)) 80 (or (cdr (assoc "content-type" headers))
@@ -74,8 +95,14 @@
74 (eww-display-image)) 95 (eww-display-image))
75 (t 96 (t
76 (eww-display-raw charset))) 97 (eww-display-raw charset)))
77 (when point 98 (cond
78 (goto-char point))) 99 (point
100 (goto-char point))
101 (shr-target-id
102 (let ((point (next-single-property-change
103 (point-min) 'shr-target-id)))
104 (when point
105 (goto-char (1+ point)))))))
79 (kill-buffer data-buffer)))) 106 (kill-buffer data-buffer))))
80 107
81(defun eww-parse-headers () 108(defun eww-parse-headers ()
@@ -101,15 +128,56 @@
101 (libxml-parse-html-region (point) (point-max))))) 128 (libxml-parse-html-region (point) (point-max)))))
102 (eww-setup-buffer) 129 (eww-setup-buffer)
103 (setq eww-current-url url) 130 (setq eww-current-url url)
131 (eww-update-header-line-format)
104 (let ((inhibit-read-only t) 132 (let ((inhibit-read-only t)
133 (shr-width nil)
105 (shr-external-rendering-functions 134 (shr-external-rendering-functions
106 '((form . eww-tag-form) 135 '((title . eww-tag-title)
136 (form . eww-tag-form)
107 (input . eww-tag-input) 137 (input . eww-tag-input)
138 (textarea . eww-tag-textarea)
139 (body . eww-tag-body)
108 (select . eww-tag-select)))) 140 (select . eww-tag-select))))
109 (shr-insert-document document) 141 (shr-insert-document document)
110 (eww-convert-widgets)) 142 (eww-convert-widgets))
111 (goto-char (point-min)))) 143 (goto-char (point-min))))
112 144
145(defun eww-update-header-line-format ()
146 (if eww-header-line-format
147 (setq header-line-format (format-spec eww-header-line-format
148 `((?u . ,eww-current-url)
149 (?t . ,eww-current-title))))
150 (setq header-line-format nil)))
151
152(defun eww-tag-title (cont)
153 (setq eww-current-title "")
154 (dolist (sub cont)
155 (when (eq (car sub) 'text)
156 (setq eww-current-title (concat eww-current-title (cdr sub)))))
157 (eww-update-header-line-format))
158
159(defun eww-tag-body (cont)
160 (let* ((start (point))
161 (fgcolor (cdr (or (assq :fgcolor cont)
162 (assq :text cont))))
163 (bgcolor (cdr (assq :bgcolor cont)))
164 (shr-stylesheet (list (cons 'color fgcolor)
165 (cons 'background-color bgcolor))))
166 (shr-generic cont)
167 (eww-colorize-region start (point) fgcolor bgcolor)))
168
169(defun eww-colorize-region (start end fg &optional bg)
170 (when (or fg bg)
171 (let ((new-colors (shr-color-check fg bg)))
172 (when new-colors
173 (when fg
174 (eww-put-color start end :foreground (cadr new-colors)))
175 (when bg
176 (eww-put-color start end :background (car new-colors)))))))
177
178(defun eww-put-color (start end type color)
179 (shr-put-color-1 start end type color))
180
113(defun eww-display-raw (charset) 181(defun eww-display-raw (charset)
114 (let ((data (buffer-substring (point) (point-max)))) 182 (let ((data (buffer-substring (point) (point-max))))
115 (eww-setup-buffer) 183 (eww-setup-buffer)
@@ -240,6 +308,21 @@
240 (apply 'widget-create widget) 308 (apply 'widget-create widget)
241 (put-text-property start (point) 'eww-widget widget)))) 309 (put-text-property start (point) 'eww-widget widget))))
242 310
311(defun eww-tag-textarea (cont)
312 (let* ((start (point))
313 (widget
314 (list 'text
315 :size (string-to-number
316 (or (cdr (assq :cols cont))
317 "40"))
318 :value (or (cdr (assq 'text cont)) "")
319 :action 'eww-submit
320 :name (cdr (assq :name cont))
321 :eww-form eww-form)))
322 (nconc eww-form (list widget))
323 (apply 'widget-create widget)
324 (put-text-property start (point) 'eww-widget widget)))
325
243(defun eww-tag-select (cont) 326(defun eww-tag-select (cont)
244 (shr-ensure-paragraph) 327 (shr-ensure-paragraph)
245 (let ((menu (list 'menu-choice 328 (let ((menu (list 'menu-choice
@@ -330,22 +413,22 @@
330 (plist-get (cdr elem) :value)) 413 (plist-get (cdr elem) :value))
331 values) 414 values)
332 (setq rest nil)))))) 415 (setq rest nil))))))
333 (debug values) 416 (if (and (stringp (cdr (assq :method form)))
334 (let ((shr-base eww-current-url)) 417 (equal (downcase (cdr (assq :method form))) "post"))
335 (if (and (stringp (cdr (assq :method form))) 418 (let ((url-request-method "POST")
336 (equal (downcase (cdr (assq :method form))) "post")) 419 (url-request-extra-headers
337 (let ((url-request-method "POST") 420 '(("Content-Type" . "application/x-www-form-urlencoded")))
338 (url-request-extra-headers 421 (url-request-data (mm-url-encode-www-form-urlencoded values)))
339 '(("Content-Type" . "application/x-www-form-urlencoded"))) 422 (eww-browse-url (shr-expand-url (cdr (assq :action form))
340 (url-request-data (mm-url-encode-www-form-urlencoded values))) 423 eww-current-url)))
341 (eww-browse-url (shr-expand-url (cdr (assq :action form))))) 424 (eww-browse-url
342 (eww-browse-url 425 (concat
343 (concat 426 (if (cdr (assq :action form))
344 (if (cdr (assq :action form)) 427 (shr-expand-url (cdr (assq :action form))
345 (shr-expand-url (cdr (assq :action form))) 428 eww-current-url)
346 eww-current-url) 429 eww-current-url)
347 "?" 430 "?"
348 (mm-url-encode-www-form-urlencoded values))))))) 431 (mm-url-encode-www-form-urlencoded values))))))
349 432
350(defun eww-convert-widgets () 433(defun eww-convert-widgets ()
351 (let ((start (point-min)) 434 (let ((start (point-min))
diff --git a/lisp/gnus/shr.el b/lisp/gnus/shr.el
index c93357efd25..339b9698922 100644
--- a/lisp/gnus/shr.el
+++ b/lisp/gnus/shr.el
@@ -83,6 +83,14 @@ used."
83 (const :tag "Use the width of the window" nil)) 83 (const :tag "Use the width of the window" nil))
84 :group 'shr) 84 :group 'shr)
85 85
86(defcustom shr-bullet "* "
87 "Bullet used for unordered lists.
88Alternative suggestions are:
89- \" \"
90- \" \""
91 :type 'string
92 :group 'shr)
93
86(defvar shr-content-function nil 94(defvar shr-content-function nil
87 "If bound, this should be a function that will return the content. 95 "If bound, this should be a function that will return the content.
88This is used for cid: URLs, and the function is called with the 96This is used for cid: URLs, and the function is called with the
@@ -115,6 +123,7 @@ cid: URL as the argument.")
115(defvar shr-base nil) 123(defvar shr-base nil)
116(defvar shr-ignore-cache nil) 124(defvar shr-ignore-cache nil)
117(defvar shr-external-rendering-functions nil) 125(defvar shr-external-rendering-functions nil)
126(defvar shr-target-id nil)
118 127
119(defvar shr-map 128(defvar shr-map
120 (let ((map (make-sparse-keymap))) 129 (let ((map (make-sparse-keymap)))
@@ -303,18 +312,24 @@ size, and full-buffer size."
303 (shr-stylesheet shr-stylesheet) 312 (shr-stylesheet shr-stylesheet)
304 (start (point))) 313 (start (point)))
305 (when style 314 (when style
306 (if (string-match "color" style) 315 (if (string-match "color\\|display" style)
307 (setq shr-stylesheet (nconc (shr-parse-style style) 316 (setq shr-stylesheet (nconc (shr-parse-style style)
308 shr-stylesheet)) 317 shr-stylesheet))
309 (setq style nil))) 318 (setq style nil)))
310 (if (fboundp function) 319 ;; If we have a display:none, then just ignore this part of the
311 (funcall function (cdr dom)) 320 ;; DOM.
312 (shr-generic (cdr dom))) 321 (unless (equal (cdr (assq 'display shr-stylesheet)) "none")
313 ;; If style is set, then this node has set the color. 322 (if (fboundp function)
314 (when style 323 (funcall function (cdr dom))
315 (shr-colorize-region start (point) 324 (shr-generic (cdr dom)))
316 (cdr (assq 'color shr-stylesheet)) 325 (when (and shr-target-id
317 (cdr (assq 'background-color shr-stylesheet)))))) 326 (equal (cdr (assq :id (cdr dom))) shr-target-id))
327 (put-text-property start (1+ start) 'shr-target-id shr-target-id))
328 ;; If style is set, then this node has set the color.
329 (when style
330 (shr-colorize-region start (point)
331 (cdr (assq 'color shr-stylesheet))
332 (cdr (assq 'background-color shr-stylesheet)))))))
318 333
319(defun shr-generic (cont) 334(defun shr-generic (cont)
320 (dolist (sub cont) 335 (dolist (sub cont)
@@ -484,31 +499,51 @@ size, and full-buffer size."
484 (forward-char 1)))) 499 (forward-char 1))))
485 (not failed))) 500 (not failed)))
486 501
487(defun shr-expand-url (url) 502(defun shr-parse-base (url)
488 (if (or (not url) 503 ;; Always chop off anchors.
489 (string-match "\\`[a-z]*:" url) 504 (when (string-match "#.*" url)
490 (not shr-base)) 505 (setq url (substring url 0 (match-beginning 0))))
491 ;; Absolute URL. 506 (let* ((parsed (url-generic-parse-url url))
492 url 507 (local (url-filename parsed)))
493 (let ((base shr-base)) 508 (setf (url-filename parsed) "")
494 ;; Chop off query string. 509 ;; Chop off the bit after the last slash.
495 (when (string-match "\\`\\([^?]+\\)[?]" base) 510 (when (string-match "\\`\\(.*/\\)[^/]+\\'" local)
496 (setq base (match-string 1 base))) 511 (setq local (match-string 1 local)))
497 ;; Chop off the bit after the last slash. 512 ;; Always make the local bit end with a slash.
498 (when (string-match "\\`\\(.*\\)[/][^/]+" base) 513 (when (and (not (zerop (length local)))
499 (setq base (match-string 1 base))) 514 (not (eq (aref local (1- (length local))) ?/)))
500 (cond 515 (setq local (concat local "/")))
501 ((and (string-match "\\`//" url) 516 (list (url-recreate-url parsed)
502 (string-match "\\`[a-z]*:" base)) 517 local
503 (concat (match-string 0 base) url)) 518 (url-type parsed)
504 ((and (not (string-match "/\\'" base)) 519 url)))
505 (not (string-match "\\`/" url))) 520
506 (concat base "/" url)) 521(defun shr-expand-url (url &optional base)
507 ((and (string-match "\\`/" url) 522 (setq base
508 (string-match "\\(\\`[^:]*://[^/]+\\)/" base)) 523 (if base
509 (concat (match-string 1 base) url)) 524 (shr-parse-base base)
510 (t 525 ;; Bound by the parser.
511 (concat base url)))))) 526 shr-base))
527 (when (zerop (length url))
528 (setq url nil))
529 (cond ((or (not url)
530 (not base)
531 (string-match "\\`[a-z]*:" url))
532 ;; Absolute URL.
533 (or url (car base)))
534 ((eq (aref url 0) ?/)
535 (if (and (> (length url) 1)
536 (eq (aref url 1) ?/))
537 ;; //host...; just use the protocol
538 (concat (nth 2 base) ":" url)
539 ;; Just use the host name part.
540 (concat (car base) url)))
541 ((eq (aref url 0) ?#)
542 ;; A link to an anchor.
543 (concat (nth 3 base) url))
544 (t
545 ;; Totally relative.
546 (concat (car base) (cadr base) url))))
512 547
513(defun shr-ensure-newline () 548(defun shr-ensure-newline ()
514 (unless (zerop (current-column)) 549 (unless (zerop (current-column))
@@ -894,8 +929,31 @@ ones, in case fg and bg are nil."
894(defun shr-tag-comment (cont) 929(defun shr-tag-comment (cont)
895 ) 930 )
896 931
932(defun shr-dom-to-xml (dom)
933 "Convert DOM into a string containing the xml representation."
934 (let ((arg " ")
935 (text ""))
936 (dolist (sub (cdr dom))
937 (cond
938 ((listp (cdr sub))
939 (setq text (concat text (shr-dom-to-xml sub))))
940 ((eq (car sub) 'text)
941 (setq text (concat text (cdr sub))))
942 (t
943 (setq arg (concat arg (format "%s=\"%s\" "
944 (substring (symbol-name (car sub)) 1)
945 (cdr sub)))))))
946 (format "<%s%s>%s</%s>"
947 (car dom)
948 (substring arg 0 (1- (length arg)))
949 text
950 (car dom))))
951
897(defun shr-tag-svg (cont) 952(defun shr-tag-svg (cont)
898 ) 953 (when (image-type-available-p 'svg)
954 (funcall shr-put-image-function
955 (shr-dom-to-xml (cons 'svg cont))
956 "SVG Image")))
899 957
900(defun shr-tag-sup (cont) 958(defun shr-tag-sup (cont)
901 (let ((start (point))) 959 (let ((start (point)))
@@ -965,7 +1023,7 @@ ones, in case fg and bg are nil."
965 plist))) 1023 plist)))
966 1024
967(defun shr-tag-base (cont) 1025(defun shr-tag-base (cont)
968 (setq shr-base (cdr (assq :href cont))) 1026 (setq shr-base (shr-parse-base (cdr (assq :href cont))))
969 (shr-generic cont)) 1027 (shr-generic cont))
970 1028
971(defun shr-tag-a (cont) 1029(defun shr-tag-a (cont)
@@ -1087,14 +1145,14 @@ ones, in case fg and bg are nil."
1087 (shr-ensure-paragraph)) 1145 (shr-ensure-paragraph))
1088 1146
1089(defun shr-tag-li (cont) 1147(defun shr-tag-li (cont)
1090 (shr-ensure-paragraph) 1148 (shr-ensure-newline)
1091 (shr-indent) 1149 (shr-indent)
1092 (let* ((bullet 1150 (let* ((bullet
1093 (if (numberp shr-list-mode) 1151 (if (numberp shr-list-mode)
1094 (prog1 1152 (prog1
1095 (format "%d " shr-list-mode) 1153 (format "%d " shr-list-mode)
1096 (setq shr-list-mode (1+ shr-list-mode))) 1154 (setq shr-list-mode (1+ shr-list-mode)))
1097 "* ")) 1155 shr-bullet))
1098 (shr-indentation (+ shr-indentation (length bullet)))) 1156 (shr-indentation (+ shr-indentation (length bullet))))
1099 (insert bullet) 1157 (insert bullet)
1100 (shr-generic cont))) 1158 (shr-generic cont)))
@@ -1352,6 +1410,13 @@ ones, in case fg and bg are nil."
1352 widths)) 1410 widths))
1353 1411
1354(defun shr-make-table (cont widths &optional fill) 1412(defun shr-make-table (cont widths &optional fill)
1413 (or (cadr (assoc (list cont widths fill) shr-content-cache))
1414 (let ((data (shr-make-table-1 cont widths fill)))
1415 (push (list (list cont widths fill) data)
1416 shr-content-cache)
1417 data)))
1418
1419(defun shr-make-table-1 (cont widths &optional fill)
1355 (let ((trs nil)) 1420 (let ((trs nil))
1356 (dolist (row cont) 1421 (dolist (row cont)
1357 (when (eq (car row) 'tr) 1422 (when (eq (car row) 'tr)
@@ -1385,32 +1450,16 @@ ones, in case fg and bg are nil."
1385 (setq style (nconc (list (cons 'color fgcolor)) style))) 1450 (setq style (nconc (list (cons 'color fgcolor)) style)))
1386 (when style 1451 (when style
1387 (setq shr-stylesheet (append style shr-stylesheet))) 1452 (setq shr-stylesheet (append style shr-stylesheet)))
1388 (let ((cache (cdr (assoc (cons width cont) shr-content-cache)))) 1453 (let ((shr-width width)
1389 (if cache 1454 (shr-indentation 0))
1390 (progn 1455 (shr-descend (cons 'td cont)))
1391 (insert (car cache)) 1456 ;; Delete padding at the bottom of the TDs.
1392 (let ((end (length (car cache)))) 1457 (delete-region
1393 (dolist (overlay (cadr cache)) 1458 (point)
1394 (let ((new-overlay 1459 (progn
1395 (shr-make-overlay (1+ (- end (nth 0 overlay))) 1460 (skip-chars-backward " \t\n")
1396 (1+ (- end (nth 1 overlay))))) 1461 (end-of-line)
1397 (properties (nth 2 overlay))) 1462 (point)))
1398 (while properties
1399 (overlay-put new-overlay
1400 (pop properties) (pop properties)))))))
1401 (let ((shr-width width)
1402 (shr-indentation 0))
1403 (shr-descend (cons 'td cont)))
1404 ;; Delete padding at the bottom of the TDs.
1405 (delete-region
1406 (point)
1407 (progn
1408 (skip-chars-backward " \t\n")
1409 (end-of-line)
1410 (point)))
1411 (push (list (cons width cont) (buffer-string)
1412 (shr-overlays-in-region (point-min) (point-max)))
1413 shr-content-cache)))
1414 (goto-char (point-min)) 1463 (goto-char (point-min))
1415 (let ((max 0)) 1464 (let ((max 0))
1416 (while (not (eobp)) 1465 (while (not (eobp))