FanFictionNavigator

Mark and hide fanfics or authors

目前為 2018-10-04 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        FanFictionNavigator
// @name:ru     FanFictionNavigator
// @namespace   window
// @description:en  Mark and hide fanfics or authors
// @description:ru  Выделяет цветом/скрывает фанфики или авторов
// @include     https://ficbook.net/*
// @include     https://www.fanfiction.net/*
// @include     https://archiveofourown.org/*
// @include     http://archiveofourown.org/*
// @include     https://tbooklist.org/*
// @run-at      document-end

// @require     https://code.jquery.com/jquery-1.7.2.min.js
// @require     https://greasyfork.org/scripts/17419-underscore-js-1-8-3/code/Underscorejs%20183.js?version=109803
// @version     34
// @grant       GM_addStyle
// @description Mark and hide fanfics or authors
// ==/UserScript==

// Based on https://chrome.google.com/webstore/detail/fanfiction-organizer/adlnghnicfngjnofbljedmclmdoepcbe
// by Stefan Hayden

// Fics:
const FIC_LIKED = 0;
const FIC_DISLIKED = 1;
const FIC_MARKED = 2;
const FIC_INLIBRARY = 3;

// Authors:
const AUTHOR_LIKED = 0;
const AUTHOR_DISLIKED = 1;

// colors. now used for like/dislike/etc links
const COLOR_LIKED = '#C4FFCA';
const COLOR_DISLIKED = '#FCB0B0';
const COLOR_MARKED = '#CCCCCC';
const COLOR_INLIBRARY = '#F1D173';
const COLOR_CLEARED = '#FFF';
const COLOR_FB_CLEAR = '#FFF';


// styles for author/story links; <a> links should have only one of these so order doesn't matter
GM_addStyle("a.ffn_dislike_fic {text-decoration: line-through; font-weight: bold;}");
GM_addStyle("a.ffn_like_fic {font-weight: bold;} ");
GM_addStyle("a.ffn_dislike_author {text-decoration: line-through; font-weight: bold;}");
GM_addStyle("a.ffn_like_author {font-weight: bold;} ");
GM_addStyle("a.ffn_mark {font-weight: bold;}");
GM_addStyle("a.ffn_inlibrary {font-weight: bold;}");

// styles for box background; fic style should overwrite author style
GM_addStyle(".ffn_like_author:not(a) {background-color:#C4FFCA !important;}");
GM_addStyle(".ffn_dislike_author:not(a) {background-color:#FCB0B0 !important;}");
GM_addStyle(".ffn_like_fic:not(a) {background-color:#C4FFCA !important;}");
GM_addStyle(".ffn_dislike_fic:not(a) {background-color:#FCB0B0 !important;}");
GM_addStyle(".ffn_mark:not(a) {background-color:#CCCCCC !important;}");
GM_addStyle(".ffn_inlibrary:not(a) {background-color:#F1D173 !important;}");



// styles for boxes, they differ between sites

/*
switch(window.location.hostname){
case "www.fanfiction.net":
case "tbooklist.org":
    GM_addStyle("div.ffn_dislike {background-color:#FCB0B0 !important;}");
    GM_addStyle("div.ffn_like {background-color:#C4FFCA !important;}");
    GM_addStyle("div.ffn_mark {background-color:#CCCCCC !important;}");
    GM_addStyle("div.ffn_inlibrary {background-color:#F1D173 !important;}");
break
case "archiveofourown.org":
    GM_addStyle(".ffn_dislike {background-color:#FCB0B0 !important;}");
    GM_addStyle(".ffn_like {background-color:#C4FFCA !important;}");
    GM_addStyle(".ffn_mark {background-color:#CCCCCC !important;}");
    GM_addStyle(".ffn_inlibrary {background-color:#F1D173 !important;}");
break
case "ficbook.net":
    GM_addStyle("div.ffn_dislike {background-color:#FCB0B0 !important;}");
    GM_addStyle("div.ffn_like {background-color:#C4FFCA !important;}");
    GM_addStyle("div.ffn_mark {background-color:#CCCCCC !important;}");
    GM_addStyle("div.ffn_inlibrary {background-color:#F1D173 !important;}");
    GM_addStyle("ul.ffn_dislike {background-color:#FCB0B0 !important;}");
    GM_addStyle("ul.ffn_like {background-color:#C4FFCA !important;}");
    GM_addStyle("ul.ffn_mark {background-color:#CCCCCC !important;}");
    GM_addStyle("ul.ffn_inlibrary {background-color:#F1D173 !important;}");
break
}
*/

// prevent conflicts with websites' jQuery version
this.ffn$ = this.jQuery = jQuery.noConflict(true);


var db = JSON.parse(localStorage.getItem("FFLikerAA") || '{}');
db.options = db.options || {};
db.version = db.version || '0.2';


//
// APP
//

// Main
var Application = function Application(optionsin) {
	var a = {};
	var options = optionsin || {};

	if(!options.namespace) { throw new Error("namespace is required"); }
	if(!options.db) { throw new Error("database object is required"); }

	a.namespace = options.namespace;
	var db = options.db;
	db[a.namespace] = db[a.namespace] || { fic: {}, author:{} };

	a.collection = [];

	a.color = {
		link_default: ffn$("ol.work.index.group > li:first a:first").css("color"),
		like_link:'',
		like_background:'',
		dislike_link:'',
		dislike_background:'',
	};

	a.save = function(type,id,value){
		if(type == "fic" || type == "author") {
			a.saveNameSpaced(type,id,value);
		} else {
			if(value === "clear") {
				delete db[type][id];
			} else {
				db[type][id] = value;
			}
			localStorage.setItem("FFLikerAA", JSON.stringify(db));
		}
	};

	a.saveNameSpaced = function(type,id,value){
		if(value === "clear") {
			delete db[a.namespace][type][id];
		} else {
			db[a.namespace][type][id] = value;
		}
		localStorage.setItem("FFLikerAA", JSON.stringify(db));
	};


	a.author = {};

		a.author.get = function(id){
			return db[a.namespace].author[id];
		};

		a.author.like = function(id) {
			a.save("author",id,AUTHOR_LIKED);

			_.each(a.author.getFics(id), function(story){
				story.author = AUTHOR_LIKED;
				story.like_author();
			});
		};

		a.author.dislike = function(id) {
			a.save("author",id,AUTHOR_DISLIKED);
			//ga('set', 'metric3', 1);

			_.each(a.author.getFics(id), function(story){
				story.author = AUTHOR_DISLIKED;
				story.dislike_author();
			});
		};

		a.author.clear = function(id) {
			a.save("author",id,"clear");

			_.each(a.author.getFics(id), function(story){
				story.author = '';
				story.clear_author();
			});
		};

		a.author.getFics = function(id) {
			return _.filter(a.collection,function(story){
				return story.authorId() == id;
			});
		};

	a.fic = {};

		a.fic.get = function(id) {
			return db[a.namespace].fic[id];
		};

		a.fic.like = function(id) {
			a.save("fic",id,FIC_LIKED);

			var story = _.find(a.collection,function(story){
				return story.ficId() == id;
			});

			story.fic = FIC_LIKED;
			story.like_story();
		};

		a.fic.dislike = function(id) {
			a.save("fic",id,FIC_DISLIKED);
			var story = _.find(a.collection,function(story){
				return story.ficId() == id;
			});
			story.fic = FIC_DISLIKED;
			story.dislike_story();
		};

        a.fic.mark = function(id) {
            a.save("fic",id,FIC_MARKED);
            var story = _.find(a.collection,function(story){
				return story.ficId() == id;
			});
            story.fic = FIC_MARKED;
            story.mark_story();
        };

        a.fic.inlibrary = function(id) {
            a.save("fic",id,FIC_INLIBRARY);
            var story = _.find(a.collection,function(story){
				return story.ficId() == id;
			});
            story.fic = FIC_INLIBRARY;
            story.inlibrary_story();
        };


		a.fic.clear = function(id) {
			a.save("fic",id,"clear");
			var story = _.find(a.collection,function(story){
				return story.ficId() == id;
			});
			story.fic = '';
			story.clear_story();
		};

	a.options = function(name, value) {

		if(!name) { throw new Error("name is required. what option are you looking for?"); }

		if(typeof value !== "undefined") {
			a.save("options",name,value);
			return false;
		} else {
			return db.options[name];
		}
	};

	return a;
};

var Story = function(optionsin) {

	var a = {};
	var options  = optionsin || {};

	if(!options.instance) { throw new Error("instance of this is required"); }
	if(!options.namespace) { throw new Error("namespace is required"); }

	var _this = ffn$(options.instance);

	a["default"] = {
		template: function() {
			var template =	'<div class="new_like_actions" style="margin:0px 0px 0px 20px; font-size:11px;">'+

								'Story: <a href="" class="like_story"><font color="'+COLOR_LIKED+'">Like</font></a> | '+
								'<a href="" class="dislike_story"><font color="'+COLOR_DISLIKED+'">Dislike</font></a> | '+
    							'<a href="" class="mark_story"><font color="'+COLOR_MARKED+'">Mark</font></a> | '+
    							'<a href="" class="inlibrary_story"><font color="'+COLOR_INLIBRARY+'">InLibrary</font></a> | '+
								'<a href="" class="clear_story" style="color:blue;">Clear</a>'+

								'   Author: <a href="" class="like_author" style="color:blue;">Like</a> | '+
								'<a href="" class="dislike_author" style="color:blue;">Dislike</a> | '+
								'<a href="" class="clear_author" style="color:blue;">Clear</a>'+

							'</div>';
			return template;
		},
		addActions: function() {
			var instance = this;
			_this.append(this.template());

			_this.find('.new_like_actions .like_author').click(function(){ app.author.like(instance.authorId()); return false; });
			_this.find('.new_like_actions .dislike_author').click(function(){ app.author.dislike(instance.authorId()); return false; });
			_this.find('.new_like_actions .clear_author').click(function(){ app.author.clear(instance.authorId()); return false; });

			_this.find('.new_like_actions .like_story').click(function(){ app.fic.like(instance.ficId()); return false; });
			_this.find('.new_like_actions .dislike_story').click(function(){ app.fic.dislike(instance.ficId()); return false; });
    		_this.find('.new_like_actions .mark_story').click(function(){ app.fic.mark(instance.ficId()); return false; });
    		_this.find('.new_like_actions .inlibrary_story').click(function(){ app.fic.inlibrary(instance.ficId()); return false; });
			_this.find('.new_like_actions .clear_story').click(function(){ app.fic.clear(instance.ficId()); return false; });
		},
		hide: function() {
			_this.hide();
		},
		set_story: function(){
            switch(this.fic){
            case FIC_LIKED:
//    			_this.css('background-color',COLOR_LIKED);
//				this.$fic.css('font-weight','900')
				_this.addClass("ffn_like_fic");
				this.$fic.addClass("ffn_like_fic");
                break;
			case FIC_DISLIKED:
    			_this.addClass("ffn_dislike_fic");
				this.$fic.addClass("ffn_dislike_fic");
                break;
            case FIC_MARKED:
    			_this.addClass("ffn_mark");
				this.$fic.addClass("ffn_mark");
                break;
            case FIC_INLIBRARY:
    			_this.addClass("ffn_inlibrary");
				this.$fic.addClass("ffn_inlibrary");
                break;
			}
		},
		set_author: function() {
			if(this.author === AUTHOR_LIKED) {
				this.$author.addClass("ffn_like_author");
					_this.addClass("ffn_like_author");
			}
			if(this.author === AUTHOR_DISLIKED) {
				this.$author.addClass("ffn_dislike_author");
				_this.addClass("ffn_dislike_author");
			}
		},
     	like_story: function(){
        this.clear_story();
        _this.addClass("ffn_like_fic");
        this.$fic.addClass("ffn_like_fic");
		},
		  dislike_story: function(){
        this.clear_story();
        _this.addClass("ffn_dislike_fic");
        this.$fic.addClass("ffn_dislike_fic");
		},
    	mark_story: function(){
        this.clear_story();
    		_this.addClass("ffn_mark");
        this.$fic.addClass("ffn_mark");
		},
      inlibrary_story: function(){
        this.clear_story();
    		_this.addClass("ffn_inlibrary");
        this.$fic.addClass("ffn_inlibrary");
		},
  	  clear_story: function(){
        _this.removeClass("ffn_like_fic ffn_dislike_fic ffn_mark ffn_inlibrary");
        this.$fic.removeClass("ffn_like_fic ffn_dislike_fic ffn_mark ffn_inlibrary");

		},
		like_author: function(){
        this.clear_author();
			  this.$author.addClass("ffn_like_author");
        _this.addClass("ffn_like_author");
		},
		dislike_author: function(){
        this.clear_author();
			  this.$author.addClass("ffn_dislike_author");
        _this.addClass("ffn_dislike_author");
		},
    	clear_author: function(){
        _this.removeClass("ffn_like_author ffn_dislike_author");
        this.$author.removeClass("ffn_like_author ffn_dislike_author");
		}
	};

// Specific sites overrides

	a["www.fanfiction.net"] = {
		$author: _this.find('a[href^="/u"]:first'),
		$fic: _this.find('a[href^="/s"]:first'),
		authorId: function() {
            if (typeof this.$author.attr('href') === "undefined") {
                return window.location.pathname.split("/")[2];
            } else {
        		return this.$author.attr('href').split('/')[2];
            }
        },
		ficId: function() {
            if (this.$fic.length === 0) {
                return window.location.pathname.split("/")[2];
            } else {
                return this.$fic.attr('href').split('/')[2];
            }
		},
    	hide: function() {
            // do not hide story header on reading page and story block on author page
            if (! window.location.pathname.split("/")[1].match("^s$|^u$")) _this.hide();
		}
	};

//

	a["archiveofourown.org"] = {
    	$author: _this.find('a[href^="/users/"]:first'),
		$fic: _this.find('a[href^="/works/"]:first'),
		authorId: function() {
			// old: return this.$author.attr('href').split('/')[2];
            // Contributed by Vannis:
            if (this.$author.length === 0) {
                return 0;
            } else {
                return this.$author.attr('href').split('/')[2];
            }
		},
        ficId: function() {
            if (this.$fic.length === 0) {
                return window.location.pathname.split("/")[2];
            } else {
                return this.$fic.attr('href').split('/')[2];
            }
		},
        hide:function(){
            if (window.location.pathname.split("/")[3]!=="chapters") {
                _this.hide();
            }
        }
	};

//

    a["ficbook.net"] = {
        $author: _this.find('a[href^="/authors"]:first'),
        $fic: _this.find('a[href^="/readfic"]:first'),
		authorId: function() {
			return this.$author.attr('href').split('/')[2];
		},
        ficId: function() {
            if (this.$fic.length === 0) {
                return window.location.pathname.split("/")[2].replace(/(\d+).*?$/,"$1");
            } else {
                return this.$fic.attr('href').split('/')[2].replace(/(\d+).*?$/,"$1");
            }
		},
        hide:function(){

            if (window.location.pathname.split("/")[1]!=="readfic" && window.location.pathname.split("/")[2]!=="favourites") {
                _this.parent().hide();
            }
        }
	};

    a["tbooklist.org"] = {
        $author: _this.find('a[href^="https://tbooklist.org/authors"]:first'),
        $fic: _this.find('a[href*="https://tbooklist.org/books"]:first'),
     	  authorId: function() {
            if (this.$author.length === 0) {
                return 0;
            } else {
                return this.$author.attr('href').trim().split('/')[4];
            }
		},
        ficId: function() {
            if (window.location.pathname.split("/")[1] === "books") {

                return window.location.pathname.trim().split("/")[2];
            }
            if (this.$fic.length === 0) {
                return 0;
            } else {
                return this.$fic.attr('href').trim().split('/')[4];
            }
		},
        hide:function(){
            // do not hide when viewing fanfic details
            if(window.location.pathname.split("/")[1] !== "books") {
                _this.hide();
            }
        }
	};

	var b = ffn$.extend({}, a["default"], a[options.namespace]);
	b.fic = app.fic.get(b.ficId());

	b.author = app.author.get(b.authorId());
    // do not show liker links if ficid or authorid are undefined (tweak for tbooklist.org)
    if (b.ficId() !== 0 && b.authorId() !== 0) {
    	b.addActions();
    }
	b.set_story();
	b.set_author();

	//hide
	if((app.options("hide_dislikes") === true && (b.fic === FIC_DISLIKED || b.author === AUTHOR_DISLIKED)) ||
       (app.options("hide_likes") === true && (b.fic === FIC_LIKED || b.author === AUTHOR_LIKED)) ||
       (app.options("hide_marked") === true && b.fic === FIC_MARKED) ||
       (app.options("hide_inlibrary") === true && b.fic === FIC_INLIBRARY)){
//		if(b.fic !== true && b.author) { // for liked fics of disliked authors
			b.hide();
//		}
	}
	return b;
};


var app  = new Application({namespace:document.location.host, db: db});

// Adding action links and navigation shortcuts to pages
switch(window.location.hostname){
    case "www.fanfiction.net":
        // adding hotkeys
        // added toggle option, suggested by Vannius
        if (app.options("enable_list_hotkeys")) {
            document.addEventListener('keydown', function(e){
                switch (e.keyCode){
                    case 37:
                        var Prev = ffn$("a:contains('« Prev')");
                        if (typeof(Prev[0])!=='undefined') {Prev[0].click();}
                        break;
                    case 39:
                        var Next = ffn$("a:contains('Next »')");
                        if (typeof(Next[0])!=='undefined') {Next[0].click();}
                        break;
                }
            }, false);
        }
        if (app.options("enable_read_hotkeys")) {
            document.addEventListener('keydown', function(e){
            console.log("enale_read_hk");
                switch (e.keyCode){
                    case 37:
                        var Prev = ffn$("button:contains('< Prev')");
                        if (typeof(Prev[0])!=='undefined') {Prev.click();}
                        break;
                    case 39:
                        var Next = ffn$("button:contains('Next >')");
                        if (typeof(Next[0])!=='undefined') {Next.click();}
                        break;
                }
            }, false);
        }
        // links in list
        ffn$(".z-list").each(function(){
            var story = new Story({ namespace: app.namespace, instance: this });
            app.collection.push(story);
        });

        // links on reading page
        ffn$("div#profile_top").each(function(){
            var story = new Story({ namespace: app.namespace, instance: this });
            app.collection.push(story);
        });

        // hide/show options
        ffn$('div#content_wrapper_inner').after(
            '<div class="liker_script_options" style="padding:5px; border:1px solid #333399; margin-bottom:5px; background:#D8D8FF;">'+
            '<b>Liker Options:</b> '+
            '</div>'
        );
        break;
    case "archiveofourown.org":
        // adding hotkeys
        if (app.options("enable_list_hotkeys")) {
            document.addEventListener('keydown', function(e){
                switch (e.keyCode){
                    case 37:
                        var Prev = ffn$("a:contains('← Previous')");
                        if (typeof(Prev[0])!=='undefined') {Prev[0].click();}
                        break;
                    case 39:
                        var Next = ffn$("a:contains('Next →')");
                        if (typeof(Next[0])!=='undefined') {Next[0].click();}
                        break;
                }
            }, false);
        }
        if (app.options("enable_read_hotkeys")) {
            document.addEventListener('keydown', function(e){
                switch (e.keyCode){
                    case 37:
                        var Prev = ffn$("a:contains('←Previous Chapter')");
                        if (typeof(Prev[0])!=='undefined') {Prev[0].click();}
                        break;
                    case 39:
                        var Next = ffn$("a:contains('Next Chapter →')");
                        if (typeof(Next[0])!=='undefined') {Next[0].click();}
                        break;
                }
            }, false);
        }
        // in lists
        // old: ffn$("ol.work.index.group > li").each(function(){
        // contribution by Vannius from greasyfork site
        ffn$(".blurb").each(function(){
            var story = new Story({ namespace: app.namespace, instance: this });
            app.collection.push(story);
        });
        // on reading page
        ffn$("div.preface.group").each(function(){
            //        console.log(this);
            var story = new Story({ namespace: app.namespace, instance: this });
            app.collection.push(story);
        });
        // hide/show options
        ffn$('div.navigation.actions.module').after(
            '<div class="liker_script_options" style="padding:5px; border:1px solid #333399; margin-bottom:5px; background:#D8D8FF;">'+
            '<b>Liker Options:</b> '+
            '</div>'
        );
        break;
    case "ficbook.net":
        // on reading page
        patharr = window.location.pathname.split("/");
        if (patharr[1]==="readfic"){
            ffn$("div.row.hat-row > ul.list-unstyled").each(function() {
                var story = new Story({
                    namespace: app.namespace,
                    instance: this
                });
                app.collection.push(story);
            });
            if (app.options("enable_read_hotkeys")) {
                document.addEventListener('keydown', function(e){
                    switch (e.keyCode){
                        case 37:
                            var Prev = ffn$("a.btn-back");
                            if (Prev.length>0) window.location.href = Prev[0];
                            break;
                        case 39:
                            var Next = ffn$("a.btn-next");
                            if (Next.length>0) window.location.href = Next[0];
                            break;
                    }
                }, false);
            }
        }
        // in lists
        if (patharr[1]==="find" ||
            (patharr[1]==="collections") ||
            (patharr[3]==="profile" && patharr[4]==="works") ||            // in author profile / works
            (patharr[1] === "home" && ["favourites","collections"].indexOf(patharr[2])!=-1) ){ // indexOf => checks if patharr[2] is in [] array
            //ffn$(".description").each(function() {
            ffn$("article.block > div.description").each(function() {
                //    console.log(this)
                var story = new Story({
                    namespace: app.namespace,
                    instance: this
                });

                app.collection.push(story);
                // button for quickly reading/unreading story
                if (patharr[1]==="find" || (patharr[1]==="authors" && patharr[3]==="profile" && patharr[4]==="works")) {
                    if (ffn$(this).find(".read-notification").length===0) {
                        ffn$(this).append('<button type="button" class="btn btn-primary btn-default js-mark-readed" data-fanfic-id="'+ story.ficId() +'"><i class="icon-checkbox-unchecked2"></i> Прочитано!</button>');
                    } else {
                        ffn$(this).append('<button type="button" class="btn btn-primary btn-success js-mark-readed" data-fanfic-id="'+ story.ficId() +'"><i class="icon-checkbox-checked2"></i> Прочитано!</button>');
                    }
                }
            });
            // add hotkeys
            if (app.options("enable_list_hotkeys")) {
                document.addEventListener('keydown', function(e){
                    switch (e.keyCode){
                        case 37:
                            var Prev = ffn$("a[aria-label='Предыдущая']");
                            if (Prev.length>0) Prev[0].click();
                            break;
                        case 39:
                            var Next = ffn$("a[aria-label='Следующая']");
                            if (Next.length>0) Next[0].click();
                            break;
                    }
                }, false);
            }
        }
        // hide/show options
        ffn$('section.content-section').after(
            '<div class="liker_script_options" style="padding:5px; border:1px solid #333399; margin-bottom:5px; background:#D8D8FF;">'+
            '<b>Liker Options:</b> '+
            '</div>'
        );
        break;
    case "tbooklist.org":
        var patharr = window.location.pathname.split("/");
        // in feed
        if (patharr[1]==="feed"){
            ffn$("div.content-block > div.regular").each(function() {
                var story = new Story({
                    namespace: app.namespace,
                    instance: this
                });
                app.collection.push(story);
            });
        }
        // book page
        else if (patharr[1]==="books"){
            ffn$("div.cmedia-divided__child__top").each(function() {
                var story = new Story({
                    namespace: app.namespace,
                    instance: this
                });
                app.collection.push(story);
            });
        }
        // hide/show options
        ffn$('div.content-block').after(
            '<div class="liker_script_options" style="padding:5px; border:1px solid #333399; margin-bottom:5px; background:#D8D8FF;">'+
            '<b>Liker Options:</b> '+
            '</div>'
        );
        break;
}

//	OPTIONS
//	-  show/hide global options
//

if(app.options("hide_likes")){
	ffn$('.liker_script_options').append('<a href="" class="show_likes" style="color:blue">Show Likes</a>');
	ffn$('.liker_script_options .show_likes').click(function(){ show_likes();  });
} else {
	ffn$('.liker_script_options').append('<a href="" class="hide_likes" style="color:blue">Hide Likes</a>');
	ffn$('.liker_script_options .hide_likes').click(function(){ hide_likes(); });
}
ffn$('.liker_script_options').append('| ');

if(app.options("hide_dislikes")){
	ffn$('.liker_script_options').append('<a href="" class="show_dislikes" style="color:blue">Show Dislikes</a>');
	ffn$('.liker_script_options .show_dislikes').click(function(){ show_dislikes();  });
} else {
	ffn$('.liker_script_options').append('<a href="" class="hide_dislikes" style="color:blue">Hide Dislikes</a>');
	ffn$('.liker_script_options .hide_dislikes').click(function(){ hide_dislikes(); });
}
ffn$('.liker_script_options').append('| ');

if(app.options("hide_marked")){
	ffn$('.liker_script_options').append('<a href="" class="show_marked" style="color:blue">Show Marked</a>');
	ffn$('.liker_script_options .show_marked').click(function(){ show_marked();  });
} else {
	ffn$('.liker_script_options').append('<a href="" class="hide_marked" style="color:blue">Hide Marked</a>');
	ffn$('.liker_script_options .hide_marked').click(function(){ hide_marked(); });
}
ffn$('.liker_script_options').append('| ');

if(app.options("hide_inlibrary")){
	ffn$('.liker_script_options').append('<a href="" class="show_inlibrary" style="color:blue">Show InLibrary</a>');
	ffn$('.liker_script_options .show_inlibrary').click(function(){ show_inlibrary(); });
} else {
	ffn$('.liker_script_options').append('<a href="" class="hide_inlibrary" style="color:blue">Hide InLibrary</a>');
	ffn$('.liker_script_options .hide_inlibrary').click(function(){ hide_inlibrary(); });
}

// test dislike all
if (window.location.hostname === "www.fanfiction.net") {
    ffn$('.liker_script_options').append('| ');
    ffn$('.liker_script_options').append('<a href="" class="dislike_all" style="color:blue">Dislike All Authors</a>');
	ffn$('.liker_script_options .dislike_all').click(function(){ dislike_all();return(false);});
}
//



ffn$('.liker_script_options').append('| <a href="" id="ffn_OptionsToggle" style="color:blue">FFN Options</a>');
ffn$('.liker_script_options').after(
    "<div id='ffn_options_block' style='display:none;'>" +
    "<input type='checkbox' id='ffn_checkbox_hide_likes'>Hide Likes</br>" +
    "<input type='checkbox' id='ffn_checkbox_hide_dislikes'>Hide Dislikes</br>" +
    "<input type='checkbox' id='ffn_checkbox_hide_marked'>Hide Marked</br>" +
    "<input type='checkbox' id='ffn_checkbox_hide_inlibrary'>Hide InLibrary</br>" +
    "</br>" +
    "<input type='checkbox' id='ffn_checkbox_enable_list_hotkeys'>Enable left/right arrow keys on lists pages</br>" +
    "<input type='checkbox' id='ffn_checkbox_enable_read_hotkeys'>Enable left/right arrow keys on reading pages</br>" +
    "</br>" +
    "<button id='ffn_options_button_save'>Save options and reload page</button>" + " | " +
    "<a href='' class='backupToggle' style='color:blue'>Manage Site Data</a>'" +
    "    <div class='backup_text' style='display:none'>" +
    "    <table><tr>" +
    "    <td class='backup_data' valign='top'>" +
    "    	<b>Backup data</b><br />" +
    "    	Copy this text some where safe<br />" +
    "    	<textarea class=''></textarea>" +
    "    </td>" +
    "    <td>&nbsp;&nbsp;</td>" +
    "    <td class='save_new_data' valign='top'>" +
    "    	<b>Upload new Data</b><br>" +
    "    	Upload data you had previously saved<br />" +
    "    	<textarea></textarea><br >" +
    "    	<button class='new_data_save'>save</button>" +
    "    </td></tr></table>" +
    "    </div>" +
    "</div>"

);
ffn$('#ffn_OptionsToggle').click(function(){
    ffn$("#ffn_options_block").toggle();
    ffn$("#ffn_checkbox_hide_likes").prop("checked",app.options("hide_likes"));
    ffn$("#ffn_checkbox_hide_dislikes").prop("checked",app.options("hide_dislikes"));
    ffn$("#ffn_checkbox_hide_marked").prop("checked",app.options("hide_marked"));
    ffn$("#ffn_checkbox_hide_inlibrary").prop("checked",app.options("hide_inlibrary"));
    ffn$("#ffn_checkbox_enable_list_hotkeys").prop("checked",app.options("enable_list_hotkeys"));
    ffn$("#ffn_checkbox_enable_read_hotkeys").prop("checked",app.options("enable_read_hotkeys"));
    return false;
});
ffn$('#ffn_options_button_save').click(function(){
    app.options("hide_likes", ffn$("#ffn_checkbox_hide_likes").prop("checked"));
    app.options("hide_dislikes", ffn$("#ffn_checkbox_hide_dislikes").prop("checked"));
    app.options("hide_marked", ffn$("#ffn_checkbox_hide_marked").prop("checked"));
    app.options("hide_inlibrary", ffn$("#ffn_checkbox_hide_inlibrary").prop("checked"));
    app.options("enable_list_hotkeys", ffn$("#ffn_checkbox_enable_list_hotkeys").prop("checked"));
    app.options("enable_read_hotkeys", ffn$("#ffn_checkbox_enable_read_hotkeys").prop("checked"));
    location.reload();
    return false;
});

// import/export db data

ffn$('.backup_text .backup_data textarea').on("click",function(){
    ffn$(this).select();
});

ffn$('.backup_text .save_new_data button').on("click",function(){
    var v = ffn$('.backup_text .save_new_data textarea').val();
    try {
        var new_db = JSON.parse(v);
    } catch(err) {
        alert("that data is not valid");
        return;
    }
    localStorage.setItem("FFLikerAA", JSON.stringify(new_db));
    document.location = document.location;
});

ffn$('.backupToggle').click(function(){
    ffn$(".backup_text").toggle();
    ffn$(".backup_text .backup_data textarea").html(JSON.stringify(db));
    return false;
});

function show_dislikes(){
    app.options("hide_dislikes",false);
	return false;
}

function hide_dislikes(){
	app.options("hide_dislikes",true);
	return false;
}

function show_likes(){
	app.options("hide_likes",false);
	return false;
}

function hide_likes(){
	app.options("hide_likes",true);
	return false;
}

function show_marked(){
	app.options("hide_marked",false);
	return false;
}

function hide_marked(){
	app.options("hide_marked",true);
	return false;
}

function show_inlibrary(){
	app.options("hide_inlibrary",false);
	return false;
}

function hide_inlibrary(){
	app.options("hide_inlibrary",true);
	return false;
}

function dislike_all(){
        this.ffn$("div.z-list:visible").each(function() {
//            console.log(this);
           var story = new Story({
               namespace: app.namespace,
               instance: this
           });

            app.collection.push(story);
            app.author.dislike(story.authorId());
        });
}