root/lang/javascript/vimperator-plugins/trunk/marker_reader.js

Revision 36334, 8.7 kB (checked in by hogelog, 8 months ago)
  • fix removeMarkers
Line 
1/*** BEGIN LICENSE BLOCK {{{
2  Copyright (c) 2009 hogelog<konbu.komuro@gmail.com>
3
4  Released under the GPL license
5  http://www.gnu.org/copyleft/gpl.html
6}}}  END LICENSE BLOCK ***/
7// PLUGIN_INFO//{{{
8var PLUGIN_INFO =
9<VimperatorPlugin>
10    <name>{NAME}</name>
11    <description>marker PageDown/PageUp.</description>
12    <author mail="konbu.komuro@gmail.com" homepage="http://d.hatena.ne.jp/hogelog/">hogelog</author>
13    <version>0.0.15</version>
14    <license>GPL</license>
15    <minVersion>2.2pre</minVersion>
16    <maxVersion>2.2pre</maxVersion>
17    <updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/marker_reader.js</updateURL>
18<detail><![CDATA[
19   
20== OPTION ==
21>||
22let g:marker_reader_scroll_ratio = "0.7"
23||<
24mnext, mprev scroll 0.7 * <screen height>.
25
26>||
27let g:marker_reader_onload = 0
28||<
29prevent PageLoad insert markers action.
30
31>||
32javascript <<EOM
33liberator.globalVariables.marker_reader_ignore = [
34    /^https?:\/\/mail\.google\.com\//,
35    /^http:\/\/(?:reader\.livedoor|fastladder)\.com\/(?:reader|public)\//,
36];
37EOM
38||<
39prevent PageLoad insert markers action on these pages;
40
41>||
42let g:marker_reader_mapping = "J,K"
43||<
44adds mapping J = mnext, K = mprev.
45
46]]></detail>
47</VimperatorPlugin>;
48//}}}
49plugins.marker_reader = (function() {
50
51const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
52
53var libly = liberator.plugins.libly;
54var $U = libly.$U;
55var logger = $U.getLogger("marker");
56
57let ignorePages = liberator.globalVariables.marker_reader_ignore ||
58[/^https?:\/\/mail\.google\.com\//,
59/^http:\/\/(?:reader\.livedoor|fastladder)\.com\/(?:reader|public)\//];
60
61function near(p1, p2, e) p1-e <= p2 && p2 <= p1+e;
62function focusDocument(win)
63{
64    let frames = win.frames;
65    if (!frames) return win.document;
66    for (let i=0,len=win.frames.length;i<len;++i) {
67        let doc = win.frames[i].document;
68        if (doc.hasFocus()) return doc;
69    }
70    return win.document;
71}
72function autoInsert(win)
73{
74    let uri = win.location.href;
75    if (ignorePages.some(function(r) r.test(uri))) return;
76    let doc = win.document;
77    if (!(doc instanceof HTMLDocument)) return;
78    if (doc.contentType != "text/html") return;
79
80    reader.removeMarkers(doc);
81    reader.insertMarkers(doc);
82
83    let frames = win.frames; for (let i=0,len=frames.length;i<len;++i) autoInsert(frames[i]);
84}
85function onResize(event)
86{
87    let win = event.target;
88    autoInsert(win);
89}
90function onLoad(event)
91{
92    let win = (event.target.contentDocument||event.target).defaultView;
93    autoInsert(win);
94}
95
96var reader = {
97    pageNaviCss:
98    <style type="text/css"><![CDATA[
99        .vimperator-marker_reader-marker {
100            background-color: #faa;
101            opacity: 0.30;
102            margin: 0px;
103            height: 1.5em;
104            width: 100%;
105            text-align: left;
106            position: absolute;
107            z-index = 6000;
108            -moz-border-radius: 5px;
109        }
110        ]]></style>,
111    // insertMarkers have to act synchronized function
112    insertMarkers: function(doc)
113    {
114        // this operation have to atomic {
115        if (doc.markers) return false;
116        doc.markers = [];
117        // }
118
119        let win = doc.defaultView;
120
121        if (win.scrollMaxY == 0) return false;
122        if (win.innerHeight == 0) return false;
123        if (!win.scrollbars.visible) return false;
124
125        let css = $U.xmlToDom(reader.pageNaviCss, doc);
126        let node = doc.importNode(css, true);
127        doc.body.insertBefore(node, doc.body.firstChild);
128
129        let scroll_ratio = parseFloat(liberator.globalVariables.marker_reader_scroll_ratio) || 0.9;
130        let scroll = win.innerHeight * scroll_ratio;
131        let count = Math.ceil(win.scrollMaxY / scroll);
132
133        let div = doc.createElementNS(HTML_NAMESPACE, "div");
134        div.id = "vimperator-marker_reader-markers";
135        for (let pageNum=2;pageNum<=count+1;++pageNum)
136        {
137            let p = doc.createElementNS(HTML_NAMESPACE, "p");
138            let id = "vimperator-marker_reader-" + pageNum;
139            p.id = id;
140            if (liberator.globalVariables.marker_reader_pagelink) {
141                p.innerHTML = '<a href="#' + id + '">' + pageNum + "</a>";
142            } else {
143                p.setAttribute("mousethrough", "always");
144                //p.innerHTML = "";
145            }
146            p.className = "vimperator-marker_reader-marker";
147
148            p.style.left = "0px";
149            p.style.top = Math.ceil((pageNum-1)*scroll)+"px";
150            div.appendChild(p);
151            doc.markers.push(p);
152        }
153        doc.body.appendChild(div);
154        return doc.markers;
155    },
156    // removeMarkers have to act synchronized function
157    removeMarkers: function(doc)
158    {
159        // this operation have to atomic {
160        if (!doc.markers) return false;
161        doc.markers = null;
162        // }
163
164        doc.body.removeChild(doc.getElementById("vimperator-marker_reader-markers"));
165        let win = doc.defaultView;
166        let frames = win.frames;
167        if (frames) {
168            for (let i=0,len=frames.length;i<len;++i)
169                if (!reader.removeMarkers(frames[i].document)) return false;
170        }
171        return true;
172    },
173    currentPage: function(doc)
174    {
175        let win = doc.defaultView;
176        if (win.scrollMaxY == 0) return 1.0;
177        if (!win.scrollbars.visible) return 1.0;
178
179        let markers = doc.markers;
180        if(!markers) markers = reader.insertMarkers(doc);
181        if(!markers && markers.length==0) return 1.0;
182
183        let curPos = win.scrollY;
184
185        // top of page
186        if (curPos <= 0) return 1.0;
187
188        // bottom of page
189        if (curPos >= win.scrollMaxY) {
190            if (markers.length > 0) {
191                let lastMarker = markers[markers.length-1].offsetTop;
192                if (curPos <= lastMarker) return markers.length;
193            }
194            return markers.length + 0.5;
195        }
196
197        // return n.5 if between n and n+1
198        let page = 2.0;
199        for (let i=0,len=markers.length;i<len;++i)
200        {
201            let pos = parseInt(markers[i].offsetTop);
202            if (near(curPos, pos, 1)) return page;
203            if (curPos < pos) return page - 0.5;
204            ++page;
205        }
206        return page - 0.5;
207    },
208    focusNavi: function(doc, count)
209    {
210        function navi(win, page)
211        {
212            let elem = doc.getElementById("vimperator-marker_reader-" + page);
213            if (elem) {
214                win.scrollTo(win.scrollX, elem.offsetTop);
215                return true;
216            }
217            return false;
218        }
219        let win = doc.defaultView;
220        let curPage = reader.currentPage(doc);
221        let page = (count < 0 ? Math.round : Math.floor)(curPage + count);
222        if (page <= 1) {
223            win.scrollTo(win.scrollX, 0);
224            return true;
225        } else if (navi(win, page)) {
226            return true;
227        }
228
229        reader.removeMarkers(doc);
230        reader.insertMarkers(doc);
231        curPage = reader.currentPage(doc);
232        page = (count < 0 ? Math.round : Math.floor)(curPage + count);
233        if (navi(win, page)) return true;
234
235        win.scrollTo(win.scrollX, win.scrollMaxY);
236        return true;
237    },
238    setAutoInsert: function(set)
239    {
240        if (!set) {
241            window.removeEventListener("resize", onResize, true);
242            gBrowser.removeEventListener("load", onLoad, true);
243        } else {
244            window.addEventListener("resize", onResize, true);
245            gBrowser.addEventListener("load", onLoad, true);
246        }
247    },
248};
249
250if (liberator.globalVariables.marker_reader_mapping) {
251    let [down, up] = liberator.globalVariables.marker_reader_mapping.split(/,/);
252    mappings.addUserMap([config.browserModes],
253        [down], "marker PageDown",
254        function (count)
255        {
256            reader.focusNavi(focusDocument(content), count>1 ? count : 1);
257        },
258        {count: true});
259    mappings.addUserMap([config.browserModes],
260        [up], "marker PageUp",
261        function (count)
262        {
263            reader.focusNavi(focusDocument(content), -(count>1 ? count : 1));
264        },
265        {count: true});
266}
267commands.addUserCommand(["markersinsert", "minsert"], "insert markers",
268    function ()
269    {
270        reader.insertMarkers(focusDocument(content));
271    });
272commands.addUserCommand(["markersremove", "mremove"], "remove markers",
273    function ()
274    {
275        reader.removeMarkers(focusDocument(content));
276    });
277commands.addUserCommand(["markernext", "mnext"], "marker PageDown",
278    function ()
279    {
280        reader.focusNavi(focusDocument(content), 1);
281    });
282commands.addUserCommand(["markerprev", "mprev"], "marker PageUp",
283    function ()
284    {
285        reader.focusNavi(focusDocument(content), -1);
286    });
287
288if (liberator.globalVariables.marker_reader_onload) {
289    reader.setAutoInsert(true);
290}
291
292return reader;
293})();
294// vim: fdm=marker sw=4 ts=4 et:
Note: See TracBrowser for help on using the browser.