diff options
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 7 | ||||
| -rw-r--r-- | lisp/net/shr.el | 55 |
2 files changed, 40 insertions, 22 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 652bc537ee5..12e98657af0 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2014-11-13 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 2 | |||
| 3 | * net/shr.el (shr-descend): Don't descend further than | ||
| 4 | `max-specpdl-size' allows (bug#16587). | ||
| 5 | (shr-depth): New variable. | ||
| 6 | (shr-warning): New variable. | ||
| 7 | |||
| 1 | 2014-11-13 Ivan Shmakov <ivan@siamics.net> | 8 | 2014-11-13 Ivan Shmakov <ivan@siamics.net> |
| 2 | 9 | ||
| 3 | * net/shr.el (shr-parse-base): Handle <base href=""> correctly. | 10 | * net/shr.el (shr-parse-base): Handle <base href=""> correctly. |
diff --git a/lisp/net/shr.el b/lisp/net/shr.el index cc90097102a..a4b004d7c1b 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el | |||
| @@ -137,6 +137,8 @@ cid: URL as the argument.") | |||
| 137 | (defvar shr-table-depth 0) | 137 | (defvar shr-table-depth 0) |
| 138 | (defvar shr-stylesheet nil) | 138 | (defvar shr-stylesheet nil) |
| 139 | (defvar shr-base nil) | 139 | (defvar shr-base nil) |
| 140 | (defvar shr-depth 0) | ||
| 141 | (defvar shr-warning nil) | ||
| 140 | (defvar shr-ignore-cache nil) | 142 | (defvar shr-ignore-cache nil) |
| 141 | (defvar shr-external-rendering-functions nil) | 143 | (defvar shr-external-rendering-functions nil) |
| 142 | (defvar shr-target-id nil) | 144 | (defvar shr-target-id nil) |
| @@ -198,9 +200,13 @@ DOM should be a parse tree as generated by | |||
| 198 | (shr-state nil) | 200 | (shr-state nil) |
| 199 | (shr-start nil) | 201 | (shr-start nil) |
| 200 | (shr-base nil) | 202 | (shr-base nil) |
| 203 | (shr-depth 0) | ||
| 204 | (shr-warning nil) | ||
| 201 | (shr-internal-width (or shr-width (1- (window-width))))) | 205 | (shr-internal-width (or shr-width (1- (window-width))))) |
| 202 | (shr-descend (shr-transform-dom dom)) | 206 | (shr-descend (shr-transform-dom dom)) |
| 203 | (shr-remove-trailing-whitespace start (point)))) | 207 | (shr-remove-trailing-whitespace start (point)) |
| 208 | (when shr-warning | ||
| 209 | (message "%s" shr-warning)))) | ||
| 204 | 210 | ||
| 205 | (defun shr-remove-trailing-whitespace (start end) | 211 | (defun shr-remove-trailing-whitespace (start end) |
| 206 | (let ((width (window-width))) | 212 | (let ((width (window-width))) |
| @@ -406,29 +412,34 @@ size, and full-buffer size." | |||
| 406 | (intern (concat "shr-tag-" (symbol-name (car dom))) obarray))) | 412 | (intern (concat "shr-tag-" (symbol-name (car dom))) obarray))) |
| 407 | (style (cdr (assq :style (cdr dom)))) | 413 | (style (cdr (assq :style (cdr dom)))) |
| 408 | (shr-stylesheet shr-stylesheet) | 414 | (shr-stylesheet shr-stylesheet) |
| 415 | (shr-depth (1+ shr-depth)) | ||
| 409 | (start (point))) | 416 | (start (point))) |
| 410 | (when style | 417 | ;; shr uses about 12 frames per nested node. |
| 411 | (if (string-match "color\\|display\\|border-collapse" style) | 418 | (if (> shr-depth (/ max-specpdl-size 12)) |
| 412 | (setq shr-stylesheet (nconc (shr-parse-style style) | 419 | (setq shr-warning "Too deeply nested to render properly; consider increasing `max-specpdl-size'") |
| 413 | shr-stylesheet)) | ||
| 414 | (setq style nil))) | ||
| 415 | ;; If we have a display:none, then just ignore this part of the DOM. | ||
| 416 | (unless (equal (cdr (assq 'display shr-stylesheet)) "none") | ||
| 417 | (if (fboundp function) | ||
| 418 | (funcall function (cdr dom)) | ||
| 419 | (shr-generic (cdr dom))) | ||
| 420 | (when (and shr-target-id | ||
| 421 | (equal (cdr (assq :id (cdr dom))) shr-target-id)) | ||
| 422 | ;; If the element was empty, we don't have anything to put the | ||
| 423 | ;; anchor on. So just insert a dummy character. | ||
| 424 | (when (= start (point)) | ||
| 425 | (insert "*")) | ||
| 426 | (put-text-property start (1+ start) 'shr-target-id shr-target-id)) | ||
| 427 | ;; If style is set, then this node has set the color. | ||
| 428 | (when style | 420 | (when style |
| 429 | (shr-colorize-region start (point) | 421 | (if (string-match "color\\|display\\|border-collapse" style) |
| 430 | (cdr (assq 'color shr-stylesheet)) | 422 | (setq shr-stylesheet (nconc (shr-parse-style style) |
| 431 | (cdr (assq 'background-color shr-stylesheet))))))) | 423 | shr-stylesheet)) |
| 424 | (setq style nil))) | ||
| 425 | ;; If we have a display:none, then just ignore this part of the DOM. | ||
| 426 | (unless (equal (cdr (assq 'display shr-stylesheet)) "none") | ||
| 427 | (if (fboundp function) | ||
| 428 | (funcall function (cdr dom)) | ||
| 429 | (shr-generic (cdr dom))) | ||
| 430 | (when (and shr-target-id | ||
| 431 | (equal (cdr (assq :id (cdr dom))) shr-target-id)) | ||
| 432 | ;; If the element was empty, we don't have anything to put the | ||
| 433 | ;; anchor on. So just insert a dummy character. | ||
| 434 | (when (= start (point)) | ||
| 435 | (insert "*")) | ||
| 436 | (put-text-property start (1+ start) 'shr-target-id shr-target-id)) | ||
| 437 | ;; If style is set, then this node has set the color. | ||
| 438 | (when style | ||
| 439 | (shr-colorize-region | ||
| 440 | start (point) | ||
| 441 | (cdr (assq 'color shr-stylesheet)) | ||
| 442 | (cdr (assq 'background-color shr-stylesheet)))))))) | ||
| 432 | 443 | ||
| 433 | (defmacro shr-char-breakable-p (char) | 444 | (defmacro shr-char-breakable-p (char) |
| 434 | "Return non-nil if a line can be broken before and after CHAR." | 445 | "Return non-nil if a line can be broken before and after CHAR." |