aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Magne Ingebrigtsen2013-06-10 14:11:01 +0000
committerKatsumi Yamaoka2013-06-10 14:11:01 +0000
commit2644071e8ef9de418b58c4d84ef7b13f1ea5d1fe (patch)
tree0ff9c7d122268fd73ff8a4a692e9c98b035154f0
parent266c63b5c13c519c2deb051de10fdfea2470c4c3 (diff)
downloademacs-2644071e8ef9de418b58c4d84ef7b13f1ea5d1fe.tar.gz
emacs-2644071e8ef9de418b58c4d84ef7b13f1ea5d1fe.zip
lisp/gnus/eww.el: Add form support; Make form submission work; Support POST
-rw-r--r--lisp/gnus/ChangeLog7
-rw-r--r--lisp/gnus/eww.el78
-rw-r--r--lisp/gnus/shr.el39
3 files changed, 106 insertions, 18 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index ee540465a3c..69137ff7358 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,6 +1,13 @@
12013-06-10 Lars Magne Ingebrigtsen <larsi@gnus.org> 12013-06-10 Lars Magne Ingebrigtsen <larsi@gnus.org>
2 2
3 * eww.el (eww-submit): Make form submission work.
4
5 * shr.el (shr-descend): Allow other packages to override (or provide)
6 rendering of elements.
7 (shr-expand-url): Strip query strings from URLs before expanding them.
8
3 * eww.el: Don't require cl-lib. 9 * eww.el: Don't require cl-lib.
10 (eww-tag-form): Start form support.
4 11
5 * eww.el: Start writing a new, tiny web browser. 12 * eww.el: Start writing a new, tiny web browser.
6 (eww-previous-url): New command. 13 (eww-previous-url): New command.
diff --git a/lisp/gnus/eww.el b/lisp/gnus/eww.el
index c4a664022ac..63ad6fd4f8a 100644
--- a/lisp/gnus/eww.el
+++ b/lisp/gnus/eww.el
@@ -27,6 +27,7 @@
27(eval-when-compile (require 'cl)) 27(eval-when-compile (require 'cl))
28(require 'shr) 28(require 'shr)
29(require 'url) 29(require 'url)
30(require 'mm-url)
30 31
31(defvar eww-current-url nil) 32(defvar eww-current-url nil)
32(defvar eww-history nil) 33(defvar eww-history nil)
@@ -82,8 +83,13 @@
82 (libxml-parse-html-region (point) (point-max))))) 83 (libxml-parse-html-region (point) (point-max)))))
83 (eww-setup-buffer) 84 (eww-setup-buffer)
84 (setq eww-current-url url) 85 (setq eww-current-url url)
85 (let ((inhibit-read-only t)) 86 (let ((inhibit-read-only t)
86 (shr-insert-document document)) 87 (shr-external-rendering-functions
88 '((form . eww-tag-form)
89 (input . eww-tag-input)
90 (submit . eww-tag-submit))))
91 (shr-insert-document document)
92 (eww-convert-widgets))
87 (goto-char (point-min)))) 93 (goto-char (point-min))))
88 94
89(defun eww-display-raw (charset) 95(defun eww-display-raw (charset)
@@ -102,6 +108,8 @@
102 108
103(defun eww-setup-buffer () 109(defun eww-setup-buffer ()
104 (pop-to-buffer (get-buffer-create "*eww*")) 110 (pop-to-buffer (get-buffer-create "*eww*"))
111 (remove-overlays)
112 (setq widget-field-list nil)
105 (let ((inhibit-read-only t)) 113 (let ((inhibit-read-only t))
106 (erase-buffer)) 114 (erase-buffer))
107 (eww-mode)) 115 (eww-mode))
@@ -128,7 +136,7 @@
128 mode-name "eww") 136 mode-name "eww")
129 (set (make-local-variable 'eww-current-url) 'author) 137 (set (make-local-variable 'eww-current-url) 'author)
130 (set (make-local-variable 'browse-url-browser-function) 'eww-browse-url) 138 (set (make-local-variable 'browse-url-browser-function) 'eww-browse-url)
131 (setq buffer-read-only t) 139 ;;(setq buffer-read-only t)
132 (use-local-map eww-mode-map)) 140 (use-local-map eww-mode-map))
133 141
134(defun eww-browse-url (url &optional new-window) 142(defun eww-browse-url (url &optional new-window)
@@ -150,6 +158,70 @@
150 (let ((prev (pop eww-history))) 158 (let ((prev (pop eww-history)))
151 (url-retrieve (car prev) 'eww-render (list (car prev) (cadr prev))))) 159 (url-retrieve (car prev) 'eww-render (list (car prev) (cadr prev)))))
152 160
161;; Form support.
162
163(defvar eww-form nil)
164
165(defun eww-tag-form (cont)
166 (let ((eww-form
167 (list (assq :method cont)
168 (assq :action cont)))
169 (start (point)))
170 (shr-ensure-paragraph)
171 (shr-generic cont)
172 (shr-ensure-paragraph)
173 (put-text-property start (1+ start)
174 'eww-form eww-form)))
175
176(defun eww-tag-input (cont)
177 (let ((start (point))
178 (widget (list
179 'editable-field
180 :size (string-to-number
181 (or (cdr (assq :size cont))
182 "40"))
183 :value (or (cdr (assq :value cont)) "")
184 :action 'eww-submit
185 :name (cdr (assq :name cont))
186 :eww-form eww-form)))
187 (apply 'widget-create widget)
188 (shr-generic cont)
189 (put-text-property start (point) 'eww-widget widget)))
190
191(defun eww-submit (widget dummy)
192 (let ((form (getf (cdr widget) :eww-form))
193 values)
194 (dolist (overlay (overlays-in (point-min) (point-max)))
195 (let ((field (getf (overlay-properties overlay) 'field)))
196 (when (eq (getf (cdr field) :eww-form) form)
197 (let ((name (getf (cdr field) :name)))
198 (when name
199 (push (cons name (widget-value field))
200 values))))))
201 (let ((shr-base eww-current-url))
202 (if (and (stringp (getf form :method))
203 (equal (downcase (getf form :method)) "post"))
204 (let ((url-request-method "POST")
205 (url-request-data (mm-url-encode-www-form-urlencoded values)))
206 (eww-browse-url (shr-expand-url (getf form :action))))
207 (eww-browse-url
208 (shr-expand-url
209 (concat
210 (getf form :action)
211 "?"
212 (mm-url-encode-www-form-urlencoded values))))))))
213
214(defun eww-convert-widgets ()
215 (let ((start (point-min))
216 widget)
217 (while (setq start (next-single-property-change start 'eww-widget))
218 (setq widget (get-text-property start 'eww-widget))
219 (goto-char start)
220 (delete-region start (next-single-property-change start 'eww-widget))
221 (apply 'widget-create widget)
222 (put-text-property start (point) 'not-read-only t))
223 (widget-setup)))
224
153(provide 'eww) 225(provide 'eww)
154 226
155;;; eww.el ends here 227;;; eww.el ends here
diff --git a/lisp/gnus/shr.el b/lisp/gnus/shr.el
index 6e0aa26e376..bf9f5a4e3d4 100644
--- a/lisp/gnus/shr.el
+++ b/lisp/gnus/shr.el
@@ -114,6 +114,7 @@ cid: URL as the argument.")
114(defvar shr-stylesheet nil) 114(defvar shr-stylesheet nil)
115(defvar shr-base nil) 115(defvar shr-base nil)
116(defvar shr-ignore-cache nil) 116(defvar shr-ignore-cache nil)
117(defvar shr-external-rendering-functions nil)
117 118
118(defvar shr-map 119(defvar shr-map
119 (let ((map (make-sparse-keymap))) 120 (let ((map (make-sparse-keymap)))
@@ -291,7 +292,12 @@ size, and full-buffer size."
291 (nreverse result))) 292 (nreverse result)))
292 293
293(defun shr-descend (dom) 294(defun shr-descend (dom)
294 (let ((function (intern (concat "shr-tag-" (symbol-name (car dom))) obarray)) 295 (let ((function
296 (or
297 ;; Allow other packages to override (or provide) rendering
298 ;; of elements.
299 (cdr (assq (car dom) shr-external-rendering-functions))
300 (intern (concat "shr-tag-" (symbol-name (car dom))) obarray)))
295 (style (cdr (assq :style (cdr dom)))) 301 (style (cdr (assq :style (cdr dom))))
296 (shr-stylesheet shr-stylesheet) 302 (shr-stylesheet shr-stylesheet)
297 (start (point))) 303 (start (point)))
@@ -478,20 +484,23 @@ size, and full-buffer size."
478 (not failed))) 484 (not failed)))
479 485
480(defun shr-expand-url (url) 486(defun shr-expand-url (url)
481 (cond 487 (if (or (not url)
482 ;; Absolute URL. 488 (string-match "\\`[a-z]*:" url)
483 ((or (not url) 489 (not shr-base))
484 (string-match "\\`[a-z]*:" url) 490 ;; Absolute URL.
485 (not shr-base)) 491 url
486 url) 492 (let ((base shr-base))
487 ((and (string-match "\\`//" url) 493 (when (string-match "^\\([^?]+\\)[?]" base)
488 (string-match "\\`[a-z]*:" shr-base)) 494 (setq base (match-string 1 base)))
489 (concat (match-string 0 shr-base) url)) 495 (cond
490 ((and (not (string-match "/\\'" shr-base)) 496 ((and (string-match "\\`//" url)
491 (not (string-match "\\`/" url))) 497 (string-match "\\`[a-z]*:" base))
492 (concat shr-base "/" url)) 498 (concat (match-string 0 base) url))
493 (t 499 ((and (not (string-match "/\\'" base))
494 (concat shr-base url)))) 500 (not (string-match "\\`/" url)))
501 (concat base "/" url))
502 (t
503 (concat base url))))))
495 504
496(defun shr-ensure-newline () 505(defun shr-ensure-newline ()
497 (unless (zerop (current-column)) 506 (unless (zerop (current-column))