Skip to content

Instantly share code, notes, and snippets.

@sigma
Created October 10, 2011 18:00
Show Gist options
  • Save sigma/1276002 to your computer and use it in GitHub Desktop.
Save sigma/1276002 to your computer and use it in GitHub Desktop.
vBulletinTags greasemonkey script
// ==UserScript==
// @name vBulletinTags
// @namespace http://www.hodique.info/gmscripts
// @include http://www.denofangels.com/forums/showthread.php?*
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js
// @require https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js
// @require https://raw.github.com/gist/1273800/1a880db0bc3abceb2c0e2841b72babceefa0fa17/jquerytagsinput.js
// @require https://raw.github.com/gist/1275791/1972165bbe3bbffc16025483f3ea850d1a780f56/jquery.purr.js
// @resource tagImg https://developer.mozilla.org/skins/mdn/Transitional/img/icons/tag-tiny.png
// ==/UserScript==
var IndexedDB = unsafeWindow.mozIndexedDB;
var IDBTransaction = unsafeWindow.IDBTransaction.wrappedJSObject;
var IDBKeyRange = unsafeWindow.IDBKeyRange.wrappedJSObject;
var CurrentURL = window.location.pathname;
var CurrentProtocol = window.location.protocol;
var CurrentHost = window.location.host;
var vBulletinTags = {};
vBulletinTags.tagsDB = {};
vBulletinTags.tagsDB.db = null;
vBulletinTags.tagsDB.completion_list = null;
vBulletinTags.tagsDB.open = function(cb) {
var request = IndexedDB.open("tags");
request.onsuccess = function(e) {
var v = "1.1";
vBulletinTags.tagsDB.db = e.target.result;
var db = vBulletinTags.tagsDB.db;
// We can only create Object stores in a setVersion transaction;
if(v!= db.version) {
var setVrequest = db.setVersion(v);
// onsuccess is the only place we can create Object Stores
setVrequest.onfailure = vBulletinTags.tagsDB.onerror;
setVrequest.onsuccess = function(e) {
db.createObjectStore("tag", {keyPath: "name"});
db.createObjectStore("post", {keyPath: "id"});
};
}
cb();
};
request.onfailure = vBulletinTags.tagsDB.onerror;
};
var topic = $('link[rel="canonical"]').attr('href').split("?",2)[1];
vBulletinTags.TagContext = function(context_id, post_id) {
this.tagInserter = function(tag) {
return vBulletinTags.TagContext.prototype._tagInserter(tag, context_id,
post_id);
};
this.tagRemover = function(tag) {
return vBulletinTags.TagContext.prototype._tagRemover(tag, context_id);
};
}
vBulletinTags.TagContext.prototype._tagInserter = function(tag, context_id,
post_id) {
if (tag == "") return;
var db = vBulletinTags.tagsDB.db;
if ($.inArray(tag, vBulletinTags.tagsDB.completion_list) == -1) {
var trans = db.transaction(["tag"], IDBTransaction.READ_WRITE, 0);
var store = trans.objectStore("tag");
var req = store.put({'name': tag});
req.onsuccess = function(e) {
vBulletinTags.tagsDB.completion_list.push(tag);
}
req.onerror = function(e) {
alert("error inserting tag !");
}
}
var trans = db.transaction(["post"], IDBTransaction.READ_ONLY, 0);
var store = trans.objectStore("post");
var req = store.get(context_id);
req.onsuccess = function(e) {
var result = e.target.result;
var tags;
if(!!result == false) {
tags = new Array();
} else {
tags = result.tags;
}
if ($.inArray(tag, tags) == -1)
tags.push(tag);
var trans = db.transaction(["post"], IDBTransaction.READ_WRITE, 0);
var store = trans.objectStore("post");
var obj = {'id': context_id, 'tags': tags};
var req = store.put(obj);
};
var last_tag = $("#tags_" + post_id + "_addTag").prev();
last_tag.click(function () {
var txt = $(this).text();
txt = txt.substring(0,txt.length - 3);
vBulletinTags.displayTag(txt);
});
};
vBulletinTags.TagContext.prototype._tagRemover = function(tag, context_id) {
if (tag == "") return;
var db = vBulletinTags.tagsDB.db;
var trans = db.transaction(["post"], IDBTransaction.READ_ONLY, 0);
var store = trans.objectStore("post");
var req = store.get(context_id);
req.onsuccess = function(e) {
var result = e.target.result;
var tags;
if(!!result == false) {
tags = new Array();
} else {
tags = result.tags;
}
var new_tags = new Array();
for each (var t in tags) {
if (t != tag) {
new_tags.push(t);
}
}
var trans = db.transaction(["post"], IDBTransaction.READ_WRITE, 0);
var store = trans.objectStore("post");
var obj = {'id': context_id, 'tags': new_tags};
var req = store.put(obj);
};
};
vBulletinTags.TagContext.prototype.tagCompleter = function(prefix, cb) {
prefix = prefix.term;
var l = new Array();
if (vBulletinTags.tagsDB.completion_list != null) {
for each (var val in vBulletinTags.tagsDB.completion_list) {
if (val.indexOf(prefix) == 0) {
l.push(val);
}
}
}
cb(l);
};
vBulletinTags.insertTags = function(index) {
var post_id = $(this).attr('id').split('_',2)[1];
var id = topic + "#post" + post_id;
var context = new vBulletinTags.TagContext(id, post_id);
var img = document.createElement('img');
img.src = GM_getResourceURL("tagImg");
$(img).css('float', 'left');
$(img).css('padding-right', '10px');
$(img).click(function() {
vBulletinTags.manageTags();
});
var tags = document.createElement('p');
tags.id = 'tags_' + post_id;
var position = $(this).children().last().prev();
position.prepend(tags);
position.prepend(img);
var target = $('#' + tags.id);
target.tagsInput({'interactive':true,
'height': '30px',
'autocomplete': {
'autoFocus': true
},
'autocomplete_url': context.tagCompleter,
'onRemoveTag': context.tagRemover,
'onAddTag': context.tagInserter,
'removeWithBackspace': false
});
var db = vBulletinTags.tagsDB.db;
var trans = db.transaction(["post"]);
var store = trans.objectStore("post");
var req = store.get(id);
req.onsuccess = function(e) {
var result = e.target.result;
if(!!result == false)
return;
$(result.tags).each(function () {
target.addTag(this);
});
};
req.onerror = vBulletinTags.tagsDB.onerror;
};
vBulletinTags.addGlobalStyle = function(css) {
var head, style;
head = document.getElementsByTagName('head')[0];
if (!head) { return; }
style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
};
//SETTING UP OUR POPUP
//0 means disabled; 1 means enabled;
vBulletinTags.popupStatus = 0;
//loading popup with jQuery magic!
vBulletinTags.loadPopup = function() {
//loads popup only if it is disabled
if(vBulletinTags.popupStatus == 0){
$("#backgroundPopup").css({"opacity": "0.7"});
$("#backgroundPopup").fadeIn("slow");
$("#popupContact").fadeIn("slow");
vBulletinTags.popupStatus = 1;
}
};
//disabling popup with jQuery magic!
vBulletinTags.disablePopup = function() {
//disables popup only if it is enabled
if(vBulletinTags.popupStatus == 1){
$("#backgroundPopup").fadeOut("slow");
$("#popupContact").fadeOut("slow");
vBulletinTags.popupStatus = 0;
}
$("#popupContact").remove();
$("#backgroundPopup").remove();
};
//centering popup
vBulletinTags.centerPopup = function() {
//request data for centering
var windowWidth = document.documentElement.clientWidth;
var windowHeight = document.documentElement.clientHeight;
var popupHeight = $("#popupContact").height();
var popupWidth = $("#popupContact").width();
//centering
$("#popupContact").css({"top": windowHeight/2-popupHeight/2,
"left": windowWidth/2-popupWidth/2
});
//only need force for IE6
$("#backgroundPopup").css({"height": windowHeight});
};
vBulletinTags.displayTag = function(tag) {
vBulletinTags.popup("Query : " + tag, "");
$("#contactArea").append($("<li />"));
vBulletinTags.renderTags(tag, $("#contactArea > li"))
};
vBulletinTags.renderTags = function(tag, li) {
var db = vBulletinTags.tagsDB.db;
var trans = db.transaction(["post"]);
var store = trans.objectStore("post");
var keyRange = IDBKeyRange.lowerBound(0);
var req = store.openCursor(keyRange);
var checked = $("#popupContact > input:checkbox:checked").val();
var idx = 1;
req.onsuccess = function(e) {
var result = e.target.result;
if(!!result == false)
return;
var tags = result.value.tags;
if ($.inArray(tag, tags) != -1) {
var link;
if (checked) {
link = '[URL="' + CurrentProtocol + "//" + CurrentHost + CurrentURL + "?" + result.value.id + '"](' + idx + ')[/URL] ';
li.append(link);
} else {
link = '<a href="' + CurrentURL + "?" + result.value.id + '">' + result.value.id + '</a>';
li.append("<ul>" + link + "</ul>");
}
idx = idx + 1;
}
result.continue();
};
};
vBulletinTags.manageTags = function() {
vBulletinTags.popup("Manage :", "");
var target = $("#contactArea");
target.tagsInput({'interactive':false,
'width': '100%',
'onRemoveTag': vBulletinTags.tagDeleter,
'onAddTag': vBulletinTags.tagBrowser,
});
$("#contactArea_tagsinput").after($("<hr /><li />"));
for each (var t in vBulletinTags.tagsDB.completion_list.sort()) {
target.addTag(t);
}
};
vBulletinTags.tagDeleter = function(tag) {
alert("Not implemented !");
};
vBulletinTags.tagBrowser = function(tag) {
var last_tag = $("#contactArea_addTag").prev();
var li = $("#contactArea_tagsinput").next().next();
last_tag.click(function () {
var txt = $(this).text();
txt = txt.substring(0,txt.length - 3);
li.append("<p>" + txt + "</p><li />");
vBulletinTags.renderTags(txt, li.children().last());
});
};
vBulletinTags.popup = function(title, body) {
var div = $('<div style="z-index: 99; overflow:auto;" id="popupContact">'
+ '<a id="popupContactClose">x</a>'
+ '<h1>' + title + '</h1>'
+ 'As BBcode: <input type="checkbox" />'
+ '<div id="contactArea">'
+ body
+ '</div>'
+ '</div>'
+ '<div style="height: 929px; opacity: 0.7; display: none; z-index: 98;" id="backgroundPopup"></div>'
);
$(document.body).append(div);
//centering with css
vBulletinTags.centerPopup();
//load popup
vBulletinTags.loadPopup();
//CLOSING POPUP
//Click the x event!
$("#popupContactClose").click(function(){
vBulletinTags.disablePopup();
});
//Click out event!
$("#backgroundPopup").click(function(){
vBulletinTags.disablePopup();
});
};
vBulletinTags.installHack = function() {
var db = vBulletinTags.tagsDB.db;
var trans = db.transaction(["tag"]);
var store = trans.objectStore("tag");
var keyRange = IDBKeyRange.lowerBound(0);
var req = store.openCursor(keyRange);
req.onsuccess = function(e) {
if (vBulletinTags.tagsDB.completion_list == null) {
vBulletinTags.tagsDB.completion_list = new Array();
}
var result = e.target.result;
if(!!result == false)
return;
vBulletinTags.tagsDB.completion_list.push(result.value.name);
result.continue();
};
req.onerror = function(e) {
vBulletinTags.tagsDB.completion_list = new Array();
}
// add tags for posts
$(".postcontainer").each(vBulletinTags.insertTags);
// purr style
vBulletinTags.addGlobalStyle("#purr-container {" +
"position: fixed;" +
"top: 0;" +
"left: 0;" +
"z-index: 99;" +
"}" +
".notice {" +
"position: relative;" +
"width: 324px;" +
"}" +
".notice .close {" +
"position: absolute;" +
"top: 12px;" +
"right: 12px;" +
"display: block;" +
"width: 18px;" +
"height: 17px;" +
"text-indent: -9999px;" +
"background: url(http://kitchen.net-perspective.com/purr-example/purrClose.png) no-repeat 0 10px;" +
"}" +
".notice-body {" +
"min-height: 50px;" +
"padding: 22px 22px 0 22px;" +
"background: url(http://kitchen.net-perspective.com/purr-example/purrTop.png) no-repeat left top;" +
"color: #f9f9f9;" +
"}" +
".notice-body img {" +
"width: 50px;" +
"margin: 0 10px 0 0;" +
"float: left;" +
"}" +
".notice-body h3 {" +
"margin: 0;" +
"font-size: 1.1em;" +
"}" +
".notice-body p {" +
"margin: 5px 0 0 60px;" +
"font-size: 0.8em;" +
"line-height: 1.4em;" +
"}" +
".notice-bottom {" +
"height: 22px;" +
"background: url(http://kitchen.net-perspective.com/purr-example/purrBottom.png) no-repeat left top;" +
"}"
);
// popup style
vBulletinTags.addGlobalStyle("#backgroundPopup{" +
"display:none;" +
"position:fixed;" +
"height:100%;" +
"width:100%;" +
"top:0;" +
"left:0;" +
"background:#000000;" +
"border:1px solid #cecece;" +
"z-index:1;" +
"}" +
"#popupContact{" +
"display:none;" +
"position:fixed;" +
"height: 80%;" +
"width:80%;" +
"background:#FFFFFF;" +
"border:2px solid #cecece;" +
"z-index:2;" +
"padding:12px;" +
"font-size:13px;" +
"}" +
"#popupContact h1{" +
"text-align:left;" +
"color:#6FA5FD;" +
"font-size:22px;" +
"font-weight:700;" +
"border-bottom:1px dotted #D3D3D3;" +
"padding-bottom:2px;" +
"margin-bottom:20px;" +
"}" +
"#popupContactClose{" +
"font-size:14px;" +
"line-height:14px;" +
"right:6px;" +
"top:4px;" +
"position:absolute;" +
"color:#6fa5fd;" +
"font-weight:700;" +
"display:block;" +
"}" +
"#button{" +
"text-align:center;" +
"margin:100px;" +
"}" +
"a{" +
"cursor: pointer;" +
"text-decoration:none;" +
"}"
);
// tag style
vBulletinTags.addGlobalStyle(".tag{" +
"cursor: pointer;" +
"background-color: rgb(188,188,188);" +
"color: rgb(34,34,34);" +
"padding-left: 4px;" +
"padding-right: 6px;" +
"font: 10px verdana,arial,sans-serif;" +
"margin: 2px;" +
"border-radius: 10%;" +
"}" +
"#contactArea_tagsinput > .tag{" +
"float: left;" +
"}"
);
};
vBulletinTags.tagsDB.open(vBulletinTags.installHack);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment