User talk:Void Singer/SL Forum Ignore

From Second Life Wiki
Jump to navigation Jump to search

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>

-- Strife (talk|contribs) 07:47, 14 February 2010 (UTC)