// ==UserScript== // @version 1.9.0 // @include *.fanfiction.net/s/* // @namespace ffnet // @name Fanfiction.net story export script. // @author Alssn // @description Writes all chapters of the story on one page. // @require http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js // @grant GM.setClipboard // @grant GM_xmlhttpRequest // @connect fanfiction.net // @downloadURL none // ==/UserScript== //Chapters are downloaded with a delay to prevent ff.net from limiting connections var delay = 500; var chapters=[]; var style = $(""); $('body').append(style); function addButtons(){ // Adding buttons let res = document.getElementById('f_size'); // creating links var node = $('.lc').first(); var exportMenu = $('fE'); var exportContainer = $(''); var addIndexButton = $('Index'); var expAllButton = $('Story'); var expRestButton = $('Rest'); var expButton = $('Text'); var headersSwitch = $('Add headers '); var delayInput = $('Delay '); var copyButton = $('Copy'); exportMenu.append(exportContainer); exportContainer.append(expAllButton,expRestButton, headersSwitch, delayInput,'| ',addIndexButton,'| ',expButton, copyButton); node.append(exportMenu); expAllButton.click(exportChapters); expRestButton.click(exportRest); expButton.click(exportCh); addIndexButton.click(addIndex); copyButton.click(copyText); $('#ffne_button').click(function(){ var cont = $('#ffne_export'); if (cont.hasClass('ffne_hidden')){cont.removeClass('ffne_hidden');}else{cont.addClass('ffne_hidden')} }); } //Adding buttons to page; addButtons(); //Adding table of contents function addIndex(){ var chapters = $('div[name="ffnee_chapter"]'); var index = $('

Table of contents

'); var toC = $('
    '); index.append(toC); for (var i=0;i'+item.attr('title')+'')); } $('#storytext').prepend(index); } //adding headers, as entered by author function addHeaders(){ var chapters = document.getElementsByName('ffnee_chapter'); for (var i=0;i'; item.insertBefore(header,item.firstChild); } } function addTitle(){ var titleText = $('b.xcontrast_txt','#profile_top').first().html(); var title = $('

    '+titleText+'

    '); var authorText = $('a.xcontrast_txt[href^="/u/"]','#profile_top').first().html(); var author = $('

    '+authorText+'

    '); var storytext = $('#storytext'); storytext.prepend(title, author); } function exportCh(){ document.body.innerHTML='
    '+document.getElementById('storytextp').innerHTML+'
    '; } function copyText(){ GM.setClipboard(document.getElementById('storytextp').innerText); } function exportRest(e){ var chap_select = document.getElementById('chap_select'); console.log('exporting rest'); exportChapters(e,chap_select.value-1); } function exportChapters(e,start,end){ // Main actions // Progress indicator delay = document.getElementById('ffneInputDelay').value; var expDiv = document.getElementById('exportAllButton'); var expText = expDiv.childNodes[0]; var hr=location.href; var chapterNumIndex=hr.search(/\/\d{1,3}\//); //Getting number of chapters var storyLength=getLength(); if (storyLength == 1){ expText.nodeValue = 'Oneshot'; return; } if (start==undefined){ start=0; } if (end==undefined){ end=storyLength; } storyLength = end-start; let i = start; var totalStoryLength = storyLength;//reference console.log('retrieving '+totalStoryLength+' chapters'); console.log('start index is: '+start+', end is: '+end); setTimeout(function tick(){ console.log(`Starting to load chapter ${i}`); loadChapter(i+1,function(response,num){ console.log('Loaded chapter '+num); chapters[num]=parseChapter(response, num+1); expText.nodeValue = 'Export: Chapter '+String(totalStoryLength-storyLength+1)+' out of '+totalStoryLength; storyLength--; if (storyLength==0){ console.log(chapters); parseStory(chapters); expText.nodeValue='Story (again)'; } }); i++; if (i