Difference between revisions of "User:Void Singer/SL Forum Ignore"
(condense the xpath (small speedup i think)...) |
Void Singer (talk | contribs) m (updated) |
||
Line 15: | Line 15: | ||
// @name SL Forum Ignore | // @name SL Forum Ignore | ||
// @namespace Private | // @namespace Private | ||
// @description | // @description +Ignore Links on User Posts on SL Forum Discussions/Questions, +Make Linden Names RED, +OP Edit fix | ||
// @include https://blogs.secondlife.com/thread/* | // @include https://blogs.secondlife.com/thread/* | ||
// @include https://blogs.secondlife.com/message/* | // @include https://blogs.secondlife.com/message/* | ||
// @match https://blogs.secondlife.com/thread/* | |||
// @match https://blogs.secondlife.com/message/* | |||
// @version 1.3 | |||
// @copyright Void Singer 2009 [ 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 --//*/ | |||
//-- 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 | function uHide( vPostNode ){ | ||
vPostNode.className += ' ignored-user'; | |||
} | |||
//-- function contributed by BlindWanderer | |||
function uShow( vPostNode ){ | |||
vPostNode.className = vPostNode.className.split( ' ' ).filter( function( v ){ return v != 'ignored-user';} ).join( ' ' ); | |||
} | } | ||
//-- | //-- function contributed by BlindWanderer, modifed by Void Singer | ||
function | function uToggleIgnore(){ | ||
//-- no ancestor support outside of xpath? | |||
GM_setValue( | var vName = this.getAttribute( 'username' ); | ||
//-- ?is there really any savings to caching instead of a direct call to GM_getValue? | |||
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 )] ); | |||
} | |||
} | |||
//-- adds styles, ignore toggles, and marks post containers | |||
function uTweakPage(){ | |||
//-- use style to reduce load, contributed by BlindWanderer, modifed by Void Singer | |||
GM_addStyle( [ | |||
'.GM-Fix-Thread-Edit {', | |||
' background: url( "../images/jive-icon-edit-16x16.gif" ) no-repeat scroll left center transparent;', | |||
' font-weight: bold;', | |||
' padding-left: 17px;', | |||
' margin-right: 0.5em;', | |||
' float: right;}', | |||
'', | |||
'.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;}', | |||
'', | |||
'div[class$=".Linden"] div.jive-author div.jive-username-link-wrapper > a { color:#BB0000!important; }', | |||
].join( '\n' ) ); | |||
//-- clone edit thread link to OP | |||
var vGetOP = document.getElementsByClassName( 'jive-thread-post-details' ).item( 0 ); | |||
var vGetEdit = document.getElementsByClassName( 'jive-link-edit' ).item( 0 ); | |||
if ((null != vGetEdit) && (null != vGetOP)){ //-- need to text both for flat paged views (edit still shows on follow-up pages) | |||
var vCloneEdit = vGetEdit.cloneNode( true ); | |||
vGetOP.appendChild( vCloneEdit ); | |||
vCloneEdit.className = 'GM-Fix-Thread-Edit'; | |||
} | |||
//-- 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( 'Ignore' ) ); | |||
span.className = 'ignore'; | |||
vToggleBox.appendChild(span); | |||
} | |||
{ | |||
var span = document.createElement( 'span' ); | |||
span.appendChild( document.createTextNode( '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 | |||
//-- ?is there really any savings to caching instead of a direct call to GM_getValue? | |||
var vIsIgnored = vIgnoreCache[vName] = GM_getValue( vName, false ); | |||
if (vIsIgnored){ | |||
uHide( vPostNodes.item( vCount ).parentNode ); | |||
} | |||
//-- clone ignore toggle into user info box, and tie it the switch function | |||
var vIgnoreToggle = vToggleBox.cloneNode( true ); | |||
//-- ?no ancestor support outside of xpath? | |||
vIgnoreToggle.setAttribute( 'username', vName ); | |||
vUserLink.parentNode.insertBefore( vIgnoreToggle, vUserLink.nextSibling ); //--contributed by Blind Wanderer | |||
vIgnoreToggle.addEventListener( 'click', uToggleIgnore, false ); | |||
} | |||
} | } | ||
} | } | ||
//-- 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 | |||
} | } | ||
//-- ?is there really any savings to caching instead of a direct call to GM_getValue? | |||
var vIgnoreCache = {}; //-- contributed by BlindWanderer | |||
/ | //-- jive version checking | ||
if (document.getElementsByClassName( 'jiveVersion' ).item( 0 ).textContent.indexOf( '80211' ) != -1){ | |||
uTweakPage(); | |||
}</javascript> | |||
</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]] | ||
}} | }} |
Revision as of 20:41, 21 February 2010
SL Forum Ignore
Features:
- requires FireFox 2.0
- requires Greasemonkey some-version-or-another
User Script
<javascript>// ==UserScript== // @name SL Forum Ignore // @namespace Private // @description +Ignore Links on User Posts on SL Forum Discussions/Questions, +Make Linden Names RED, +OP Edit fix // @include https://blogs.secondlife.com/thread/* // @include https://blogs.secondlife.com/message/* // @match https://blogs.secondlife.com/thread/* // @match https://blogs.secondlife.com/message/* // @version 1.3 // @copyright Void Singer 2009 [ 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 --//*/
//-- 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 ){ vPostNode.className += ' ignored-user'; }
//-- function contributed by BlindWanderer
function uShow( vPostNode ){ vPostNode.className = vPostNode.className.split( ' ' ).filter( function( v ){ return v != 'ignored-user';} ).join( ' ' ); }
//-- function contributed by BlindWanderer, modifed by Void Singer
function uToggleIgnore(){ //-- no ancestor support outside of xpath? var vName = this.getAttribute( 'username' ); //-- ?is there really any savings to caching instead of a direct call to GM_getValue? 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 )] ); } }
//-- adds styles, ignore toggles, and marks post containers function uTweakPage(){ //-- use style to reduce load, contributed by BlindWanderer, modifed by Void Singer GM_addStyle( [ '.GM-Fix-Thread-Edit {', ' background: url( "../images/jive-icon-edit-16x16.gif" ) no-repeat scroll left center transparent;', ' font-weight: bold;', ' padding-left: 17px;', ' margin-right: 0.5em;', ' float: right;}', , '.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;}', , 'div[class$=".Linden"] div.jive-author div.jive-username-link-wrapper > a { color:#BB0000!important; }', ].join( '\n' ) );
//-- clone edit thread link to OP var vGetOP = document.getElementsByClassName( 'jive-thread-post-details' ).item( 0 ); var vGetEdit = document.getElementsByClassName( 'jive-link-edit' ).item( 0 ); if ((null != vGetEdit) && (null != vGetOP)){ //-- need to text both for flat paged views (edit still shows on follow-up pages) var vCloneEdit = vGetEdit.cloneNode( true ); vGetOP.appendChild( vCloneEdit ); vCloneEdit.className = 'GM-Fix-Thread-Edit'; }
//-- 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( 'Ignore' ) ); span.className = 'ignore'; vToggleBox.appendChild(span); } { var span = document.createElement( 'span' ); span.appendChild( document.createTextNode( '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 //-- ?is there really any savings to caching instead of a direct call to GM_getValue? var vIsIgnored = vIgnoreCache[vName] = GM_getValue( vName, false ); if (vIsIgnored){ uHide( vPostNodes.item( vCount ).parentNode ); } //-- clone ignore toggle into user info box, and tie it the switch function var vIgnoreToggle = vToggleBox.cloneNode( true ); //-- ?no ancestor support outside of xpath? vIgnoreToggle.setAttribute( 'username', vName ); vUserLink.parentNode.insertBefore( vIgnoreToggle, vUserLink.nextSibling ); //--contributed by Blind Wanderer vIgnoreToggle.addEventListener( 'click', uToggleIgnore, false ); } } } //-- 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 }
//-- ?is there really any savings to caching instead of a direct call to GM_getValue? var vIgnoreCache = {}; //-- contributed by BlindWanderer
//-- jive version checking if (document.getElementsByClassName( 'jiveVersion' ).item( 0 ).textContent.indexOf( '80211' ) != -1){ uTweakPage(); }</javascript>