// ==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='
';
}
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