User talk:Void Singer/SL Forum Ignore
Design
I'm curious why you are injecting code, it seems to complicate things. You could put everything in the uPersist function (I'd rename the function). I'm a pretty experienced GM script writer and I wouldn't mind making the changes. If you haven't already, consider posting it on UserScripts.org (it's got version tracking and makes script installation easy, oh and it's free). -- Strife (talk|contribs) 18:51, 13 February 2010 (UTC)
P.S. The onclick attribute has fallen out of favor. addEventListener is the approved method of registering events.
- originally I had been injecting the whole script, but didn't know about the changes to GM_*Value context or some of the newer methods (haven't played with javascript for awhile since I quite doing web work)... took me awhile to dig up a useful example for grabbing variables back to the sandbox context... current version is only beta while I make sure the features I have, work, then I'll rewrite for max efficiency...
- There is a more recent version on userscripts [1] that adds jive version testing and wrappers the the GM_*Value functions for safe degrading to localStorage w/ JSON for Chrome/Opera/Safari/IE8 (although I'm not sure all the other methods will pass... I can't get a good idea what level of XPATH support they have, for instance). My understanding was that FF didn't have support for GM_* before v3 though? But that was just a matter of quick reading out of date resources...
- Oh and I didn't know you could "or" the classes like that... nice, I was reading the MSDN for XPATH and must've missed it. (I also didn't realize we have javascript code wrappers on the wiki). I'd more than welcome input/suggestion/assistance on the script, I've got a few planned feature tweaks to make it nicer (listed on the new forum under beta testers), but some of them run in different directories on the new forum, so I haven't decided whether to make them separate scripts or not to cut down on page parsing...
- The page layout on the Blogorums is... messy. and the wysiwyg editor loves to overuse and there's lots of garbage spacing every... plus I forgot to convert childNodes to getElementByTagName since in both cases there's only 1 html element in the container, and it's an anchor. anyways, I'm rambling so I'll stop here
-- Void (talk|contribs) 00:33, 14 February 2010 (UTC)
I tried to tweak it to be better... but it turned out to be easier to rewrite it from scratch. I redid just about everything with fuzzy xpath (I love "ancestor"). This final version is a lot similar than my previous version (which instead of mod'ing the post classes on the fly, it generated custom style elements on the fly; it did not scale). It looks like there is more CSS than code.
As to debugging JS in firefox, I recommend:
- FireXPath - XPath tab in Firebug, easier to use than XPather.
- XPather - Has an excellent concise XPath help window.
<javascript> // ==UserScript== // @name SL Forum Ignore // @namespace http://home.comcast.net/~mailerdaemon // @description Adds Ignore Links to User Posts on SL Forum Discussions/Questions (And Make Linden Names RED) // @include https://blogs.secondlife.com/thread/* // @include https://blogs.secondlife.com/message/* // ==/UserScript==
var names = {};
GM_addStyle([
".GM-ignore-link-wrapper { cursor:pointer; }", "", ".GM-ignore-link-wrapper .ignore { display:block;}", ".GM-ignore-link-wrapper .unignore { display:none;}", ".ignored-user .GM-ignore-link-wrapper .ignore {display:none;}", ".ignored-user .GM-ignore-link-wrapper .unignore {display:block;}", "", ".ignored-user .jive-author { padding-top:0; padding-bottom:0; }", ".ignored-user .jive-author-avatar-container { display:none!important; }", ".ignored-user .jive-author-avatar-container { background-image: none !important; }", ".ignored-user .jive-author > em { display:none; }", "", ".ignored-user .jive-thread-post-body-container { min-height:0; background-image: none !important; padding-bottom:8px; }", ".ignored-user .jive-thread-post-subject { float: left; width:auto; }", ".ignored-user .jive-thread-post-subject h2 { display:none; }", ".ignored-user .jive-thread-post-message { display:none; }", ".ignored-user .jive-thread-post-details { background-image: none !important; padding-top:0; margin-top:0; width:auto;}", ".ignored-user .jive-thread-post-subject-content { background-image: none !important; padding-bottom:0; margin-bottom:0; }", ".ignored-user .jive-thread-post-subject-content .jive-thread-post-reply { display:none; }", "", ".ignored-user .jive-thread-reply-body-container { min-height:0; padding-bottom:6px; }", ".ignored-user .jive-thread-reply-subject { float: left; width:auto; padding-bottom:0!important;}", ".ignored-user .jive-thread-reply-subject strong { display:none!important; }", ".ignored-user .jive-thread-reply-message { display:none; }", ".ignored-user .jive-content-controls { text-align:right; width:auto; padding-top:0; padding-bottom:0;}", ].join("\n"));
var box;
$Z("//div[@class='jive-thread-post-body' or @class='jive-thread-reply-body']", function(r,i){
var linkwrapper = $X("./div[@class='jive-author']/div[@class='jive-username-link-wrapper']", r); var fullname = $X("./a", linkwrapper).textContent; var name = fullname.split(" "); if(name[1] != "Linden") {//this all could be made part of the original selector but... that would be ugly to say the least. var hidden = names[fullname] = Boolean(GM_getValue(fullname, false)); r.parentNode.setAttribute("username", fullname); if(!box) { box = document.createElement("div"); box.className = "GM-ignore-link-wrapper"; { var span = document.createElement("span"); span.appendChild(document.createTextNode("Ignore")); span.className="ignore"; box.appendChild(span); } { var span = document.createElement("span"); span.appendChild(document.createTextNode("Unignore")); span.className="unignore"; box.appendChild(span); } } if(hidden) QuickHide(r.parentNode); var boxy = box.cloneNode(true); insertAfter(boxy, linkwrapper); boxy.addEventListener("click", toggleIgnore, false); } });
function QuickHide(r){ r.className = r.className + " ignored-user"; } function QuickShow(r){ r.className = r.className.split(" ").filter(function(v){ return v != "ignored-user";}).join(" "); }
function toggleIgnore(event){
var base = $X("./ancestor::div[@username]", event.currentTarget); var fullname = base.getAttribute("username"); var hidden = names[fullname] = !names[fullname]; if(hidden) GM_setValue(fullname, true); else GM_deleteValue(fullname); $Z("//div[@username='"+fullname+"']", hidden?QuickHide:QuickShow, base);
}
function insertAfter(insert, after){return after.parentNode.insertBefore(insert, after.nextSibling);} function insertBefore(insert, before){return before.parentNode.insertBefore(insert, before);}
function $X(_xpath, node){//to search in a frame, you must traverse the .contentDocument or .contentWindow attribute.
var doc = (node && (node.document || node.ownerDocument || node)) || document; return doc.evaluate(_xpath, node || doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
} function $Y(_xpath, node){
var doc = (node && (node.document || node.ownerDocument || node)) || document; return doc.evaluate(_xpath, node || doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
} function $Z(_xpath, func, node){
var doc = (node && (node.document || node.ownerDocument || node)) || document; var res = doc.evaluate(_xpath, node || doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var args = Array.prototype.slice.call(arguments, 3); var i = 0; for (; i < res.snapshotLength; ++i) func.apply(func, [res.snapshotItem(i), i].concat(args)); return i;
} </javascript>