root/lang/javascript/vimperator-plugins/branches/2.2/marker_reader.js

Revision 34243, 8.6 kB (checked in by anekos, 14 months ago)

follow HEAD(2.2pre)

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        for (let pageNum=2;pageNum<=count+1;++pageNum)
134        {
135            let p = doc.createElementNS(HTML_NAMESPACE, "p");
136            let id = "vimperator-marker_reader-" + pageNum;
137            p.id = id;
138            if (liberator.globalVariables.marker_reader_pagelink) {
139                p.innerHTML = '<a href="#' + id + '">' + pageNum + "</a>";
140            } else {
141                p.setAttribute("mousethrough", "always");
142                //p.innerHTML = "";
143            }
144            p.className = "vimperator-marker_reader-marker";
145
146            p.style.left = "0px";
147            p.style.top = Math.ceil((pageNum-1)*scroll)+"px";
148            doc.body.appendChild(p);
149            doc.markers.push(p);
150        }
151        return doc.markers;
152    },
153    // removeMarkers have to act synchronized function
154    removeMarkers: function(doc)
155    {
156        // this operation have to atomic {
157        let markers = doc.markers;
158        if (!markers) return false;
159        doc.markers = null;
160        // }
161
162        for (let i=0,len=markers.length;i<len;++i)
163        {
164            doc.body.removeChild(markers[i]);
165        }
166        let win = doc.defaultView;
167        let frames = win.frames;
168        if (frames) {
169            for (let i=0,len=frames.length;i<len;++i)
170                if (!reader.removeMarkers(frames[i].document)) return false;
171        }
172        return true;
173    },
174    currentPage: function(doc)
175    {
176        let win = doc.defaultView;
177        if (win.scrollMaxY == 0) return 1.0;
178        if (!win.scrollbars.visible) return 1.0;
179
180        let markers = doc.markers;
181        if(!markers) markers = reader.insertMarkers(doc);
182        if(!markers && markers.length==0) return 1.0;
183
184        let curPos = win.scrollY;
185
186        // top of page
187        if (curPos <= 0) return 1.0;
188
189        // bottom of page
190        if (curPos >= win.scrollMaxY) {
191            if (markers.length > 0) {
192                let lastMarker = markers[markers.length-1].offsetTop;
193                if (curPos <= lastMarker) return markers.length;
194            }
195            return markers.length + 0.5;
196        }
197
198        // return n.5 if between n and n+1
199        let page = 2.0;
200        for (let i=0,len=markers.length;i<len;++i)
201        {
202            let pos = parseInt(markers[i].offsetTop);
203            if (near(curPos, pos, 1)) return page;
204            if (curPos < pos) return page - 0.5;
205            ++page;
206        }
207        return page - 0.5;
208    },
209    focusNavi: function(doc, count)
210    {
211        function navi(win, page)
212        {
213            let elem = doc.getElementById("vimperator-marker_reader-" + page);
214            if (elem) {
215                win.scrollTo(win.scrollX, elem.offsetTop);
216                return true;
217            }
218            return false;
219        }
220        let win = doc.defaultView;
221        let curPage = reader.currentPage(doc);
222        let page = (count < 0 ? Math.round : Math.floor)(curPage + count);
223        if (page <= 1) {
224            win.scrollTo(win.scrollX, 0);
225            return true;
226        } else if (navi(win, page)) {
227            return true;
228        }
229
230        reader.removeMarkers(doc);
231        reader.insertMarkers(doc);
232        curPage = reader.currentPage(doc);
233        page = (count < 0 ? Math.round : Math.floor)(curPage + count);
234        if (navi(win, page)) return true;
235
236        win.scrollTo(win.scrollX, win.scrollMaxY);
237        return true;
238    },
239    setAutoInsert: function(set)
240    {
241        if (!set) {
242            window.removeEventListener("resize", onResize, true);
243            gBrowser.removeEventListener("load", onLoad, true);
244        } else {
245            window.addEventListener("resize", onResize, true);
246            gBrowser.addEventListener("load", onLoad, true);
247        }
248    },
249};
250
251if (liberator.globalVariables.marker_reader_mapping) {
252    let [down, up] = liberator.globalVariables.marker_reader_mapping.split(/,/);
253    mappings.addUserMap([config.browserModes],
254        [down], "marker PageDown",
255        function (count)
256        {
257            reader.focusNavi(focusDocument(content), count>1 ? count : 1);
258        },
259        {count: true});
260    mappings.addUserMap([config.browserModes],
261        [up], "marker PageUp",
262        function (count)
263        {
264            reader.focusNavi(focusDocument(content), -(count>1 ? count : 1));
265        },
266        {count: true});
267}
268commands.addUserCommand(["markersinsert", "minsert"], "insert markers",
269    function ()
270    {
271        reader.insertMarkers(focusDocument(content));
272    });
273commands.addUserCommand(["markersremove", "mremove"], "remove markers",
274    function ()
275    {
276        reader.removeMarkers(focusDocument(content));
277    });
278commands.addUserCommand(["markernext", "mnext"], "marker PageDown",
279    function ()
280    {
281        reader.focusNavi(focusDocument(content), 1);
282    });
283commands.addUserCommand(["markerprev", "mprev"], "marker PageUp",
284    function ()
285    {
286        reader.focusNavi(focusDocument(content), -1);
287    });
288
289if (liberator.globalVariables.marker_reader_onload) {
290    reader.setAutoInsert(true);
291}
292
293return reader;
294})();
295// vim: fdm=marker sw=4 ts=4 et:
Note: See TracBrowser for help on using the browser.