├── .gitignore ├── .travis.yml ├── Makefile ├── chrome.manifest ├── chrome ├── content │ └── zotfile │ │ ├── ProgressWindow.js │ │ ├── include.js │ │ ├── notifier.js │ │ ├── options-projects.xul │ │ ├── options.js │ │ ├── options.xul │ │ ├── optionsFolderEditor.xul │ │ ├── overlay.xul │ │ ├── pdfAnnotations.js │ │ ├── pdfOutline.js │ │ ├── pdfextract │ │ ├── extract.html │ │ ├── extract.js │ │ ├── pdfjs │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ └── src │ │ │ │ ├── core │ │ │ │ ├── annotation.js │ │ │ │ ├── arithmetic_decoder.js │ │ │ │ ├── bidi.js │ │ │ │ ├── charsets.js │ │ │ │ ├── chunked_stream.js │ │ │ │ ├── cmap.js │ │ │ │ ├── colorspace.js │ │ │ │ ├── core.js │ │ │ │ ├── crypto.js │ │ │ │ ├── evaluator.js │ │ │ │ ├── font_renderer.js │ │ │ │ ├── fonts.js │ │ │ │ ├── function.js │ │ │ │ ├── glyphlist.js │ │ │ │ ├── image.js │ │ │ │ ├── jbig2.js │ │ │ │ ├── jpg.js │ │ │ │ ├── jpx.js │ │ │ │ ├── metrics.js │ │ │ │ ├── murmurhash3.js │ │ │ │ ├── network.js │ │ │ │ ├── obj.js │ │ │ │ ├── parser.js │ │ │ │ ├── pattern.js │ │ │ │ ├── pdf_manager.js │ │ │ │ ├── ps_parser.js │ │ │ │ ├── stream.js │ │ │ │ └── worker.js │ │ │ │ ├── display │ │ │ │ ├── annotation_helper.js │ │ │ │ ├── api.js │ │ │ │ ├── canvas.js │ │ │ │ ├── font_loader.js │ │ │ │ ├── metadata.js │ │ │ │ ├── pattern_helper.js │ │ │ │ ├── svg.js │ │ │ │ └── webgl.js │ │ │ │ ├── doc_helper.js │ │ │ │ ├── getPDFAnnotations.js │ │ │ │ ├── images │ │ │ │ └── logo.svg │ │ │ │ ├── pdf.js │ │ │ │ ├── shared │ │ │ │ ├── cffStandardStrings.js │ │ │ │ ├── fonts_utils.js │ │ │ │ └── util.js │ │ │ │ └── worker_loader.js │ │ ├── toc.html │ │ └── toc.js │ │ ├── progressWindow.xul │ │ ├── tablet.js │ │ ├── ui.js │ │ ├── utils.js │ │ ├── wildcards.js │ │ └── zotfile.js ├── locale │ ├── de-DE │ │ ├── options-projects.dtd │ │ ├── options.dtd │ │ ├── options.properties │ │ ├── optionsFolderEditor.dtd │ │ ├── overlay.dtd │ │ └── zotfile.properties │ ├── en-US │ │ ├── options-projects.dtd │ │ ├── options.dtd │ │ ├── options.properties │ │ ├── optionsFolderEditor.dtd │ │ ├── overlay.dtd │ │ └── zotfile.properties │ ├── fr-FR │ │ ├── options-projects.dtd │ │ ├── options.dtd │ │ ├── options.properties │ │ ├── optionsFolderEditor.dtd │ │ ├── overlay.dtd │ │ └── zotfile.properties │ └── it-IT │ │ ├── options-projects.dtd │ │ ├── options.dtd │ │ ├── options.properties │ │ ├── optionsFolderEditor.dtd │ │ ├── overlay.dtd │ │ └── zotfile.properties └── skin │ └── default │ └── zotfile │ ├── accept.png │ ├── exclamation.png │ └── information.png ├── defaults └── preferences │ └── defaults.js ├── docs ├── CNAME ├── _config.yml ├── _layouts │ └── default.html ├── assets │ └── css │ │ └── style.scss ├── index.md ├── javascripts │ ├── highlight.js │ └── scale.fix.js ├── pics │ ├── CollegeWhiz.png │ ├── Socie.png │ ├── gear.png │ ├── pdf-annotation-full.png │ └── zotfile-reader-rename.jpg ├── readme.md ├── stylesheets │ ├── pygment_trac.css │ └── styles.css ├── wildcards-default-min.json ├── wildcards-default.json └── zotfile-update.rdf ├── install.rdf ├── readme.md └── zotfile-update.rdf /.gitignore: -------------------------------------------------------------------------------- 1 | /Makefile.in 2 | .DS_Store 3 | *.xpi 4 | *.icloud 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | script: make 3 | after_success: 4 | - mv *.xpi zotfile-build-$TRAVIS_BUILD_NUMBER.xpi 5 | - curl -F "file=@zotfile-build-$TRAVIS_BUILD_NUMBER.xpi" https://api.anonfile.com/upload 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: Makefile.in 2 | 3 | -include Makefile.in 4 | 5 | RELEASE:=$(shell grep em:version install.rdf | head -n 1 | sed -e 's/ *//' -e 's/<\/em:version>//') 6 | 7 | zotfile.xpi: FORCE 8 | rm -rf $@ 9 | zip -r $@ chrome chrome.manifest defaults install.rdf -x \*.DS_Store 10 | 11 | zotfile-%-fx.xpi: zotfile.xpi 12 | mv $< $@ 13 | 14 | Makefile.in: install.rdf 15 | echo "all: zotfile-${RELEASE}-fx.xpi" > Makefile.in 16 | 17 | FORCE: 18 | -------------------------------------------------------------------------------- /chrome.manifest: -------------------------------------------------------------------------------- 1 | content zotfile chrome/content/zotfile/ 2 | skin zotfile default chrome/skin/default/zotfile/ 3 | 4 | overlay chrome://zotero/content/zoteroPane.xul chrome://zotfile/content/overlay.xul 5 | 6 | locale zotfile de-DE chrome/locale/de-DE/ 7 | locale zotfile en-US chrome/locale/en-US/ 8 | locale zotfile fr-FR chrome/locale/fr-FR/ 9 | locale zotfile it-IT chrome/locale/it-IT/ 10 | -------------------------------------------------------------------------------- /chrome/content/zotfile/include.js: -------------------------------------------------------------------------------- 1 | // Only create main object once 2 | if (!Zotero.ZotFile) { 3 | var zotfileLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] 4 | .getService(Components.interfaces.mozIJSSubScriptLoader); 5 | var scripts = ['zotfile', 'pdfAnnotations', 'pdfOutline', 'wildcards', 'tablet', 'utils', 'notifier', 'ui']; 6 | scripts.forEach(s => zotfileLoader.loadSubScript('chrome://zotfile/content/' + s + '.js')); 7 | } 8 | 9 | window.addEventListener('load', function(e) { 10 | Zotero.ZotFile.init(); 11 | if(window.ZoteroPane) { 12 | var doc = window.ZoteroPane.document; 13 | // add event listener for zotfile menu items 14 | doc.getElementById('zotero-itemmenu').addEventListener('popupshowing', Zotero.ZotFile.UI.showMenu, false); 15 | // add event listener for zotfile collection menu 16 | doc.getElementById('zotero-collectionmenu').addEventListener('popupshowing', Zotero.ZotFile.UI.showCollectionMenu, false); 17 | // add event listener to update saved search for modified tablet attachments 18 | doc.getElementById('zotero-collections-tree').addEventListener('click', Zotero.ZotFile.Tablet.updateModifiedAttachmentsSearch, false); 19 | } 20 | }, false); 21 | -------------------------------------------------------------------------------- /chrome/content/zotfile/notifier.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Callback implementing the notify() method to pass to the Notifier 4 | */ 5 | Zotero.ZotFile.notifierCallback = new function() { 6 | 7 | this.progress_win = null; 8 | 9 | /** 10 | * Callback function for the event listener 11 | * https://www.zotero.org/support/dev/client_coding/javascript_api#notification_system 12 | * @param {string} event Event: add (c, s, i, t, ci, it), modify (c, s, i, t), 13 | * delete (c, s, i, t), remove (ci, it), move (c, for changing collection parent) 14 | * @param {string} type Item type: c = collection, s = search (saved search), i = item, 15 | * t = tag, ci = collection-item, it = item-tag 16 | * @param {array} ids Array with object ids. 17 | * @param {object} extraData Extra data (e.g. deleted items) 18 | * @return {void} 19 | */ 20 | this.notify = Zotero.Promise.coroutine(function* (event, type, ids, extraData) { 21 | // automatic renaming 22 | if (type == 'item' && event == 'add' && this.getPref('automatic_renaming') != 1) { 23 | // retrieve the added/modified items 24 | let atts = Zotero.Items.get(ids) 25 | .filter(att => att.isImportedAttachment() && !att.isTopLevelItem()) 26 | .filter(Zotero.ZotFile.checkFileType); 27 | atts = yield Zotero.Promise.filter(atts, att => att.fileExists()); 28 | // rename attachments 29 | if (atts.length > 0) setTimeout(() => rename(atts), 100); 30 | } 31 | // extract outline from pdf 32 | if (type == 'item' && event == 'add' && this.getPref('pdfOutline.getToc')) { 33 | let atts = Zotero.Items.get(ids) 34 | .filter(att => att.isAttachment()) 35 | .filter(att => att.attachmentContentType == 'application/pdf'); 36 | atts = yield Zotero.Promise.filter(atts, att => att.fileExists()); 37 | // get outline of file 38 | if (atts.length > 0) setTimeout(() => this.pdfOutline.getOutline(atts.map(att => att.id)), 100); 39 | } 40 | }.bind(Zotero.ZotFile)); 41 | 42 | /** 43 | * Automatic renaming of Items 44 | * @param {array} attachments Array with attachment items 45 | * @return {void} 46 | */ 47 | var rename = Zotero.Promise.coroutine(function* (attachments) { 48 | var auto_rename = this.getPref('automatic_renaming'); 49 | // iterate through attachments 50 | for (var i = 0; i < attachments.length; i++) { 51 | // get id and key 52 | var att = attachments[i], 53 | item = Zotero.Items.get(att.parentItemID); 54 | // check whether key is excluded 55 | if(this.excludeAutorenameKeys.includes(att.key) || this.excludeAutorenameKeys.includes(item.key)) { 56 | this.Utils.removeFromArray(this.excludeAutorenameKeys, item.key); 57 | continue; 58 | } 59 | // skip if file already has correct filename 60 | var filename = att.attachmentFilename.replace(/\.[^/.]+$/, ''); 61 | if(filename.indexOf(this.getFilename(item, filename)) === 0) continue; 62 | // exclude current key for next event 63 | this.excludeAutorenameKeys.push(att.key); 64 | // user message 65 | var duration = this.getPref('info_window_duration_clickable'); 66 | var message = { 67 | lines: [att.attachmentFilename], 68 | txt: this.ZFgetString('renaming.clickMoveRename'), 69 | icons: [att.getImageSrc()] 70 | }; 71 | // always ask user 72 | if(auto_rename == 2) 73 | this.infoWindow(this.ZFgetString('general.newAttachment'), message, duration, () => on_confirm(att)); 74 | // ask user if item has other attachments 75 | if(auto_rename == 3) { 76 | var item_atts = Zotero.Items.get(item.getAttachments()) 77 | .filter(this.checkFileType) 78 | .filter(att => att.isImportedAttachment() || att.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_FILE); 79 | if (item_atts.length == 1) on_confirm(att); 80 | if (item_atts.length > 1) 81 | this.infoWindow(this.ZFgetString('general.newAttachment'), message, duration, () => on_confirm(att)); 82 | } 83 | // always rename 84 | if(auto_rename == 4) on_confirm(att); 85 | } 86 | }.bind(Zotero.ZotFile)); 87 | 88 | var on_confirm = Zotero.Promise.coroutine(function* (att) { 89 | // rename attachment 90 | att = yield this.renameAttachment(att); 91 | // user notification 92 | var progress_win = this.progressWindow(this.ZFgetString('general.newAttachmentRenamed')); 93 | var progress = new progress_win.ItemProgress(att.getImageSrc(), att.getField('title')); 94 | progress.setProgress(100); 95 | progress_win.startCloseTimer(); 96 | }.bind(Zotero.ZotFile)); 97 | } 98 | -------------------------------------------------------------------------------- /chrome/content/zotfile/optionsFolderEditor.xul: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 31 | 32 | 33 | 42 | 43 | 50 | 51 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfOutline.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * pdfOutline class to extract pdf outline 4 | * Runs code to get outline from pdf 5 | */ 6 | Zotero.ZotFile.pdfOutline = new function() { 7 | 8 | this.atts = []; 9 | this.toc_url = 'chrome://zotfile/content/pdfextract/toc.html'; 10 | this.progressWin = null; 11 | this.itemProgress = []; 12 | 13 | this.getOutline = Zotero.Promise.coroutine(function* (attIDs, verbose) { 14 | var verbose = false; 15 | this.progressWin = null; 16 | this.itemProgress = []; 17 | // get selected attachments if no att ids are passed 18 | if(attIDs == null) { 19 | verbose = true; 20 | attIDs = Zotero.ZotFile.getSelectedAttachments(); 21 | Zotero.ZotFile.showWarningMessages(Zotero.ZotFile.ZFgetString('general.warning.skippedAtt'),Zotero.ZotFile.ZFgetString('general.warning.skippedAtt.msg')); 22 | } 23 | // get attachment item, parent and file 24 | // filter attachments 25 | this.atts = Zotero.Items.get(attIDs) 26 | .filter(att => att.isAttachment() && !att.isTopLevelItem()) 27 | .filter(att => att.attachmentContentType == 'application/pdf'); 28 | this.atts = yield Zotero.Promise.filter(this.atts, att => att.fileExists()); 29 | if (this.atts.length==0) return; 30 | if (Zotero.isFx36) { 31 | Zotero.ZotFile.infoWindow(Zotero.ZotFile.ZFgetString('general.error'),Zotero.ZotFile.ZFgetString('extraction.outdatedFirefox')); 32 | return; 33 | } 34 | // progresswindow 35 | this.progressWin = new Zotero.ZotFile.ProgressWindow(); 36 | this.progressWin.changeHeadline('Zotfile: Getting Table of Contents...'); 37 | var icon_pdf = 'chrome://zotero/skin/treeitem-attachment-pdf.png'; 38 | for (var i = 0; i < this.atts.length; i++) { 39 | this.itemProgress.push(new this.progressWin.ItemProgress(icon_pdf, this.atts[i].getField('title'))); 40 | }; 41 | this.progressWin.addDescription("Zotfile can only extract the TOC for PDFs that have a TOC."); 42 | if(verbose) this.progressWin.show(); 43 | // get outline in hidden browser 44 | this.pdfHiddenBrowser = Zotero.Browser.createHiddenBrowser(); 45 | this.pdfHiddenBrowser.loadURI(this.toc_url); 46 | }); 47 | 48 | this.getOutlineFromFiles = function() { 49 | var attachment = this.atts.shift(); 50 | var itemProgress = this.itemProgress.shift(); 51 | var args = {}; 52 | args.url = attachment.getFilePath(); 53 | args.att = attachment; 54 | args.itemProgress = itemProgress; 55 | args.callbackObj = this; 56 | args.callback = this.complete; 57 | Zotero.ZotFile.PdfGetOutline.getOutline(args); 58 | }; 59 | 60 | this.createOutline = function(att, outline, itemProgress) { 61 | var zz = Zotero.ZotFile; 62 | itemProgress.setProgress(100); 63 | // [JavaScript Error: "mismatched tag. Expected:

."] 64 | if (outline===null) { 65 | itemProgress.setError(); 66 | return; 67 | } 68 | // create toc from outline 69 | var win = Services.wm.getMostRecentWindow("navigator:browser"), 70 | toc = win.document.createElementNS(zz.xhtml, 'ul'), 71 | key = att.key, 72 | lib = att.library.libraryType == 'user' ? 0 : att.libraryID, 73 | href = 'zotero://open-pdf/%(lib)_%(key)/%(page)', 74 | style = 'list-style-type: none; padding-left:%(padding)px', 75 | lvl = 1, 76 | firstElement = true; 77 | // style toc 78 | toc.setAttribute('style', 'list-style-type: none; padding-left:0px'); 79 | toc.setAttribute('id', 'toc'); 80 | var create_toc = function(entry) { 81 | var li = win.document.createElementNS(zz.xhtml, 'li'), 82 | a = win.document.createElementNS(zz.xhtml, 'a'); 83 | if (!firstElement) 84 | li.setAttribute('style', entry.items.length>0 ? 'padding-top:8px' : 'padding-top:4px'); 85 | firstElement = false; 86 | a.setAttribute('href', zz.Utils.str_format(href, {'lib': lib, 'key': key, 'page': entry.page + 1})); 87 | a.textContent = Zotero.Utilities.htmlSpecialChars(entry.title); 88 | a.textContent = a.textContent.replace(/'/g, "'"); 89 | if(entry.page!==undefined) 90 | li.appendChild(a); 91 | if(entry.page!==undefined && entry.items.length>0) 92 | lvl++; 93 | // add subitems 94 | if(entry.items.length>0 && lvl <= zz.getPref('pdfOutline.tocDepth')) { 95 | var ul = win.document.createElementNS(zz.xhtml, 'ul'); 96 | ul.setAttribute('style', zz.Utils.str_format(style, {'padding': 12*(lvl-1)})); 97 | entry.items.forEach(create_toc, ul); 98 | li.appendChild(ul); 99 | } 100 | if(entry.page!==undefined && entry.items.length>0) 101 | lvl--; 102 | this.appendChild(li); 103 | }; 104 | outline.forEach(create_toc, toc); 105 | // add toc to note 106 | var note = win.document.createElementNS(zz.xhtml, 'div'), 107 | title = win.document.createElementNS(zz.xhtml, 'p'), 108 | content = att.getNote().replace(/zotero:\/\//g, 'http://zotfile.com/'); 109 | note.appendChild(zz.Utils.parseHTML(content)); 110 | // title 111 | title.setAttribute('id', 'title'); 112 | var txt = win.document.createElementNS(zz.xhtml, 'strong'); 113 | txt.textContent = 'Contents'; 114 | title.appendChild(txt); 115 | // remove previous title and toc 116 | var pre_toc = note.querySelector('#toc'); 117 | if (pre_toc!==null) note.removeChild(pre_toc); 118 | var pre_title = note.querySelector('#title'); 119 | if (pre_title!==null) note.removeChild(pre_title); 120 | // add toc at beginning of note 121 | note.insertBefore(toc, note.firstChild); 122 | note.insertBefore(title, note.firstChild); 123 | // save toc in note 124 | att.setNote(note.innerHTML.replace(/http:\/\/zotfile.com\//g, 'zotero://')); 125 | att.saveTx(); 126 | // done with this att... 127 | itemProgress.setIcon('chrome://zotero/skin/tick.png'); 128 | }; 129 | 130 | this.complete = function(att, outline, itemProgress) { 131 | // create outline 132 | this.createOutline(att, outline, itemProgress); 133 | // move on to the next pdf, if there is one 134 | if (this.atts.length > 0) { 135 | this.getOutlineFromFiles(); 136 | } else { // we're done 137 | Zotero.Browser.deleteHiddenBrowser(this.pdfHiddenBrowser); 138 | this.pdfHiddenBrowser = null; 139 | this.progressWin.startCloseTimer(Zotero.ZotFile.getPref("info_window_duration")); 140 | } 141 | }; 142 | }; 143 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/extract.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | Extracting PDF metadata... 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/extract.js: -------------------------------------------------------------------------------- 1 | /* globals Zotero, Components, OS, Uint8Array, PDFJS, logError */ 2 | 3 | 'use strict'; 4 | var SUPPORTED_ANNOTS = ["Text", "Highlight", "Underline"]; 5 | 6 | Zotero.ZotFile.PdfExtractor = { 7 | 8 | /** Extract annotations from a single PDF. 9 | * @see Zotero.ZotFile.pdfAnnotations.pdfAttachmentsForExtraction (zotfile.js) 10 | * for documentation on args object. 11 | */ 12 | 13 | extractAnnotations: function(args) { 14 | function logError(msg) { 15 | Components.utils.reportError(msg); 16 | Zotero.ZotFile.pdfAnnotations.errorExtractingAnnotations = true; 17 | } 18 | 19 | // read file 20 | // https://developer.mozilla.org/en-US/docs/JavaScript_OS.File/OS.File_for_the_main_thread 21 | Components.utils.import("resource://gre/modules/osfile.jsm"); 22 | OS.File.read(args.url).then( 23 | function onSuccess(array) { 24 | // create Uint8Array from file data 25 | var int8View = new Uint8Array(array); 26 | // set options for extractions 27 | var removeHyphens = Zotero.ZotFile.getPref("pdfExtraction.NoteRemoveHyphens"); 28 | args.itemProgress.setProgress(0); 29 | var progress = function(x, y) { 30 | args.itemProgress.setProgress(x*100/y); 31 | }; 32 | // extract annotations 33 | PDFJS.getPDFAnnotations(int8View, removeHyphens, progress).then(function(obj) { 34 | args.itemProgress.setProgress(100); 35 | var icon = obj.annotations.length>0 ? 'chrome://zotero/skin/tick.png' : 'chrome://zotero/skin/cross.png'; 36 | args.itemProgress.setIcon(icon); 37 | args.callback.call(args.callbackObj, obj.annotations, args.item, args.att); 38 | }, function(error) { 39 | args.itemProgress.setError(); 40 | logError('error opening PDF: ' + args.url + ' ' + error); 41 | args.callback.call(args.callbackObj, [], args.item, args.att); 42 | }); 43 | 44 | // error handler for file promise 45 | }, function onFileError(msg) { 46 | args.itemProgress.setError(); 47 | logError('error opening PDF: ' + args.url + ' ' + msg); 48 | args.callback.call(args.callbackObj, [], args.item, args.att); 49 | }); // file promise 50 | 51 | } // extractAnnotations() 52 | 53 | }; // Zotero.ZotFile.PdfExtractor 54 | 55 | // starts extraction for the first PDF 56 | Zotero.ZotFile.pdfAnnotations.extractAnnotationsFromFiles(); 57 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/README.md: -------------------------------------------------------------------------------- 1 | # PDF.js 2 | 3 | PDF.js is a Portable Document Format (PDF) viewer that is built with HTML5. 4 | 5 | PDF.js is community-driven and supported by Mozilla Labs. Our goal is to 6 | create a general-purpose, web standards-based platform for parsing and 7 | rendering PDFs. 8 | 9 | ## Contributing 10 | 11 | PDF.js is an open source project and always looking for more contributors. To 12 | get involved checkout: 13 | 14 | + [Workflow](https://github.com/mozilla/pdf.js/wiki/Contributing) 15 | + [Style Guide](https://github.com/mozilla/pdf.js/wiki/Style-Guide) 16 | + [FAQ](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions) 17 | + [Good Beginner Bugs](https://github.com/mozilla/pdf.js/issues?direction=desc&labels=5-good-beginner-bug&page=1&sort=created&state=open) 18 | + [Priorities](https://github.com/mozilla/pdf.js/milestones) 19 | + [Attend a Public Meeting](https://github.com/mozilla/pdf.js/wiki/Weekly-Public-Meetings) 20 | 21 | For further questions or guidance feel free to stop by #pdfjs on 22 | irc.mozilla.org. 23 | 24 | ## Getting Started 25 | 26 | ### Online demo 27 | 28 | + http://mozilla.github.io/pdf.js/web/viewer.html 29 | 30 | ### Browser Extensions 31 | 32 | #### Firefox 33 | 34 | PDF.js is built into version 19+ of Firefox, however two extensions are still 35 | available that are updated at a different rate: 36 | 37 | + [Development Version](http://mozilla.github.io/pdf.js/extensions/firefox/pdf.js.xpi) - This version is updated every time new code is merged into the PDF.js codebase. This should be quite stable but still might break from time to time. 38 | + [Stable Version](https://addons.mozilla.org/firefox/addon/pdfjs) - After version 24 of Firefox is released we no longer plan to support the stable extension. The stable version will then be considered whatever is built into Firefox. 39 | 40 | #### Chrome and Opera 41 | 42 | The Chromium extension is still somewhat experimental but it can be installed two 43 | ways: 44 | 45 | + [Unofficial Version](https://chrome.google.com/webstore/detail/pdf-viewer/oemmndcbldboiebfnladdacbdfmadadm) - *This extension is maintained by a PDF.js contributor.* 46 | + Build Your Own - Get the code as explained below and issue `node make chromium`. Then open 47 | Chrome, go to `Tools > Extension` and load the (unpackaged) extension from the 48 | directory `build/chromium`. 49 | 50 | The version of the extension for the Opera browser can be found at the [Opera add-ons catalog](https://addons.opera.com/en/extensions/details/pdf-viewer/). 51 | 52 | ## Getting the Code 53 | 54 | To get a local copy of the current code, clone it using git: 55 | 56 | $ git clone git://github.com/mozilla/pdf.js.git pdfjs 57 | $ cd pdfjs 58 | 59 | Next, you need to start a local web server as some browsers don't allow opening 60 | PDF files for a file:// url: 61 | 62 | $ node make server 63 | 64 | You can install Node via [nvm](https://github.com/creationix/nvm) or the 65 | [official package](http://nodejs.org). If everything worked out, you can now 66 | serve 67 | 68 | + http://localhost:8888/web/viewer.html 69 | 70 | You can also view all the test pdf files on the right side serving 71 | 72 | + http://localhost:8888/test/pdfs/?frame 73 | 74 | ## Building PDF.js 75 | 76 | In order to bundle all `src/` files into two productions scripts and build the generic 77 | viewer, issue: 78 | 79 | $ node make generic 80 | 81 | This will generate `pdf.js` and `pdf.worker.js` in the `build/generic/build/` directory. 82 | Both scripts are needed but only `pdf.js` needs to be included since `pdf.worker.js` will 83 | be loaded by `pdf.js`. If you want to support more browsers than Firefox you'll also need 84 | to include `compatibility.js` from `build/generic/web/`. The PDF.js files are large and 85 | should be minified for production. 86 | 87 | ## Learning 88 | 89 | You can play with the PDF.js API directly from your browser through the live 90 | demos below: 91 | 92 | + [Hello world](http://mozilla.github.io/pdf.js/examples/learning/helloworld.html) 93 | + [Simple reader with prev/next page controls](http://mozilla.github.io/pdf.js/examples/learning/prevnext.html) 94 | 95 | The repo contains a hello world example that you can run locally: 96 | 97 | + [examples/helloworld/](https://github.com/mozilla/pdf.js/blob/master/examples/helloworld/) 98 | 99 | For an introduction to the PDF.js code, check out the presentation by our 100 | contributor Julian Viereck: 101 | 102 | + http://www.youtube.com/watch?v=Iv15UY-4Fg8 103 | 104 | You can read more about PDF.js here: 105 | 106 | + http://andreasgal.com/2011/06/15/pdf-js/ 107 | + http://blog.mozilla.com/cjones/2011/06/15/overview-of-pdf-js-guts/ 108 | 109 | Even more learning resources can be found at: 110 | 111 | + https://github.com/mozilla/pdf.js/wiki/Additional-Learning-Resources 112 | 113 | ## Questions 114 | 115 | Check out our FAQs and get answers to common questions: 116 | 117 | + https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions 118 | 119 | Talk to us on IRC: 120 | 121 | + #pdfjs on irc.mozilla.org 122 | 123 | Join our mailing list: 124 | 125 | + dev-pdf-js@lists.mozilla.org 126 | 127 | Subscribe either using lists.mozilla.org or Google Groups: 128 | 129 | + https://lists.mozilla.org/listinfo/dev-pdf-js 130 | + https://groups.google.com/group/mozilla.dev.pdf-js/topics 131 | 132 | Follow us on twitter: @pdfjs 133 | 134 | + http://twitter.com/#!/pdfjs 135 | 136 | Weekly Public Meetings 137 | 138 | + https://github.com/mozilla/pdf.js/wiki/Weekly-Public-Meetings 139 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/core/arithmetic_decoder.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 3 | /* Copyright 2012 Mozilla Foundation 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | /* This class implements the QM Coder decoding as defined in 21 | * JPEG 2000 Part I Final Committee Draft Version 1.0 22 | * Annex C.3 Arithmetic decoding procedure 23 | * available at http://www.jpeg.org/public/fcd15444-1.pdf 24 | * 25 | * The arithmetic decoder is used in conjunction with context models to decode 26 | * JPEG2000 and JBIG2 streams. 27 | */ 28 | var ArithmeticDecoder = (function ArithmeticDecoderClosure() { 29 | // Table C-2 30 | var QeTable = [ 31 | {qe: 0x5601, nmps: 1, nlps: 1, switchFlag: 1}, 32 | {qe: 0x3401, nmps: 2, nlps: 6, switchFlag: 0}, 33 | {qe: 0x1801, nmps: 3, nlps: 9, switchFlag: 0}, 34 | {qe: 0x0AC1, nmps: 4, nlps: 12, switchFlag: 0}, 35 | {qe: 0x0521, nmps: 5, nlps: 29, switchFlag: 0}, 36 | {qe: 0x0221, nmps: 38, nlps: 33, switchFlag: 0}, 37 | {qe: 0x5601, nmps: 7, nlps: 6, switchFlag: 1}, 38 | {qe: 0x5401, nmps: 8, nlps: 14, switchFlag: 0}, 39 | {qe: 0x4801, nmps: 9, nlps: 14, switchFlag: 0}, 40 | {qe: 0x3801, nmps: 10, nlps: 14, switchFlag: 0}, 41 | {qe: 0x3001, nmps: 11, nlps: 17, switchFlag: 0}, 42 | {qe: 0x2401, nmps: 12, nlps: 18, switchFlag: 0}, 43 | {qe: 0x1C01, nmps: 13, nlps: 20, switchFlag: 0}, 44 | {qe: 0x1601, nmps: 29, nlps: 21, switchFlag: 0}, 45 | {qe: 0x5601, nmps: 15, nlps: 14, switchFlag: 1}, 46 | {qe: 0x5401, nmps: 16, nlps: 14, switchFlag: 0}, 47 | {qe: 0x5101, nmps: 17, nlps: 15, switchFlag: 0}, 48 | {qe: 0x4801, nmps: 18, nlps: 16, switchFlag: 0}, 49 | {qe: 0x3801, nmps: 19, nlps: 17, switchFlag: 0}, 50 | {qe: 0x3401, nmps: 20, nlps: 18, switchFlag: 0}, 51 | {qe: 0x3001, nmps: 21, nlps: 19, switchFlag: 0}, 52 | {qe: 0x2801, nmps: 22, nlps: 19, switchFlag: 0}, 53 | {qe: 0x2401, nmps: 23, nlps: 20, switchFlag: 0}, 54 | {qe: 0x2201, nmps: 24, nlps: 21, switchFlag: 0}, 55 | {qe: 0x1C01, nmps: 25, nlps: 22, switchFlag: 0}, 56 | {qe: 0x1801, nmps: 26, nlps: 23, switchFlag: 0}, 57 | {qe: 0x1601, nmps: 27, nlps: 24, switchFlag: 0}, 58 | {qe: 0x1401, nmps: 28, nlps: 25, switchFlag: 0}, 59 | {qe: 0x1201, nmps: 29, nlps: 26, switchFlag: 0}, 60 | {qe: 0x1101, nmps: 30, nlps: 27, switchFlag: 0}, 61 | {qe: 0x0AC1, nmps: 31, nlps: 28, switchFlag: 0}, 62 | {qe: 0x09C1, nmps: 32, nlps: 29, switchFlag: 0}, 63 | {qe: 0x08A1, nmps: 33, nlps: 30, switchFlag: 0}, 64 | {qe: 0x0521, nmps: 34, nlps: 31, switchFlag: 0}, 65 | {qe: 0x0441, nmps: 35, nlps: 32, switchFlag: 0}, 66 | {qe: 0x02A1, nmps: 36, nlps: 33, switchFlag: 0}, 67 | {qe: 0x0221, nmps: 37, nlps: 34, switchFlag: 0}, 68 | {qe: 0x0141, nmps: 38, nlps: 35, switchFlag: 0}, 69 | {qe: 0x0111, nmps: 39, nlps: 36, switchFlag: 0}, 70 | {qe: 0x0085, nmps: 40, nlps: 37, switchFlag: 0}, 71 | {qe: 0x0049, nmps: 41, nlps: 38, switchFlag: 0}, 72 | {qe: 0x0025, nmps: 42, nlps: 39, switchFlag: 0}, 73 | {qe: 0x0015, nmps: 43, nlps: 40, switchFlag: 0}, 74 | {qe: 0x0009, nmps: 44, nlps: 41, switchFlag: 0}, 75 | {qe: 0x0005, nmps: 45, nlps: 42, switchFlag: 0}, 76 | {qe: 0x0001, nmps: 45, nlps: 43, switchFlag: 0}, 77 | {qe: 0x5601, nmps: 46, nlps: 46, switchFlag: 0} 78 | ]; 79 | 80 | // C.3.5 Initialisation of the decoder (INITDEC) 81 | function ArithmeticDecoder(data, start, end) { 82 | this.data = data; 83 | this.bp = start; 84 | this.dataEnd = end; 85 | 86 | this.chigh = data[start]; 87 | this.clow = 0; 88 | 89 | this.byteIn(); 90 | 91 | this.chigh = ((this.chigh << 7) & 0xFFFF) | ((this.clow >> 9) & 0x7F); 92 | this.clow = (this.clow << 7) & 0xFFFF; 93 | this.ct -= 7; 94 | this.a = 0x8000; 95 | } 96 | 97 | ArithmeticDecoder.prototype = { 98 | // C.3.4 Compressed data input (BYTEIN) 99 | byteIn: function ArithmeticDecoder_byteIn() { 100 | var data = this.data; 101 | var bp = this.bp; 102 | if (data[bp] === 0xFF) { 103 | var b1 = data[bp + 1]; 104 | if (b1 > 0x8F) { 105 | this.clow += 0xFF00; 106 | this.ct = 8; 107 | } else { 108 | bp++; 109 | this.clow += (data[bp] << 9); 110 | this.ct = 7; 111 | this.bp = bp; 112 | } 113 | } else { 114 | bp++; 115 | this.clow += bp < this.dataEnd ? (data[bp] << 8) : 0xFF00; 116 | this.ct = 8; 117 | this.bp = bp; 118 | } 119 | if (this.clow > 0xFFFF) { 120 | this.chigh += (this.clow >> 16); 121 | this.clow &= 0xFFFF; 122 | } 123 | }, 124 | // C.3.2 Decoding a decision (DECODE) 125 | readBit: function ArithmeticDecoder_readBit(contexts, pos) { 126 | // contexts are packed into 1 byte: 127 | // highest 7 bits carry cx.index, lowest bit carries cx.mps 128 | var cx_index = contexts[pos] >> 1, cx_mps = contexts[pos] & 1; 129 | var qeTableIcx = QeTable[cx_index]; 130 | var qeIcx = qeTableIcx.qe; 131 | var d; 132 | var a = this.a - qeIcx; 133 | 134 | if (this.chigh < qeIcx) { 135 | // exchangeLps 136 | if (a < qeIcx) { 137 | a = qeIcx; 138 | d = cx_mps; 139 | cx_index = qeTableIcx.nmps; 140 | } else { 141 | a = qeIcx; 142 | d = 1 ^ cx_mps; 143 | if (qeTableIcx.switchFlag === 1) { 144 | cx_mps = d; 145 | } 146 | cx_index = qeTableIcx.nlps; 147 | } 148 | } else { 149 | this.chigh -= qeIcx; 150 | if ((a & 0x8000) !== 0) { 151 | this.a = a; 152 | return cx_mps; 153 | } 154 | // exchangeMps 155 | if (a < qeIcx) { 156 | d = 1 ^ cx_mps; 157 | if (qeTableIcx.switchFlag === 1) { 158 | cx_mps = d; 159 | } 160 | cx_index = qeTableIcx.nlps; 161 | } else { 162 | d = cx_mps; 163 | cx_index = qeTableIcx.nmps; 164 | } 165 | } 166 | // C.3.3 renormD; 167 | do { 168 | if (this.ct === 0) { 169 | this.byteIn(); 170 | } 171 | 172 | a <<= 1; 173 | this.chigh = ((this.chigh << 1) & 0xFFFF) | ((this.clow >> 15) & 1); 174 | this.clow = (this.clow << 1) & 0xFFFF; 175 | this.ct--; 176 | } while ((a & 0x8000) === 0); 177 | this.a = a; 178 | 179 | contexts[pos] = cx_index << 1 | cx_mps; 180 | return d; 181 | } 182 | }; 183 | 184 | return ArithmeticDecoder; 185 | })(); 186 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/core/charsets.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 3 | /* Copyright 2012 Mozilla Foundation 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | var ISOAdobeCharset = [ 21 | '.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 22 | 'percent', 'ampersand', 'quoteright', 'parenleft', 'parenright', 23 | 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', 24 | 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 25 | 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question', 26 | 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 27 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 28 | 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore', 29 | 'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 30 | 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 31 | 'braceleft', 'bar', 'braceright', 'asciitilde', 'exclamdown', 'cent', 32 | 'sterling', 'fraction', 'yen', 'florin', 'section', 'currency', 33 | 'quotesingle', 'quotedblleft', 'guillemotleft', 'guilsinglleft', 34 | 'guilsinglright', 'fi', 'fl', 'endash', 'dagger', 'daggerdbl', 35 | 'periodcentered', 'paragraph', 'bullet', 'quotesinglbase', 36 | 'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis', 37 | 'perthousand', 'questiondown', 'grave', 'acute', 'circumflex', 'tilde', 38 | 'macron', 'breve', 'dotaccent', 'dieresis', 'ring', 'cedilla', 39 | 'hungarumlaut', 'ogonek', 'caron', 'emdash', 'AE', 'ordfeminine', 40 | 'Lslash', 'Oslash', 'OE', 'ordmasculine', 'ae', 'dotlessi', 'lslash', 41 | 'oslash', 'oe', 'germandbls', 'onesuperior', 'logicalnot', 'mu', 42 | 'trademark', 'Eth', 'onehalf', 'plusminus', 'Thorn', 'onequarter', 43 | 'divide', 'brokenbar', 'degree', 'thorn', 'threequarters', 'twosuperior', 44 | 'registered', 'minus', 'eth', 'multiply', 'threesuperior', 'copyright', 45 | 'Aacute', 'Acircumflex', 'Adieresis', 'Agrave', 'Aring', 'Atilde', 46 | 'Ccedilla', 'Eacute', 'Ecircumflex', 'Edieresis', 'Egrave', 'Iacute', 47 | 'Icircumflex', 'Idieresis', 'Igrave', 'Ntilde', 'Oacute', 'Ocircumflex', 48 | 'Odieresis', 'Ograve', 'Otilde', 'Scaron', 'Uacute', 'Ucircumflex', 49 | 'Udieresis', 'Ugrave', 'Yacute', 'Ydieresis', 'Zcaron', 'aacute', 50 | 'acircumflex', 'adieresis', 'agrave', 'aring', 'atilde', 'ccedilla', 51 | 'eacute', 'ecircumflex', 'edieresis', 'egrave', 'iacute', 'icircumflex', 52 | 'idieresis', 'igrave', 'ntilde', 'oacute', 'ocircumflex', 'odieresis', 53 | 'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', 'udieresis', 54 | 'ugrave', 'yacute', 'ydieresis', 'zcaron' 55 | ]; 56 | 57 | var ExpertCharset = [ 58 | '.notdef', 'space', 'exclamsmall', 'Hungarumlautsmall', 'dollaroldstyle', 59 | 'dollarsuperior', 'ampersandsmall', 'Acutesmall', 'parenleftsuperior', 60 | 'parenrightsuperior', 'twodotenleader', 'onedotenleader', 'comma', 61 | 'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle', 62 | 'twooldstyle', 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle', 63 | 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', 64 | 'colon', 'semicolon', 'commasuperior', 'threequartersemdash', 65 | 'periodsuperior', 'questionsmall', 'asuperior', 'bsuperior', 66 | 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior', 67 | 'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', 68 | 'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', 69 | 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', 70 | 'Asmall', 'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', 71 | 'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall', 'Msmall', 'Nsmall', 72 | 'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', 73 | 'Vsmall', 'Wsmall', 'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', 74 | 'onefitted', 'rupiah', 'Tildesmall', 'exclamdownsmall', 'centoldstyle', 75 | 'Lslashsmall', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', 76 | 'Brevesmall', 'Caronsmall', 'Dotaccentsmall', 'Macronsmall', 77 | 'figuredash', 'hypheninferior', 'Ogoneksmall', 'Ringsmall', 78 | 'Cedillasmall', 'onequarter', 'onehalf', 'threequarters', 79 | 'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', 80 | 'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior', 81 | 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior', 82 | 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', 83 | 'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior', 84 | 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', 85 | 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', 86 | 'periodinferior', 'commainferior', 'Agravesmall', 'Aacutesmall', 87 | 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall', 'Aringsmall', 88 | 'AEsmall', 'Ccedillasmall', 'Egravesmall', 'Eacutesmall', 89 | 'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall', 90 | 'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall', 91 | 'Ogravesmall', 'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall', 92 | 'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall', 93 | 'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall', 94 | 'Ydieresissmall' 95 | ]; 96 | 97 | var ExpertSubsetCharset = [ 98 | '.notdef', 'space', 'dollaroldstyle', 'dollarsuperior', 99 | 'parenleftsuperior', 'parenrightsuperior', 'twodotenleader', 100 | 'onedotenleader', 'comma', 'hyphen', 'period', 'fraction', 101 | 'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle', 102 | 'fouroldstyle', 'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle', 103 | 'eightoldstyle', 'nineoldstyle', 'colon', 'semicolon', 'commasuperior', 104 | 'threequartersemdash', 'periodsuperior', 'asuperior', 'bsuperior', 105 | 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior', 106 | 'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', 107 | 'tsuperior', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'parenleftinferior', 108 | 'parenrightinferior', 'hyphensuperior', 'colonmonetary', 'onefitted', 109 | 'rupiah', 'centoldstyle', 'figuredash', 'hypheninferior', 'onequarter', 110 | 'onehalf', 'threequarters', 'oneeighth', 'threeeighths', 'fiveeighths', 111 | 'seveneighths', 'onethird', 'twothirds', 'zerosuperior', 'onesuperior', 112 | 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior', 113 | 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', 114 | 'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior', 115 | 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', 116 | 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', 117 | 'periodinferior', 'commainferior' 118 | ]; 119 | 120 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/core/murmurhash3.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 3 | 4 | /* Copyright 2014 Opera Software ASA 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * 18 | * 19 | * Based on https://code.google.com/p/smhasher/wiki/MurmurHash3. 20 | * Hashes roughly 100 KB per millisecond on i7 3.4 GHz. 21 | */ 22 | /* globals Uint32ArrayView */ 23 | 24 | 'use strict'; 25 | 26 | var MurmurHash3_64 = (function MurmurHash3_64Closure (seed) { 27 | // Workaround for missing math precison in JS. 28 | var MASK_HIGH = 0xffff0000; 29 | var MASK_LOW = 0xffff; 30 | 31 | function MurmurHash3_64 (seed) { 32 | var SEED = 0xc3d2e1f0; 33 | this.h1 = seed ? seed & 0xffffffff : SEED; 34 | this.h2 = seed ? seed & 0xffffffff : SEED; 35 | } 36 | 37 | var alwaysUseUint32ArrayView = false; 38 | //#if !(FIREFOX || MOZCENTRAL || B2G || CHROME) 39 | // old webkits have issues with non-aligned arrays 40 | try { 41 | new Uint32Array(new Uint8Array(5).buffer, 0, 1); 42 | } catch (e) { 43 | alwaysUseUint32ArrayView = true; 44 | } 45 | //#endif 46 | 47 | MurmurHash3_64.prototype = { 48 | update: function MurmurHash3_64_update(input) { 49 | var useUint32ArrayView = alwaysUseUint32ArrayView; 50 | var i; 51 | if (typeof input === 'string') { 52 | var data = new Uint8Array(input.length * 2); 53 | var length = 0; 54 | for (i = 0; i < input.length; i++) { 55 | var code = input.charCodeAt(i); 56 | if (code <= 0xff) { 57 | data[length++] = code; 58 | } 59 | else { 60 | data[length++] = code >>> 8; 61 | data[length++] = code & 0xff; 62 | } 63 | } 64 | } else if (input instanceof Uint8Array) { 65 | data = input; 66 | length = data.length; 67 | } else if (typeof input === 'object' && ('length' in input)) { 68 | // processing regular arrays as well, e.g. for IE9 69 | data = input; 70 | length = data.length; 71 | useUint32ArrayView = true; 72 | } else { 73 | throw new Error('Wrong data format in MurmurHash3_64_update. ' + 74 | 'Input must be a string or array.'); 75 | } 76 | 77 | var blockCounts = length >> 2; 78 | var tailLength = length - blockCounts * 4; 79 | // we don't care about endianness here 80 | var dataUint32 = useUint32ArrayView ? 81 | new Uint32ArrayView(data, blockCounts) : 82 | new Uint32Array(data.buffer, 0, blockCounts); 83 | var k1 = 0; 84 | var k2 = 0; 85 | var h1 = this.h1; 86 | var h2 = this.h2; 87 | var C1 = 0xcc9e2d51; 88 | var C2 = 0x1b873593; 89 | var C1_LOW = C1 & MASK_LOW; 90 | var C2_LOW = C2 & MASK_LOW; 91 | 92 | for (i = 0; i < blockCounts; i++) { 93 | if (i & 1) { 94 | k1 = dataUint32[i]; 95 | k1 = (k1 * C1 & MASK_HIGH) | (k1 * C1_LOW & MASK_LOW); 96 | k1 = k1 << 15 | k1 >>> 17; 97 | k1 = (k1 * C2 & MASK_HIGH) | (k1 * C2_LOW & MASK_LOW); 98 | h1 ^= k1; 99 | h1 = h1 << 13 | h1 >>> 19; 100 | h1 = h1 * 5 + 0xe6546b64; 101 | } else { 102 | k2 = dataUint32[i]; 103 | k2 = (k2 * C1 & MASK_HIGH) | (k2 * C1_LOW & MASK_LOW); 104 | k2 = k2 << 15 | k2 >>> 17; 105 | k2 = (k2 * C2 & MASK_HIGH) | (k2 * C2_LOW & MASK_LOW); 106 | h2 ^= k2; 107 | h2 = h2 << 13 | h2 >>> 19; 108 | h2 = h2 * 5 + 0xe6546b64; 109 | } 110 | } 111 | 112 | k1 = 0; 113 | 114 | switch (tailLength) { 115 | case 3: 116 | k1 ^= data[blockCounts * 4 + 2] << 16; 117 | /* falls through */ 118 | case 2: 119 | k1 ^= data[blockCounts * 4 + 1] << 8; 120 | /* falls through */ 121 | case 1: 122 | k1 ^= data[blockCounts * 4]; 123 | /* falls through */ 124 | k1 = (k1 * C1 & MASK_HIGH) | (k1 * C1_LOW & MASK_LOW); 125 | k1 = k1 << 15 | k1 >>> 17; 126 | k1 = (k1 * C2 & MASK_HIGH) | (k1 * C2_LOW & MASK_LOW); 127 | if (blockCounts & 1) { 128 | h1 ^= k1; 129 | } else { 130 | h2 ^= k1; 131 | } 132 | } 133 | 134 | this.h1 = h1; 135 | this.h2 = h2; 136 | return this; 137 | }, 138 | 139 | hexdigest: function MurmurHash3_64_hexdigest () { 140 | var h1 = this.h1; 141 | var h2 = this.h2; 142 | 143 | h1 ^= h2 >>> 1; 144 | h1 = (h1 * 0xed558ccd & MASK_HIGH) | (h1 * 0x8ccd & MASK_LOW); 145 | h2 = (h2 * 0xff51afd7 & MASK_HIGH) | 146 | (((h2 << 16 | h1 >>> 16) * 0xafd7ed55 & MASK_HIGH) >>> 16); 147 | h1 ^= h2 >>> 1; 148 | h1 = (h1 * 0x1a85ec53 & MASK_HIGH) | (h1 * 0xec53 & MASK_LOW); 149 | h2 = (h2 * 0xc4ceb9fe & MASK_HIGH) | 150 | (((h2 << 16 | h1 >>> 16) * 0xb9fe1a85 & MASK_HIGH) >>> 16); 151 | h1 ^= h2 >>> 1; 152 | 153 | for (var i = 0, arr = [h1, h2], str = ''; i < arr.length; i++) { 154 | var hex = (arr[i] >>> 0).toString(16); 155 | while (hex.length < 8) { 156 | hex = '0' + hex; 157 | } 158 | str += hex; 159 | } 160 | 161 | return str; 162 | } 163 | }; 164 | 165 | return MurmurHash3_64; 166 | })(); 167 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/core/network.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 3 | /* Copyright 2012 Mozilla Foundation 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | // NOTE: Be careful what goes in this file, as it is also used from the context 19 | // of the addon. So using warn/error in here will break the addon. 20 | 21 | 'use strict'; 22 | 23 | 24 | //#if (FIREFOX || MOZCENTRAL) 25 | // 26 | //Components.utils.import('resource://gre/modules/Services.jsm'); 27 | // 28 | //var EXPORTED_SYMBOLS = ['NetworkManager']; 29 | // 30 | //var console = { 31 | // log: function console_log(aMsg) { 32 | // var msg = 'network.js: ' + (aMsg.join ? aMsg.join('') : aMsg); 33 | // Services.console.logStringMessage(msg); 34 | // // TODO(mack): dump() doesn't seem to work here... 35 | // dump(msg + '\n'); 36 | // } 37 | //} 38 | //#endif 39 | 40 | var NetworkManager = (function NetworkManagerClosure() { 41 | 42 | var OK_RESPONSE = 200; 43 | var PARTIAL_CONTENT_RESPONSE = 206; 44 | 45 | function NetworkManager(url, args) { 46 | this.url = url; 47 | args = args || {}; 48 | this.isHttp = /^https?:/i.test(url); 49 | this.httpHeaders = (this.isHttp && args.httpHeaders) || {}; 50 | this.withCredentials = args.withCredentials || false; 51 | this.getXhr = args.getXhr || 52 | function NetworkManager_getXhr() { 53 | //#if B2G 54 | // return new XMLHttpRequest({ mozSystem: true }); 55 | //#else 56 | return new XMLHttpRequest(); 57 | //#endif 58 | }; 59 | 60 | this.currXhrId = 0; 61 | this.pendingRequests = {}; 62 | this.loadedRequests = {}; 63 | } 64 | 65 | function getArrayBuffer(xhr) { 66 | var data = xhr.response; 67 | if (typeof data !== 'string') { 68 | return data; 69 | } 70 | var length = data.length; 71 | var array = new Uint8Array(length); 72 | for (var i = 0; i < length; i++) { 73 | array[i] = data.charCodeAt(i) & 0xFF; 74 | } 75 | return array.buffer; 76 | } 77 | 78 | NetworkManager.prototype = { 79 | requestRange: function NetworkManager_requestRange(begin, end, listeners) { 80 | var args = { 81 | begin: begin, 82 | end: end 83 | }; 84 | for (var prop in listeners) { 85 | args[prop] = listeners[prop]; 86 | } 87 | return this.request(args); 88 | }, 89 | 90 | requestFull: function NetworkManager_requestFull(listeners) { 91 | return this.request(listeners); 92 | }, 93 | 94 | request: function NetworkManager_request(args) { 95 | var xhr = this.getXhr(); 96 | var xhrId = this.currXhrId++; 97 | var pendingRequest = this.pendingRequests[xhrId] = { 98 | xhr: xhr 99 | }; 100 | 101 | xhr.open('GET', this.url); 102 | xhr.withCredentials = this.withCredentials; 103 | for (var property in this.httpHeaders) { 104 | var value = this.httpHeaders[property]; 105 | if (typeof value === 'undefined') { 106 | continue; 107 | } 108 | xhr.setRequestHeader(property, value); 109 | } 110 | if (this.isHttp && 'begin' in args && 'end' in args) { 111 | var rangeStr = args.begin + '-' + (args.end - 1); 112 | xhr.setRequestHeader('Range', 'bytes=' + rangeStr); 113 | pendingRequest.expectedStatus = 206; 114 | } else { 115 | pendingRequest.expectedStatus = 200; 116 | } 117 | 118 | if (args.onProgressiveData) { 119 | xhr.responseType = 'moz-chunked-arraybuffer'; 120 | if (xhr.responseType === 'moz-chunked-arraybuffer') { 121 | pendingRequest.onProgressiveData = args.onProgressiveData; 122 | pendingRequest.mozChunked = true; 123 | } else { 124 | xhr.responseType = 'arraybuffer'; 125 | } 126 | } else { 127 | xhr.responseType = 'arraybuffer'; 128 | } 129 | 130 | if (args.onError) { 131 | xhr.onerror = function(evt) { 132 | args.onError(xhr.status); 133 | }; 134 | } 135 | xhr.onreadystatechange = this.onStateChange.bind(this, xhrId); 136 | xhr.onprogress = this.onProgress.bind(this, xhrId); 137 | 138 | pendingRequest.onHeadersReceived = args.onHeadersReceived; 139 | pendingRequest.onDone = args.onDone; 140 | pendingRequest.onError = args.onError; 141 | pendingRequest.onProgress = args.onProgress; 142 | 143 | xhr.send(null); 144 | 145 | return xhrId; 146 | }, 147 | 148 | onProgress: function NetworkManager_onProgress(xhrId, evt) { 149 | var pendingRequest = this.pendingRequests[xhrId]; 150 | if (!pendingRequest) { 151 | // Maybe abortRequest was called... 152 | return; 153 | } 154 | 155 | if (pendingRequest.mozChunked) { 156 | var chunk = getArrayBuffer(pendingRequest.xhr); 157 | pendingRequest.onProgressiveData(chunk); 158 | } 159 | 160 | var onProgress = pendingRequest.onProgress; 161 | if (onProgress) { 162 | onProgress(evt); 163 | } 164 | }, 165 | 166 | onStateChange: function NetworkManager_onStateChange(xhrId, evt) { 167 | var pendingRequest = this.pendingRequests[xhrId]; 168 | if (!pendingRequest) { 169 | // Maybe abortRequest was called... 170 | return; 171 | } 172 | 173 | var xhr = pendingRequest.xhr; 174 | if (xhr.readyState >= 2 && pendingRequest.onHeadersReceived) { 175 | pendingRequest.onHeadersReceived(); 176 | delete pendingRequest.onHeadersReceived; 177 | } 178 | 179 | if (xhr.readyState !== 4) { 180 | return; 181 | } 182 | 183 | if (!(xhrId in this.pendingRequests)) { 184 | // The XHR request might have been aborted in onHeadersReceived() 185 | // callback, in which case we should abort request 186 | return; 187 | } 188 | 189 | delete this.pendingRequests[xhrId]; 190 | 191 | // success status == 0 can be on ftp, file and other protocols 192 | if (xhr.status === 0 && this.isHttp) { 193 | if (pendingRequest.onError) { 194 | pendingRequest.onError(xhr.status); 195 | } 196 | return; 197 | } 198 | var xhrStatus = xhr.status || OK_RESPONSE; 199 | 200 | // From http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.2: 201 | // "A server MAY ignore the Range header". This means it's possible to 202 | // get a 200 rather than a 206 response from a range request. 203 | var ok_response_on_range_request = 204 | xhrStatus === OK_RESPONSE && 205 | pendingRequest.expectedStatus === PARTIAL_CONTENT_RESPONSE; 206 | 207 | if (!ok_response_on_range_request && 208 | xhrStatus !== pendingRequest.expectedStatus) { 209 | if (pendingRequest.onError) { 210 | pendingRequest.onError(xhr.status); 211 | } 212 | return; 213 | } 214 | 215 | this.loadedRequests[xhrId] = true; 216 | 217 | var chunk = getArrayBuffer(xhr); 218 | if (xhrStatus === PARTIAL_CONTENT_RESPONSE) { 219 | var rangeHeader = xhr.getResponseHeader('Content-Range'); 220 | var matches = /bytes (\d+)-(\d+)\/(\d+)/.exec(rangeHeader); 221 | var begin = parseInt(matches[1], 10); 222 | pendingRequest.onDone({ 223 | begin: begin, 224 | chunk: chunk 225 | }); 226 | } else if (pendingRequest.onProgressiveData) { 227 | pendingRequest.onDone(null); 228 | } else { 229 | pendingRequest.onDone({ 230 | begin: 0, 231 | chunk: chunk 232 | }); 233 | } 234 | }, 235 | 236 | hasPendingRequests: function NetworkManager_hasPendingRequests() { 237 | for (var xhrId in this.pendingRequests) { 238 | return true; 239 | } 240 | return false; 241 | }, 242 | 243 | getRequestXhr: function NetworkManager_getXhr(xhrId) { 244 | return this.pendingRequests[xhrId].xhr; 245 | }, 246 | 247 | isStreamingRequest: function NetworkManager_isStreamingRequest(xhrId) { 248 | return !!(this.pendingRequests[xhrId].onProgressiveData); 249 | }, 250 | 251 | isPendingRequest: function NetworkManager_isPendingRequest(xhrId) { 252 | return xhrId in this.pendingRequests; 253 | }, 254 | 255 | isLoadedRequest: function NetworkManager_isLoadedRequest(xhrId) { 256 | return xhrId in this.loadedRequests; 257 | }, 258 | 259 | abortAllRequests: function NetworkManager_abortAllRequests() { 260 | for (var xhrId in this.pendingRequests) { 261 | this.abortRequest(xhrId | 0); 262 | } 263 | }, 264 | 265 | abortRequest: function NetworkManager_abortRequest(xhrId) { 266 | var xhr = this.pendingRequests[xhrId].xhr; 267 | delete this.pendingRequests[xhrId]; 268 | xhr.abort(); 269 | } 270 | }; 271 | 272 | return NetworkManager; 273 | })(); 274 | 275 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/core/pdf_manager.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 3 | /* Copyright 2012 Mozilla Foundation 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | /* globals NotImplementedException, MissingDataException, Promise, Stream, 18 | PDFDocument, ChunkedStreamManager, createPromiseCapability */ 19 | 20 | 'use strict'; 21 | 22 | // The maximum number of bytes fetched per range request 23 | var RANGE_CHUNK_SIZE = 65536; 24 | 25 | // TODO(mack): Make use of PDFJS.Util.inherit() when it becomes available 26 | var BasePdfManager = (function BasePdfManagerClosure() { 27 | function BasePdfManager() { 28 | throw new Error('Cannot initialize BaseManagerManager'); 29 | } 30 | 31 | BasePdfManager.prototype = { 32 | onLoadedStream: function BasePdfManager_onLoadedStream() { 33 | throw new NotImplementedException(); 34 | }, 35 | 36 | ensureDoc: function BasePdfManager_ensureDoc(prop, args) { 37 | return this.ensure(this.pdfDocument, prop, args); 38 | }, 39 | 40 | ensureXRef: function BasePdfManager_ensureXRef(prop, args) { 41 | return this.ensure(this.pdfDocument.xref, prop, args); 42 | }, 43 | 44 | ensureCatalog: function BasePdfManager_ensureCatalog(prop, args) { 45 | return this.ensure(this.pdfDocument.catalog, prop, args); 46 | }, 47 | 48 | getPage: function BasePdfManager_pagePage(pageIndex) { 49 | return this.pdfDocument.getPage(pageIndex); 50 | }, 51 | 52 | cleanup: function BasePdfManager_cleanup() { 53 | return this.pdfDocument.cleanup(); 54 | }, 55 | 56 | ensure: function BasePdfManager_ensure(obj, prop, args) { 57 | return new NotImplementedException(); 58 | }, 59 | 60 | requestRange: function BasePdfManager_ensure(begin, end) { 61 | return new NotImplementedException(); 62 | }, 63 | 64 | requestLoadedStream: function BasePdfManager_requestLoadedStream() { 65 | return new NotImplementedException(); 66 | }, 67 | 68 | sendProgressiveData: function BasePdfManager_sendProgressiveData(chunk) { 69 | return new NotImplementedException(); 70 | }, 71 | 72 | updatePassword: function BasePdfManager_updatePassword(password) { 73 | this.pdfDocument.xref.password = this.password = password; 74 | if (this._passwordChangedCapability) { 75 | this._passwordChangedCapability.resolve(); 76 | } 77 | }, 78 | 79 | passwordChanged: function BasePdfManager_passwordChanged() { 80 | this._passwordChangedCapability = createPromiseCapability(); 81 | return this._passwordChangedCapability.promise; 82 | }, 83 | 84 | terminate: function BasePdfManager_terminate() { 85 | return new NotImplementedException(); 86 | } 87 | }; 88 | 89 | return BasePdfManager; 90 | })(); 91 | 92 | var LocalPdfManager = (function LocalPdfManagerClosure() { 93 | function LocalPdfManager(data, password) { 94 | var stream = new Stream(data); 95 | this.pdfDocument = new PDFDocument(this, stream, password); 96 | this._loadedStreamCapability = createPromiseCapability(); 97 | this._loadedStreamCapability.resolve(stream); 98 | } 99 | 100 | LocalPdfManager.prototype = Object.create(BasePdfManager.prototype); 101 | LocalPdfManager.prototype.constructor = LocalPdfManager; 102 | 103 | LocalPdfManager.prototype.ensure = 104 | function LocalPdfManager_ensure(obj, prop, args) { 105 | return new Promise(function (resolve, reject) { 106 | try { 107 | var value = obj[prop]; 108 | var result; 109 | if (typeof value === 'function') { 110 | result = value.apply(obj, args); 111 | } else { 112 | result = value; 113 | } 114 | resolve(result); 115 | } catch (e) { 116 | reject(e); 117 | } 118 | }); 119 | }; 120 | 121 | LocalPdfManager.prototype.requestRange = 122 | function LocalPdfManager_requestRange(begin, end) { 123 | return Promise.resolve(); 124 | }; 125 | 126 | LocalPdfManager.prototype.requestLoadedStream = 127 | function LocalPdfManager_requestLoadedStream() { 128 | }; 129 | 130 | LocalPdfManager.prototype.onLoadedStream = 131 | function LocalPdfManager_getLoadedStream() { 132 | return this._loadedStreamCapability.promise; 133 | }; 134 | 135 | LocalPdfManager.prototype.terminate = 136 | function LocalPdfManager_terminate() { 137 | return; 138 | }; 139 | 140 | return LocalPdfManager; 141 | })(); 142 | 143 | var NetworkPdfManager = (function NetworkPdfManagerClosure() { 144 | function NetworkPdfManager(args, msgHandler) { 145 | 146 | this.msgHandler = msgHandler; 147 | 148 | var params = { 149 | msgHandler: msgHandler, 150 | httpHeaders: args.httpHeaders, 151 | withCredentials: args.withCredentials, 152 | chunkedViewerLoading: args.chunkedViewerLoading, 153 | disableAutoFetch: args.disableAutoFetch, 154 | initialData: args.initialData 155 | }; 156 | this.streamManager = new ChunkedStreamManager(args.length, RANGE_CHUNK_SIZE, 157 | args.url, params); 158 | 159 | this.pdfDocument = new PDFDocument(this, this.streamManager.getStream(), 160 | args.password); 161 | } 162 | 163 | NetworkPdfManager.prototype = Object.create(BasePdfManager.prototype); 164 | NetworkPdfManager.prototype.constructor = NetworkPdfManager; 165 | 166 | NetworkPdfManager.prototype.ensure = 167 | function NetworkPdfManager_ensure(obj, prop, args) { 168 | var pdfManager = this; 169 | 170 | return new Promise(function (resolve, reject) { 171 | function ensureHelper() { 172 | try { 173 | var result; 174 | var value = obj[prop]; 175 | if (typeof value === 'function') { 176 | result = value.apply(obj, args); 177 | } else { 178 | result = value; 179 | } 180 | resolve(result); 181 | } catch(e) { 182 | if (!(e instanceof MissingDataException)) { 183 | reject(e); 184 | return; 185 | } 186 | pdfManager.streamManager.requestRange(e.begin, e.end, ensureHelper); 187 | } 188 | } 189 | 190 | ensureHelper(); 191 | }); 192 | }; 193 | 194 | NetworkPdfManager.prototype.requestRange = 195 | function NetworkPdfManager_requestRange(begin, end) { 196 | return new Promise(function (resolve) { 197 | this.streamManager.requestRange(begin, end, function() { 198 | resolve(); 199 | }); 200 | }.bind(this)); 201 | }; 202 | 203 | NetworkPdfManager.prototype.requestLoadedStream = 204 | function NetworkPdfManager_requestLoadedStream() { 205 | this.streamManager.requestAllChunks(); 206 | }; 207 | 208 | NetworkPdfManager.prototype.sendProgressiveData = 209 | function NetworkPdfManager_sendProgressiveData(chunk) { 210 | this.streamManager.onReceiveData({ chunk: chunk }); 211 | }; 212 | 213 | NetworkPdfManager.prototype.onLoadedStream = 214 | function NetworkPdfManager_getLoadedStream() { 215 | return this.streamManager.onLoadedStream(); 216 | }; 217 | 218 | NetworkPdfManager.prototype.terminate = 219 | function NetworkPdfManager_terminate() { 220 | this.streamManager.networkManager.abortAllRequests(); 221 | }; 222 | 223 | return NetworkPdfManager; 224 | })(); 225 | 226 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/core/ps_parser.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 3 | /* Copyright 2014 Mozilla Foundation 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | /* globals EOF, error, Lexer */ 18 | 19 | 'use strict'; 20 | 21 | var PostScriptParser = (function PostScriptParserClosure() { 22 | function PostScriptParser(lexer) { 23 | this.lexer = lexer; 24 | this.operators = []; 25 | this.token = null; 26 | this.prev = null; 27 | } 28 | PostScriptParser.prototype = { 29 | nextToken: function PostScriptParser_nextToken() { 30 | this.prev = this.token; 31 | this.token = this.lexer.getToken(); 32 | }, 33 | accept: function PostScriptParser_accept(type) { 34 | if (this.token.type === type) { 35 | this.nextToken(); 36 | return true; 37 | } 38 | return false; 39 | }, 40 | expect: function PostScriptParser_expect(type) { 41 | if (this.accept(type)) { 42 | return true; 43 | } 44 | error('Unexpected symbol: found ' + this.token.type + ' expected ' + 45 | type + '.'); 46 | }, 47 | parse: function PostScriptParser_parse() { 48 | this.nextToken(); 49 | this.expect(PostScriptTokenTypes.LBRACE); 50 | this.parseBlock(); 51 | this.expect(PostScriptTokenTypes.RBRACE); 52 | return this.operators; 53 | }, 54 | parseBlock: function PostScriptParser_parseBlock() { 55 | while (true) { 56 | if (this.accept(PostScriptTokenTypes.NUMBER)) { 57 | this.operators.push(this.prev.value); 58 | } else if (this.accept(PostScriptTokenTypes.OPERATOR)) { 59 | this.operators.push(this.prev.value); 60 | } else if (this.accept(PostScriptTokenTypes.LBRACE)) { 61 | this.parseCondition(); 62 | } else { 63 | return; 64 | } 65 | } 66 | }, 67 | parseCondition: function PostScriptParser_parseCondition() { 68 | // Add two place holders that will be updated later 69 | var conditionLocation = this.operators.length; 70 | this.operators.push(null, null); 71 | 72 | this.parseBlock(); 73 | this.expect(PostScriptTokenTypes.RBRACE); 74 | if (this.accept(PostScriptTokenTypes.IF)) { 75 | // The true block is right after the 'if' so it just falls through on 76 | // true else it jumps and skips the true block. 77 | this.operators[conditionLocation] = this.operators.length; 78 | this.operators[conditionLocation + 1] = 'jz'; 79 | } else if (this.accept(PostScriptTokenTypes.LBRACE)) { 80 | var jumpLocation = this.operators.length; 81 | this.operators.push(null, null); 82 | var endOfTrue = this.operators.length; 83 | this.parseBlock(); 84 | this.expect(PostScriptTokenTypes.RBRACE); 85 | this.expect(PostScriptTokenTypes.IFELSE); 86 | // The jump is added at the end of the true block to skip the false 87 | // block. 88 | this.operators[jumpLocation] = this.operators.length; 89 | this.operators[jumpLocation + 1] = 'j'; 90 | 91 | this.operators[conditionLocation] = endOfTrue; 92 | this.operators[conditionLocation + 1] = 'jz'; 93 | } else { 94 | error('PS Function: error parsing conditional.'); 95 | } 96 | } 97 | }; 98 | return PostScriptParser; 99 | })(); 100 | 101 | var PostScriptTokenTypes = { 102 | LBRACE: 0, 103 | RBRACE: 1, 104 | NUMBER: 2, 105 | OPERATOR: 3, 106 | IF: 4, 107 | IFELSE: 5 108 | }; 109 | 110 | var PostScriptToken = (function PostScriptTokenClosure() { 111 | function PostScriptToken(type, value) { 112 | this.type = type; 113 | this.value = value; 114 | } 115 | 116 | var opCache = {}; 117 | 118 | PostScriptToken.getOperator = function PostScriptToken_getOperator(op) { 119 | var opValue = opCache[op]; 120 | if (opValue) { 121 | return opValue; 122 | } 123 | return opCache[op] = new PostScriptToken(PostScriptTokenTypes.OPERATOR, op); 124 | }; 125 | 126 | PostScriptToken.LBRACE = new PostScriptToken(PostScriptTokenTypes.LBRACE, 127 | '{'); 128 | PostScriptToken.RBRACE = new PostScriptToken(PostScriptTokenTypes.RBRACE, 129 | '}'); 130 | PostScriptToken.IF = new PostScriptToken(PostScriptTokenTypes.IF, 'IF'); 131 | PostScriptToken.IFELSE = new PostScriptToken(PostScriptTokenTypes.IFELSE, 132 | 'IFELSE'); 133 | return PostScriptToken; 134 | })(); 135 | 136 | var PostScriptLexer = (function PostScriptLexerClosure() { 137 | function PostScriptLexer(stream) { 138 | this.stream = stream; 139 | this.nextChar(); 140 | 141 | this.strBuf = []; 142 | } 143 | PostScriptLexer.prototype = { 144 | nextChar: function PostScriptLexer_nextChar() { 145 | return (this.currentChar = this.stream.getByte()); 146 | }, 147 | getToken: function PostScriptLexer_getToken() { 148 | var comment = false; 149 | var ch = this.currentChar; 150 | 151 | // skip comments 152 | while (true) { 153 | if (ch < 0) { 154 | return EOF; 155 | } 156 | 157 | if (comment) { 158 | if (ch === 0x0A || ch === 0x0D) { 159 | comment = false; 160 | } 161 | } else if (ch === 0x25) { // '%' 162 | comment = true; 163 | } else if (!Lexer.isSpace(ch)) { 164 | break; 165 | } 166 | ch = this.nextChar(); 167 | } 168 | switch (ch | 0) { 169 | case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: // '0'-'4' 170 | case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: // '5'-'9' 171 | case 0x2B: case 0x2D: case 0x2E: // '+', '-', '.' 172 | return new PostScriptToken(PostScriptTokenTypes.NUMBER, 173 | this.getNumber()); 174 | case 0x7B: // '{' 175 | this.nextChar(); 176 | return PostScriptToken.LBRACE; 177 | case 0x7D: // '}' 178 | this.nextChar(); 179 | return PostScriptToken.RBRACE; 180 | } 181 | // operator 182 | var strBuf = this.strBuf; 183 | strBuf.length = 0; 184 | strBuf[0] = String.fromCharCode(ch); 185 | 186 | while ((ch = this.nextChar()) >= 0 && // and 'A'-'Z', 'a'-'z' 187 | ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A))) { 188 | strBuf.push(String.fromCharCode(ch)); 189 | } 190 | var str = strBuf.join(''); 191 | switch (str.toLowerCase()) { 192 | case 'if': 193 | return PostScriptToken.IF; 194 | case 'ifelse': 195 | return PostScriptToken.IFELSE; 196 | default: 197 | return PostScriptToken.getOperator(str); 198 | } 199 | }, 200 | getNumber: function PostScriptLexer_getNumber() { 201 | var ch = this.currentChar; 202 | var strBuf = this.strBuf; 203 | strBuf.length = 0; 204 | strBuf[0] = String.fromCharCode(ch); 205 | 206 | while ((ch = this.nextChar()) >= 0) { 207 | if ((ch >= 0x30 && ch <= 0x39) || // '0'-'9' 208 | ch === 0x2D || ch === 0x2E) { // '-', '.' 209 | strBuf.push(String.fromCharCode(ch)); 210 | } else { 211 | break; 212 | } 213 | } 214 | var value = parseFloat(strBuf.join('')); 215 | if (isNaN(value)) { 216 | error('Invalid floating point number: ' + value); 217 | } 218 | return value; 219 | } 220 | }; 221 | return PostScriptLexer; 222 | })(); 223 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/display/annotation_helper.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 3 | /* Copyright 2014 Mozilla Foundation 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | /* globals PDFJS, Util, AnnotationType */ 18 | 19 | 'use strict'; 20 | 21 | var HIGHLIGHT_OFFSET = 4; // px 22 | var ANNOT_MIN_SIZE = 10; // px 23 | 24 | var AnnotationUtils = (function AnnotationUtilsClosure() { 25 | // TODO(mack): This dupes some of the logic in CanvasGraphics.setFont() 26 | function setTextStyles(element, item, fontObj) { 27 | 28 | var style = element.style; 29 | style.fontSize = item.fontSize + 'px'; 30 | style.direction = item.fontDirection < 0 ? 'rtl': 'ltr'; 31 | 32 | if (!fontObj) { 33 | return; 34 | } 35 | 36 | style.fontWeight = fontObj.black ? 37 | (fontObj.bold ? 'bolder' : 'bold') : 38 | (fontObj.bold ? 'bold' : 'normal'); 39 | style.fontStyle = fontObj.italic ? 'italic' : 'normal'; 40 | 41 | var fontName = fontObj.loadedName; 42 | var fontFamily = fontName ? '"' + fontName + '", ' : ''; 43 | // Use a reasonable default font if the font doesn't specify a fallback 44 | var fallbackName = fontObj.fallbackName || 'Helvetica, sans-serif'; 45 | style.fontFamily = fontFamily + fallbackName; 46 | } 47 | 48 | // TODO(mack): Remove this, it's not really that helpful. 49 | function getEmptyContainer(tagName, rect, borderWidth) { 50 | var bWidth = borderWidth || 0; 51 | var element = document.createElement(tagName); 52 | element.style.borderWidth = bWidth + 'px'; 53 | var width = rect[2] - rect[0] - 2 * bWidth; 54 | var height = rect[3] - rect[1] - 2 * bWidth; 55 | element.style.width = width + 'px'; 56 | element.style.height = height + 'px'; 57 | return element; 58 | } 59 | 60 | function initContainer(item) { 61 | var container = getEmptyContainer('section', item.rect, item.borderWidth); 62 | container.style.backgroundColor = item.color; 63 | 64 | var color = item.color; 65 | var rgb = []; 66 | for (var i = 0; i < 3; ++i) { 67 | rgb[i] = Math.round(color[i] * 255); 68 | } 69 | item.colorCssRgb = Util.makeCssRgb(rgb); 70 | 71 | var highlight = document.createElement('div'); 72 | highlight.className = 'annotationHighlight'; 73 | highlight.style.left = highlight.style.top = -HIGHLIGHT_OFFSET + 'px'; 74 | highlight.style.right = highlight.style.bottom = -HIGHLIGHT_OFFSET + 'px'; 75 | highlight.setAttribute('hidden', true); 76 | 77 | item.highlightElement = highlight; 78 | container.appendChild(item.highlightElement); 79 | 80 | return container; 81 | } 82 | 83 | function getHtmlElementForTextWidgetAnnotation(item, commonObjs) { 84 | var element = getEmptyContainer('div', item.rect, 0); 85 | element.style.display = 'table'; 86 | 87 | var content = document.createElement('div'); 88 | content.textContent = item.fieldValue; 89 | var textAlignment = item.textAlignment; 90 | content.style.textAlign = ['left', 'center', 'right'][textAlignment]; 91 | content.style.verticalAlign = 'middle'; 92 | content.style.display = 'table-cell'; 93 | 94 | var fontObj = item.fontRefName ? 95 | commonObjs.getData(item.fontRefName) : null; 96 | setTextStyles(content, item, fontObj); 97 | 98 | element.appendChild(content); 99 | 100 | return element; 101 | } 102 | 103 | function getHtmlElementForTextAnnotation(item) { 104 | var rect = item.rect; 105 | 106 | // sanity check because of OOo-generated PDFs 107 | if ((rect[3] - rect[1]) < ANNOT_MIN_SIZE) { 108 | rect[3] = rect[1] + ANNOT_MIN_SIZE; 109 | } 110 | if ((rect[2] - rect[0]) < ANNOT_MIN_SIZE) { 111 | rect[2] = rect[0] + (rect[3] - rect[1]); // make it square 112 | } 113 | 114 | var container = initContainer(item); 115 | container.className = 'annotText'; 116 | 117 | var image = document.createElement('img'); 118 | image.style.height = container.style.height; 119 | image.style.width = container.style.width; 120 | var iconName = item.name; 121 | image.src = PDFJS.imageResourcesPath + 'annotation-' + 122 | iconName.toLowerCase() + '.svg'; 123 | image.alt = '[{{type}} Annotation]'; 124 | image.dataset.l10nId = 'text_annotation_type'; 125 | image.dataset.l10nArgs = JSON.stringify({type: iconName}); 126 | 127 | var contentWrapper = document.createElement('div'); 128 | contentWrapper.className = 'annotTextContentWrapper'; 129 | contentWrapper.style.left = Math.floor(rect[2] - rect[0] + 5) + 'px'; 130 | contentWrapper.style.top = '-10px'; 131 | 132 | var content = document.createElement('div'); 133 | content.className = 'annotTextContent'; 134 | content.setAttribute('hidden', true); 135 | 136 | var i, ii; 137 | if (item.hasBgColor) { 138 | var color = item.color; 139 | var rgb = []; 140 | for (i = 0; i < 3; ++i) { 141 | // Enlighten the color (70%) 142 | var c = Math.round(color[i] * 255); 143 | rgb[i] = Math.round((255 - c) * 0.7) + c; 144 | } 145 | content.style.backgroundColor = Util.makeCssRgb(rgb); 146 | } 147 | 148 | var title = document.createElement('h1'); 149 | var text = document.createElement('p'); 150 | title.textContent = item.title; 151 | 152 | if (!item.content && !item.title) { 153 | content.setAttribute('hidden', true); 154 | } else { 155 | var e = document.createElement('span'); 156 | var lines = item.content.split(/(?:\r\n?|\n)/); 157 | for (i = 0, ii = lines.length; i < ii; ++i) { 158 | var line = lines[i]; 159 | e.appendChild(document.createTextNode(line)); 160 | if (i < (ii - 1)) { 161 | e.appendChild(document.createElement('br')); 162 | } 163 | } 164 | text.appendChild(e); 165 | 166 | var pinned = false; 167 | 168 | var showAnnotation = function showAnnotation(pin) { 169 | if (pin) { 170 | pinned = true; 171 | } 172 | if (content.hasAttribute('hidden')) { 173 | container.style.zIndex += 1; 174 | content.removeAttribute('hidden'); 175 | } 176 | }; 177 | 178 | var hideAnnotation = function hideAnnotation(unpin) { 179 | if (unpin) { 180 | pinned = false; 181 | } 182 | if (!content.hasAttribute('hidden') && !pinned) { 183 | container.style.zIndex -= 1; 184 | content.setAttribute('hidden', true); 185 | } 186 | }; 187 | 188 | var toggleAnnotation = function toggleAnnotation() { 189 | if (pinned) { 190 | hideAnnotation(true); 191 | } else { 192 | showAnnotation(true); 193 | } 194 | }; 195 | 196 | image.addEventListener('click', function image_clickHandler() { 197 | toggleAnnotation(); 198 | }, false); 199 | image.addEventListener('mouseover', function image_mouseOverHandler() { 200 | showAnnotation(); 201 | }, false); 202 | image.addEventListener('mouseout', function image_mouseOutHandler() { 203 | hideAnnotation(); 204 | }, false); 205 | 206 | content.addEventListener('click', function content_clickHandler() { 207 | hideAnnotation(true); 208 | }, false); 209 | } 210 | 211 | content.appendChild(title); 212 | content.appendChild(text); 213 | contentWrapper.appendChild(content); 214 | container.appendChild(image); 215 | container.appendChild(contentWrapper); 216 | 217 | return container; 218 | } 219 | 220 | function getHtmlElementForLinkAnnotation(item) { 221 | var container = initContainer(item); 222 | container.className = 'annotLink'; 223 | 224 | container.style.borderColor = item.colorCssRgb; 225 | container.style.borderStyle = 'solid'; 226 | 227 | var link = document.createElement('a'); 228 | link.href = link.title = item.url || ''; 229 | 230 | container.appendChild(link); 231 | 232 | return container; 233 | } 234 | 235 | function getHtmlElement(data, objs) { 236 | switch (data.annotationType) { 237 | case AnnotationType.WIDGET: 238 | return getHtmlElementForTextWidgetAnnotation(data, objs); 239 | case AnnotationType.TEXT: 240 | return getHtmlElementForTextAnnotation(data); 241 | case AnnotationType.LINK: 242 | return getHtmlElementForLinkAnnotation(data); 243 | default: 244 | throw new Error('Unsupported annotationType: ' + data.annotationType); 245 | } 246 | } 247 | 248 | return { 249 | getHtmlElement: getHtmlElement 250 | }; 251 | })(); 252 | PDFJS.AnnotationUtils = AnnotationUtils; 253 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/display/metadata.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 3 | /* globals Document, error, PDFJS */ 4 | /* Copyright 2012 Mozilla Foundation 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | 'use strict'; 20 | 21 | var Metadata = PDFJS.Metadata = (function MetadataClosure() { 22 | function fixMetadata(meta) { 23 | return meta.replace(/>\\376\\377([^<]+)/g, function(all, codes) { 24 | var bytes = codes.replace(/\\([0-3])([0-7])([0-7])/g, 25 | function(code, d1, d2, d3) { 26 | return String.fromCharCode(d1 * 64 + d2 * 8 + d3 * 1); 27 | }); 28 | var chars = ''; 29 | for (var i = 0; i < bytes.length; i += 2) { 30 | var code = bytes.charCodeAt(i) * 256 + bytes.charCodeAt(i + 1); 31 | chars += code >= 32 && code < 127 && code !== 60 && code !== 62 && 32 | code !== 38 && false ? String.fromCharCode(code) : 33 | '&#x' + (0x10000 + code).toString(16).substring(1) + ';'; 34 | } 35 | return '>' + chars; 36 | }); 37 | } 38 | 39 | function Metadata(meta) { 40 | if (typeof meta === 'string') { 41 | // Ghostscript produces invalid metadata 42 | meta = fixMetadata(meta); 43 | 44 | var parser = new DOMParser(); 45 | meta = parser.parseFromString(meta, 'application/xml'); 46 | } else if (!(meta instanceof Document)) { 47 | error('Metadata: Invalid metadata object'); 48 | } 49 | 50 | this.metaDocument = meta; 51 | this.metadata = {}; 52 | this.parse(); 53 | } 54 | 55 | Metadata.prototype = { 56 | parse: function Metadata_parse() { 57 | var doc = this.metaDocument; 58 | var rdf = doc.documentElement; 59 | 60 | if (rdf.nodeName.toLowerCase() !== 'rdf:rdf') { // Wrapped in 61 | rdf = rdf.firstChild; 62 | while (rdf && rdf.nodeName.toLowerCase() !== 'rdf:rdf') { 63 | rdf = rdf.nextSibling; 64 | } 65 | } 66 | 67 | var nodeName = (rdf) ? rdf.nodeName.toLowerCase() : null; 68 | if (!rdf || nodeName !== 'rdf:rdf' || !rdf.hasChildNodes()) { 69 | return; 70 | } 71 | 72 | var children = rdf.childNodes, desc, entry, name, i, ii, length, iLength; 73 | for (i = 0, length = children.length; i < length; i++) { 74 | desc = children[i]; 75 | if (desc.nodeName.toLowerCase() !== 'rdf:description') { 76 | continue; 77 | } 78 | 79 | for (ii = 0, iLength = desc.childNodes.length; ii < iLength; ii++) { 80 | if (desc.childNodes[ii].nodeName.toLowerCase() !== '#text') { 81 | entry = desc.childNodes[ii]; 82 | name = entry.nodeName.toLowerCase(); 83 | this.metadata[name] = entry.textContent.trim(); 84 | } 85 | } 86 | } 87 | }, 88 | 89 | get: function Metadata_get(name) { 90 | return this.metadata[name] || null; 91 | }, 92 | 93 | has: function Metadata_has(name) { 94 | return typeof this.metadata[name] !== 'undefined'; 95 | } 96 | }; 97 | 98 | return Metadata; 99 | })(); 100 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/doc_helper.js: -------------------------------------------------------------------------------- 1 | /* Copyright 2012 Mozilla Foundation 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | /* 17 | NOTE: This file is created as a helper to assist with JSDoc html files. 18 | It is not for use in the executable code. 19 | */ 20 | 21 | /** 22 | * PDFJS scope object that contains all functions, objects and variables related 23 | * to the PDF.js. 24 | * @constructor 25 | */ 26 | function PDFJS() { 27 | // Mock class constructor. See src/display/api.js. 28 | } 29 | 30 | /** 31 | * Represents the eventual result of an asynchronous operation. 32 | * @external Promise 33 | * @see {@link http://promisesaplus.com/ Promise/A+} 34 | */ 35 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/getPDFAnnotations.js: -------------------------------------------------------------------------------- 1 | /** 2 | * PDF.js extension that extracts highlighted text and annotations from pdf files. 3 | * Based on modified version of pdf.js available here https://github.com/jlegewie/pdf.js 4 | * (see various extract branches). See 'PDF Reference Manual 1.7' section 8.4 for details on 5 | * annotations in pdf files. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | /** 11 | * @return {Promise} A promise that is resolved with an Object 12 | * that includes elements for path, time, and annotations. 13 | */ 14 | PDFJS.getPDFAnnotations = function(url, removeHyphens, progress, debug) { 15 | // set default values 16 | removeHyphens = typeof removeHyphens !== 'undefined' ? removeHyphens : true; 17 | progress = typeof progress !== 'undefined' ? progress : function(x, y) {}; 18 | debug = typeof debug !== 'undefined' ? debug : false; 19 | var legacyPromise = PDFJS.Promise!==undefined; 20 | // Return a new promise (with support for legacy pdf.js promises) 21 | /* http://www.html5rocks.com/en/tutorials/es6/promises*/ 22 | var extract = function(resolve, reject) { 23 | var SUPPORTED_ANNOTS = ['Text','Highlight','Underline'], 24 | obj = {annotations: [], 25 | time:null, 26 | url: typeof url=='string' ? url : '' 27 | }; 28 | // Fetch the PDF document from the URL using promices 29 | PDFJS.getDocument(url).then(function(pdf) { 30 | var n_annos = 0, 31 | numPages = pdf.numPages, 32 | time_start = performance.now(); 33 | 34 | // function to handle page (render and extract annotations) 35 | var getAnnotationsFromPage = function(page) { 36 | var scale = 1; 37 | var viewport = page.getViewport(scale); 38 | // Prepare canvas using PDF page dimensions 39 | var canvas = document.getElementById('the-canvas'); 40 | var context = canvas.getContext('2d'); 41 | canvas.height = viewport.height; 42 | canvas.width = viewport.width; 43 | // Render PDF page into canvas context 44 | var renderContext = { 45 | canvasContext: context, 46 | viewport: viewport 47 | }; 48 | // error handler 49 | var errorHandler = function(error) { 50 | progress(page.pageNumber, numPages); 51 | console.log(error); 52 | // continue with next page 53 | if(numPages>page.pageNumber) 54 | pdf.getPage(page.pageNumber+1).then( 55 | getAnnotationsFromPage, 56 | function(err) {legacyPromise ? promise.reject(obj) : reject(err);}); 57 | else { 58 | var end = performance.now(); 59 | obj.time = end-time_start; 60 | legacyPromise ? promise.resolve(obj) : resolve(obj); 61 | } 62 | }; 63 | // function to convert deviceRGB to RGB 64 | var convertDeviceRGBtoRGB = function(dr, dg, db) { 65 | var r = Math.round(dr*255); 66 | var g = Math.round(dg*255); 67 | var b = Math.round(db*255); 68 | return [r, g, b]; 69 | }; 70 | // get annotations 71 | page.getAnnotations().then(function extractAnno(annos) { 72 | // compatibility for old pdf.js version and filter for supported annotations 73 | annos = annos 74 | .map(function(anno) { 75 | if (anno.subtype===undefined) anno.subtype=anno.type; 76 | return anno; 77 | }) 78 | .filter(function(anno) { 79 | return SUPPORTED_ANNOTS.indexOf(anno.subtype) >= 0; 80 | }); 81 | // skip page if there is nothing interesting 82 | if (annos.length===0) { 83 | progress(page.pageNumber,numPages); 84 | if(numPages>page.pageNumber) 85 | pdf.getPage(page.pageNumber+1).then( 86 | getAnnotationsFromPage, 87 | function(err) {legacyPromise ? promise.reject(obj) : reject(err);}); 88 | else { 89 | var end = performance.now(); 90 | obj.time = end-time_start; 91 | legacyPromise ? promise.resolve(obj) : resolve(obj); 92 | } 93 | return; 94 | } 95 | // render page 96 | var render = page.render(renderContext, annos); 97 | if (render.promise!==undefined) render = render.promise; 98 | render.then(function() { 99 | // clean markup 100 | annos = annos.map(function(anno) { 101 | anno.page = page.pageNumber; 102 | if('color' in anno) 103 | anno.color = convertDeviceRGBtoRGB(anno.color[0],anno.color[1],anno.color[2]); 104 | // clean markup 105 | if(anno.markup) { 106 | anno.markup = anno.markup 107 | .map(function(part) {return part.trim();}) 108 | .join(' ').trim() 109 | // translate ligatures (e.g. 'fi') 110 | .replace('\ufb00','ff').replace('\ufb01','fi').replace('\ufb02','fl') 111 | .replace(/\ufb03/g,'ffi').replace(/\ufb04/g,'ffl').replace(/\ufb05/g,'ft') 112 | .replace(/\ufb06/g,'st').replace(/\uFB00/g,'ff').replace(/\uFB01/g,'fi') 113 | .replace(/\uFB02/g,'fl').replace(/\u201D/g,'"').replace(/\u201C/g,'"') 114 | .replace(/\u2019/g,"'").replace(/\u2018/g,"'").replace(/\u2013/g,'-'). 115 | replace(/''/g,'"').replace(/`/g,"'"); 116 | if(removeHyphens) 117 | anno.markup = anno.markup.replace(/([a-zA-Z])- ([a-zA-Z])/g, '$1$2'); 118 | } 119 | // clean anno 120 | if(!debug) { 121 | delete anno.annotationFlags; 122 | delete anno.borderWidth; 123 | delete anno.chars; 124 | delete anno.hasAppearance; 125 | delete anno.markupGeom; 126 | delete anno.quadPoints; 127 | delete anno.rect; 128 | delete anno.rect; 129 | delete anno.spaceSize; 130 | delete anno.name; 131 | } 132 | // return 133 | return anno; 134 | }); 135 | // add annotations to return object 136 | obj.annotations.push.apply(obj.annotations, annos); 137 | 138 | // render next page 139 | progress(page.pageNumber, numPages); 140 | if(numPages>page.pageNumber) 141 | pdf.getPage(page.pageNumber+1).then( 142 | getAnnotationsFromPage, 143 | function(err) {legacyPromise ? promise.reject(obj) : reject(err);} ); 144 | else { 145 | var end = performance.now(); 146 | obj.time = end-time_start; 147 | legacyPromise ? promise.resolve(obj) : resolve(obj); 148 | } 149 | }, errorHandler); 150 | }, errorHandler); 151 | }; 152 | 153 | // Using promise to fetch the page 154 | pdf.getPage(1).then( 155 | getAnnotationsFromPage, 156 | function(err) {console.log('error getting the page:' + err);} 157 | ); 158 | 159 | }, 160 | function(err) { 161 | console.log('unable to open pdf: ' + err); 162 | legacyPromise ? promise.reject(obj) : reject(err); 163 | }); 164 | }; 165 | if (legacyPromise) { 166 | var promise = new PDFJS.Promise(); 167 | extract(); 168 | return promise; 169 | } 170 | else 171 | return new Promise(extract); 172 | }; -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 12 | 18 | 24 | 25 | 28 | 31 | 34 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/pdf.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 3 | /* Copyright 2012 Mozilla Foundation 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | /*jshint globalstrict: false */ 18 | /* globals PDFJS */ 19 | 20 | // Initializing PDFJS global object (if still undefined) 21 | if (typeof PDFJS === 'undefined') { 22 | (typeof window !== 'undefined' ? window : this).PDFJS = {}; 23 | } 24 | 25 | //#if BUNDLE_VERSION 26 | //#expand PDFJS.version = '__BUNDLE_VERSION__'; 27 | //#endif 28 | //#if BUNDLE_BUILD 29 | //#expand PDFJS.build = '__BUNDLE_BUILD__'; 30 | //#endif 31 | 32 | (function pdfjsWrapper() { 33 | // Use strict in our context only - users might not want it 34 | 'use strict'; 35 | 36 | //#expand __BUNDLE__ 37 | 38 | }).call((typeof window === 'undefined') ? this : window); 39 | 40 | //#if !(MOZCENTRAL || FIREFOX) 41 | if (!PDFJS.workerSrc && typeof document !== 'undefined') { 42 | // workerSrc is not set -- using last script url to define default location 43 | PDFJS.workerSrc = (function () { 44 | 'use strict'; 45 | var scriptTagContainer = document.body || 46 | document.getElementsByTagName('head')[0]; 47 | var pdfjsSrc = scriptTagContainer.lastChild.src; 48 | return pdfjsSrc && pdfjsSrc.replace(/\.js$/i, '.worker.js'); 49 | })(); 50 | } 51 | //#endif 52 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/shared/cffStandardStrings.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 3 | /* Copyright 2012 Mozilla Foundation 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | var CFFEncodingMap = { 21 | '0': '-reserved-', 22 | '1': 'hstem', 23 | '2': '-reserved-', 24 | '3': 'vstem', 25 | '4': 'vmoveto', 26 | '5': 'rlineto', 27 | '6': 'hlineto', 28 | '7': 'vlineto', 29 | '8': 'rrcurveto', 30 | '9': '-reserved-', 31 | '10': 'callsubr', 32 | '11': 'return', 33 | '12': { 34 | '3': 'and', 35 | '4': 'or', 36 | '5': 'not', 37 | '9': 'abs', 38 | '10': 'add', 39 | '11': 'div', 40 | '12': 'sub', 41 | '14': 'neg', 42 | '15': 'eq', 43 | '18': 'drop', 44 | '20': 'put', 45 | '21': 'get', 46 | '22': 'ifelse', 47 | '23': 'random', 48 | '24': 'mul', 49 | '26': 'sqrt', 50 | '27': 'dup', 51 | '28': 'exch', 52 | '29': 'index', 53 | '30': 'roll', 54 | '34': 'hflex', 55 | '35': 'flex', 56 | '36': 'hflex1', 57 | '37': 'flex1' 58 | }, 59 | '13': '-reserved-', 60 | '14': 'endchar', 61 | '15': '-reserved-', 62 | '16': '-reserved-', 63 | '17': '-reserved-', 64 | '18': 'hstemhm', 65 | '19': 'hintmask', 66 | '20': 'cntrmask', 67 | '21': 'rmoveto', 68 | '22': 'hmoveto', 69 | '23': 'vstemhm', 70 | '24': 'rcurveline', 71 | '25': 'rlivecurve', 72 | '26': 'vvcurveto', 73 | '27': 'hhcurveto', 74 | '29': 'callgsubr', 75 | '30': 'vhcurveto', 76 | '31': 'hvcurveto' 77 | }; 78 | 79 | var CFFDictDataMap = { 80 | '0': { 81 | name: 'version', 82 | operand: 'SID' 83 | }, 84 | '1': { 85 | name: 'Notice', 86 | operand: 'SID' 87 | }, 88 | '2': { 89 | name: 'FullName', 90 | operand: 'SID' 91 | }, 92 | '3': { 93 | name: 'FamilyName', 94 | operand: 'SID' 95 | }, 96 | '4': { 97 | name: 'Weight', 98 | operand: 'SID' 99 | }, 100 | '5': { 101 | name: 'FontBBox', 102 | operand: [0, 0, 0, 0] 103 | }, 104 | '6': { 105 | name: 'BlueValues' 106 | }, 107 | '7': { 108 | name: 'OtherBlues' 109 | }, 110 | '8': { 111 | name: 'FamilyBlues' 112 | }, 113 | '9': { 114 | name: 'FamilyOtherBlues' 115 | }, 116 | '10': { 117 | name: 'StdHW' 118 | }, 119 | '11': { 120 | name: 'StdVW' 121 | }, 122 | '12': { 123 | '0': { 124 | name: 'Copyright', 125 | operand: 'SID' 126 | }, 127 | '1': { 128 | name: 'IsFixedPitch', 129 | operand: false 130 | }, 131 | '2': { 132 | name: 'ItalicAngle', 133 | operand: 0 134 | }, 135 | '3': { 136 | name: 'UnderlinePosition', 137 | operand: -100 138 | }, 139 | '4': { 140 | name: 'UnderlineThickness', 141 | operand: 50 142 | }, 143 | '5': { 144 | name: 'PaintType', 145 | operand: 0 146 | }, 147 | '6': { 148 | name: 'CharstringType', 149 | operand: 2 150 | }, 151 | '7': { 152 | name: 'FontMatrix', 153 | operand: [0.001, 0, 0, 0.001, 0 , 0] 154 | }, 155 | '8': { 156 | name: 'StrokeWidth', 157 | operand: 0 158 | }, 159 | '9': { 160 | name: 'BlueScale' 161 | }, 162 | '10': { 163 | name: 'BlueShift' 164 | }, 165 | '11': { 166 | name: 'BlueFuzz' 167 | }, 168 | '12': { 169 | name: 'StemSnapH' 170 | }, 171 | '13': { 172 | name: 'StemSnapV' 173 | }, 174 | '14': { 175 | name: 'ForceBold' 176 | }, 177 | '17': { 178 | name: 'LanguageGroup' 179 | }, 180 | '18': { 181 | name: 'ExpansionFactor' 182 | }, 183 | '19': { 184 | name: 'initialRandomSeed' 185 | }, 186 | '20': { 187 | name: 'SyntheticBase', 188 | operand: null 189 | }, 190 | '21': { 191 | name: 'PostScript', 192 | operand: 'SID' 193 | }, 194 | '22': { 195 | name: 'BaseFontName', 196 | operand: 'SID' 197 | }, 198 | '23': { 199 | name: 'BaseFontBlend', 200 | operand: 'delta' 201 | } 202 | }, 203 | '13': { 204 | name: 'UniqueID', 205 | operand: null 206 | }, 207 | '14': { 208 | name: 'XUID', 209 | operand: [] 210 | }, 211 | '15': { 212 | name: 'charset', 213 | operand: 0 214 | }, 215 | '16': { 216 | name: 'Encoding', 217 | operand: 0 218 | }, 219 | '17': { 220 | name: 'CharStrings', 221 | operand: null 222 | }, 223 | '18': { 224 | name: 'Private', 225 | operand: 'number number' 226 | }, 227 | '19': { 228 | name: 'Subrs' 229 | }, 230 | '20': { 231 | name: 'defaultWidthX' 232 | }, 233 | '21': { 234 | name: 'nominalWidthX' 235 | } 236 | }; 237 | 238 | var CFFDictPrivateDataMap = { 239 | '6': { 240 | name: 'BluesValues', 241 | operand: 'delta' 242 | }, 243 | '7': { 244 | name: 'OtherBlues', 245 | operand: 'delta' 246 | }, 247 | '8': { 248 | name: 'FamilyBlues', 249 | operand: 'delta' 250 | }, 251 | '9': { 252 | name: 'FamilyOtherBlues', 253 | operand: 'delta' 254 | }, 255 | '10': { 256 | name: 'StdHW', 257 | operand: null 258 | }, 259 | '11': { 260 | name: 'StdVW', 261 | operand: null 262 | }, 263 | '12': { 264 | '9': { 265 | name: 'BlueScale', 266 | operand: 0.039625 267 | }, 268 | '10': { 269 | name: 'BlueShift', 270 | operand: 7 271 | }, 272 | '11': { 273 | name: 'BlueFuzz', 274 | operand: 1 275 | }, 276 | '12': { 277 | name: 'StemSnapH', 278 | operand: 'delta' 279 | }, 280 | '13': { 281 | name: 'StemSnapV', 282 | operand: 'delta' 283 | }, 284 | '14': { 285 | name: 'ForceBold', 286 | operand: 'boolean' 287 | }, 288 | '17': { 289 | name: 'LanguageGroup', 290 | operand: 0 291 | }, 292 | '18': { 293 | name: 'ExpansionFactor', 294 | operand: 0.06 295 | }, 296 | '19': { 297 | name: 'initialRandomSeed', 298 | operand: 0 299 | } 300 | }, 301 | '19': { 302 | name: 'Subrs', 303 | operand: null 304 | }, 305 | '20': { 306 | name: 'defaultWidthX', 307 | operand: 0 308 | }, 309 | '21': { 310 | name: 'nominalWidthX', 311 | operand: 0 312 | } 313 | }; 314 | 315 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/pdfjs/src/worker_loader.js: -------------------------------------------------------------------------------- 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 3 | /* Copyright 2012 Mozilla Foundation 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | /* globals PDFJS, Util */ 18 | 19 | 'use strict'; 20 | 21 | // List of shared files to include; 22 | var sharedFiles = [ 23 | 'shared/util.js' 24 | ]; 25 | 26 | // List of other files to include; 27 | var otherFiles = [ 28 | 'core/network.js', 29 | 'core/chunked_stream.js', 30 | 'core/pdf_manager.js', 31 | 'core/core.js', 32 | 'core/obj.js', 33 | 'core/charsets.js', 34 | 'core/annotation.js', 35 | 'core/function.js', 36 | 'core/colorspace.js', 37 | 'core/crypto.js', 38 | 'core/pattern.js', 39 | 'core/evaluator.js', 40 | 'core/cmap.js', 41 | 'core/fonts.js', 42 | 'core/font_renderer.js', 43 | 'core/glyphlist.js', 44 | 'core/image.js', 45 | 'core/metrics.js', 46 | 'core/parser.js', 47 | 'core/ps_parser.js', 48 | 'core/stream.js', 49 | 'core/worker.js', 50 | 'core/arithmetic_decoder.js', 51 | 'core/jpg.js', 52 | 'core/jpx.js', 53 | 'core/jbig2.js', 54 | 'core/bidi.js', 55 | 'core/murmurhash3.js' 56 | ]; 57 | 58 | function loadInOrder(index, path, files) { 59 | if (index >= files.length) { 60 | PDFJS.fakeWorkerFilesLoadedCapability.resolve(); 61 | return; 62 | } 63 | PDFJS.Util.loadScript(path + files[index], 64 | loadInOrder.bind(null, ++index, path, files)); 65 | } 66 | 67 | // Load all the files. 68 | if (typeof PDFJS === 'undefined' || !PDFJS.fakeWorkerFilesLoadedCapability) { 69 | var files = sharedFiles.concat(otherFiles); 70 | for (var i = 0; i < files.length; i++) { 71 | importScripts(files[i]); 72 | } 73 | } else { 74 | var src = PDFJS.workerSrc; 75 | var path = src.substr(0, src.indexOf('worker_loader.js')); 76 | // If Util is available, we assume that shared files are already loaded. Can 77 | // happen that they are not if PDF.js is bundled inside a special namespace. 78 | var skipShared = typeof Util !== 'undefined'; 79 | var files = skipShared ? otherFiles : sharedFiles.concat(otherFiles); 80 | loadInOrder(0, path, files); 81 | } 82 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/toc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | Get toc from PDF... 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /chrome/content/zotfile/pdfextract/toc.js: -------------------------------------------------------------------------------- 1 | /* globals Zotero, Components, OS, Uint8Array, PDFJS, logError */ 2 | 3 | 'use strict'; 4 | 5 | Zotero.ZotFile.PdfGetOutline = { 6 | 7 | /** Get outline from a single PDF. 8 | * @see Zotero.ZotFile.pdfOutline (zotfile.js) 9 | * for documentation on args object. 10 | */ 11 | 12 | getOutline: function(args) { 13 | function logError(msg) { 14 | Components.utils.reportError(msg); 15 | } 16 | 17 | // read file 18 | // https://developer.mozilla.org/en-US/docs/JavaScript_OS.File/OS.File_for_the_main_thread 19 | Components.utils.import("resource://gre/modules/osfile.jsm"); 20 | OS.File.read(args.url).then( 21 | function onSuccess(array) { 22 | // create Uint8Array from file data 23 | var int8View = new Uint8Array(array); 24 | // get pdf outline 25 | PDFJS.getDocument(int8View).then(function(pdf) { 26 | // get table of content for pdfs 27 | pdf.getOutline().then(function(outline) { 28 | if(outline===null) { 29 | args.callback.call(args.callbackObj, args.att, null, args.itemProgress); 30 | return; 31 | } 32 | // build page index 33 | var pageIndex = [], 34 | pageMap = {}; 35 | var buildIndex = function(obj) { 36 | if(obj.dest && obj.dest[0]) 37 | pageIndex.push(obj.dest); 38 | obj.items.forEach(buildIndex); 39 | }; 40 | outline.forEach(buildIndex); 41 | 42 | // create page map 43 | pdf.getDestinations().then(function(dest) { 44 | var sequence = Promise.resolve(); 45 | pageIndex.reduce(function(sequence, ref) { 46 | // Add these actions to the end of the sequence 47 | return sequence.then(function() { 48 | // return pdf.getPageIndex(ref); 49 | return typeof ref == 'string' ? 50 | ((ref in dest && dest[ref]!==null) ? pdf.getPageIndex(dest[ref][0]) : 0) : 51 | pdf.getPageIndex(ref[0]); 52 | }).then(function(page) { 53 | var key = typeof ref =='string' ? ref : JSON.stringify(ref[0]); 54 | pageMap[key] = page; 55 | }); 56 | }, Promise.resolve()).then(function() { 57 | var toc = function(obj) { 58 | var key, page; 59 | if(obj.dest) { 60 | key = typeof obj.dest =='string' ? obj.dest : JSON.stringify(obj.dest[0]); 61 | page = pageMap[key]; 62 | } 63 | return { 64 | 'page': page, 65 | 'title': obj.title, 66 | 'items': obj.items.map(toc) 67 | }; 68 | }; 69 | outline = outline.map(toc); 70 | // remove highest level if it just has one item 71 | if(outline.length==1) 72 | if(outline[0].items.length>0) 73 | outline = outline[0].items; 74 | // returned outline 75 | args.callback.call(args.callbackObj, args.att, outline, args.itemProgress); 76 | }); 77 | }); /* getDestinations() */ 78 | }); /* getOutline() */ 79 | }, 80 | // error handler for getDocument 81 | function(err) { 82 | args.itemProgress.setError(); 83 | logError('error opening PDF: ' + args.url + ' ' + err); 84 | args.callback.call(args.callbackObj, args.att, null, args.itemProgress); 85 | }); 86 | 87 | // error handler for file promise 88 | }, function onFileError(msg) { 89 | args.itemProgress.setError(); 90 | logError('error opening PDF: ' + args.url + ' ' + msg); 91 | args.callback.call(args.callbackObj, args.att, null, args.itemProgress); 92 | }); // file promise 93 | 94 | } // getOutline() 95 | 96 | }; // Zotero.ZotFile.PdfOutline 97 | 98 | // starts extraction for the first PDF 99 | Zotero.ZotFile.pdfOutline.getOutlineFromFiles(); 100 | -------------------------------------------------------------------------------- /chrome/content/zotfile/progressWindow.xul: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |