/**
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
// DEBUG HINTS
// For most reliable re-run, ininstall, reinstall
/**
* @package Climate Audit Assistant
* @Copyright ClimateAudit.org 2009+. All right reserved
* @authors: MrPete
* @created: January 8, 2010
* @version 0.0.9
* @credits: Inspired by Mafia Wars Autoplayer script and more
*
* History:
* 0.0.9 Support new Lucia version.
* 0.0.8 All Open Science Blog Ring sites now should work. Comment reorder now optional. Many bugfixes.
*/
//
// Sites listed below are members of the new Open Source Webring
//
// ==UserScript==
// @name CA Assistant, Open Science webring edition
// @namespace ca-assist
// @description Enhances user experience on Open Science Web Ring courtesy of Climate Audit
// @copyright 2009+, MrPete (http://www.ClimateAudit.org) All right reserved
// @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html
// @include http://climateaudit.org/*
// @include http://www.climateaudit.org/*
// @include http://noconsensus.wordpress.com/*
// @include http://statpad.wordpress.com/*
// @include http://rankexploits.com/musings/*
// @include http://wattsupwiththat.com/*
// @include http://danhughes.auditblogs.com/*
// @include http://localhost/*
// @version 0.0.9
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
// @require http://www.climateaudit.info/ca-assist/jquery.ba-untils.min.js
// @require http://www.climateaudit.info/ca-assist/ca-assist-comment.js
// ==/UserScript==
var $j = jQuery.noConflict();
var SCRIPT = { // URL of the script for updates
url: 'http://climateaudit.info/ca-assist/ca-assist.user.js',
version: '0.0.9',
build: '41',
ajaxPage: 'inner2',
};
// Register debugOnOff, etc with Greasemonkey (for later)
GM_registerMenuCommand('CA Assistant - Turn Debugging Log On/Off', debugOnOff);
GM_registerMenuCommand('CA Assistant - Clear Saved Values', function() { clearSettings(); loadHome(); });
function loadHome() {}
if (window.top != window.self) { //don't run on frames or iframes
return;
}
String.prototype.trim = function() {
return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}
String.prototype.ltrim = function() {
return this.replace(/^\s\s*/, '');
}
String.prototype.rtrim = function() {
return this.replace(/\s\s*$/, '');
}
String.prototype.untag = function() {
//console.log('UNTAG:'+this);
return this.replace(/<[^>]+>/g, '');
}
/* **************************************************
Sort the comment tree
************************************************** */
//
// Detect which website style we're assisting
//
var siteType='CA'; // assume CA
//console.log('Testing site type');
//console.log('host:'+location.hostname);
var bFound=true;
switch(location.hostname) {
case 'climateaudit.org': siteType='CA';break;
case 'statpad.wordpress.com': siteType='RomanM';break;
case 'wattsupwiththat.com': siteType='WUWT';break;
case 'localhost':
case 'rankexploits.com': siteType='Lucia';break;
case 'danhughes.auditblogs.com': siteType='DanH';break;
case 'noconsensus.wordpress.com': siteType='JeffId';break;
default: // this only really works on a comment page...
bFound=false;
if ($j('#comments-list').length) {
// CA, RomanM
if ($j('#comments-list > ul:first').length) {
siteType='RomanM'; // UL instead of OL
}
} else if ($j('ol.commentlist').length) {
// DanH, JeffId
if ($j('ol.commentlist > li.comment:first').length) {
siteType='JeffId';
} else {
siteType='DanH'; // comment LI has no consistent class
}
} else if ($j('#content > span.KonaFilter').length) {
siteType='Lucia';
} else if ($j('dl.commentlist').length) {
siteType='WUWT';
}
}
DEBUG('Site type: '+siteType+(bFound? '*' : ''));
//listID where to find the comment list
//bSeqDate True if date element precedes each comment element (WUWT)
//dtRegEx string for finding date/time--convert to regex
//dtRegRep string for date/time result
//itemElm how to find each comment in the list
//dateText how to find date text, given we're pointing to the comment (or preceding item)
//replyElm on which element to attach the Paste Reply link
//bHasReply true if there's a reply link on each comment (otw, Paste Link will say "Re:")
switch (siteType) {
case 'RomanM': var cmtForm= { 'listID': 'ul.comment_list', 'listElm':'#commentListOL li','hideElm':'div.entry',
'threadElm':'#commentListOL > li','bSeqDate':0,'topDiv':'#container','replyElm':'div.reply:first',
'authElm':'span.comment_author:first','itemElm': 'li.comment', 'dateText': '.comment-meta:first', 'bHasReply':true };break;
case 'JeffId': var cmtForm= { 'listID': 'ol.commentlist', 'listElm':'#commentListOL li','hideElm':'',
'threadElm':'#commentListOL > li','bSeqDate':0,'topDiv':'#sitename','replyElm':'.comment-meta',
'authElm':'.comment-author cite','itemElm': 'li.comment', 'dateText': '.comment-meta', 'bHasReply':false };break;
case 'DanH': var cmtForm= { 'listID': 'ol.commentlist', 'listElm':'#commentListOL li','hideElm':'',
'threadElm':'#commentListOL > li','bSeqDate':0,'topDiv':'#header','replyElm':'.commentmetadata',
'authElm':'cite > a.url','itemElm': 'li', 'dateText': '.commentmetadata', 'bHasReply':false };break;
case 'Lucia': var cmtForm= { 'listID': 'div.commentlist', 'listElm':'div.comment','hideElm':'div.comment-text',
'threadElm':'div.comment','bSeqDate':0,'topDiv':'#bodyinner','replyElm':'.commentmetadata',
'authElm':'.comment-author','itemElm': 'div.comment', 'dateText': '.comment-date', 'bHasReply':false };break;
case 'WUWT': var cmtForm= { 'listID': 'dl.commentlist','listElm':'#commentListOL > div','hideElm':'',
'threadElm':'#commentListOL > div','bSeqDate':1,'topDiv':'#header','replyElm':'span.commentmetadata',
'authElm':'.comment-author:first','itemElm': 'dd.comment', 'dateText': 'span.commentmetadata', 'bHasReply':false };break;
default:
case 'CA': var cmtForm= { 'listID': '#comments-list ol','listElm':'#commentListOL li','hideElm':'',
'threadElm':'#commentListOL > li','bSeqDate':0, 'topDiv':'#header','replyElm':'.comment-meta:first',
'authElm':'.comment-author:first','itemElm': 'li.comment', 'dateText': '.comment-meta:first', 'bHasReply':true };break;
};
function getCmtDate(txt,bTest) {
// made a separate function. RegEx variables appear to cause Big Trouble.
//[optional 'Posted ', then mm ddth, yyyy at hh:mm pm
txt = txt.split('|',1)[0]; // remove any option stuff at the end...
var sRep='$1$3 $4';
var res = txt.replace(/(?:Posted )?([A-Za-z]+ [0-9]+)([a-z]*)(, [0-9]+) at ([0-9]+:[0-9]+ (AM|PM))+/i, sRep).trim();
return res;
}
//
// ICON INITIALIZATIONS
//
//create data uris for mini icon usage
var tabSelectedImage = '';
var infoIcon = '';
var closeButtonIcon = '';
var updateGoodIcon = '';
var badIcon = '';
var processIcon = '';
var goodIcon = '';
var warningIcon = '';
var hideIcon = '';
var redBgImage = '';
var autoLog = true;
var isNew = 8; // a "new" comment is less than 8 hours ago
var isOld = 24; // an "old" comment is more than 48 hours (values are NOT the official defaults; just set her temporarily)
var bShowThreads = 1; // default: do show threads
var bRecentLast = 1; // default: show in oldest-to-recent order
var bEnableOrder= 1; // default: do reorder comments
var bHideOld = 1; // default: do hide old comments
var bColorAge = 1; // default: do color comments by age
var bReorgRcntCmt = 1; // default: reorganize recent comments widget
//
// INIT
//
if (!initialized) {
//alert('INIT');
//console.log('do init');
var settingsOpen = false;
var debug = isChecked('enableDebug');
//console.log('debug is:'+(debug? 'true' :'false'));
// Check for a version change.
if (GM_getValue('version') != SCRIPT.version ||
GM_getValue('build') != SCRIPT.build) {
//console.log('do ver chg');
handleVersionChange();
//console.log('did ver chg');
}
// Check for missing settings.
//console.log('settings check');
if (GM_getValue('isOld') == undefined) {
saveDefaultSettings();
//console.log('saved default');
addToLog('info Icon', 'If you want to customize your view, please adjust your settings.');
//console.log('logged it');
}
//console.log('do refresh settings');
refreshSettings();
//console.log('refresh done');
var initialized = true;
//console.log('log refresh');
DEBUG('Completed initialize.');
} else {
alert('ALREADY INIT -- tell MrPete!');
}
//
// CODE HERE
//
DEBUG('Set up masthead');
customizeMasthead();
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
// MISC FIXUPS ON ***ALL*** PAGES
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
//
// Reorganize Recent Comments Sidebar
//
/////////////////////////////////////////////////////////////////
/* function sortrc(a,b) {
return a.id > b.id ? 1 : -1;
} */
if (bReorgRcntCmt) {
var elmRC = $j('ul#recentcomments');
var rcList= new Array();
if (elmRC.length) {
$j('.recentcomments').each(function (i) {
var elmLinks=$j('a',this);
switch (elmLinks.length) {
default:
case 1: // normal
var elm= $j(this).get(0);
var sAuth = elm.childNodes[0].textContent;
sAuth = sAuth.substring(0, sAuth.length-4);
var sURL = $j(elmLinks).attr('href');
var sTopic = $j(elmLinks).text();
break;
case 2: // Auth has a link
var elmA = $j('a:first',this);
var sAuth = elmA.text();
elmA = elmA.next();
var sURL = elmA.attr('href');
var sTopic = elmA.text();
break;
}
if (rcList[sTopic] == undefined) { rcList[sTopic]=''; }
rcList[sTopic]+= '
\n';
});
var sOut='';
for (rcKey in rcList) {
sOut +='
'+rcKey+'
\n';
// Create a nested list of the recent comments within the current post
sOut +='
\n'+rcList[rcKey]+'\n
\n';
}
$j(elmRC).html(sOut);
}
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
// AFTER THIS: functions ONLY on comment pages
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
DEBUG('Initial site-dependent comment page prep');
if (!$j(cmtForm.listID).length) { // don't waste time on non-comment pages
DEBUG('Not a comment page');
return;
}
switch (siteType) {
/* case 'Lucia':
$j('#comment').val(''); // clear comment block; has tabs for some reason??!
$j('.comment').wrapAll(''); // Wrap up comments inside a div
break; */
default:
$j(cmtForm.listID).attr('id','commentListOL');
}
DEBUG('Define main comment page functions');
var cmtDates = new Array();
var cmtCurDate = new Date;
var cmtOldAge, cmtNewAge;
function setAgeValues() {
cmtOldAge = cmtCurDate.valueOf() - isOld*60*60*1000;
cmtNewAge = cmtCurDate.valueOf() - isNew*60*60*1000;
}
const AGE_OLD = 0;
const AGE_NORM = 1;
const AGE_NEW = 2;
function getCommentAge(elm) {
// console.log('test:'+(cmtDates[elm.id]));
// console.log('diffn:'+(cmtDates[elm.id] - cmtOldAge));
// console.log('diffb:'+(cmtDates[elm.id] >= cmtOldAge));
var cmtAge = cmtDates[elm.id];
if (cmtAge <= cmtOldAge) return AGE_OLD;
if (cmtAge >= cmtNewAge) return AGE_NEW;
return AGE_NORM;
}
function getCmtNum(cmt) {
var id=cmt.id;
return 0+id.split('-').slice(-1);
}
//
// Sort comments, ascending/descending and threaded/unthreaded
//
function sortIDasc(a,b) {
return a.id > b.id ? 1 : -1;
}
function sortIDdesc(a,b) {
return a.id < b.id ? 1 : -1;
}
function getMaxTreeID(a) {
// Return max id from a and its child comment objects
var maxC=getCmtNum(a);
$j(cmtForm.itemElm,a).each(function (i) {
var cNum = getCmtNum(this);
if (cNum > maxC) { maxC = cNum; }
});
return maxC;
}
function sortTreeIDasc(a,b) {
return getMaxTreeID(a) > getMaxTreeID(b) ? 1 : -1;
}
function sortTreeIDdesc(a,b) {
return getMaxTreeID(a) < getMaxTreeID(b) ? 1 : -1;
}
var sReplyTxt= cmtForm.bHasReply ? "Paste Link" : "Reply w/ Link";
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
//
// WUWT wrap-pairs
// Each comment is a pair of
elements. Wrap them in a div
//
function setWUWTpairs() {
//var div = $j(cmtForm.listID).get (0);
//console.log('get all dt in: '+cmtForm.listID);
$j("dt",cmtForm.listID).each(function(){
var sDate=$j(this).text();
//console.log('raw date:'+sDate);
sDate=sDate.replace(/(\d+)[\s\c]*(\d+)[\s\c]*(\d+)/,'$2/$1/$3').trim();
var dd=$j(this).next().get(0);
// console.log('dd type:'+dd.nodeName);
var sTime=$j('span.comment-meta > small',dd).text().replace(/[()]/g,'');
var sID = dd.id;
var wrapID='caa'+sID;
var cmtURL='#'+sID;
// console.log('new date time:'+sDate+' '+sTime);
// console.log('id:'+sID);
$j(this).add(dd).wrapAll('');
// console.log('wrapped');
var elm=$j('#'+wrapID).get(0);
var cmtDate=new Date(sDate+' '+sTime);
// console.log(elm.nodeName);
cmtDates[wrapID]=cmtDate.valueOf();
if (isNaN(cmtDates[wrapID])) {
DEBUG('NaN: "'+cmtDateStr+'"');
}
$j(cmtForm.replyElm,elm).append(' | '+sReplyTxt+'');
if (bHideOld || bColorAge) AgeComment(elm);
});
}
//
//
// Lucia's Fix (comments need id's, auths marked, dates extracted, etc)
//
function setCommentInfo(elm) {
//console.log('finding id');
var iFound=1;
var bIsComment=1;
var div = $j("p.commenticon",elm).get (0);
for (var i in div.childNodes) {
if (!bIsComment || iFound > 6) break;
var child = div.childNodes[i];
if (child.nodeType === 1 || child.nodeType === 3) {
//console.log ('childTxt: "'+child.textContent+'" (iFound:'+iFound+')');
//console.log ('childHTML:'+child.innerHTML);
switch (iFound++) {
case 1: var sAuth = child.textContent.trim();$j(child).addClass('comment-author');break;
case 2: break; // paren
case 3: if (child.textContent != 'Comment') bIsComment=0;
break;
case 4: var sId = child.textContent.replace(/\#([\d]+)\)/,'Comment-$1').trim();break;
case 5: break; // blank
case 6: var sDate = child.textContent.trim(); break;
}
}
}
if (bIsComment) {
$j(elm).attr('id',sId);
// Now set up the id, reply link, etc
var cmtURL='#'+elm.id;
var cmtDateStr = getCmtDate(sDate,false);
var cmtDate = new Date(cmtDateStr);
cmtDates[elm.id]=cmtDate.valueOf();
if (isNaN(cmtDates[elm.id])) {
DEBUG('NaN: "'+cmtDateStr+'"');
}
$j(cmtForm.replyElm,elm).append(' | '+sReplyTxt+'');
}
}
//
// ADD REPLY LINKS
//
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
function setReplyLink(elm) {
var cmtURL='#'+elm.id;
var cmtDateStr = getCmtDate($j(cmtForm.dateText,elm).text(),false);
var cmtDate = new Date(cmtDateStr);
cmtDates[elm.id]=cmtDate.valueOf();
if (isNaN(cmtDates[elm.id])) {
DEBUG('NaN: "'+cmtDateStr+'"');
}
var dbgText = ''; // (debug ? ' (id:'+elm.id+',dt:'+cmtDateStr+')' : '');
$j(cmtForm.replyElm,elm).append(' | '+sReplyTxt+''+dbgText);
}
// operates on an object inside the comment of interest. The comment is 2nd-level parent.
// the cmtDates[] array is not available; not certain why.
function pasteReplyLink() {
var cmtElm = $j(this).parent();
switch(siteType) {
case 'WUWT': cmtElm=$j(cmtElm).parent(); // two extra for WUWT
case 'Lucia': cmtElm=$j(cmtElm).parent(); // one extra
default:
cmtElm=$j(cmtElm).parent(); // up one
}
if (siteType=='WUWT') {
var cmtURL='#'+$j('dd',cmtElm).attr('id');
} else {
var cmtURL='#'+cmtElm.attr('id');
}
var cmtAuth = $j(cmtForm.authElm,cmtElm).text().trim();
if (siteType=='WUWT') {
var sDate=$j('dt',cmtElm).text();
sDate=sDate.replace(/(\d+)[\s\c]*(\d+)[\s\c]*(\d+)/,'$2/$1/$3').trim();
var sTime=$j('dd span.comment-meta > small',cmtElm).text().replace(/[()]/g,'');
var cmtDateStr = sDate+' '+sTime;
} else {
var cmtDateStr = getCmtDate($j(cmtForm.dateText,cmtElm).text(),false);
}
var cmtDate = new Date(cmtDateStr);
var cmtM= months[cmtDate.getMonth()];
var cmtHr = cmtDate.getHours();
var cmtMin = cmtDate.getMinutes();
if (cmtHr < 10) {cmtHr = '0'+cmtHr; }
if (cmtMin < 10) {cmtMin = '0'+cmtMin; }
var cmtFmtDate = cmtM+' '+cmtDate.getDate()+' '+cmtHr+':'+cmtMin;
var myValue = ((cmtForm.bHasReply) && ($j(this).text()=='Paste Link')) ? '' : 'Re: ';
myValue +=''+cmtAuth+' ('+cmtFmtDate+')'+', ';
var sel, startPos, endPos, scrollTop;
myField=document.getElementById('comment');
//IE support
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
myField.focus();
}
//MOZILLA/NETSCAPE support
else if (myField.selectionStart || myField.selectionStart == '0') {
startPos = myField.selectionStart;
endPos = myField.selectionEnd;
scrollTop = myField.scrollTop;
myField.value = myField.value.substring(0, startPos)
+ myValue
+ myField.value.substring(endPos, myField.value.length);
myField.focus();
myField.selectionStart = startPos + myValue.length;
myField.selectionEnd = startPos + myValue.length;
myField.scrollTop = scrollTop;
} else {
myField.value += myValue;
myField.focus();
}
}
//
// Update each comment:
// - set Reply Link
// - color and/or hide as needed
//
function AgeComment(elm) {
switch (getCommentAge(elm)) {
case AGE_OLD:
if (bHideOld) {
(cmtForm.hideElm.length ? $j(cmtForm.hideElm,elm) : $j(elm)).css("display","none");
} else if (bColorAge) { $j(elm).addClass("cmtOld"); }
break;
case AGE_NEW:
if (bColorAge) { $j(elm).addClass("cmtNew"); }
break;
case AGE_NORM:
if (bColorAge) { $j(elm).addClass("cmtNorm"); }
}
}
function FixComment(i) {
// console.log('Fixing '+i);
/* if (siteType=='Lucia') {
setCommentInfo(this);
if (bHideOld || bColorAge) AgeComment(this);
} else { */
setReplyLink(this); // only need to do this one time
if (bHideOld || bColorAge) AgeComment(this);
// }
}
function setupComments() {
setAgeValues();
if (siteType=='WUWT') {
setWUWTpairs();
} else {
DEBUG('cmt setup');
//$j(cmtForm.listID).css("display","none"); // hide them all for a bit
//DEBUG('Comments hidden');
$j(cmtForm.listElm).each(FixComment);
DEBUG('Comments enhanced');
}
if (bEnableOrder) {
DEBUG('cmt ReOrdering:');
if (bShowThreads) {
DEBUG('Threaded, '+$j(cmtForm.threadElm).length+' items');
if (bRecentLast) {
$j(cmtForm.threadElm).sort(sortTreeIDasc).prependTo('#commentListOL');//threaded tree
} else {
$j(cmtForm.threadElm).sort(sortTreeIDdesc).prependTo('#commentListOL');//threaded tree
}
} else {
DEBUG('UNthreaded, '+$j(cmtForm.listElm).length+' items');
if (bRecentLast) {
$j(cmtForm.listElm).sort(sortIDasc).prependTo('#commentListOL');//threaded tree
} else {
$j(cmtForm.listElm).sort(sortIDdesc).prependTo('#commentListOL');//threaded tree
}
}
DEBUG('comments reordered');
}
$j('a.comment-paste-link').click(pasteReplyLink);
$j('a.comment-reply-link').click(pasteReplyLink);
DEBUG('comment links activated');
//$j(cmtForm.listID).css("display","inline"); // restore the comments
//DEBUG('comment display restored');
}
setupComments();
//
// Comment preview arrives through the new CA-Assist-Comment module :)
//
//
// UTILITY FUNCTIONS
//
//
// UI for CA-Assistant
//
function customizeMasthead() {
if ($j('#wpa_menu').length) return;
// Get the masthead.
if (!$j(cmtForm.topDiv).length) return;
// Make a container for the ca-assist menu.
var wpaTitle = 'CA-Assist ['+siteType+'] ' + SCRIPT.version + ' (Build ' + SCRIPT.build + ')';
$j(cmtForm.topDiv).append('
'+wpaTitle+'
Settings | Log
');
$j('span#wpa_settings').click(toggleSettingsBox);
$j('span#wpa_log').click(showLogBox);
// Show resume or paused based on if we are running or not.
// updateMastheadMenu();
}
// ********************************************************************
// ********************************************************************
// DEBUG AND LOG BOX
// ********************************************************************
// ********************************************************************
function showLogBox() {
if (!$j('#wpaLogBox').length) {
createLogBox();
} else {
$j('#wpaLogBox').css('display','block');
}
if (!debug && GM_getValue('logOpen') != 'open' &&
!isChecked('autoLog')) {
alert('Logging is not enabled. To see new activity here, please open your settings and check "Enable logging" in the General tab.');
}
GM_setValue('logOpen', 'open');
}
function hideLogBox() {
$j('#wpaLogBox').css('display','none');
GM_setValue('logOpen', 'closed');
}
function clearLog() {
GM_setValue('itemLog', '');
//reset the log box
$j('#logBox').text('');
}
function createLogBox() {
// Define CSS styles.
makeElement('style', document.getElementsByTagName('head')[0], {'type':'text/css'}).appendChild(document.createTextNode(
'#wpaLogBox div.mouseunderline:hover{text-decoration:underline}' +
'#wpaLogBox .logEvent{border-bottom:1px solid #333; padding:4px 0px}' +
'#wpaLogBox .eventTime{color:#888; font-size: 10px; width:75px; float:left}' +
'#wpaLogBox .eventBody{width:330px; float:right}' +
'#wpaLogBox .eventTime,#wpaLogBox .eventIcon,#wpaLogBox .eventBody{}' +
'#wpaLogBox .eventBody .good {color:#52E259;font-weight:bold;}' +
'#wpaLogBox .eventBody .bad {color:#EC2D2D;font-weight:bold;}' +
'#wpaLogBox .eventBody .warn {color:#EC2D2D;}' +
'#wpaLogBox .eventBody .user {color:#FFD927;}' +
'#wpaLogBox .clear{clear:both}' +
'#wpaLogBox .logEvent.Icon{background-repeat: no-repeat; background-position: 75px}' +
'#wpaLogBox .logEvent.process.Icon{background-image:url(' + stripURI(processIcon) + ')}' +
'#wpaLogBox .logEvent.warning.Icon{background-image:url(' + stripURI(warningIcon) + ')}' +
'#wpaLogBox .logEvent.info.Icon{background-image:url(' + stripURI(infoIcon) + ')}' +
'#wpaLogBox .logEvent.updateGood.Icon{background-image:url(' + stripURI(updateGoodIcon) + ')}' +
'#wpaLogBox .logEvent.good.Icon{background-image:url(' + stripURI(goodIcon) + ')}' +
'#wpaLogBox .logEvent.bad.Icon{background-image:url(' + stripURI(badIcon) + ')}'
));
var wpaLogBox = makeElement('div', document.body, {'id':'wpaLogBox', 'style':'position: fixed; right: 30px; top: 55px; bottom: 10px; width: 450px; background: black url(http://climateaudit.files.wordpress.com/2009/11/climateauditbannerplain.jpg) no-repeat; text-align: left; padding: 5px; border: 1px solid; border-color: #FFFFFF; z-index: 98; font-size: 12px;'});
var logClrButton = makeElement('div', wpaLogBox, {'class':'mouseunderline', 'style':'position: absolute; left: 5px; top: 0px; font-weight: 600; cursor: pointer; color: rgb(255, 217, 39);'});
logClrButton.appendChild(document.createTextNode('clear log'));
logClrButton.addEventListener('click', clearLog, false);
var closeLogButton = makeElement('div', wpaLogBox, {'class':'mouseunderline', 'id':'wpa_close_log','style':'position: absolute; right: 5px; top: 0px; font-weight: 600; cursor: pointer; color: rgb(255, 217, 39);'});
closeLogButton.appendChild(document.createTextNode('close'));
closeLogButton.addEventListener('click', hideLogBox, false);
var title = 'Click to toggle debug log';
var debugElt = makeElement('div', wpaLogBox, {'class':'mouseunderline', 'title':title,'id':'wpa_debug_log', 'style':'position: absolute; right: 80px; top: 0px; font-weight: 600; cursor: pointer; color: rgb(' + (debug ? '255' : '100') + ', 0, 0);'});
debugElt.appendChild(document.createTextNode('debug'));
debugElt.addEventListener('click', debugOnOff, false);
var logBox = makeElement('div', wpaLogBox, {'id':'logBox', 'style':'position: absolute; overflow: auto; right: 0px; top: 20px; bottom: 68px; width: 448px; background-color: #111111; font-size:11px; color: #BCD2EA; text-align: left; padding: 5px; border: 1px solid;'});
logBox.innerHTML = GM_getValue('itemLog', '');
}
function debugOnOff() {
var debugElt = document.getElementById('wpa_debug_log');
if (isChecked('enableDebug')) {
addToLog('info Icon', 'Debug logging disabled.');
GM_setValue('enableDebug', 0);
debug = false;
if (GM_getValue('logOpen') != 'open') {
alert('Debug logging disabled.');
} else {
if (debugElt) debugElt.style.color = 'rgb(100, 0, 0)';
}
} else {
GM_setValue('enableDebug', 'checked');
debug = true;
showLogBox();
addToLog('info Icon', 'Debug logging enabled.');
if (debugElt) debugElt.style.color = 'rgb(255, 0, 0)';
debugDumpSettings();
}
}
function DEBUG(line, level) {
var level = (level == null) ? 0 : level;
if (debug) {
addToLog('info Icon', line);
GM_log(line, level);
}
}
function isLoggable(line) { return 1; } // maybe someday
function addToLog(icon, line) {
if (!debug && !isChecked('autoLog')) {
return;
}
// Do not log anything if log filter condition is met
if (!isLoggable(line)) {
return;
}
// Create a datestamp, formatted for the log.
var currentTime = new Date();
var m_names = new Array('Jan', 'Feb', 'Mar',
'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec');
var timestampdate = m_names[currentTime.getMonth()] + ' ' + currentTime.getDate();
// Create a timestamp, formatted for the log.
var hours = currentTime.getHours();
if (hours >= 12) {
hours = hours - 12;
var ampm = ' PM';
} else {
var ampm = ' AM';
}
if (hours == 0) {
hours = 12;
}
var timestamptime = hours + ':' +
(currentTime.getMinutes() < 10 ? 0 : '') +
currentTime.getMinutes() + ':' +
(currentTime.getSeconds() < 10 ? 0 : '') +
currentTime.getSeconds() +
ampm;
// Get a log box to work with.
var logBox = document.getElementById('logBox');
if (!logBox) {
if (!addToLog.logBox) {
// There's no log box, so create one.
addToLog.logBox = document.createElement('div');
addToLog.logBox.innerHTML = GM_getValue('itemLog', '');
}
logBox = addToLog.logBox;
}
var logLen = logBox.childNodes.length;
// Determine whether the new line repeats the most recent one.
var repeatCount;
if (!logLen) console.log("No logLEN!!");
if (logLen) {
var elt = logBox.firstChild.childNodes[1];
if (elt && ((elt.innerHTML).untag()).indexOf(((line).untag())) == 0) {
if (elt.innerHTML.match(/\((\d+) times\)$/)) {
repeatCount = parseInt(RegExp.$1) + 1;
} else {
repeatCount = 2;
}
line += ' (' + repeatCount + ' times)';
}
}
// Create the new log entry.
var lineToAdd = document.createElement('div');
lineToAdd.className = 'logEvent ' + icon;
lineToAdd.innerHTML = '
Display ReOrder \n'+
'(On largest pages, can take a few seconds) \n'+
'
\n'+
'
\n'+
' \n'+
'
\n'+
'
\n'+
' \n'+
'
\n'+
' \n'+
'
\n'+
'
\n'+
' \n'+
'
\n'+
'
\n'+
' \n'+
' \n'+
'
\n'+
'
\n'+
' \n'+
'
\n'+
'
\n'+
' \n'+
'
\n'+
'
\n'+
' \n'+
'
\n'+
' \n'+
'
\n'+
'';
$j(list).append(sThreadDisplay);
return commentsTab;
}
// Create About tab
function createAboutTab () {
var elt, title, id, label;
var aboutTab = makeElement('div', null, {'id':'aboutTab', 'class':'tabcontent', 'style':'background: #030;width:380px'});
var sAbout = ''+
'
CA Assist, Version \n'+SCRIPT.version+
', Build '+SCRIPT.build+'
\n'+
'
What Is This: \n'+
'The CA Assist tool helps ease the way toward substantial discussion of Open Science topics. It has been tuned to support blog sites that participate or encourage an Open Science process, particularly with respect to in-depth multidisciplinary understanding of Climate Science. (For now, only certain sites are supported.)\n'+
'
Contributors: \n'+
'MrPete\n'+
' With much thanks to the Open Source Software community, especially the makers of jQuery, GreaseMonkey, etc\n'+
'';
$j(aboutTab).append(sAbout);
return aboutTab;
}
function handleVersionChange() {
addToLog('updateGood Icon', 'Now running version ' + SCRIPT.version + ' build ' + SCRIPT.build);
GM_setValue('version', SCRIPT.version);
GM_setValue('build', SCRIPT.build);
// Check for invalid settings and upgrade them.
}
function saveDefaultSettings() {
// Assume all settings have been cleared and set defaults.
// For groups of radio buttons, one must be checked and all others cleared.
// For checkboxes, no need to default if the option should be off.
// General tab.
GM_setValue('autoLog', 'checked');
GM_setValue('autoLogLength', '300');
GM_setValue('enableDebug','checked');
GM_setValue('isNew', '8');
GM_setValue('isOld', '24');
GM_setValue("bColorAge",'checked');
GM_setValue("bHideOld",'checked');
GM_setValue("bShowThreads",'checked');
GM_setValue("bRecentLast",'checked');
GM_setValue("bEnableOrder",'checked');
GM_setValue("bReorgRcntCmt",'checked');
// Other settings.
GM_setValue('logOpen', 'open');
addToLog('process Icon', 'Options reset to defaults.');
}
function helpSettings() {
// Open the instructions page.
var tabs = document.getElementById('tabNav');
var helpName;
// Get the active tab and open corresponding wiki page
if (tabs) {
for (var i = 0, iLength=tabs.childNodes.length; i < iLength; ++i) {
if (tabs.childNodes[i].className == 'selected')
helpName = tabs.childNodes[i].id;
}
window.open('http://climateaudit.org/ca-assistant/#' + helpName);
}
}
function saveSettings() {
autoLog = (document.getElementById('autoLog').checked === true);
bColorAge = (document.getElementById('bColorAge').checked === true);
bHideOld = (document.getElementById('bHideOld').checked === true);
bShowThreads = (document.getElementById('bShowThreads').checked === true);
bRecentLast = (document.getElementById('bRecentLast').checked === true);
bEnableOrder = (document.getElementById('bEnableOrder').checked === true);
bReorgRcntCmt = (document.getElementById('bReorgRcntCmt').checked === true);
isNew = document.getElementById('isNew').value;
isOld = document.getElementById('isOld').value;
GM_setValue ('isNew', isNew);
GM_setValue ('isOld', isOld);
saveCheckBoxElementArray(['autoLog','bColorAge','bHideOld','bShowThreads','bRecentLast','bEnableOrder','bReorgRcntCmt']);
toggleSettingsBox();
}
function refreshSettings() {
autoLog = GM_getValue('autoLog','checked');
bColorAge = GM_getValue('bColorAge','checked');
bHideOld = GM_getValue('bHideOld','checked');
bShowThreads = GM_getValue('bShowThreads','checked');
bRecentLast = GM_getValue('bRecentLast','checked');
bEnableOrder = GM_getValue('bEnableOrder','checked');
bReorgRcntCmt = GM_getValue('bReorgRcntCmt','checked');
isNew = GM_getValue('isNew',8);
isOld = GM_getValue('isOld',48);
}
//update the script (by Richard Gibson; changed by ms99 and blannie)
function updateScript() {
try {
if (!GM_getValue) {
return; // Only do this inside GM
}
GM_xmlhttpRequest({
method: 'GET',
url: SCRIPT.url + '?source', // don't increase the 'installed' count; just for checking
onload: function(result) {
if (result.status != 200) {
return;
}
if (!result.responseText.match(/build:\s+'(\d+)/)) return;
var theOtherBuild = parseInt(RegExp.$1);
var runningBuild = parseInt(SCRIPT.build);
var theOtherVersion = result.responseText.match(/@version\s+([\d.]+)/)? RegExp.$1 : '';
if (theOtherBuild < runningBuild) {
if (window.confirm('You have a beta version (build ' + runningBuild + ') installed.\n\nDo you want to DOWNGRADE to the most recent official release (version ' + theOtherVersion + ')?\n')) {
//clearSettings();
window.location.href = SCRIPT.url;
}
return;
} else if (theOtherBuild > runningBuild ||
theOtherVersion != SCRIPT.version) {
if (window.confirm('Version ' + theOtherVersion + ' is available!\n\n' + 'Do you want to upgrade?' + '\n')) {
//clearSettings();
window.location.href = SCRIPT.url;
}
} else {
alert('You already have the latest version.');
return;
}
}
});
} catch (ex) {
addToLog('warning Icon', ex);
}
}
function makeElement(type, appendto, attributes, checked, chkdefault) {
var element = document.createElement(type);
if (attributes != null) {
for (var i in attributes) {
element.setAttribute(i, attributes[i]);
}
}
if (checked != null) {
if (GM_getValue(checked, chkdefault) == 'checked') {
element.setAttribute('checked', 'checked');
}
}
if (appendto) {
appendto.appendChild(element);
}
return element;
}
// Toggle checkbox element and return true if it is checked
function toggleCheckElt(eltId) {
if (isChecked(eltId)) {
GM_setValue(eltId, '0');
return false;
} else {
GM_setValue(eltId, 'checked');
return true;
}
}
// Save an array of checkbox elements
function saveCheckBoxElementArray(arrayEltIds) {
for (var i=0; i