aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Magne Ingebrigtsen2013-06-10 22:12:47 +0000
committerKatsumi Yamaoka2013-06-10 22:12:47 +0000
commitf22255bdbd0dd71d87f810f2ede419e6ec35370f (patch)
treec2500107626636bb65440369f5cd372ca1d79525
parent08c0a604a289168bec624cb96c09adf357491890 (diff)
downloademacs-f22255bdbd0dd71d87f810f2ede419e6ec35370f.tar.gz
emacs-f22255bdbd0dd71d87f810f2ede419e6ec35370f.zip
lisp/gnus/eww.el (eww-tag-input): Implement submit buttons
(eww-click-radio): Implement radio and checkboxes (eww-submit): Handle hidden elements (eww-submit): Get submit button logic right lisp/gnus/shr.el (shr-expand-url): Expand URLs that start with a slash correctly
-rw-r--r--lisp/gnus/ChangeLog12
-rw-r--r--lisp/gnus/eww.el144
-rw-r--r--lisp/gnus/shr.el8
3 files changed, 135 insertions, 29 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 69137ff7358..f4d45e9fd0b 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,6 +1,18 @@
12013-06-10 Lars Magne Ingebrigtsen <larsi@gnus.org> 12013-06-10 Lars Magne Ingebrigtsen <larsi@gnus.org>
2 2
3 * shr.el (shr-expand-url): Expand URLs that start with a slash
4 correctly.
5
6 * eww.el (eww-submit): Get submit button logic right.
7
8 * shr.el (shr-final-table-render): New variable to signal when we're
9 doing the final table rendering so that we can collect more data at
10 that point.
11
3 * eww.el (eww-submit): Make form submission work. 12 * eww.el (eww-submit): Make form submission work.
13 (eww-tag-input): Implement submit buttons.
14 (eww-click-radio): Implement radio and checkboxes.
15 (eww-submit): Handle hidden elements.
4 16
5 * shr.el (shr-descend): Allow other packages to override (or provide) 17 * shr.el (shr-descend): Allow other packages to override (or provide)
6 rendering of elements. 18 rendering of elements.
diff --git a/lisp/gnus/eww.el b/lisp/gnus/eww.el
index 63ad6fd4f8a..1a072244fb4 100644
--- a/lisp/gnus/eww.el
+++ b/lisp/gnus/eww.el
@@ -118,6 +118,7 @@
118 (let ((map (make-sparse-keymap))) 118 (let ((map (make-sparse-keymap)))
119 (suppress-keymap map) 119 (suppress-keymap map)
120 (define-key map "q" 'eww-quit) 120 (define-key map "q" 'eww-quit)
121 (define-key map "g" 'eww-reload)
121 (define-key map [tab] 'widget-forward) 122 (define-key map [tab] 'widget-forward)
122 (define-key map [backtab] 'widget-backward) 123 (define-key map [backtab] 'widget-backward)
123 (define-key map [delete] 'scroll-down-command) 124 (define-key map [delete] 'scroll-down-command)
@@ -158,6 +159,12 @@
158 (let ((prev (pop eww-history))) 159 (let ((prev (pop eww-history)))
159 (url-retrieve (car prev) 'eww-render (list (car prev) (cadr prev))))) 160 (url-retrieve (car prev) 'eww-render (list (car prev) (cadr prev)))))
160 161
162(defun eww-reload ()
163 "Reload the current page."
164 (interactive)
165 (url-retrieve eww-current-url 'eww-render
166 (list eww-current-url (point))))
167
161;; Form support. 168;; Form support.
162 169
163(defvar eww-form nil) 170(defvar eww-form nil)
@@ -174,40 +181,112 @@
174 'eww-form eww-form))) 181 'eww-form eww-form)))
175 182
176(defun eww-tag-input (cont) 183(defun eww-tag-input (cont)
177 (let ((start (point)) 184 (let* ((start (point))
178 (widget (list 185 (type (downcase (or (cdr (assq :type cont))
179 'editable-field 186 "text")))
180 :size (string-to-number 187 (widget
181 (or (cdr (assq :size cont)) 188 (cond
182 "40")) 189 ((equal type "submit")
183 :value (or (cdr (assq :value cont)) "") 190 (list
184 :action 'eww-submit 191 'push-button
185 :name (cdr (assq :name cont)) 192 :notify 'eww-submit
186 :eww-form eww-form))) 193 :name (cdr (assq :name cont))
187 (apply 'widget-create widget) 194 :eww-form eww-form
188 (shr-generic cont) 195 (or (cdr (assq :value cont)) "Submit")))
196 ((or (equal type "radio")
197 (equal type "checkbox"))
198 (list 'checkbox
199 :notify 'eww-click-radio
200 :name (cdr (assq :name cont))
201 :checkbox-value (cdr (assq :value cont))
202 :eww-form eww-form
203 (cdr (assq :checked cont))))
204 ((equal type "hidden")
205 (list 'hidden
206 :name (cdr (assq :name cont))
207 :value (cdr (assq :value cont))))
208 (t
209 (list
210 'editable-field
211 :size (string-to-number
212 (or (cdr (assq :size cont))
213 "40"))
214 :value (or (cdr (assq :value cont)) "")
215 :action 'eww-submit
216 :name (cdr (assq :name cont))
217 :eww-form eww-form)))))
218 (if (eq (car widget) 'hidden)
219 (when shr-final-table-render
220 (nconc eww-form (list widget)))
221 (apply 'widget-create widget))
189 (put-text-property start (point) 'eww-widget widget))) 222 (put-text-property start (point) 'eww-widget widget)))
190 223
191(defun eww-submit (widget dummy) 224(defun eww-click-radio (widget &rest ignore)
192 (let ((form (getf (cdr widget) :eww-form)) 225 (let ((form (plist-get (cdr widget) :eww-form))
226 (name (plist-get (cdr widget) :name)))
227 (if (widget-value widget)
228 ;; Switch all the other radio buttons off.
229 (dolist (overlay (overlays-in (point-min) (point-max)))
230 (let ((field (plist-get (overlay-properties overlay) 'button)))
231 (when (and (eq (plist-get (cdr field) :eww-form) form)
232 (equal name (plist-get (cdr field) :name)))
233 (unless (eq field widget)
234 (widget-value-set field nil)))))
235 (widget-value-set widget t))
236 (eww-fix-widget-keymap)))
237
238(defun eww-submit (widget &rest ignore)
239 (let ((form (plist-get (cdr widget) :eww-form))
240 (first-button t)
193 values) 241 values)
194 (dolist (overlay (overlays-in (point-min) (point-max))) 242 (dolist (overlay (sort (overlays-in (point-min) (point-max))
195 (let ((field (getf (overlay-properties overlay) 'field))) 243 (lambda (o1 o2)
196 (when (eq (getf (cdr field) :eww-form) form) 244 (< (overlay-start o1) (overlay-start o2)))))
197 (let ((name (getf (cdr field) :name))) 245 (let ((field (or (plist-get (overlay-properties overlay) 'field)
246 (plist-get (overlay-properties overlay) 'button)
247 (plist-get (overlay-properties overlay) 'eww-hidden))))
248 (when (eq (plist-get (cdr field) :eww-form) form)
249 (let ((name (plist-get (cdr field) :name)))
198 (when name 250 (when name
199 (push (cons name (widget-value field)) 251 (cond
200 values)))))) 252 ((eq (car field) 'checkbox)
253 (when (widget-value field)
254 (push (cons name (plist-get (cdr field) :checkbox-value))
255 values)))
256 ((eq (car field) 'eww-hidden)
257 (push (cons name (plist-get (cdr field) :value))
258 values))
259 ((eq (car field) 'push-button)
260 ;; We want the values from buttons if we hit a button,
261 ;; or we're submitting something and this is the first
262 ;; button displayed.
263 (when (or (and (eq (car widget) 'push-button)
264 (eq widget field))
265 (and (not (eq (car widget) 'push-button))
266 (eq (car field) 'push-button)
267 first-button))
268 (setq first-button nil)
269 (push (cons name (widget-value field))
270 values)))
271 (t
272 (push (cons name (widget-value field))
273 values))))))))
274 (dolist (elem form)
275 (when (and (consp elem)
276 (eq (car elem) 'hidden))
277 (push (cons (plist-get (cdr elem) :name)
278 (plist-get (cdr elem) :value))
279 values)))
201 (let ((shr-base eww-current-url)) 280 (let ((shr-base eww-current-url))
202 (if (and (stringp (getf form :method)) 281 (if (and (stringp (plist-get form :method))
203 (equal (downcase (getf form :method)) "post")) 282 (equal (downcase (plist-get form :method)) "post"))
204 (let ((url-request-method "POST") 283 (let ((url-request-method "POST")
205 (url-request-data (mm-url-encode-www-form-urlencoded values))) 284 (url-request-data (mm-url-encode-www-form-urlencoded values)))
206 (eww-browse-url (shr-expand-url (getf form :action)))) 285 (eww-browse-url (shr-expand-url (plist-get form :action))))
207 (eww-browse-url 286 (eww-browse-url
208 (shr-expand-url 287 (shr-expand-url
209 (concat 288 (concat
210 (getf form :action) 289 (cdr (assq :action form))
211 "?" 290 "?"
212 (mm-url-encode-www-form-urlencoded values)))))))) 291 (mm-url-encode-www-form-urlencoded values))))))))
213 292
@@ -217,10 +296,19 @@
217 (while (setq start (next-single-property-change start 'eww-widget)) 296 (while (setq start (next-single-property-change start 'eww-widget))
218 (setq widget (get-text-property start 'eww-widget)) 297 (setq widget (get-text-property start 'eww-widget))
219 (goto-char start) 298 (goto-char start)
220 (delete-region start (next-single-property-change start 'eww-widget)) 299 (let ((end (next-single-property-change start 'eww-widget)))
221 (apply 'widget-create widget) 300 (dolist (overlay (overlays-in start end))
222 (put-text-property start (point) 'not-read-only t)) 301 (when (plist-get (overlay-properties overlay) 'button)
223 (widget-setup))) 302 (delete-overlay overlay)))
303 (delete-region start end))
304 (apply 'widget-create widget))
305 (widget-setup)
306 (eww-fix-widget-keymap)))
307
308(defun eww-fix-widget-keymap ()
309 (dolist (overlay (overlays-in (point-min) (point-max)))
310 (when (plist-get (overlay-properties overlay) 'button)
311 (overlay-put overlay 'local-map widget-keymap))))
224 312
225(provide 'eww) 313(provide 'eww)
226 314
diff --git a/lisp/gnus/shr.el b/lisp/gnus/shr.el
index bf9f5a4e3d4..d9e267e5288 100644
--- a/lisp/gnus/shr.el
+++ b/lisp/gnus/shr.el
@@ -115,6 +115,7 @@ cid: URL as the argument.")
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(defvar shr-external-rendering-functions nil)
118(defvar shr-final-table-render nil)
118 119
119(defvar shr-map 120(defvar shr-map
120 (let ((map (make-sparse-keymap))) 121 (let ((map (make-sparse-keymap)))
@@ -490,6 +491,7 @@ size, and full-buffer size."
490 ;; Absolute URL. 491 ;; Absolute URL.
491 url 492 url
492 (let ((base shr-base)) 493 (let ((base shr-base))
494 ;; Chop off query string.
493 (when (string-match "^\\([^?]+\\)[?]" base) 495 (when (string-match "^\\([^?]+\\)[?]" base)
494 (setq base (match-string 1 base))) 496 (setq base (match-string 1 base)))
495 (cond 497 (cond
@@ -499,6 +501,9 @@ size, and full-buffer size."
499 ((and (not (string-match "/\\'" base)) 501 ((and (not (string-match "/\\'" base))
500 (not (string-match "\\`/" url))) 502 (not (string-match "\\`/" url)))
501 (concat base "/" url)) 503 (concat base "/" url))
504 ((and (string-match "\\`/" url)
505 (string-match "\\(\\`[^:]*://[^/]+\\)/" base))
506 (concat (match-string 1 base) url))
502 (t 507 (t
503 (concat base url)))))) 508 (concat base url))))))
504 509
@@ -1177,7 +1182,8 @@ ones, in case fg and bg are nil."
1177 (frame-width)) 1182 (frame-width))
1178 (setq truncate-lines t)) 1183 (setq truncate-lines t))
1179 ;; Then render the table again with these new "hard" widths. 1184 ;; Then render the table again with these new "hard" widths.
1180 (shr-insert-table (shr-make-table cont sketch-widths t) sketch-widths)) 1185 (let ((shr-final-table-render t))
1186 (shr-insert-table (shr-make-table cont sketch-widths t) sketch-widths)))
1181 ;; Finally, insert all the images after the table. The Emacs buffer 1187 ;; Finally, insert all the images after the table. The Emacs buffer
1182 ;; model isn't strong enough to allow us to put the images actually 1188 ;; model isn't strong enough to allow us to put the images actually
1183 ;; into the tables. 1189 ;; into the tables.