├── .gitignore ├── CHANGELOG ├── README.md ├── icons ├── fb2.ico ├── fb2_icons.png ├── icon-128.png ├── icon-128.xcf ├── icon-16-2x.png ├── icon-16-2x.xcf ├── icon-16.png ├── icon-16.xcf ├── icon-24.png ├── icon-24.xcf ├── icon-32.png ├── icon-32.xcf ├── icon-48.png ├── icon-48.xcf ├── icon-64.png ├── icon-64.xcf ├── icon-96.png ├── icon-96.xcf └── toolbar.xcf ├── userstyles └── example.user.css └── webext-src ├── css ├── fb2.css ├── html.css └── print.css ├── icons ├── icon-128.png ├── icon-16-2x.png ├── icon-16.png ├── icon-24.png ├── icon-32.png ├── icon-48.png ├── icon-64.png └── icon-96.png ├── jszip.js ├── local.js ├── manifest.json ├── streamfilter.js └── tools.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 0.31, 2018-06-09 2 | * Local unzipped fb2 file support 3 | 4 | 0.30, 2017-10-29 5 | * WebExtension 6 | 7 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 | 9 | 0.28.1, 2018-10-22 10 | * Added Pale Moon support 11 | 12 | 0.28, 2016-03-23 13 | * added Galician 14 | * hidden element 15 | 16 | 0.26, 2014-12-09 17 | * added Spanish(ES) locale, changed homepage to GitHub 18 | 19 | 0.25, 2014-06-26 20 | * added icon for Australis palette 21 | * reading position is now saved on close, not scroll 22 | * added Estonian, Portuguese(Brazil), German and Turkish locales, updated Serbian 23 | 24 | 0.24, 2012-12-06 25 | * added max-width for images, in order for big ones not to break out of page 26 | 27 | 0.23, 2012-11-22 28 | * added unprefixed box-radius and shadows 29 | * ensured space for § menu 30 | * switched from GlobalStorage to Sqlite for position saving 31 | * added lots of locales from Babelzilla 32 | 33 | 0.22, 2011-07-11 34 | * prevent images from being displayed in list of contents 35 | * delete temporary files 36 | * warn about non-latin filenames in zips 37 | * a little less global variables 38 | 39 | 0.21, 2011-03-06 40 | * use DOM Storage for saving read position 41 | 42 | 0.20, 2011-03-05 43 | * Updates will be served by AMO. They disabled self-hosted addons yet I want to be listed 44 | * Reading position is saved per-book 45 | 46 | 0.19, 2010-12-28 47 | * Printing and print preview 48 | 49 | 0.18, 2010-12-28 50 | * Link navigation works much better 51 | 52 | 0.17, 2010-12-27 53 | * Added book index 54 | 55 | 0.16, 2010-12-26 56 | * Added toolbar toggle button 57 | 58 | 0.15, 2010-12-25 59 | * Much better storing of favicon/title in history and bookmarks 60 | * Added large icons for Firefox 4 and Seamonkey 2.1 61 | 62 | 0.13, 2010-12-22 63 | * A bit nicer display of short tooltips 64 | * Added Preference for 'booky' and 'computer' paragraphs 65 | * Max-width is set to 50em; 66 | 67 | 0.12, 2010-10-25 68 | * Bugfix for opening never-before opened local files 69 | 70 | 0.11, 2010-10-25 71 | * Opening of files that are proposed as attachments 72 | For chtyvo.org.ua and fictionbook.ru 73 | 74 | 0.10, 2010-10-21 75 | * Firefox 4.0 compartibility 76 | * Favicons and Titles are recorded in history 77 | * Some speed improvements 78 | 79 | 0.9.2, 2010-01-26 80 | * P are now more bookish 81 | 82 | 0.9.1, 2010-01-25 83 | * bugfix: JS was failing in Firefox, bored with AMO 84 | 85 | 0.9, 2010-01-22 86 | * External and internal(quirky) links are supported 87 | 88 | 0.8, 2010-01-13 89 | * Seamonkey support 90 | 91 | 0.7, 2009-12-22 92 | * Added proper error pages for broken zips and malformed XML 93 | * Those are localized into Ukrainian and Russian 94 | * Updates now will be served by AMO 95 | 96 | 0.6, 2009-11-29 97 | * Added support for zipped books 98 | 99 | 0.5, 2009-11-20 100 | * No crash on books without id 101 | 102 | 0.4, 2009-11-18 103 | * CSS updated to display poems nicely 104 | 105 | 0.3, 2009-11-17 106 | * Displays images 107 | * Shows notes 108 | 109 | 0.2 110 | * Added FB2 favicon on tabs 111 | * Book title is shown on tab 112 | 113 | 0.1 114 | * .fb2 opens and styles 115 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FictionBook (.fb2) e-book reader addon for Firefox 2 | 3 | **Install from Mozilla Addons**, also see screenshots and reviews there. 4 | 5 | --- 6 | 7 | The reader supports links, images, footnotes, TOC, tables, zipped books (only online, local books have to be unzipped) 8 | 9 | Firefox Integration 10 | ------------------- 11 | 12 | * Bookmarks 13 | * Searching with Ctrl+F 14 | * Font size and typeface 15 | * Print and Print preview 16 | * Styling with Stylus 17 | 18 | FAQ 19 | --- 20 | 21 | ### Reading local .fb2 files in Linux 22 | 23 | Requires setting FB2 mimetype to text/xml. See [issue#8](https://github.com/tymofij/fb2reader/issues/8) for details. 24 | 25 | ### How do I set text font? 26 | 27 | Go to Firefox _Preferences_ and in Fonts and Colors section pick _Default font_. 28 | 29 | ### How do I download an .fb2 file? 30 | 31 | Right-click on a file link and pick _Save As…_ 32 | 33 | ### How can I completely change the book style? 34 | 35 | Install [Stylus](https://addons.mozilla.org/firefox/addon/styl-us/) addon and then add your styles, see the [Example](https://github.com/tymofij/fb2reader/raw/refs/heads/main/userstyles/example.user.css). 36 | 37 | Known Issues 38 | ------------- 39 | 40 | * _View Source_ does not work. 41 | * _File - Save Page_ barely works. 42 | 43 | Legacy XPI 44 | ---------- 45 | See branch [`legacy-xpi`](https://github.com/tymofij/fb2reader/tree/legacy-xpi) -------------------------------------------------------------------------------- /icons/fb2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/fb2.ico -------------------------------------------------------------------------------- /icons/fb2_icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/fb2_icons.png -------------------------------------------------------------------------------- /icons/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-128.png -------------------------------------------------------------------------------- /icons/icon-128.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-128.xcf -------------------------------------------------------------------------------- /icons/icon-16-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-16-2x.png -------------------------------------------------------------------------------- /icons/icon-16-2x.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-16-2x.xcf -------------------------------------------------------------------------------- /icons/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-16.png -------------------------------------------------------------------------------- /icons/icon-16.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-16.xcf -------------------------------------------------------------------------------- /icons/icon-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-24.png -------------------------------------------------------------------------------- /icons/icon-24.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-24.xcf -------------------------------------------------------------------------------- /icons/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-32.png -------------------------------------------------------------------------------- /icons/icon-32.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-32.xcf -------------------------------------------------------------------------------- /icons/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-48.png -------------------------------------------------------------------------------- /icons/icon-48.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-48.xcf -------------------------------------------------------------------------------- /icons/icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-64.png -------------------------------------------------------------------------------- /icons/icon-64.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-64.xcf -------------------------------------------------------------------------------- /icons/icon-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-96.png -------------------------------------------------------------------------------- /icons/icon-96.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/icon-96.xcf -------------------------------------------------------------------------------- /icons/toolbar.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/icons/toolbar.xcf -------------------------------------------------------------------------------- /userstyles/example.user.css: -------------------------------------------------------------------------------- 1 | /* ==UserStyle== 2 | @name Example Fb2 user style 3 | @description FictionBook UserCSS example 4 | @namespace github.com/tymofij/fb2reader 5 | @author Tim Babych 6 | @version 1.0.0 7 | ==/UserStyle== */ 8 | 9 | @namespace url(http://www.gribuser.ru/xml/fictionbook/2.0); 10 | @namespace html url(http://www.w3.org/1999/xhtml); 11 | /* IMG's and A's live in html namespace, so refer to them as html|img and html|a */ 12 | 13 | FictionBook { 14 | /* fixed width, centered */ 15 | width: 800px ; margin:0 auto !important; 16 | /* default font */ 17 | font: 13px Verdana; 18 | } 19 | 20 | /* Justify text */ 21 | p { text-align: justify; } 22 | 23 | /* Make titles special */ 24 | title {font-family: Trebuchet MS; font-weight:bold;} 25 | 26 | /* Make titles centered */ 27 | title, title p {text-align: center; } 28 | 29 | /* Make images centered */ 30 | FictionBook html|img {display: block; margin: 0 auto;} -------------------------------------------------------------------------------- /webext-src/css/fb2.css: -------------------------------------------------------------------------------- 1 | @namespace "http://www.gribuser.ru/xml/fictionbook/2.0"; 2 | 3 | FictionBook { 4 | display: block; 5 | padding: 2.5em; 6 | /* 7 | http://www.maxdesign.com.au/articles/em/ 8 | http://habrahabr.ru/blogs/personal/96770/ 9 | */ 10 | max-width: 45em; 11 | margin: 0 auto; 12 | } 13 | 14 | /* hide metadata */ 15 | description title-info > *, document-info, src-title-info, publish-info, custom-info, binary, stylesheet {display: none; } 16 | /* but show coverpage and the annotation */ 17 | coverpage, annotation {display:block !important;} 18 | 19 | annotation {margin: 0 0 0.4em 40%; font-size:smaller;} 20 | annotation > *:first-child {margin-top:0} 21 | 22 | /* those are blocky */ 23 | section, title, subtitle, p, cite, epigraph, poem, stanza, v, empty-line {display: block; } 24 | 25 | /* paragraphs */ 26 | p { text-align: justify; } 27 | /* browser-style, default */ 28 | p { margin: 1em 0; text-indent: 0; } 29 | 30 | empty-line {margin: 1em 0;} 31 | 32 | body > title {font-size: x-large; } 33 | title {font-size: large;} 34 | title p {margin: 0.3em 0;} 35 | title, title p, subtitle { 36 | text-align: center; text-indent: 0; 37 | } 38 | 39 | subtitle {font-weight:bold;} 40 | 41 | /* visuals */ 42 | emphasis {font-style: italic;} 43 | strong {font-weight:bold;} 44 | strikethrough { text-decoration: line-through; } 45 | sub {vertical-align: sub;font-size: xx-small;} 46 | sup {vertical-align: super;font-size: xx-small;} 47 | code {white-space: pre; font-family: monospace;} 48 | 49 | /* citations and epigraphs */ 50 | cite {border-left: 5px solid silver; background: #eee; padding: 0.4em 1em;} 51 | cite > p:first-child, cite > p:last-child {margin: 0;} 52 | 53 | text-author {margin-left: 5em; font-style: italic;} 54 | epigraph {margin-left: 50%;} 55 | epigraph text-author {margin-left: 0;} 56 | 57 | /* poems */ 58 | poem {margin-left: 10%} 59 | stanza {margin: 0.5em 0;} 60 | v {} 61 | 62 | table {display: table; border-collapse: collapse; margin: 0 auto;} 63 | tr {display: table-row;} 64 | td, th { 65 | display: table-cell; 66 | padding: 0.2em 0.5em; 67 | border: 1px solid silver; 68 | } 69 | th { font-weight: bold; } 70 | 71 | td[align="left"], th[align="left"] {text-align: left;} 72 | td[align="right"], th[align="right"] {text-align: right;} 73 | td[align="center"], th[align="center"] {text-align: center;} 74 | 75 | td[valign="top"], th[valign="top"] {vertical-align: top;} 76 | td[valign="middle"], th[valign="middle"] {vertical-align: middle;} 77 | td[valign="bottom"], th[valign="bottom"] {vertical-align: bottom;} 78 | 79 | /* notes */ 80 | body[name="notes"] {display:none;} 81 | 82 | a[type='note'] { 83 | background:#f5f5b5; 84 | position:relative; 85 | cursor: help; 86 | } 87 | a[type='note']:hover section {display:block; } 88 | a[type='note'] section { 89 | cursor: default; 90 | z-index:2; 91 | position: absolute; 92 | top:0.5em; left: 0.5em; 93 | display:none; 94 | background: #f5f5b5; 95 | border: 1px solid #baba45; 96 | border-radius: 4px; 97 | font-size: small; 98 | font-family: sans-serif; 99 | width: -moz-max-content; 100 | max-width: 20em; 101 | max-height:20em; 102 | overflow-y: auto; 103 | -moz-box-shadow: 2px 2px 3px silver; 104 | box-shadow: 2px 2px 3px silver; 105 | } 106 | a[type='note'] section p { 107 | margin: 0.1em 0.3em; 108 | text-align: left; 109 | text-indent: 0; 110 | } 111 | a[type='note'] section title { display:none; } 112 | a[type='note'] section[position_h='left'] { left:auto; right: 0.5em;} 113 | a[type='note'] section[position_v='up'] { top:auto; bottom: 0.5em;} 114 | -------------------------------------------------------------------------------- /webext-src/css/html.css: -------------------------------------------------------------------------------- 1 | @namespace "http://www.w3.org/1999/xhtml"; 2 | @namespace fb2 "http://www.gribuser.ru/xml/fictionbook/2.0"; 3 | 4 | * {margin: 0; padding: 0} 5 | img { 6 | display: block; margin: 0 auto; 7 | max-width: 100%; /* to fit into FictionBook */ 8 | } 9 | 10 | a:focus { outline: none } 11 | 12 | div#contents { 13 | z-index:3; 14 | background: cornsilk; 15 | border: 1px solid orange; 16 | border-left: 0; 17 | border-top: 0; 18 | position: fixed; 19 | top:0; 20 | left:0; 21 | font-family: sans-serif; 22 | width: -moz-max-content; 23 | max-width: 25em; 24 | -moz-border-radius-bottomright: 1em; 25 | border-bottom-right-radius: 1em; 26 | -moz-box-shadow: 2px 2px 3px silver; 27 | box-shadow: 2px 2px 3px silver; 28 | max-height:90%; 29 | overflow-y: auto; 30 | } 31 | div#contents > div { 32 | font-family: serif; 33 | font-size: 2em; 34 | color: #666; 35 | text-align: center; 36 | padding: 0.1em 0.25em 0.25em 0.25em; 37 | } 38 | div#contents:hover > div { 39 | display: none; 40 | } 41 | div#contents:hover li { 42 | display: block; 43 | } 44 | div#contents li { 45 | display: none; 46 | line-height: 95%; 47 | } 48 | /* sometimes images happen to be in titles, hide 'em */ 49 | div#contents img { display: none } 50 | 51 | div#contents fb2|* { 52 | font-size: small; 53 | text-align: left; 54 | display: inline; 55 | } 56 | div#contents a { 57 | color: black; 58 | text-decoration: none; 59 | padding: 0.2em 0.5em 0.2em 1em; 60 | display: block; 61 | } 62 | div#contents a:visited { color: black; } 63 | div#contents li a { padding-left: 1em; } 64 | div#contents li li a { padding-left: 2em; } 65 | div#contents li li li a { padding-left: 3em; } 66 | div#contents li li li li a { padding-left: 4em; } 67 | div#contents li li li li li a { padding-left: 5em; } 68 | div#contents a:hover { 69 | background: ivory; 70 | text-decoration: underline; 71 | } 72 | div#contents fb2|title fb2|a[type="note"]{ 73 | display:none; 74 | } 75 | -------------------------------------------------------------------------------- /webext-src/css/print.css: -------------------------------------------------------------------------------- 1 | @namespace "http://www.gribuser.ru/xml/fictionbook/2.0"; 2 | @namespace html "http://www.w3.org/1999/xhtml"; 3 | 4 | FictionBook { 5 | padding: 0; margin: 0; 6 | max-width: 100%; 7 | } 8 | 9 | html|div#contents {display: none;} 10 | -------------------------------------------------------------------------------- /webext-src/icons/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/webext-src/icons/icon-128.png -------------------------------------------------------------------------------- /webext-src/icons/icon-16-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/webext-src/icons/icon-16-2x.png -------------------------------------------------------------------------------- /webext-src/icons/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/webext-src/icons/icon-16.png -------------------------------------------------------------------------------- /webext-src/icons/icon-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/webext-src/icons/icon-24.png -------------------------------------------------------------------------------- /webext-src/icons/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/webext-src/icons/icon-32.png -------------------------------------------------------------------------------- /webext-src/icons/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/webext-src/icons/icon-48.png -------------------------------------------------------------------------------- /webext-src/icons/icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/webext-src/icons/icon-64.png -------------------------------------------------------------------------------- /webext-src/icons/icon-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tymofij/fb2reader/dcc7f98727c612fea37c2f79a0d1ae31943171ec/webext-src/icons/icon-96.png -------------------------------------------------------------------------------- /webext-src/local.js: -------------------------------------------------------------------------------- 1 | let txt_html_doc = ` 2 | 3 | 4 | Untitled Fb2 5 | 6 | 7 | 12 | 13 | 14 |
§
15 | 16 | ` 17 | 18 | let parser = new DOMParser(); 19 | let bookTree = document.documentElement 20 | let bookHTML = parser.parseFromString(txt_html_doc, 'application/xml'); 21 | 22 | let title_tags = bookTree.getElementsByTagName("book-title") 23 | if (title_tags.length != 0) { 24 | let title = title_tags[0].textContent; 25 | bookHTML.getElementsByTagName('title')[0].textContent = title; 26 | console.log("FB title found: " + title); 27 | } 28 | bookTree.appendChild(bookHTML.documentElement) 29 | fb2.init(document) 30 | -------------------------------------------------------------------------------- /webext-src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Read FB2 e-Books with Firefox", 3 | "manifest_version": 2, 4 | "name": "FB2 Reader", 5 | "version": "0.31", 6 | "homepage_url": "https://github.com/tymofij/fb2reader", 7 | "icons": { 8 | "16": "icons/icon-16.png", 9 | "24": "icons/icon-24.png", 10 | "32": "icons/icon-32.png", 11 | "48": "icons/icon-48.png", 12 | "64": "icons/icon-64.png", 13 | "96": "icons/icon-96.png", 14 | "128": "icons/icon-128.png" 15 | }, 16 | 17 | "permissions": [ 18 | "webRequest", "webRequestBlocking", 19 | "*://*/*.fb2*", 20 | "*://*/*.FB2*", 21 | "*://*/*.Fb2*", 22 | "*://*/*.fB2*" 23 | ], 24 | 25 | "background": { 26 | "scripts": ["jszip.js", "streamfilter.js"] 27 | }, 28 | 29 | "applications": { 30 | "gecko": { 31 | "id": "fb2reader@clear.com.ua", 32 | "strict_min_version": "57.0a1" 33 | } 34 | }, 35 | 36 | "content_scripts": [ 37 | { 38 | "matches": [ 39 | "file:///*.fb2", 40 | "file:///*.FB2", 41 | "file:///*.Fb2", 42 | "file:///*.fB2" 43 | ], 44 | 45 | "js": ["tools.js", "local.js"] 46 | } 47 | ], 48 | 49 | "web_accessible_resources": [ 50 | "icons/icon-16.png", 51 | "icons/icon-16-2x.png", 52 | "css/fb2.css", 53 | "css/html.css", 54 | "css/print.css", 55 | "tools.js" 56 | ] 57 | 58 | } 59 | -------------------------------------------------------------------------------- /webext-src/streamfilter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let txt_html_doc = ` 4 | 5 | 6 | Untitled Fb2 7 | 8 | 9 | 14 | 15 | 19 | 20 | 21 |
§
22 | 23 | ` 24 | const FB2_REGEX = /\.fb2(\.zip)?(#.*)?$/i 25 | 26 | browser.webRequest.onHeadersReceived.addListener( 27 | details => { 28 | if (details.statusCode != 200 || !details.url.match(FB2_REGEX)) { 29 | // do not attach body listeners to redirects and non-book urls 30 | return {} 31 | } 32 | removeHeader(details.responseHeaders, "Content-Disposition"); 33 | setHeader(details.responseHeaders, "Content-Type", "text/xml; charset=utf-8"); 34 | 35 | let decoder = new TextDecoder(); 36 | let encoder = new TextEncoder(); 37 | let parser = new DOMParser(); 38 | let serializer = new XMLSerializer(); 39 | 40 | let filter = browser.webRequest.filterResponseData(details.requestId); 41 | let received_data = new Uint8Array() 42 | 43 | filter.ondata = event => { 44 | console.log('ondata') 45 | let new_data = new Uint8Array(event.data) 46 | received_data = mergeTypedArrays(received_data, new_data) 47 | } 48 | 49 | filter.onstop = event => { 50 | console.log('onstop') 51 | if (received_data[0] == 80 && received_data[1] == 75){ // PK header 52 | console.log('PK header') 53 | let fb_zip = new JSZip(received_data); 54 | for (let filename in fb_zip.files){ 55 | if (filename.endsWith('.fb2')) { 56 | received_data = fb_zip.files[filename].asUint8Array() 57 | break; 58 | } 59 | } 60 | } 61 | // Try to detect the XML encoding if declared in the file 62 | let header = decoder.decode(received_data.slice(0,100)) 63 | let charset = 'utf-8' 64 | if (header.match(/ window.innerWidth - SCROLLBAR) 46 | note.setAttribute('position_h', 'left') 47 | if ( note.getBoundingClientRect().left < 0 ) 48 | note.setAttribute('position_h', '') 49 | 50 | // alters the note's box position_v to keep it on screen 51 | if ( note.getBoundingClientRect().bottom > window.innerHeight - SCROLLBAR) 52 | note.setAttribute('position_v', 'up') 53 | if ( note.getBoundingClientRect().top < 0 ) 54 | note.setAttribute('position_v', '') 55 | } 56 | }, 57 | 58 | init: function(doc) { 59 | // for each fb2 image we will create xHTML one 60 | var images = getElements(doc, "image") 61 | for ( var i=0 ; i < images.snapshotLength; i++ ) { 62 | try { // ignore malformed images 63 | var img = images.snapshotItem(i) 64 | // we get corresponding binary node 65 | var bin = getSingleElement(doc, "binary[@id='" + getHrefVal(img) + "']") 66 | // create xhtml image and set src to its base64 data 67 | var ximg = doc.createElementNS(HTML_NS, 'img') 68 | ximg.src='data:' + bin.getAttribute('content-type') + ';base64,' + bin.textContent 69 | img.parentNode.insertBefore(ximg, img) 70 | } catch(e) { 71 | console.log(e) 72 | } 73 | } 74 | 75 | // add listener to all footnote links 76 | var notelinks = getElements(doc, "a[@type='note']") 77 | for ( var i=0 ; i < notelinks.snapshotLength; i++ ) { 78 | var note = notelinks.snapshotItem(i) 79 | note.addEventListener("mouseover", fb2.tooltip, true) 80 | } 81 | 82 | // build index 83 | var body = getSingleElement(doc, "body[@name!='notes' or not(@name)]") 84 | var div = doc.getElementById('contents') 85 | var ul = doc.createElementNS(HTML_NS, 'ul') 86 | div.appendChild(ul) 87 | 88 | var title_counter = 1; 89 | var walk_sections = function(start, ul) { 90 | var sections = doc.evaluate("./fb2:section", start, 91 | nsResolver, 92 | XPathResult.ORDERED_NODE_SNAPSHOT_TYPE , null 93 | ); 94 | for ( var i=0 ; i < sections.snapshotLength; i++ ) { 95 | var section = sections.snapshotItem(i) 96 | var title = doc.evaluate("./fb2:title", section, 97 | nsResolver, 98 | XPathResult.FIRST_ORDERED_NODE_TYPE, null 99 | ).singleNodeValue; 100 | if (title) { 101 | var title_copy = title.cloneNode(true) 102 | 103 | // cleanse ids of copied intitle elements 104 | var kids = doc.evaluate("//fb2:*", title_copy, 105 | nsResolver, 106 | XPathResult.ORDERED_NODE_SNAPSHOT_TYPE , null 107 | ); 108 | for(var j=0; j