Difference between revisions of "User:Void Singer/SL Forum Ignore"

From Second Life Wiki
Jump to navigation Jump to search
m
(updated to current public version)
 
(4 intermediate revisions by 3 users not shown)
Line 7: Line 7:
|title=SL Forum Ignore
|title=SL Forum Ignore
|content=
|content=
=== Features: ===
=== Requirements ===
* requires FireFox 2.0
* FireFox 2.0+, with Greasemonkey some-version-or-another
* requires Greasemonkey some-version-or-another
* Google Chrome (natively supported)
* Opera10.5+ and Safari4+ ''should'' be supported (post confirmation or bugs to the [https://wiki.secondlife.com/wiki/User_talk:Void_Singer/SL_Forum_Ignore discussion page])
 
=== Features and limitations ===
* Works on:
** Second Life Forums
** Second Life Answers
** Second Life Commerce
* in thread/message views [Flat or Threaded mode (large threaded thread may work slowly)]
** Persistent (dark red) (un)ignore links on User posts
** Clones "Edit" or "Report Abuse" buttons to bottom of Opening Posts as appropriate
* in "all-content" and "discussion" views..
** Persistent (dark red) (un)ignore links on User threads
** Persistent (un)collapse (Gear icon) link for "side bar" content
** Persistent (un)collapse ([Red'-', Green'+'] icon) link for "Featured" thread box


=== User Script ===
=== User Script ===
Line 15: Line 29:
// @name          SL Forum Ignore
// @name          SL Forum Ignore
// @namespace      Private
// @namespace      Private
// @description    Adds Ignore Links to User Posts on SL Forum Discussions/Questions (And Make Linden Names RED)
// @description    +Ignore Links (threads/posts), +OP Edit/Abuse fix, +'Featured' and Sidebar collapsing
// @include        http://blogs.secondlife.com/thread/*
// @include        http://blogs.secondlife.com/message/*
// @include        http://blogs.secondlife.com/community/forums/*
// @include        http://blogs.secondlife.com/community/answers*
// @include        http://blogs.secondlife.com/community/commerce*
// @include        https://blogs.secondlife.com/thread/*
// @include        https://blogs.secondlife.com/thread/*
// @include        https://blogs.secondlife.com/message/*
// @include        https://blogs.secondlife.com/message/*
// @include        https://blogs.secondlife.com/community/forums/*
// @include        https://blogs.secondlife.com/community/answers*
// @include        https://blogs.secondlife.com/community/commerce*
// @match          http://blogs.secondlife.com/thread/*
// @match          http://blogs.secondlife.com/message/*
// @match          http://blogs.secondlife.com/community/forums/*
// @match          http://blogs.secondlife.com/community/answers*
// @match          http://blogs.secondlife.com/community/commerce*
// @match          https://blogs.secondlife.com/thread/*
// @match          https://blogs.secondlife.com/message/*
// @match          https://blogs.secondlife.com/community/forums/*
// @match          https://blogs.secondlife.com/community/answers*
// @match          https://blogs.secondlife.com/community/commerce*
// @version        1.6.1
// @copyright      Void Singer 2010 [ https://wiki.secondlife.com/wiki/User:Void_Singer ] & BlindWanderer [ http://userscripts.org/users/4223 ]
// @license        CC-BY [ http://creativecommons.org/licenses/by/3.0 ]
// @licesne.ext    Free to copy, use, modify, distribute, or sell, with attribution.
// ==/UserScript==
// ==/UserScript==
/*//-- added match statements for compatibility with chromium 'content scripts'  --//*/
/*//-- IE7pro unsupported: lacks CSS inheritance & getElementsByClassName        --//*/
/*//-- Updated for jive version changes & http access 5:20am Wed, April 14, 2010 --//*/
/*//-- expanded ignore to cover thread views in all content and discussion views --//*/
/*//-- added sidebar removal for thread/message, all content, and discussion view--//*/
/*//-- add collapsing for featured posts in all content, and discussion view    --//*/
/*//-- removed Linden name coloring, since they added post coloring for them    --//*/
//-- compatibility replacements for Chrome4+, Opera10.5+, Safari4+, I hope
if (typeof GM_addStyle  == 'undefined'){
function GM_addStyle( vCss ){
var vStyle = document.createElement( 'style' );
vStyle.textContent = vCss;
document.getElementsByTagName( 'head' )[0].appendChild( vStyle );
}
} //-- "it's possible that *this* GM_ function is supported in chromium, but the others are not. can't find docs"
//-- compatibility replacements for Chrome4+, Opera10.5+, Safari4+, I hope
if (typeof GM_setValue  == 'undefined'){
//-- native JSON and localStorage for GM_*Value replacement
GM_getValue = function( vKey, vDefault ){
var vReturn = JSON.parse( window.localStorage.getItem( vKey ) );
return ((vReturn == null)? vDefault: vReturn);
}
GM_setValue = function( vKey, vValue ){
window.localStorage.setItem( vKey, JSON.stringify( vValue ) );
}
GM_deleteValue = function( vKey ){
window.localStorage.removeItem( vKey );
}
}
//-- function contributed by BlindWanderer
function uHide( vPostNode, vClass ){
vPostNode.className += ' ' + vClass;
}
//-- function contributed by BlindWanderer
function uShow( vNode, vClass ){
vNode.className = vNode.className.split( ' ' ).filter( function( v ){ return v != vClass;} ).join( ' ' );
}
//-- function contributed by BlindWanderer, modifed by Void Singer
function uToggleIgnore(){
//-- no ancestor support outside of xpath?
var vName = this.getAttribute( 'username' );
var vAction = (vIgnoreCache[vName] = !vIgnoreCache[vName])? uHide : uShow;
if (vIgnoreCache[vName]){
GM_setValue( vName, true );
}
else{
GM_deleteValue( vName );
}
var vSwaps = document.getElementsByClassName( vName );
var vCount = 0;
for (vCount; vCount < vSwaps.length; ++vCount){
vAction.apply( vAction, [vSwaps.item( vCount ), 'ignored-user'] );
}
}
function uSidebar(){
var vStatus = !GM_getValue( 'sidebar.hidden' );
GM_setValue( 'sidebar.hidden', vStatus );
var vTag = document.getElementById( 'jive-body-main' );
vTag.className = (vStatus)? 'GM-sidebar-hidden' : '';
}
function uFeatured(){
var vStatus = !GM_getValue( 'featured.hidden' );
GM_setValue( 'featured.hidden', vStatus );
var vNode = document.getElementById( 'GM-featured' );
var vAction = (vStatus) ? uHide : uShow;
vAction.apply( vAction, [vNode, 'GM-featured-hidden'] )
}


//-- Inject links, mark posts, and hide already ignored posts
//-- adds styles, ignore toggles, and marks post containers
function uSetupPage(){
function uTweakPage( vType ){
var vColDivs, vObjDiv, vObjLink, vStrUserName, vStrLinkText, vStrPostStyle;
//-- use style to reduce load, contributed by BlindWanderer, modifed by Void Singer
vColDivs = //-- grab the divs we need from the DOM, don't worry they ARE in page order
GM_addStyle( [
document.evaluate( "(//div[@class='jive-thread-post-body-container'] | //div[@class='jive-thread-reply-body-container'] | //div[@class='jive-username-link-wrapper'])",
'#GM-copy-control { font-weight: bold; }',
document,
'',
null,
'.GM-ignore-link-wrapper { cursor:pointer; font-weight: bold; color: rgb( 96, 0, 0 ) !important; padding-right: 1em !important; }',
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
'.font-color-meta-light .GM-ignore-link-wrapper { display:inline-block; };',
null );
'',
//-- loop through the divs in order
'.GM-sidebar-hidden #jive-body-sidebarcol-container { display: none; }',
for (var vIntCounter = 0; vIntCounter < vColDivs.snapshotLength; vIntCounter++){
'.GM-sidebar-hidden #jive-body-maincol-container { width: 98%; }',      //-- if this is set first, the view doesn't expand
vObjDiv = vColDivs.snapshotItem( vIntCounter ); //-- grab first div, AKA user name
'.GM-sidebar-hidden #jive-body-sidebarcol-container { display: none; }', //-- if this isn't re-set here the list drops but doesn't hide
vStrUserName = vObjDiv.childNodes.item( 1 ).href; //-- unsafe, needs rewritten
'',
vStrUserName = vStrUserName.substring( vStrUserName.lastIndexOf( "/" ) + 1 ); //-- grab the user name
'.GM-toggle { cursor: pointer; }',
'.GM-show-featured  { display: none; }',
if (vStrUserName.indexOf( "Linden" ) == -1){ //-- thou shalt not bite the hand that feeds you
'.GM-featured-hidden .jive-box-body { display: none; }',
if (GM_getValue( vStrUserName, 0 ) == 1){ //-- is this user already on ignore?
'.GM-featured-hidden .GM-hide-featured { display: none; }',
//-- set ignore button text and blank post attributes
'.GM-featured-hidden .GM-show-featured { display: block; }',
vStrLinkText = 'UnIgnore';
'',
vStrPostStyle = 'display:none;';
'.ignore { display:block; }',
}else{
'.unignore { display:none; }',
//-- set ignore button text attribute
'.ignored-user .ignore {display:none; }',
vStrLinkText = 'Ignore';
'.ignored-user .unignore {display:block; }',
vStrPostStyle = '';
'.jive-table-cell-author .GM-ignore-link-wrapper { float:left; }',
'',
'tr.ignored-user { line-height: 0.0; }',
'.ignored-user *[src] { display:none; }',
'.ignored-user .jive-icon-med, .ignored-user > a { display:none; }',
'.ignored-user .jive-table-cell-author .jive-username-link { float:left; padding-left: 1em; white-space: nowrap; }',
'.ignored-user .jive-table-cell-subject, .ignored-user  .jive-table-cell-modified, .ignored-user  .jive-table-cell-replies, .ignored-user .jive-table-cell-views { visibility:hidden; }',
'',
'.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' ) );
function vInsertSideBarToggle(){
var vJiveBody = document.getElementById( 'jive-body-main' );
if (GM_getValue( 'sidebar.hidden' )){
vJiveBody.className = 'GM-sidebar-hidden';
}
//-- add toggle switch
var vToggle = document.createElement( 'div' );
vToggle.className = 'jive-icon-gear jive-icon-med GM-sidebar-toggle';
vToggle.setAttribute( 'style', 'position: absolute' );
vJiveBody.insertBefore( vToggle, vJiveBody.firstChild );
vToggle.addEventListener( 'click', uSidebar, false );
}
 
//-- create generic toggle for ignore buttons, contributed by BlindWanderer
var vToggleBox = document.createElement( 'div' );
vToggleBox.className = 'GM-ignore-link-wrapper';
{
var span = document.createElement( 'span' );
span.appendChild( document.createTextNode( (vType) ? 'Ignore' : 'X' ) );
span.className = 'ignore';
vToggleBox.appendChild(span);
}
{
var span = document.createElement( 'span' );
span.appendChild( document.createTextNode( (vType) ? 'Unignore' : '#' ) );
span.className = 'unignore';
vToggleBox.appendChild(span);
}
function uInsertToggles( vPostNodes ){ //-- contributed by BlindWanderer, modifed by Void Singer
var vCount = 0;
//-- loop through posts
for (vCount; vCount < vPostNodes.length; ++vCount){
//-- get user profile link for position, and grab their system name
var vUserLink = vPostNodes.item( vCount ).getElementsByClassName( 'jive-username-link' ).item( 0 );
var vName = vUserLink.href.substring( vUserLink.href.lastIndexOf( '/' ) + 1 );
//-- tag post for ignore handling
vPostNodes.item( vCount ).parentNode.className += ' ' + vName; //-- changed to class vs custom attribute
if (vName.split( '.' ).slice( -1 )[0] != 'Linden'){
//-- check and ignore post if user already on ignore
var vIsIgnored = vIgnoreCache[vName] = GM_getValue( vName, false );
if (vIsIgnored){
uHide( vPostNodes.item( vCount ).parentNode, 'ignored-user' );
}
//-- clone ignore toggle into user info box, and tie it the switch function
var vIgnoreToggle = vToggleBox.cloneNode( true );
vIgnoreToggle.setAttribute( 'username', vName );
if (vType){
vUserLink.parentNode.insertBefore( vIgnoreToggle, vUserLink.nextSibling ); //--contributed by Blind Wanderer
}else{
vUserLink.parentNode.insertBefore( vIgnoreToggle, vUserLink );
}
vIgnoreToggle.addEventListener( 'click', uToggleIgnore, false );
}
}
//-- create, watch, and insert ignore link after user name
vObjLink = document.createElement( 'a' );
vObjLink.setAttribute( 'name', vStrUserName );
vObjLink.setAttribute( 'href', 'javascript:void( 0 );' );
vObjLink.setAttribute( 'style', 'color:orange;' );
vObjLink.setAttribute( 'onclick', "uIgnore( '" + vStrUserName + "');" );
vObjLink.textContent = vStrLinkText;
vObjLink.addEventListener( 'click', uPersist, true ); //-- this makes the magic work
vObjDiv.appendChild( document.createElement( 'br' ) );
vObjDiv.appendChild( vObjLink );
//-- jump to next div, AKA post body, insert name and style
vObjDiv = vColDivs.snapshotItem(++vIntCounter);
vObjDiv.setAttribute( 'name', vStrUserName + '.post' );
vObjDiv.setAttribute( 'style', vStrPostStyle );
}else{
vObjDiv.childNodes.item( 1 ).setAttribute( 'style', 'color:red' ); //-- unsafe, needs rewritten
vIntCounter++; //-- twas a Linden, skip the post body
}
}
}
}
}


//-- create and insert script object into page to handle ignore status changes
if (vType){
function uInjectStatusHandler(){
vInsertSideBarToggle();
var vInject = document.createElement( 'script' );
//-- insert Toggle in OP
vInject.setAttribute( 'type', 'application/javascript' );
uInsertToggles( document.getElementsByClassName( 'jive-thread-post-body' ) );
vInject.textContent =
//-- insert Toggle in replies
//-- this injected scriplet function will parse all posts / ignore links to change them when switching modes
uInsertToggles( document.getElementsByClassName( 'jive-thread-reply-body' ) );
"\nuIgnore = function( vStrName ){" +
//-- not happy with the separate inserts for OP and reply, but it wasn't worth a custom function to grab both
"\n  var vColLinks, vColPosts, vStrLinkText, vStrPostStyle;" +
"\n  vColLinks = document.getElementsByName( vStrName );" +          //-- collect all this names ignore links
"\n  vColPosts = document.getElementsByName( vStrName + '.post' );" + //-- collect all this names posts
"\n  vStrLinkText = vColLinks[0].textContent;" +                      //-- get action to preform from link text
"\n  if (vStrLinkText == 'Ignore'){" +                                //-- preset ignored attributes for links/posts
"\n    vStrLinkText = 'UnIgnore';" +
"\n    vStrPostStyle = 'display:none;';" +
"\n  }else{" +                                                        //-- preset unignored attributes for links/posts
"\n    vStrLinkText = 'Ignore';" +
"\n    vStrPostStyle = '';" +
"\n  }" +
"\n  for (var vIntCounter = vColLinks.length - 1; vIntCounter  > -1; vIntCounter --){" +                    //-- loop through and set attributes
"\n    vColLinks[vIntCounter].textContent = vStrLinkText;" +
"\n    vColPosts[vIntCounter].setAttribute( 'style', vStrPostStyle );" +
"\n  }" +
"\n}\n";
document.body.appendChild( vInject ); //-- inject scriptlet so it can run in the page context
}


//-- magic to persist ignore settings, runs in sandbox context
//-- clone edit/abuse to OP posts
function uPersist(){
var vGetOP  = document.getElementsByClassName( 'jive-thread-post-details' ).item( 0 );
if (this.textContent == "UnIgnore"){ //-- has the person been ignored?
if (null != vGetOP){
GM_setValue( this.name, 1 ); //-- store the name for future pages
vGetOP = vGetOP.getElementsByTagName( 'ul' ).item( 0 );
if (this.name == "Void.Singer"){ //-- should probably remove this if statement..... Naaaaah =P
var vGetReport = document.getElementById( 'jive-link-abuse' );
alert( "Well isn't that gratitude for ya\nYa know I wrote this ignore script... right?\n\n=p  thppppppt! " );
if (null != vGetReport){
var vClone = vGetReport.cloneNode( true );
vClone.id = 'GM-copy-control';
vClone.getElementsByTagName( 'span' ).item( 0 ).className = 'jive-icon-sml jive-icon-warn';
vGetOP.insertBefore( vClone, vGetOP.firstChild );
}else{
var vGetEdit = document.getElementById( 'jive-link-edit' );
if (null != vGetEdit){
var vClone = vGetEdit.cloneNode( true );
vClone.id = 'GM-copy-control';
vClone.getElementsByTagName( 'a' ).item( 0 ).innerHTML = '<span class="jive-icon-sml jive-icon-edit"></span>Edit';
vGetOP.insertBefore( vClone, vGetOP.firstChild );
}
}
}
}
}else{
}else{
if (GM_getValue( this.name ) == 1){ //-- delete names that aren't on ignore any more
if ((document.location.search.indexOf( '=discussions' ) > -1) || (document.location.search.indexOf( '=all' ) > -1)){
GM_deleteValue( this.name );
vInsertSideBarToggle();
 
//-- test and apply featured should be hidden
var vJiveFeatured = document.getElementById( 'jive-body-maincol' ).getElementsByClassName( 'jive-box-featured' ).item( 0 );
if (null != vJiveFeatured){
vJiveFeatured.id = 'GM-featured';
if (GM_getValue( 'featured.hidden' )){
vJiveFeatured.className += ' GM-featured-hidden';
}
}
 
//-- insert Toggle in regular threads
uInsertToggles( document.getElementsByClassName( 'jive-table-cell-author' ) );
 
if (null != vJiveFeatured){
vJiveFeatured = vJiveFeatured.getElementsByClassName( 'jive-box-header' ).item( 0 ).getElementsByTagName( 'h4' ).item( 0 );
//-- add toggle switch
var vToggle = document.createElement( 'div' );
vToggle.className = 'GM_Toggle';
{
var vSpan = document.createElement( 'span' );
vSpan.className = 'jive-icon-forbidden jive-icon-sml GM-hide-featured';
vToggle.appendChild( vSpan );
}
{
var vSpan = document.createElement( 'span' );
vSpan.className = 'jive-icon-plus jive-icon-sml GM-show-featured';
vToggle.appendChild( vSpan );
}
vJiveFeatured.insertBefore( vToggle, vJiveFeatured.firstChild );
vToggle.addEventListener( 'click', uFeatured, false );
//-- insert Toggle in feature threads
uInsertToggles( document.getElementsByClassName( 'jive-featured' ).item( 0 ).getElementsByClassName( 'font-color-meta-light' ) );
}
}
}
}
}
}
}


uInjectStatusHandler(); //-- inject status changer
var vIgnoreCache = {}; //-- contributed by BlindWanderer
uSetupPage(); //-- format the page


/*//--                           License Text                          --//*/
//-- jive version checking
/*//  Free to copy, use, modify, distribute, or sell, with attribution.   //*/
if (document.getElementsByClassName( 'jiveVersion' ).item( 0 ).textContent.indexOf( '98854' ) != -1){
/*//    (C)2009 (CC-BY) [ http://creativecommons.org/licenses/by/3.0 ]    //*/
uTweakPage( (document.location.href.indexOf( 'community' ) == -1) );
/*//  Void Singer [ https://wiki.secondlife.com/wiki/User:Void_Singer ]  //*/
}</javascript>
/*//  All usages must contain a plain text copy of the previous 2 lines. //*/
/*//--                                                                  --//*/
</javascript>
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
:[[User:Void_Singer/Programs#Return_to_Void_Singers_user_page|Return to top]]
}}
}}

Latest revision as of 07:06, 7 November 2010

SL Forum Ignore

Requirements

  • FireFox 2.0+, with Greasemonkey some-version-or-another
  • Google Chrome (natively supported)
  • Opera10.5+ and Safari4+ should be supported (post confirmation or bugs to the discussion page)

Features and limitations

  • Works on:
    • Second Life Forums
    • Second Life Answers
    • Second Life Commerce
  • in thread/message views [Flat or Threaded mode (large threaded thread may work slowly)]
    • Persistent (dark red) (un)ignore links on User posts
    • Clones "Edit" or "Report Abuse" buttons to bottom of Opening Posts as appropriate
  • in "all-content" and "discussion" views..
    • Persistent (dark red) (un)ignore links on User threads
    • Persistent (un)collapse (Gear icon) link for "side bar" content
    • Persistent (un)collapse ([Red'-', Green'+'] icon) link for "Featured" thread box

User Script

<javascript>// ==UserScript== // @name SL Forum Ignore // @namespace Private // @description +Ignore Links (threads/posts), +OP Edit/Abuse fix, +'Featured' and Sidebar collapsing // @include http://blogs.secondlife.com/thread/* // @include http://blogs.secondlife.com/message/* // @include http://blogs.secondlife.com/community/forums/* // @include http://blogs.secondlife.com/community/answers* // @include http://blogs.secondlife.com/community/commerce* // @include https://blogs.secondlife.com/thread/* // @include https://blogs.secondlife.com/message/* // @include https://blogs.secondlife.com/community/forums/* // @include https://blogs.secondlife.com/community/answers* // @include https://blogs.secondlife.com/community/commerce* // @match http://blogs.secondlife.com/thread/* // @match http://blogs.secondlife.com/message/* // @match http://blogs.secondlife.com/community/forums/* // @match http://blogs.secondlife.com/community/answers* // @match http://blogs.secondlife.com/community/commerce* // @match https://blogs.secondlife.com/thread/* // @match https://blogs.secondlife.com/message/* // @match https://blogs.secondlife.com/community/forums/* // @match https://blogs.secondlife.com/community/answers* // @match https://blogs.secondlife.com/community/commerce* // @version 1.6.1 // @copyright Void Singer 2010 [ https://wiki.secondlife.com/wiki/User:Void_Singer ] & BlindWanderer [ http://userscripts.org/users/4223 ] // @license CC-BY [ http://creativecommons.org/licenses/by/3.0 ] // @licesne.ext Free to copy, use, modify, distribute, or sell, with attribution. // ==/UserScript==

/*//-- added match statements for compatibility with chromium 'content scripts' --//*/ /*//-- IE7pro unsupported: lacks CSS inheritance & getElementsByClassName --//*/ /*//-- Updated for jive version changes & http access 5:20am Wed, April 14, 2010 --//*/ /*//-- expanded ignore to cover thread views in all content and discussion views --//*/ /*//-- added sidebar removal for thread/message, all content, and discussion view--//*/ /*//-- add collapsing for featured posts in all content, and discussion view --//*/ /*//-- removed Linden name coloring, since they added post coloring for them --//*/

//-- compatibility replacements for Chrome4+, Opera10.5+, Safari4+, I hope

if (typeof GM_addStyle == 'undefined'){ function GM_addStyle( vCss ){ var vStyle = document.createElement( 'style' ); vStyle.textContent = vCss; document.getElementsByTagName( 'head' )[0].appendChild( vStyle ); } } //-- "it's possible that *this* GM_ function is supported in chromium, but the others are not. can't find docs"

//-- compatibility replacements for Chrome4+, Opera10.5+, Safari4+, I hope

if (typeof GM_setValue == 'undefined'){ //-- native JSON and localStorage for GM_*Value replacement GM_getValue = function( vKey, vDefault ){ var vReturn = JSON.parse( window.localStorage.getItem( vKey ) ); return ((vReturn == null)? vDefault: vReturn); }

GM_setValue = function( vKey, vValue ){ window.localStorage.setItem( vKey, JSON.stringify( vValue ) ); }

GM_deleteValue = function( vKey ){ window.localStorage.removeItem( vKey ); } }

//-- function contributed by BlindWanderer

function uHide( vPostNode, vClass ){ vPostNode.className += ' ' + vClass; }

//-- function contributed by BlindWanderer

function uShow( vNode, vClass ){ vNode.className = vNode.className.split( ' ' ).filter( function( v ){ return v != vClass;} ).join( ' ' ); }

//-- function contributed by BlindWanderer, modifed by Void Singer

function uToggleIgnore(){ //-- no ancestor support outside of xpath? var vName = this.getAttribute( 'username' ); var vAction = (vIgnoreCache[vName] = !vIgnoreCache[vName])? uHide : uShow; if (vIgnoreCache[vName]){ GM_setValue( vName, true ); } else{ GM_deleteValue( vName ); } var vSwaps = document.getElementsByClassName( vName ); var vCount = 0; for (vCount; vCount < vSwaps.length; ++vCount){ vAction.apply( vAction, [vSwaps.item( vCount ), 'ignored-user'] ); } }

function uSidebar(){ var vStatus = !GM_getValue( 'sidebar.hidden' ); GM_setValue( 'sidebar.hidden', vStatus ); var vTag = document.getElementById( 'jive-body-main' ); vTag.className = (vStatus)? 'GM-sidebar-hidden' : ; }

function uFeatured(){ var vStatus = !GM_getValue( 'featured.hidden' ); GM_setValue( 'featured.hidden', vStatus ); var vNode = document.getElementById( 'GM-featured' ); var vAction = (vStatus) ? uHide : uShow; vAction.apply( vAction, [vNode, 'GM-featured-hidden'] ) }

//-- adds styles, ignore toggles, and marks post containers function uTweakPage( vType ){ //-- use style to reduce load, contributed by BlindWanderer, modifed by Void Singer GM_addStyle( [ '#GM-copy-control { font-weight: bold; }', , '.GM-ignore-link-wrapper { cursor:pointer; font-weight: bold; color: rgb( 96, 0, 0 ) !important; padding-right: 1em !important; }', '.font-color-meta-light .GM-ignore-link-wrapper { display:inline-block; };', , '.GM-sidebar-hidden #jive-body-sidebarcol-container { display: none; }', '.GM-sidebar-hidden #jive-body-maincol-container { width: 98%; }', //-- if this is set first, the view doesn't expand '.GM-sidebar-hidden #jive-body-sidebarcol-container { display: none; }', //-- if this isn't re-set here the list drops but doesn't hide , '.GM-toggle { cursor: pointer; }', '.GM-show-featured { display: none; }', '.GM-featured-hidden .jive-box-body { display: none; }', '.GM-featured-hidden .GM-hide-featured { display: none; }', '.GM-featured-hidden .GM-show-featured { display: block; }', , '.ignore { display:block; }', '.unignore { display:none; }', '.ignored-user .ignore {display:none; }', '.ignored-user .unignore {display:block; }', '.jive-table-cell-author .GM-ignore-link-wrapper { float:left; }', , 'tr.ignored-user { line-height: 0.0; }', '.ignored-user *[src] { display:none; }', '.ignored-user .jive-icon-med, .ignored-user > a { display:none; }', '.ignored-user .jive-table-cell-author .jive-username-link { float:left; padding-left: 1em; white-space: nowrap; }', '.ignored-user .jive-table-cell-subject, .ignored-user .jive-table-cell-modified, .ignored-user .jive-table-cell-replies, .ignored-user .jive-table-cell-views { visibility:hidden; }', , '.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' ) );

function vInsertSideBarToggle(){ var vJiveBody = document.getElementById( 'jive-body-main' ); if (GM_getValue( 'sidebar.hidden' )){ vJiveBody.className = 'GM-sidebar-hidden'; } //-- add toggle switch var vToggle = document.createElement( 'div' ); vToggle.className = 'jive-icon-gear jive-icon-med GM-sidebar-toggle'; vToggle.setAttribute( 'style', 'position: absolute' ); vJiveBody.insertBefore( vToggle, vJiveBody.firstChild ); vToggle.addEventListener( 'click', uSidebar, false ); }

//-- create generic toggle for ignore buttons, contributed by BlindWanderer var vToggleBox = document.createElement( 'div' ); vToggleBox.className = 'GM-ignore-link-wrapper'; { var span = document.createElement( 'span' ); span.appendChild( document.createTextNode( (vType) ? 'Ignore' : 'X' ) ); span.className = 'ignore'; vToggleBox.appendChild(span); } { var span = document.createElement( 'span' ); span.appendChild( document.createTextNode( (vType) ? 'Unignore' : '#' ) ); span.className = 'unignore'; vToggleBox.appendChild(span); }

function uInsertToggles( vPostNodes ){ //-- contributed by BlindWanderer, modifed by Void Singer var vCount = 0; //-- loop through posts for (vCount; vCount < vPostNodes.length; ++vCount){ //-- get user profile link for position, and grab their system name var vUserLink = vPostNodes.item( vCount ).getElementsByClassName( 'jive-username-link' ).item( 0 ); var vName = vUserLink.href.substring( vUserLink.href.lastIndexOf( '/' ) + 1 ); //-- tag post for ignore handling vPostNodes.item( vCount ).parentNode.className += ' ' + vName; //-- changed to class vs custom attribute if (vName.split( '.' ).slice( -1 )[0] != 'Linden'){ //-- check and ignore post if user already on ignore var vIsIgnored = vIgnoreCache[vName] = GM_getValue( vName, false ); if (vIsIgnored){ uHide( vPostNodes.item( vCount ).parentNode, 'ignored-user' ); } //-- clone ignore toggle into user info box, and tie it the switch function var vIgnoreToggle = vToggleBox.cloneNode( true ); vIgnoreToggle.setAttribute( 'username', vName ); if (vType){ vUserLink.parentNode.insertBefore( vIgnoreToggle, vUserLink.nextSibling ); //--contributed by Blind Wanderer }else{ vUserLink.parentNode.insertBefore( vIgnoreToggle, vUserLink ); } vIgnoreToggle.addEventListener( 'click', uToggleIgnore, false ); } } }

if (vType){ vInsertSideBarToggle(); //-- insert Toggle in OP uInsertToggles( document.getElementsByClassName( 'jive-thread-post-body' ) ); //-- insert Toggle in replies uInsertToggles( document.getElementsByClassName( 'jive-thread-reply-body' ) ); //-- not happy with the separate inserts for OP and reply, but it wasn't worth a custom function to grab both

//-- clone edit/abuse to OP posts var vGetOP = document.getElementsByClassName( 'jive-thread-post-details' ).item( 0 ); if (null != vGetOP){ vGetOP = vGetOP.getElementsByTagName( 'ul' ).item( 0 ); var vGetReport = document.getElementById( 'jive-link-abuse' ); if (null != vGetReport){ var vClone = vGetReport.cloneNode( true ); vClone.id = 'GM-copy-control'; vClone.getElementsByTagName( 'span' ).item( 0 ).className = 'jive-icon-sml jive-icon-warn'; vGetOP.insertBefore( vClone, vGetOP.firstChild ); }else{ var vGetEdit = document.getElementById( 'jive-link-edit' ); if (null != vGetEdit){ var vClone = vGetEdit.cloneNode( true ); vClone.id = 'GM-copy-control'; vClone.getElementsByTagName( 'a' ).item( 0 ).innerHTML = 'Edit'; vGetOP.insertBefore( vClone, vGetOP.firstChild ); } } } }else{

if ((document.location.search.indexOf( '=discussions' ) > -1)