Difference between revisions of "User talk:Void Singer/SL Forum Ignore"
Void Singer (talk | contribs) m (→Design: - reply) |
(→Design) |
||
Line 12: | Line 12: | ||
:The page layout on the Blogorums is... messy. and the wysiwyg editor loves to overuse &nbsp; 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 <br/>-- '''[[User:Void_Singer|Void]]''' <sup><small>([[User_talk:Void_Singer|talk]]|[[Special:Contributions/Void_Singer|contribs]])</small></sup> 00:33, 14 February 2010 (UTC) | :The page layout on the Blogorums is... messy. and the wysiwyg editor loves to overuse &nbsp; 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 <br/>-- '''[[User:Void_Singer|Void]]''' <sup><small>([[User_talk:Void_Singer|talk]]|[[Special:Contributions/Void_Singer|contribs]])</small></sup> 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: | |||
*[https://addons.mozilla.org/en-US/firefox/addon/11900 FireXPath] - XPath tab in Firebug, easier to use than XPather. | |||
*[http://xpath.alephzarro.com/ 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> | |||
-- '''[[User:Strife_Onizuka|Strife]]''' <sup><small>([[User talk:Strife_Onizuka|talk]]|[[Special:Contributions/Strife_Onizuka|contribs]])</small></sup> 07:47, 14 February 2010 (UTC) |
Revision as of 23:47, 13 February 2010
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>