| 1 | /* NEW BSD LICENSE {{{ |
| 2 | Copyright (c) 2012, anekos. |
| 3 | All rights reserved. |
| 4 | |
| 5 | Redistribution and use in source and binary forms, with or without modification, |
| 6 | are permitted provided that the following conditions are met: |
| 7 | |
| 8 | 1. Redistributions of source code must retain the above copyright notice, |
| 9 | this list of conditions and the following disclaimer. |
| 10 | 2. Redistributions in binary form must reproduce the above copyright notice, |
| 11 | this list of conditions and the following disclaimer in the documentation |
| 12 | and/or other materials provided with the distribution. |
| 13 | 3. The names of the authors may not be used to endorse or promote products |
| 14 | derived from this software without specific prior written permission. |
| 15 | |
| 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 19 | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| 20 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| 21 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| 24 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| 25 | THE POSSIBILITY OF SUCH DAMAGE. |
| 26 | |
| 27 | |
| 28 | ################################################################################### |
| 29 | # http://sourceforge.jp/projects/opensource/wiki/licenses%2Fnew_BSD_license # |
| 30 | # に参考になる日本語訳がありますが、有効なのは上記英文となります。 # |
| 31 | ################################################################################### |
| 32 | |
| 33 | }}} */ |
| 34 | |
| 35 | // INFO {{{ |
| 36 | let INFO = xml` |
| 37 | <plugin name="PDF.js.js" version="1.0.0" |
| 38 | href="http://vimpr.github.com/" |
| 39 | summary="PDF.js controller." |
| 40 | lang="en-US" |
| 41 | xmlns="http://vimperator.org/namespaces/liberator"> |
| 42 | <author email="anekos@snca.net">anekos</author> |
| 43 | <license>New BSD License</license> |
| 44 | <project name="Vimperator" minVersion="3.0"/> |
| 45 | <p></p> |
| 46 | <item> |
| 47 | <tags>:pdfjs-mapping-sample</tags> |
| 48 | <description><p>mapping sample</p><code><![CDATA[ |
| 49 | nnoremap -urls ^\\.pdf$ i :<C-u>pdfjs index<Space> |
| 50 | nnoremap -urls ^\\.pdf$ z :<C-u>pdfjs zoom<Space> |
| 51 | ]]></code></description> |
| 52 | </item> |
| 53 | </plugin>`; |
| 54 | // }}} |
| 55 | |
| 56 | (function () { |
| 57 | |
| 58 | let scrollCount = 1; |
| 59 | |
| 60 | // Functions {{{ |
| 61 | |
| 62 | function getScrollHeight (count) { |
| 63 | let base = content.innerHeight / 10; |
| 64 | if (count > 0) |
| 65 | scrollCount = count; |
| 66 | return base * scrollCount; |
| 67 | } |
| 68 | |
| 69 | function addMap (keys, desc, action) { |
| 70 | mappings.addUserMap( |
| 71 | [modes.NORMAL], |
| 72 | keys, |
| 73 | desc + ' - PDF.js.js', |
| 74 | action, |
| 75 | { |
| 76 | count: true, |
| 77 | matchingUrls: /\.pdf$/ |
| 78 | } |
| 79 | ); |
| 80 | } |
| 81 | |
| 82 | function getOutline () { |
| 83 | return Array.slice(content.document.querySelector('#outlineView').querySelectorAll('.outlineItem > a')); |
| 84 | } |
| 85 | |
| 86 | function getOutlineLevel (node) { |
| 87 | let level = 0; |
| 88 | while (node && (node.getAttribute('id') != 'outlineView')) { |
| 89 | node = node.parentNode; |
| 90 | level++; |
| 91 | } |
| 92 | return node ? (level / 2): 0; |
| 93 | } |
| 94 | |
| 95 | function nSpace (level) { |
| 96 | let res = ''; |
| 97 | for (i = 0; i < level; i++) |
| 98 | res += ' '; |
| 99 | return res; |
| 100 | } |
| 101 | |
| 102 | // }}} |
| 103 | |
| 104 | // Mappings {{{ |
| 105 | |
| 106 | addMap( |
| 107 | ['j'], |
| 108 | 'Scroll Down', |
| 109 | function (count) { |
| 110 | content.document.querySelector('#viewerContainer').scrollTop += getScrollHeight(count); |
| 111 | } |
| 112 | ); |
| 113 | |
| 114 | addMap( |
| 115 | ['k'], |
| 116 | 'Scroll up', |
| 117 | function (count) { |
| 118 | content.document.querySelector('#viewerContainer').scrollTop -= getScrollHeight(count); |
| 119 | } |
| 120 | ); |
| 121 | |
| 122 | addMap( |
| 123 | ['n'], |
| 124 | 'Next page', |
| 125 | function (count) { |
| 126 | content.window.wrappedJSObject.PDFView.page += (count > 0 ? count : 1); |
| 127 | } |
| 128 | ); |
| 129 | |
| 130 | addMap( |
| 131 | ['p'], |
| 132 | 'Previous page', |
| 133 | function (count) { |
| 134 | content.window.wrappedJSObject.PDFView.page -= (count > 0 ? count : 1); |
| 135 | } |
| 136 | ); |
| 137 | |
| 138 | addMap( |
| 139 | ['gg'], |
| 140 | 'Go to page top or N page.', |
| 141 | function (count) { |
| 142 | if (count > 0) |
| 143 | content.window.wrappedJSObject.PDFView.page = count; |
| 144 | else |
| 145 | content.window.wrappedJSObject.PDFView.page = 1; |
| 146 | } |
| 147 | ); |
| 148 | |
| 149 | addMap( |
| 150 | ['zh'], |
| 151 | 'Fit to page.', |
| 152 | function (count) { |
| 153 | liberator.execute('pdfjs zoom page-fit'); |
| 154 | } |
| 155 | ); |
| 156 | |
| 157 | addMap( |
| 158 | ['zw'], |
| 159 | 'Fit to page to width.', |
| 160 | function (count) { |
| 161 | liberator.execute('pdfjs zoom page-width'); |
| 162 | } |
| 163 | ); |
| 164 | |
| 165 | addMap( |
| 166 | ['za'], |
| 167 | 'Fit to page to width.', |
| 168 | function (count) { |
| 169 | liberator.execute('pdfjs zoom auto'); |
| 170 | } |
| 171 | ); |
| 172 | |
| 173 | addMap( |
| 174 | ['zz'], |
| 175 | 'Fit to page to width.', |
| 176 | function (count) { |
| 177 | commandline.open('', 'pdfjs zoom ', modes.EX); |
| 178 | } |
| 179 | ); |
| 180 | |
| 181 | // }}} |
| 182 | |
| 183 | commands.addUserCommand( // {{{ |
| 184 | ['pdfjs'], |
| 185 | 'PDF.js', |
| 186 | function () void 'Meow is best', |
| 187 | { |
| 188 | subCommands: [ |
| 189 | new Command( |
| 190 | ['i[ndex]'], |
| 191 | 'Jump page by index', |
| 192 | function (args) { |
| 193 | let index = args.literalArg.match(/^#(\d+)$/); |
| 194 | if (index) { |
| 195 | let os = getOutline(); |
| 196 | buffer.followLink(os[parseInt(index[1], 10)], liberator.CURRENT_TAB); |
| 197 | } else { |
| 198 | content.window.wrappedJSObject.PDFView.page = parseInt(args.literalArg, 10); |
| 199 | } |
| 200 | }, |
| 201 | { |
| 202 | literal: 0, |
| 203 | completer: function (context, args) { |
| 204 | function desc (o) { |
| 205 | const PageRE = /#page=(\d+)\&/; |
| 206 | if (o.href && PageRE.test(o.href)) { |
| 207 | return `${nSpace(getOutlineLevel(o))} ${o.textContent} (p${o.href.match(PageRE)[1]})`; |
| 208 | } else { |
| 209 | return `${nSpace(getOutlineLevel(o))} ${o.textContent}`; |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | let os = getOutline(); |
| 214 | context.compare = void 0; |
| 215 | context.filters = [CompletionContext.Filter.textDescription]; |
| 216 | context.completions = [ |
| 217 | [ |
| 218 | '#' + i, desc(o) |
| 219 | ] |
| 220 | for ([i, o] in Iterator(os)) |
| 221 | ]; |
| 222 | } |
| 223 | } |
| 224 | ), |
| 225 | |
| 226 | new Command( |
| 227 | ['z[oom]'], |
| 228 | 'Zoom', |
| 229 | function (args) { |
| 230 | content.window.wrappedJSObject.PDFView.parseScale(args.literalArg); |
| 231 | }, |
| 232 | { |
| 233 | literal: 0, |
| 234 | completer: function (context, args) { |
| 235 | let os = Array.slice(content.document.querySelector('#scaleSelect').querySelectorAll('option')); |
| 236 | context.completions = [ |
| 237 | [o.value, o.textContent] |
| 238 | for ([, o] in Iterator(os)) |
| 239 | ]; |
| 240 | } |
| 241 | } |
| 242 | ) |
| 243 | ] |
| 244 | }, |
| 245 | true |
| 246 | ); // }}} |
| 247 | |
| 248 | })(); |
| 249 | |
| 250 | // vim:sw=2 ts=2 et si fdm=marker: |