Created
February 16, 2013 20:17
-
-
Save markbahnman/4968550 to your computer and use it in GitHub Desktop.
My initial refactor of the Hubski Enhancement Suite using jQuery and the module pattern.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Hubski Enhancement Suite | |
// @namespace http://joshparnham.com/ | |
// @description Several feature additions to Hubski.com | |
// @copyright Josh Parnham 2013 (http://joshparnham.com/) | |
// @license LGPL | |
// @author joshparnham | |
// @include http://hubski.com/* | |
// @include https://hubski.com/* | |
// @version 0.2.1 | |
// ==/UserScript== | |
/* | |
* This function is here to provide cross-compatibility with chrome. | |
* It injects this userscript into the page so it can access jQuery. | |
* | |
* Based off the function in this blog post: | |
* http://erikvold.com/blog/index.cfm/2010/6/14/using-jquery-with-a-user-script | |
*/ | |
function addScript(callback) { | |
window.onload = function() { | |
var script = document.createElement('script'); | |
script.textContent = '(' + callback.toString() + ')();'; | |
document.body.appendChild(script); | |
} | |
} | |
function main() { | |
var currentUser = $('.topmaintitle').html(); | |
// URLs | |
var feedURL = 'http://hubski.com/feed?id='; | |
var notificationURL = 'http://hubski.com/notifications?id='; | |
var mailboxURL = 'http://hubski.com/mail?id='; | |
var composeMailURL = 'http://hubski.com/sendmail'; | |
var globalPostsURL = 'http://hubski.com/global?id='; | |
var communityURL = 'http://hubski.com/community'; | |
var badgesURL = 'http://hubski.com/badgesubs'; | |
var submissionURL = 'http://hubski.com/submit'; | |
var preferencesURL = 'http://hubski.com/pref?id='; | |
// Conditional variables for seeing what page you're on | |
var isPost = false; | |
if(window.location.href.indexOf('pub') !== -1) { | |
isPost = true; | |
} | |
var isNotifications = false; | |
if (window.location.href.indexOf('notifications') !== -1) { isNotifications = true; | |
} | |
//List of modules | |
var modules = {}; | |
modules['shortcuts'] = (function() { | |
'use strict'; | |
var Module = { | |
init: function() { | |
feed = { currentNode:$('#grid > #unit:first'),feedIndex:-1}; | |
buildKeyMap(); | |
calcSelectColor(); | |
this.keyHandler = keyUpHandler.bind(this); | |
$(document).on('keyup',this.keyHandler); | |
}, | |
isLoaded: function() { | |
return true; | |
} | |
}; | |
var keyMap = {}; | |
var feed,selectColor; | |
var bgColorOffset = 0x111111; | |
var generalShortKeys = { | |
'49': // 1 | |
function() { window.location = globalPostsURL + '1'; }, | |
'50': // 2 | |
function() { window.location = globalPostsURL + '2'; }, | |
'51': // 3 | |
function() { window.location = globalPostsURL + '3'; }, | |
'52': // 4 | |
function() { window.location = globalPostsURL + '4'; }, | |
'53': // 5 | |
function() { window.location = globalPostsURL + '5'; }, | |
'54': // 6 | |
function() { window.location = globalPostsURL + '6'; }, | |
'55': // 7 | |
function() { window.location = globalPostsURL + '7'; }, | |
'56': // 8 | |
function() { window.location = globalPostsURL + '8'; }, | |
'57': // 9 | |
function() { window.location = globalPostsURL + '9'; }, | |
'66': // 'b" | |
function() { window.location = badgesURL; }, | |
'67': // 'c" | |
function() { window.location = communityURL; }, | |
'69': // 'e' | |
function() { window.location = composeMailURL; }, | |
'70': // 'f' | |
function() { window.location = feedURL + currentUser; }, | |
'71': // 'g' | |
function() { window.location = globalPostsURL + '1'; }, | |
'77': // 'm' | |
function() { window.location = mailboxURL + currentUser; }, | |
'78': // 'n' | |
function() { window.location = notificationURL + currentUser; }, | |
'80': // 'p" | |
function() { window.location = submissionURL; }, | |
'81': // 'q" | |
function() { $('.maglink').click(); }, | |
'85': // 'u" | |
function() { window.location = preferencesURL + currentUser; } | |
}; | |
var postShortKeys = { | |
'65': // 'a' | |
function() { $('.longplusminus > a').click(); }, | |
'82': // 'r' | |
function() { $('[name="text"]').focus(); }, | |
'83': // 's' | |
function() { $('.titlelinks > a:contains("save")').click(); } | |
}; | |
var notificationKeys = { | |
'68': // 'd' | |
function() { | |
var dismissURL = $('.simplemenu').find('a').attr('href'); | |
window.location.href = dismissURL; | |
} | |
}; | |
var feedShortKeys = { | |
'13': // 'enter' | |
function() { | |
window.location = feed.currentNode.find('.feedtitle > a').attr('href'); | |
}, | |
's13': // 'shift+enter' | |
function() { | |
window.open(feed.currentNode.find('.feedtitle > a').attr('href'),'_blank'); | |
window.focus(); | |
}, | |
'65': // 'a' | |
function() { | |
if(feed.feedIndex!=-1) { | |
feed.currentNode.find('.plusminus>a').click(); | |
} | |
}, | |
'72': // 'h' | |
function() { | |
if(feed.feedIndex!=-1) { | |
feed.currentNode.find('.savesplit>a:contains("hide")').click(); | |
} | |
}, | |
'74': // 'j' | |
function () { | |
nextNode(); | |
}, | |
'75': // 'k' | |
function() { | |
prevNode(); | |
}, | |
'79': // 'o' | |
function() { | |
window.location = feed.currentNode.find('.feedtitle > a').attr('href'); | |
}, | |
's79': // 'shift+o' | |
function() { | |
window.open(feed.currentNode.find('.feedtitle > a').attr('href'),'_blank'); | |
window.focus(); | |
}, | |
'83': // 's' | |
function() { | |
if(feed.feedIndex!=-1) { | |
feed.currentNode.find('.savesplit>a:contains("save")').click(); | |
} | |
} | |
}; | |
function buildKeyMap() { | |
$.extend(keyMap,generalShortKeys); | |
if(isPost) {$.extend(keyMap,postShortKeys)}; | |
if(isNotifications) {$.extend(keyMap,notificationKeys)}; | |
if(!isPost&&!isNotifications) {$.extend(keyMap,feedShortKeys)}; | |
} | |
//Feed navitgation functions | |
function nextNode() { | |
if(feed.currentNode.next().is('div.box')) { | |
if(feed.feedIndex!=-1) { | |
feed.currentNode.css('background-color',''); | |
feed.currentNode = feed.currentNode.next(); | |
} | |
feed.currentNode.css('background-color',selectColor); | |
feed.feedIndex++; | |
} | |
} | |
function prevNode() { | |
if(feed.currentNode.prev().is('div.box')) { | |
feed.currentNode.css('background-color',''); | |
feed.currentNode = feed.currentNode.prev(); | |
feed.currentNode.css('background-color',selectColor); | |
feed.feedIndex--; | |
} else { | |
feed.currentNode.css('background-color',''); | |
feed.feedIndex = -1; | |
} | |
} | |
//Color Determination functions | |
function calcSelectColor() { | |
var bgColorAttr = $('body').css('background-color'); | |
if(bgColorAttr=='transparent') { //edge case for the snow hubski-style | |
bgColorAttr='rgb(255, 255, 255)'; | |
} | |
var originalBgColor = colorToHex(bgColorAttr); | |
var parsedHexBgColor = originalBgColor.replace('#',''); | |
parsedHexBgColor = parseInt(parsedHexBgColor, 16); | |
selectColor = '#'+((parsedHexBgColor - bgColorOffset).toString(16)); | |
} | |
/* | |
* Converting RGB color to hex | |
* http://haacked.com/archive/2009/12/29/convert-rgb-to-hex.aspx | |
*/ | |
function colorToHex(color) { | |
if (color.substr(0, 1) === '#') { | |
return color; | |
} | |
var digits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(color); | |
var red = parseInt(digits[2]); | |
var green = parseInt(digits[3]); | |
var blue = parseInt(digits[4]); | |
var rgb = blue | (green << 8) | (red << 16); | |
return digits[1] + '#' + rgb.toString(16); | |
} | |
//Event handlers | |
function keyUpHandler(e) { | |
var code = e.keyCode; | |
var shift = e.shiftKey; | |
if(shift) { | |
code = 's'+code; | |
} | |
// Make sure we're not handling keystrokes from inputs or textareas | |
var tag = e.target.tagName.toLowerCase(); | |
if (tag == 'textarea' || tag == 'input') { | |
return; | |
} | |
if(code in keyMap) { | |
keyMap[code](); | |
} | |
} | |
return Module; | |
}()); | |
modules['collapsingComments'] = (function() { | |
'use strict'; | |
var Module = { | |
init: function() { | |
insertCollapseButton(); | |
this.commentHandler = collapseHandler.bind(this); | |
$('[name="collapseComments"]').on('click',this.commentHandler); | |
}, | |
isLoaded: function() { | |
if(isPost) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
}; | |
var buttonMap = { | |
'â–¼ ':'â–¶ ', | |
'â–¶ ': 'â–¼ ' | |
}; | |
function toggleComments(node) { | |
node.find('.comm,.replytrigger').toggle(); | |
node.next('.subcom').toggle(); | |
} | |
function insertCollapseButton() { | |
$('<span name="collapseComments">â–¼ </span>').prependTo('span.comhead'); | |
} | |
function toggleButton(node) { | |
node.text(buttonMap[node.text()]); | |
} | |
function collapseHandler(event) { | |
var commentButton = $(event.target); | |
var commentDiv = commentButton.parents('.outercomm:first'); | |
toggleButton(commentButton); | |
toggleComments(commentDiv); | |
} | |
return Module; | |
}()); | |
modules['infiniteScroll'] = (function (){ | |
var Module = { | |
init: function () { | |
this.infiniteScrollHandler = scrollHandler.bind(this); | |
$(window).on('scroll',this.infiniteScrollHandler); | |
}, | |
isLoaded: function () { | |
if(!isNotifications&&!isPost) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
}; | |
function scrollHandler(event) { | |
if($(window).scrollTop() == $(document).height() - $(window).height()) { | |
if($('#loading').css('display')=='none') { | |
$('#iscroll').click(); | |
} | |
} | |
} | |
return Module; | |
}()); | |
for(mod in modules) { | |
if(modules[mod].isLoaded()) { | |
modules[mod].init(); | |
} | |
} | |
}//main | |
addScript(main); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment