There are 12 previous versions of this script.
// ==UserScript== // @version 1.3.6 // @include http://www.fanfiction.net/s/* // @namespace ffnet // @name Fanfiction.net story export script. // @author Alssn // @description Writes all chapters of the story on one page. // @changes Compatibility with Chrome,removed "Share" from chapter text // ==/UserScript== function find(expr) { var posts = document.evaluate(expr, document, null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var postsArray = new Array(); for (var i = 0; i < posts.snapshotLength; ++i) { postsArray.push(posts.snapshotItem(i)); } return postsArray; } function addButtons(){ // Adding buttons res = find("//table[@style]"); for (var i in res){ var tC=res[i].textContent; if (tC.indexOf('B s')>=0){ //creating links var addHeadersButton=document.createElement('a'); addHeadersButton.href='javascript:'; addHeadersButton.innerHTML='Headers'; addHeadersButton.setAttribute('title','Add header to each chapter'); var addIndexButton=document.createElement('a'); addIndexButton.href='javascript:'; addIndexButton.innerHTML='Index'; addIndexButton.setAttribute('title','Create table of contents'); var expAllButton=document.createElement('a'); expAllButton.id='exportAllButton'; expAllButton.href='javascript:'; expAllButton.setAttribute('title','Show the whole story on one page'); expAllButton.innerHTML='Story'; var expButton=document.createElement('a'); expButton.setAttribute('title','Show only text'); expButton.href='javascript:'; expButton.innerHTML='Text'; // Adding listeners - that's the only way to do something after main code finsihed working; expAllButton.addEventListener('click',exportAll,false); expButton.addEventListener('click',exportCh,false); addHeadersButton.addEventListener('click',addHeaders,false); addIndexButton.addEventListener('click',addIndex,false); //fE and fA var e = document.createElement('span'); e.setAttribute('style','font-family: serif;font-weight:bolder;color:#61a4e4'); e.setAttribute('title','Export'); e.innerHTML = "fE: "; var a = document.createElement('span'); a.setAttribute('title','Add'); a.setAttribute('style','font-family: serif;font-weight:bolder;color:#61a4e4'); a.innerHTML = "fA: "; insertNode = res[i].children[0].children[0] insertNode.insertBefore(document.createTextNode(' '),insertNode.firstChild); insertNode.insertBefore(addIndexButton,insertNode.firstChild); insertNode.insertBefore(document.createTextNode(' '),insertNode.firstChild); insertNode.insertBefore(addHeadersButton,insertNode.firstChild); insertNode.insertBefore(a,insertNode.firstChild); insertNode.insertBefore(document.createTextNode(' '),insertNode.firstChild); insertNode.insertBefore(expButton,insertNode.firstChild); insertNode.insertBefore(document.createTextNode(' '),insertNode.firstChild); insertNode.insertBefore(expAllButton,insertNode.firstChild); insertNode.insertBefore(e,insertNode.firstChild); } } } //Adding buttons to page; addButtons(); //Adding table of contents function addIndex(){ var storytext = document.getElementById('storytext'); //Point of insert var chapters = document.getElementsByName('ffnee_chapter'); //Creating base structure var index = document.createElement('div'); index.innerHTML = '<h2>Table of contents</h2>'; index.setAttribute('id','ffnee_index'); var toC = document.createElement('ol'); index.appendChild(toC); //Processing chapters for (var i=0;i<chapters.length;i++){ var item = chapters.item(i); //chapter we are currently processing var id = item.getAttribute('id'); var entry = document.createElement('li'); //Entry corresponding to the chapter in ToC entry.innerHTML = '<a href="#'+id+'">'+item.getAttribute('title')+'</a>'; toC.appendChild(entry); } storytext.insertBefore(index,storytext.firstChild); } //adding headers, as entered by author function addHeaders(){ var chapters = document.getElementsByName('ffnee_chapter'); for (var i=0;i<chapters.length;i++){ var item = chapters.item(i); //chapter to which we are adding a header var header = document.createElement('p'); header.innerHTML = '<h2>Chapter '+(i+1)+': '+item.getAttribute('title')+'</h2>'; item.insertBefore(header,item.firstChild); } } function exportCh(){ document.body.innerHTML='<div style=\'padding-left:2em;padding-right:2em;padding-top:1em;\'>'+document.getElementById('storytextp').innerHTML+'</div>'; //Sadly, it is not possible to automatically copy text to clipboard in firefox without changing browser settings; } function exportAll(){ // Main actions var expDiv = document.getElementById('exportAllButton'); // Progress indicator var expText = expDiv.childNodes[0]; var chapters = new Array(); 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; } var totalStoryLength = storyLength;//reference //launching retrieving of all chapters simultaneously for (var i=1;i<=storyLength;i++){ loadChapter(i); } //Functions // Converting chapters' array into a whole; function parseStory(){ var numCh= chapters.length; //document.body.innerHTML=chapters[0]; var appendNode=document.getElementById('storytext'); appendNode.innerHTML= ''; for (var i=0;i<numCh;i++){ //findHeader(chapters[i]); //smart header search var st=chapters[i]; st.setAttribute('name','ffnee_chapter'); st.setAttribute('id','ffnee_ch'+i); if (i!=0){ st.style.marginTop='10em'; } appendNode.appendChild(st); } expText.nodeValue='story(re)'; } // Getting number of chapters; function getLength(){ var chNum=document.evaluate('//SELECT[@title=\'chapter navigation\']',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); if (chNum.snapshotLength>0){ var numChapters = chNum.snapshotItem(0).length; }else{ numChapters = 1; } return (numChapters); } // This function loads chapters and extracts chapter's number and title function loadChapter(num){ var replStr='\/'+String(num)+'\/'; var currentURL=hr.replace(/\/\d{1,3}\//,replStr); GM_xmlhttpRequest({ //Internal Greesemonkey function - main reason this couldn't work as a bookmarklet. method: 'GET', url: currentURL, onload: function(responseDetails) { parseChapter(responseDetails.responseText, num); storyLength--; if (storyLength==0){ parseStory(); } } }); } function parseChapter(chapterHtml, chapterNumber){ var t=document.createElement('div'); t.innerHTML=chapterHtml; //extracting text only var ev='.//div[@id=\'storytext\']'; var xpathResult = document.evaluate(ev,t,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var chapterContent=document.createElement('div'); chapterContent.setAttribute('title',getChapterName(t)); chapterContent.innerHTML = xpathResult.snapshotItem(0).innerHTML; chapterContent.removeChild(chapterContent.firstChild); chapterContent.removeChild(chapterContent.firstChild); chapters[chapterNumber-1]=chapterContent; expText.nodeValue = 'Export: Chapter '+String(totalStoryLength-storyLength+1)+' out of '+totalStoryLength; function getChapterName(obj){ var select = obj.getElementsByTagName('select')[1].getElementsByTagName('option');
0 comments:
Post a Comment