Skip to content

Instantly share code, notes, and snippets.

@patik
Created August 30, 2012 22:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patik/3542903 to your computer and use it in GitHub Desktop.
Save patik/3542903 to your computer and use it in GitHub Desktop.
Alpha.App.Net Enhanced
// @name Enhanced Alpha.App.Net
// @description Image previews, Repost links, and Twitter character count on Alpha.App.Net
// @namespace http://patik.com/code/user-scripts/
// @include https://alpha.app.net/*
// @version v20120903.1
// ==/UserScript==
(function _adnenhance_init(win) {
var adnenh = {};
adnenh.setup = function _adnenh_twchar_setup () {
adnenh.textarea = document.querySelector('textarea[name="post"]');
adnenh.adnCharDisplay = document.querySelector('span.char-count');
adnenh.twCharDisplay = document.createElement('span');
adnenh.twchar.setup();
adnenh.rpl.setup();
adnenh.img.setup();
};
/*
* Twitter Character Count
*
*/
// To do: correctly count URLs, taking t.co shortening into account
// Fix alignment and styling when <0 chars remain
// Styles for different media queries
adnenh.twchar = {};
adnenh.twchar.setup = function _adnenh_twchar_setup () {
// Some pages don't have character displays (or are they just hidden?), so quit if none are found
// To do: add one of my own!
if (!adnenh.adnCharDisplay) { return false; }
adnenh.adnCharDisplay.classList.remove('hide');
// Create new display for Twitter char count
adnenh.twCharDisplay.className = 'char-count adnenh-char-count';
adnenh.twCharDisplay.title = 'Twitter characters remaining';
// Insert after app.net count
adnenh.twCharDisplay = adnenh.adnCharDisplay.parentNode.insertBefore(adnenh.twCharDisplay, adnenh.adnCharDisplay.nextSibling);
// Auto-update count
adnenh.twchar.updateCount();
adnenh.textarea.addEventListener('keyup', adnenh.twchar.updateCount, false);
};
// Update display
adnenh.twchar.updateCount = function _adnenh_twchar_updateCount () {
var adnCharCount = adnenh.textarea.value.length,
twCharCount = 140 - adnCharCount;
adnenh.twCharDisplay.innerText = '(' + twCharCount + ')';
// Add 'error' class if necessary
if (twCharCount < 0) {
adnenh.twCharDisplay.classList.add('error');
}
else {
adnenh.twCharDisplay.classList.remove('error');
}
};
/*
* Repost links
*
*/
adnenh.rpl = {};
// Find posts without 'repost' links
adnenh.rpl.setup = function _adnenh_rpl_setup () {
var posts = document.querySelectorAll('.post-details');
if (!posts || !posts.length) { return false; }
posts = Array.prototype.slice.call(posts);
// Check each post to see if it has a Repost link yet
posts.forEach(function(p) {
var lnk = p.querySelector('[data-adnenh-repost-link]') || null;
if (!lnk) {
adnenh.rpl.addRpLink(p);
}
else if (lnk.hasAttribute('data-adnenh-repost-link-event')) {
// Event listener hasn't been added yet
adnenh.rpl.addRpEvent(lnk);
}
});
};
// Add 'repost' link to a post
adnenh.rpl.addRpLink = function _adnenh_rpl_addRpLink (p) {
var replyLink = p.querySelector('[data-reply-to]'),
li = replyLink.parentNode,
rpLink = document.createElement('li');
rpLink.className = 'yui3-u show-on-hover';
rpLink.innerHTML = '<a href="#" data-adnenh-repost-link data-adnenh-repost-link-event><i class="icon-share-alt icon-share-adnenh-repost"></i> Repost</a>';
// Insert after reply link
rpLink = li.parentNode.insertBefore(rpLink, li.nextSibling);
adnenh.rpl.addRpEvent(rpLink);
};
// Add click listener to a 'repost' link
adnenh.rpl.addRpEvent = function _adnenh_rpl_addRpEvent (lnk) {
lnk.addEventListener('click', adnenh.rpl.repost, false);
lnk.removeAttribute('data-adnenh-repost-link-event'); // Remove flag
};
// Create repost text in the post textarea
adnenh.rpl.repost = function _adnenh_rpl_repost (evt) {
var target = evt.target,
post = adnenh.rpl.getParentWithClass(evt.target, 'content'),
username = post.querySelector('.username a').innerText,
txt = post.querySelector('.post-content span').innerText;
txt = ' RP @' + username + ': "' + txt + '"';
adnenh.textarea.value = txt;
adnenh.twchar.updateCount();
adnenh.rpl.setCursorBeginning();
// To do: set reply parameters so the messages are threaded
};
// Poor man's $.closest()
adnenh.rpl.getParentWithClass = function _adnenh_rpl_getParentWithClass (elem, clss) {
while (elem && !/^body$|^html$/i.test(elem.nodeName)) {
if (elem.classList && elem.classList.contains(clss)) {
return elem;
}
elem = elem.parentNode;
}
return null;
};
// Put cursor at the beginning of the textarea
// Thanks to http://stackoverflow.com/a/10158364
adnenh.rpl.setCursorBeginning = function _adnenh_rpl_setCursorBeginning () {
adnenh.textarea.focus();
adnenh.rpl.setCursorBeginningHelper();
// Ugh, Chrome...
win.setTimeout(adnenh.rpl.setCursorBeginningHelper, 1);
};
adnenh.rpl.setCursorBeginningHelper = function _adnenh_rpl_setCursorHelper () {
if (typeof adnenh.textarea.selectionStart === "number") {
adnenh.textarea.selectionStart = adnenh.textarea.selectionEnd = 0;
}
};
/*
* Image previews
*
*/
adnenh.img = {};
adnenh.img.setup = function _adnenh_img_setup () {
var posts = document.querySelectorAll('.post-content');
if (!posts || !posts.length) { return false; }
// Check each post to see if it has links to images
Array.prototype.slice.call(posts).forEach(function(p) {
var lnks = p.querySelectorAll('a');
if (lnks.length && !p.querySelector('.adnenh-image-preview')) {
Array.prototype.slice.call(lnks).forEach(function(url) {
url = adnenh.img.getPreviewUrl(url.href);
if (url.length) {
adnenh.img.createPreview(p, url);
}
});
}
});
};
adnenh.img.createPreview = function _adnenh_img_createPreview (post, lnk) {
var postElem = adnenh.rpl.getParentWithClass(post, 'body'),
imgContainer = document.createElement('a');
imgContainer.className = 'adnenh-image-preview';
imgContainer.href = lnk;
imgContainer.innerHTML = '<img src="' + lnk + '" alt="linked image">';
postElem.appendChild(imgContainer);
};
adnenh.img.getPreviewUrl = function _adnenh_img_getPreviewUrl (url) {
var temp;
// Straight up JPG/GIF/PNG
if (/\.png$|\.jpe?g$|\.gif$/i.test(url)) {
return url;
}
// Img.ly
else if (/img\.ly\/\w+\/?$/i.test(url)) {
temp = /img\.ly\/(\w+)\/?$/i.exec(url);
return 'http://img.ly/show/medium/' + temp[1]; // mini
}
// Instagram
else if (/instagram\.com|instagr\.am/i.test(url)) {
return url + 'media/?size=l';
}
// Yfrog
else if (url.indexOf('yfrog.com') > -1) {
if (/j|p|b|t|g/.test(url)) { // Image
return url + ":small";
}
else if (/z|f/.test(url)) { // Video
return url + ":frame";
}
}
// Twitpic
else if (url.indexOf('twitpic.com/') > -1) {
temp = url.replace(/http\:\/\/(www\.)?twitpic\.com\//, '');
return 'http://twitpic.com/show/thumb/' + temp;
}
// Flickr
else if (url.indexOf('flic.kr/p/') > -1) {
temp = url.replace('flic.kr/p/', '');
return 'http://flic.kr/p/img/' + temp + '_m.jpg';
}
return '';
};
/*
* Setup
*
*/
win.adnenh = adnenh;
adnenh.setup();
// Re-run every ten seconds to check for new posts (crappy, I know)
// To do: only run this when new posts are loaded
win.setInterval(adnenh.rpl.setup, 10000);
}(this));
// Fix alignment and styling when <0 chars remain
// Styles for different media queries
@patik
Copy link
Author

patik commented Aug 30, 2012

To do:

  • Correctly count URLs, taking t.co shortening into account
  • Fix alignment and styling when <0 chars remain
  • Styles for different media queries

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment