diff options
| author | Lars Magne Ingebrigtsen | 2013-06-10 14:11:01 +0000 |
|---|---|---|
| committer | Katsumi Yamaoka | 2013-06-10 14:11:01 +0000 |
| commit | 2644071e8ef9de418b58c4d84ef7b13f1ea5d1fe (patch) | |
| tree | 0ff9c7d122268fd73ff8a4a692e9c98b035154f0 | |
| parent | 266c63b5c13c519c2deb051de10fdfea2470c4c3 (diff) | |
| download | emacs-2644071e8ef9de418b58c4d84ef7b13f1ea5d1fe.tar.gz emacs-2644071e8ef9de418b58c4d84ef7b13f1ea5d1fe.zip | |
lisp/gnus/eww.el: Add form support; Make form submission work; Support POST
| -rw-r--r-- | lisp/gnus/ChangeLog | 7 | ||||
| -rw-r--r-- | lisp/gnus/eww.el | 78 | ||||
| -rw-r--r-- | lisp/gnus/shr.el | 39 |
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 @@ | |||
| 1 | 2013-06-10 Lars Magne Ingebrigtsen <larsi@gnus.org> | 1 | 2013-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)) |