diff --git a/extension/fimfic2epub-logo.png b/extension/fimfic2epub-logo.png new file mode 100644 index 0000000..0288cf2 Binary files /dev/null and b/extension/fimfic2epub-logo.png differ diff --git a/extension/inject.css b/extension/inject.css new file mode 100644 index 0000000..e3bd63b --- /dev/null +++ b/extension/inject.css @@ -0,0 +1,13 @@ + +#epubDialogContainer .drop-down-pop-up-container { + position: fixed; + top: 0; + left: 0; + z-index: 1001; +} +#epubDialogContainer .drop-down-pop-up-container .drop-down-pop-up { + width: 500px; +} +#epubDialogContainer .drop-down-pop-up-container .drop-down-pop-up h1 { + cursor: move; +} diff --git a/extension/manifest.json b/extension/manifest.json index fcdc3cc..44ff48b 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -18,9 +18,15 @@ "content_scripts": [ { "matches": ["https://www.fimfiction.net/story/*", "http://www.fimfiction.net/story/*"], - "js": ["fimfic2epub.js"] + "js": ["fimfic2epub.js"], + "css": ["inject.css"] } ], + + "page_action": { + "default_icon": "fimfic2epub-logo.png" + }, + "permissions": [ "http://*/*", "https://*/*" diff --git a/src/eventPage.js b/src/eventPage.js index 444bcf3..71b7558 100644 --- a/src/eventPage.js +++ b/src/eventPage.js @@ -18,9 +18,18 @@ if (typeof safari !== 'undefined') { let onMessage = chrome.extension.onMessage ? chrome.extension.onMessage : chrome.runtime.onMessage onMessage.addListener(function (request, sender, sendResponse) { - fetch(request, (blob, type) => { - sendResponse(URL.createObjectURL(blob), type) - }, 'blob') - return true + if (typeof request === 'string') { + fetch(request, (blob, type) => { + sendResponse(URL.createObjectURL(blob), type) + }, 'blob') + // required for async + return true + } else if (request.showPageAction) { + chrome.pageAction.show(sender.tab.id) + } + }) + + chrome.pageAction.onClicked.addListener(function (tab) { + chrome.tabs.sendMessage(tab.id, 'pageAction') }) } diff --git a/src/main.js b/src/main.js index 4af48f6..99a785c 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,8 @@ +/* global chrome */ +'use strict' import FimFic2Epub from './FimFic2Epub' +import m from 'mithril' import { saveAs } from 'file-saver' function blobToDataURL (blob, callback) { @@ -8,27 +11,108 @@ function blobToDataURL (blob, callback) { a.readAsDataURL(blob) } +const isChromeExt = typeof chrome !== 'undefined' + const STORY_ID = document.location.pathname.match(/^\/story\/(\d*)/)[1] -const ffc = new FimFic2Epub(STORY_ID) +let ffc const epubButton = document.querySelector('.story_container ul.chapters li.bottom a[title="Download Story (.epub)"]') +const dialogContainer = document.createElement('div') +dialogContainer.id = 'epubDialogContainer' +document.body.appendChild(dialogContainer) + +let checkbox = { + view: function (ctrl, args, text) { + return m('label.toggleable-switch', [ + m('input', {type: 'checkbox', name: args.name, checked: args.checked}), + m('a'), + text + ]) + } +} + +let dialog = { + controller (args) { + this.dragging = m.prop(false) + this.xpos = m.prop(100) + this.ypos = m.prop(100) + this.el = m.prop(null) + this.ondown = (e) => { + let el = this.el().firstChild + let rect = el.getBoundingClientRect() + let offset = {x: e.pageX - rect.left, y: e.pageY - rect.top} + this.dragging(true) + let onmove = (e) => { + e.preventDefault() + if (this.dragging()) { + let rect = el.getBoundingClientRect() + this.xpos(Math.max(0, Math.min(e.pageX - offset.x, window.innerWidth - rect.width))) + this.ypos(Math.max(0, Math.min(e.pageY - offset.y, window.innerHeight - rect.height))) + // console.log(e.pageX, e.pageY) + m.redraw() + } + } + let onup = () => { + this.dragging(false) + window.removeEventListener('mousemove', onmove) + window.removeEventListener('mouseup', onup) + } + window.addEventListener('mousemove', onmove, false) + window.addEventListener('mouseup', onup, false) + } + }, + view (ctrl, args, extras) { + return m('.drop-down-pop-up-container', {config: ctrl.el, style: {left: ctrl.xpos() + 'px', top: ctrl.ypos() + 'px'}}, m('.drop-down-pop-up', [ + m('h1', {onmousedown: ctrl.ondown}, m('i.fa.fa-book'), 'Export EPUB', m('a.close_button', {onclick: closeDialog})), + m('.drop-down-pop-up-content', [ + m(checkbox, {name: 'toggle-chapter-headings'}, 'Toggle chapter headings') + ]) + ])) + } +} + +function openDialog (args, extras) { + m.mount(dialogContainer, m(dialog, args, extras)) +} +function closeDialog () { + m.mount(dialogContainer, null) +} + +function clickButton () { + if (!STORY_ID) return + if (!ffc) ffc = new FimFic2Epub(STORY_ID) + + openDialog() + + return + + ffc.download().then(ffc.getFile.bind(ffc)).then((file) => { + console.log('Saving file...') + if (typeof safari !== 'undefined') { + blobToDataURL(file, (dataurl) => { + document.location.href = dataurl + alert('Add .epub to the filename of the downloaded file') + }) + } else { + saveAs(file, ffc.filename) + } + }) +} + if (epubButton) { + if (isChromeExt) { + chrome.runtime.sendMessage({showPageAction: true}) + chrome.runtime.onMessage.addListener(function (request) { + if (request === 'pageAction') { + clickButton() + } + }) + } + epubButton.addEventListener('click', function (e) { e.preventDefault() - ffc.download().then(() => { - ffc.getFile().then((file) => { - console.log('Saving file...') - if (typeof safari !== 'undefined') { - blobToDataURL(file, (dataurl) => { - document.location.href = dataurl - alert('Add .epub to the filename of the downloaded file') - }) - } else { - saveAs(file, ffc.filename) - } - }) - }) + clickButton() }, false) }