forked from canatella/xwwp
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathxwwp-section.el
99 lines (82 loc) · 3.84 KB
/
xwwp-section.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
;;; xwwp-section.el --- Navigate section titles in `xwidget-webkit' sessions -*- lexical-binding: t; -*-
;; Copyright (C) 2020 Q. Hong <qhong@mit.edu>
;; This file is NOT part of GNU Emacs.
;;; License:
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Add support for navigating section titles in `xwidget-webkit' sessions using fuzzy search.
;;; Code:
(require 'xwwp)
(xwwp-js-def section highlight (ids selected)
"Highlight IDS as candidate and SELECTED as selected.""
window.__xwidget_plus_section_candidates.forEach((h, id) => {
h.classList.remove('xwwp-follow-link-candidate', 'xwwp-follow-link-selected');
if (selected == id) {
h.classList.add('xwwp-follow-link-selected');
h.scrollIntoView({behavior: 'smooth', block: 'center'});
} else if (ids && ids.includes(id)) {
h.classList.add('xwwp-follow-link-candidate');
}
});
")
(xwwp-js-def section fetch ()
"Fetch all visible, non empty titles from the current page.""
var r = {};
window.__xwidget_plus_section_candidates = Array.from(document.querySelectorAll('h1, h2, h3, h4, h5, h6'));
window.__xwidget_plus_section_candidates.forEach((h, id) => {
if (h.offsetWidth || h.offsetHeight || h.getClientRects().length) {
if (h.innerText.match(/\\\\S/))
r[id] = h.innerText;
}
});
return r;
")
(xwwp-js-def section action (link-id)
"Select the title identified by LINK-ID""
__xwidget_plus_follow_link_cleanup();
")
(xwwp-js-def section cleanup ()
"Remove all custom class from titles.""
window.__xwidget_plus_section_candidates.forEach(a => {
a.classList.remove('xwwp-follow-link-candidate', 'xwwp-follow-link-selected');
});
window.__xwidget_plus_section_candidates = null;
")
(defun xwwp-section-update (xwidget)
"Highligh TITLES in XWIDGET buffer when updating candidates."
(let ((titles (xwwp-follow-link-candidates xwwp-follow-link-completion-backend-instance)))
(when titles
(let* ((selected (car titles))
(candidates (cdr titles)))
(xwwp-section-highlight xwidget candidates selected)))))
(defun xwwp-section-callback (titles)
"Ask for a TITLE belonging to the alist TITLES."
(let* ((xwidget (xwidget-webkit-current-session))
(titles (xwwp-follow-link-prepare-links titles)))
(oset xwwp-follow-link-completion-backend-instance collection titles)
(unwind-protect
(xwwp-follow-link-read xwwp-follow-link-completion-backend-instance
"Section: " titles
(apply-partially #'xwwp-section-action xwidget)
(apply-partially #'xwwp-section-update xwidget))
(xwwp-section-cleanup xwidget))
(oset xwwp-follow-link-completion-backend-instance collection nil)))
(defun xwwp-section (&optional xwidget)
"Ask for a title in the XWIDGET session or the current one and select it."
(interactive)
(setq xwwp-follow-link-completion-backend-instance (funcall (xwwp-follow-link-make-backend)))
(let ((xwidget (or xwidget (xwidget-webkit-current-session))))
(xwwp-html-inject-style xwidget "__xwidget_plus_follow_link_style" (xwwp-follow-link-style-definition))
(xwwp-js-inject xwidget 'section)
(xwwp-section-fetch xwidget #'xwwp-section-callback)))
(provide 'xwwp-section)
;;; xwwp-section.el ends here