NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name whatcd gazelle toggle bookmarks
// @include /https?://www\.empornium\.(me|sx)/torrents\.php.*/
// @include /https?://www\.empornium\.(me|sx)/user\.php.*/
// @include /https?://www\.empornium\.(me|sx)/top10\.php.*/
// @include /https?://femdomcult\.org/torrents\.php.*/
// @include /https?://femdomcult\.org/user\.php.*/
// @include /https?://femdomcult\.org/top10\.php.*/
// @version 3
// @require http://code.jquery.com/jquery-2.1.1.js
// @grant GM_addStyle
// @grant GM_unsafeWindow
// ==/UserScript==
"use strict";
// Changelog:
// * version 3
// - fixed missing non-breaking space on empty title
// * version 2
// - improved hover over download icon
// * version 1
// - initial version
GM_addStyle('' +
'.toggle-bookmarks {' +
' position: absolute;' +
' display: none;' +
' padding-right: 5px;' +
' z-index: 2;' +
'}' +
'.toggle-bookmarks .wrapper {' +
' background: white;' +
' border-radius: 3px;' +
' border: 1px solid silver;' +
'}' +
'.toggle-bookmarks.bookmarked .add,' +
'.toggle-bookmarks:not(.bookmarked) .remove {' +
' display: none;' +
'}' +
'.toggle-bookmarks svg {' +
' width: 15px;' +
' height: 15px;' +
'}' +
'');
var star_add = [
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 179.99999" height=',
'"180" width="180"><path d="M37.048 171.56l52.9-38.433 52.9 38.434-20.204-62',
'.187 52.9-38.435h-65.388L89.95 8.748 69.74 70.938H4.352l52.9 38.435z" fill-',
'rule="evenodd" stroke="#000"/><g transform="matrix(1.278 0 0 1.278 -195.438',
'-298.745)"><circle r="30" cy="337.362" cx="260" fill="#fff" stroke="#000" s',
'troke-width="3.13"/><rect ry="5" y="317.283" x="255" height="40.159" width=',
'"10" rx="5"/><rect ry="5" y="332.362" x="239.92" height="10" width="40.159"',
'rx="5"/></g></svg>'
].join('');
var star_remove = [
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 179.99999" height=',
'"180" width="180"><path d="M37.048 171.56l52.9-38.433 52.9 38.434-20.204-62',
'.187 52.9-38.435h-65.388L89.95 8.748 69.74 70.938H4.352l52.9 38.435z" fill-',
'rule="evenodd" stroke="#000"/><g transform="matrix(1.278 0 0 1.278 -195.438',
'-298.745)"><circle r="30" cy="337.362" cx="260" fill="#fff" stroke="#000" s',
'troke-width="3.13"/><rect ry="5" y="332.362" x="239.92" height="10" width="',
'40.159" rx="5"/></g></svg>'
].join('');
this.jQuery = jQuery.noConflict(true);
function Ajax() {
this.add = jQuery.proxy(this.add, this);
this.remove = jQuery.proxy(this.remove, this);
}
Ajax.prototype.get = function (action, torrent_id) {
return jQuery.get('bookmarks.php', {
action: action,
type: 'torrent',
auth: unsafeWindow.authkey,
id: torrent_id
});
};
Ajax.prototype.add = function (torrent_id) {
return this.get('add', torrent_id);
};
Ajax.prototype.remove = function (torrent_id) {
return this.get('remove', torrent_id);
};
function ToggleBookmark() {
this.el = this.create_el();
this.id = null;
this.ids = {};
this.ajax = new Ajax();
this.symbol_bookmark = '★';
this.on_mouseenter_title = jQuery.proxy(this.on_mouseenter_title, this);
this.on_mouseenter_version = jQuery.proxy(this.on_mouseenter_version, this);
this.on_mouseleave = jQuery.proxy(this.on_mouseleave, this);
this.add = jQuery.proxy(this.add, this);
this.remove = jQuery.proxy(this.remove, this);
this.el.appendTo('body');
this.attach_events();
}
ToggleBookmark.prototype.remove_char = function (value, index) {
return value.slice(0, index) + value.slice(index + 1);
};
ToggleBookmark.prototype.remove_bookmark_symbol = function (title) {
var bookmark_index = title.lastIndexOf(this.symbol_bookmark);
if (bookmark_index === -1)
return title;
return this.remove_char(title, bookmark_index);
};
ToggleBookmark.prototype.create_el = function () {
return jQuery([
'<div class="toggle-bookmarks">',
' <div class="wrapper">',
' <a href="#" class="add">', star_add, '</a>',
' <a href="#" class="remove">', star_remove, '</a>',
' </div>',
'</div>',
].join(''));
};
ToggleBookmark.prototype.attach_events = function () {
var title_selector = [
'td.cats_col + td > a[href^="torrents.php?id"]',
'td.cats_cols + td > a[href^="torrents.php?id"]'
].join(',');
var version_selector = [
'td.cats_col + td .version',
'td.cats_cols + td .version'
].join(',');
var torrent_table = jQuery('.torrent_table');
torrent_table.on('mouseenter', title_selector, this.on_mouseenter_title);
torrent_table.on('mouseenter', version_selector, this.on_mouseenter_version);
torrent_table.on('mouseleave', 'td', this.on_mouseleave);
this.el.on('click', 'a.add', this.add);
this.el.on('click', 'a.remove', this.remove);
};
ToggleBookmark.prototype.add = function (event) {
event.preventDefault();
var callback = jQuery.proxy(this.added, {
self: this,
title: this.title,
id: this.id
});
this.ajax.add(this.id).done(callback);
};
ToggleBookmark.prototype.remove = function (event) {
event.preventDefault();
var callback = jQuery.proxy(this.removed, {
self: this,
title: this.title,
id: this.id
});
this.ajax.remove(this.id).done(callback);
};
ToggleBookmark.prototype.on_toggle = function (id, value) {
this.ids[id] = value;
this.el.toggleClass('bookmarked', value);
};
ToggleBookmark.prototype.added = function () {
var title = this.self.remove_bookmark_symbol(this.title.textContent).trim();
if (title)
this.title.textContent = title + '\u00a0' + this.self.symbol_bookmark;
else
this.title.textContent = this.self.symbol_bookmark;
this.self.on_toggle(this.id, true);
};
ToggleBookmark.prototype.removed = function () {
var title = this.self.remove_bookmark_symbol(this.title.textContent).trim();
if (title)
this.title.textContent = title;
else
this.title.textContent = '\u00a0';
this.self.on_toggle(this.id, false);
};
ToggleBookmark.prototype.is_version_bookmarked = function (title) {
return title.text().indexOf('★') !== -1;
};
ToggleBookmark.prototype.is_title_bookmarked = function (parent) {
return parent.find('> span > img[alt="bookmarked"]').length > 0;
};
ToggleBookmark.prototype.get_id = function (title) {
return title.attr('href').match(/id=(\d+)/)[1];
};
ToggleBookmark.prototype.rect = function (el) {
var offset = el.offset();
var width = el.width();
var height = el.height();
var center = {
top: offset.top + height / 2,
left: offset.left + width / 2
};
return {
left: offset.left,
right: offset.left + width,
top: offset.top,
bottom: offset.top + height,
center: center,
width: width,
height: height
};
};
ToggleBookmark.prototype.on_mouseenter = function (title, parent, is_bookmarked) {
var id = this.get_id(title);
var bookmarked = this.ids[id];
if (bookmarked === undefined) {
bookmarked = is_bookmarked.call(this);
}
this.id = id;
this.title = title.contents()
.filter(function () {return this.nodeType === 3})
.filter(function () {return this.textContent.length > 0})
.first()[0];
this.el.toggleClass('bookmarked', bookmarked);
this.el.prependTo(title);
this.el.show();
}
ToggleBookmark.prototype.on_mouseenter_title = function (event) {
var title = jQuery(event.currentTarget);
var parent = title.parent();
var is_bookmarked = function() {return this.is_title_bookmarked(parent)};
this.on_mouseenter(title, parent, is_bookmarked);
var rect_title = this.rect(title);
this.set_offset({
top: rect_title.center.top,
left: rect_title.left
});
};
ToggleBookmark.prototype.on_mouseenter_version = function (event) {
var title = jQuery(event.currentTarget).find('.collapsed-title');
var parent = title.parent();
var is_bookmarked = function () {return this.is_version_bookmarked(title);}
this.on_mouseenter(title, parent, is_bookmarked);
var rect_title = this.rect(title);
var rect_parent = this.rect(parent);
this.set_offset({
top: rect_title.center.top,
left: rect_parent.left
});
};
ToggleBookmark.prototype.on_mouseleave = function (event) {
this.el.hide();
};
ToggleBookmark.prototype.set_offset = function (offset) {
this.el.offset({
top: offset.top - this.el.innerHeight() / 2,
left: offset.left - this.el.innerWidth()
});
};
new ToggleBookmark();