// ==UserScript==
// @name Facebook Chat Emoticons Bar
// @description Adds an emoticon bar to Facebook chat
// @include http://facebook.com/*
// @include http://*.facebook.com/*
// @include https://facebook.com/*
// @include https://*.facebook.com/*
// @exclude http://*.channel.facebook.com/*
// @exclude https://*.channel.facebook.com/*
// @author bitMAN
// @version 0.21
// @versionnumber 0.21
// @license Attribution-NonCommercial-NoDerivs 3.0 Unported (CC BY-NC-ND 3.0); http://creativecommons.org/licenses/by-nc-nd/3.0/
// @namespace http://userscripts.org/scripts/show/50826
// ==/UserScript==
//
// List of emoticons
// :) :( :D >:( -_- :/ o.O :p :'( >:O :v 3:) :o :3 ;) :* :|] 8) <3 (Y) :putnam: 8| ^_^ (^^^) O:) <(") :42: <(") O.o
var version, HttpsOn, ImagesURL, ResourcesURL, storage, emotsInfo, spemotsInfo, headTag, styleTag, ArrowStyleUp, ArrowStyleDown, fEmotBarDom, fEmotsListDom, fArrow;
version = 0.19;
HttpsOn = window.location.href.match('https://')?true:false;
ImagesURL = HttpsOn?'https://s-static.ak.fbcdn.net/images/':'http://static.ak.fbcdn.net/images/';
ResourcesURL = HttpsOn?'https://s-static.ak.fbcdn.net/rsrc.php/':'http://static.ak.fbcdn.net/rsrc.php/';
/* START: This part of the code was written (partialy) by Vaughan Chandler for FFixer, special thanks to him :) */
storage = 'none';
try {
if (typeof GM_getValue === 'function' && typeof GM_setValue === 'function') {
GM_setValue('testkey', 'testvalue');
if (GM_getValue('testkey', false) === 'testvalue') { storage='greasemonkey'; }
}
} catch(x) {}
if (storage=='none' && typeof localStorage == 'object') { storage='localstorage'; }
function setValue(key, value) {
switch (storage) {
case 'greasemonkey':
GM_setValue('0-'+key, value);
break;
case 'localstorage':
localStorage['femotbar-0-'+key] = value;
break;
}
}
function getValue(key, value) {
switch (storage) {
case 'greasemonkey':
return GM_getValue('0-'+key, value);
case 'localstorage':
var val = localStorage['femotbar-0-'+key];
if (val=='true') { return true; }
else if (val=='false') { return false; }
else if (val) { return val; }
break;
}
return value;
}
function xmlhttpRequest(params, callBack) {
if (typeof GM_xmlhttpRequest !== 'undefined') {
params['onload'] = callBack;
return GM_xmlhttpRequest(params);
}
return null;
}
function openInTab(url) {
if (typeof GM_openInTab !== 'undefined') { GM_openInTab(url); }
else { window.open(url); }
}
function UpdateCheck() {
if(parseInt(getValue('LastUpdate', '0')) + 86400000 <= (new Date().getTime())) {
try {
xmlhttpRequest( { method: 'GET',
url: 'http://userscripts.org/scripts/source/50826.meta.js?' + new Date().getTime(),
headers: {'Cache-Control': 'no-cache'} },
handleUpdateResponse);
}
catch (err) {
alert('An error occurred while checking for updates:\n' + err);
}
}
}
function handleUpdateResponse(r) {
setValue('LastUpdate', new Date().getTime() + '');
if (r.responseText.match(/@version\s+(\d+\.\d+)/)[1] > version) {
if(confirm( "There's an update available for 'Facebook Chat Emoticons Bar'.\n" +
"Your version: " + version + "\n" +
"New version: " + r.responseText.match(/@version\s+(\d+\.\d+)/)[1] + "\n" +
"Do you wish to install it?")
) openInTab('http://userscripts.org/scripts/source/50826.user.js');
}
}
// END
function createSelection(field, start, end) {
if( field.createTextRange ) {
var selRange = field.createTextRange();
selRange.collapse(true);
selRange.moveStart('character', start);
selRange.moveEnd('character', end);
selRange.select();
} else if( field.setSelectionRange ) {
field.setSelectionRange(start, end);
} else if( field.selectionStart ) {
field.selectionStart = start;
field.selectionEnd = end;
}
field.focus();
}
function getCursorPosition(field) {
var CursorPos = 0;
if (field.selectionStart || field.selectionStart == '0') CursorPos = field.selectionStart;
return (CursorPos);
}
UpdateCheck();
emotsInfo = [':)', ':(', ':p', ':D', ':o', ';)', '8)', '8|', '>:(', ':/', ':\'(', '3:)', 'O:)', ':*', '<3', '^_^', '-_-', 'o.O', '>:O', ':v', ':3', '(Y)'];
spemotsInfo = [':|]', 'emote/robot.gif', '(^^^)', 'emote/shark.gif', ':putnam:', 'emote/putnam.gif', '<(")', 'emote/penguin.gif', ':42:', 'emote/42.gif'];
headTag = document.getElementsByTagName('head')[0];
if (headTag) {
styleTag = document.createElement('style');
styleTag.type = 'text/css';
styleTag.innerHTML =
'.chat_tab_emot_bar {padding-top: 2px; padding-bottom: 6px; line-height: 16px; padding-left: 2px; background:#EEEEEE none repeat scroll 0 0; border-style: solid; border-width: 0px 0px 1px 0px; border-color: #C9D0DA; position: static; }'+
'.chat_arrow { background-image: url("'+ ResourcesURL + 'v1/zp/r/SBNTDM0S-7U.png"); background-position: 0 -48px; height: 5px; width: 9px; }';
headTag.appendChild(styleTag);
}
ArrowStyleUp = 'cursor: pointer; position: absolute; right: 2px; -moz-transform: rotate(180deg); -webkit-transform: rotate(180deg);'
ArrowStyleDown = 'cursor: pointer; position: absolute; right: 2px;'
fEmotBarDom = document.createElement('div');
fEmotBarDom.setAttribute('class','chat_tab_emot_bar');
fEmotsListDom = document.createElement('div');
fEmotsListDom.setAttribute('name','EmotsList');
fEmotBarDom.appendChild(fEmotsListDom);
for(i=0;i<emotsInfo.length;i+=1) {
var fEmotsDom = document.createElement('img');
fEmotsDom.setAttribute('alt',emotsInfo[i]);
fEmotsDom.setAttribute('style','cursor: pointer; background-position: -'+ 16*i +'px 0px;');
fEmotsDom.setAttribute('src',ImagesURL + 'blank.gif');
fEmotsDom.setAttribute('class','emote_img');
fEmotsListDom.appendChild(fEmotsDom);
}
for(i=0;i<spemotsInfo.length;i+=2) {
var fEmotsDom = document.createElement('img');
fEmotsDom.setAttribute('alt',spemotsInfo[i]);
fEmotsDom.setAttribute('src',ImagesURL + spemotsInfo[i+1]);
fEmotsDom.setAttribute('style','cursor: pointer;');
fEmotsDom.setAttribute('class','emote_custom');
fEmotsListDom.appendChild(fEmotsDom);
}
fArrow = document.createElement('i');
fArrow.setAttribute('alt','');
fArrow.setAttribute('class','img chat_arrow');
fArrow.setAttribute('style',ArrowStyleUp);
fEmotBarDom.appendChild(fArrow);
var setting_visible = getValue('visible',true);
document.addEventListener('DOMNodeInserted', fInsertedNodeHandler, false);
function fInsertedNodeHandler(event) {
if(event.target.getElementsByClassName && event.target.getElementsByClassName('fbNubFlyout fbDockChatTabFlyout')[0])
fInsertEmotBar(event.target);
}
function fInsertEmotBar(fChatWrapper) {
fChatToolBox = fChatWrapper.getElementsByClassName('fbNubFlyoutHeader')[0]
fNewEmotBar = fEmotBarDom.cloneNode(true);
setVisibility(fNewEmotBar);
for(i=0;i<fNewEmotBar.firstChild.childNodes.length;i++) fNewEmotBar.firstChild.childNodes[i].addEventListener('click', fEmotClickHandler , false);
fNewEmotBar.childNodes[1].addEventListener('click', fHideShowEmotBar , false);
if(fChatToolBox.childNodes) fChatToolBox.insertBefore(fNewEmotBar,fChatToolBox.childNodes[1]);
}
function fEmotClickHandler(event){
var fChatInput = event.target.parentNode.parentNode.parentNode.parentNode.getElementsByClassName('fbNubFlyoutFooter')[0].getElementsByClassName('inputContainer')[0].getElementsByClassName('uiTextareaAutogrow input')[0];
var pos = getCursorPosition(fChatInput);
var txtbef = ''; var txtaft = '';
if (fChatInput.value.charAt(pos-1) != ' ' && pos-1 > 0) txtbef = ' ';
if (fChatInput.value.charAt(pos) != ' ') txtaft = ' ';
fChatInput.value = fChatInput.value.substring(0,pos) + txtbef + event.target.getAttribute('alt') + txtaft + fChatInput.value.substring(pos);
createSelection(fChatInput,pos + event.target.getAttribute('alt').length + txtaft.length + txtbef.length,pos + event.target.getAttribute('alt').length + txtaft.length + txtbef.length);
}
function fHideShowEmotBar(event){
fChatBar = document.getElementsByName('EmotsList');
if(fChatBar[0].getAttribute('style') == 'display: none;') {
for(i=0;i<fChatBar.length;i++) {
fChatBar[i].setAttribute('style','display: block;');
fChatBar[i].parentNode.childNodes[1].setAttribute('style',ArrowStyleUp);
fixHeightAndScroll(fChatBar[i]);
}
}
else {
for(i=0;i<fChatBar.length;i++) {
fChatBar[i].setAttribute('style','display: none;');
fChatBar[i].parentNode.childNodes[1].setAttribute('style',ArrowStyleDown);
fixHeightAndScroll(fChatBar[i]);
}
}
setValue('visible',!setting_visible);
setting_visible = !setting_visible;
}
function setVisibility(DOM) {
if(setting_visible) {
DOM.firstChild.setAttribute('style','display: block;');
DOM.childNodes[1].setAttribute('style',ArrowStyleUp);
}
else {
DOM.firstChild.setAttribute('style','display: none;');
DOM.childNodes[1].setAttribute('style',ArrowStyleDown);
}
}
function fixHeightAndScroll(bar) {
fChatContainer = bar.parentNode.parentNode.parentNode;
var oldheight = parseInt(fChatContainer.children[2].style.height.replace("px",""));
var newheight = 285 - (fChatContainer.children[0].clientHeight + fChatContainer.children[1].clientHeight + fChatContainer.children[3].clientHeight + 1);
fChatContainer.children[2].style.height = newheight + "px";
fChatContainer.children[2].scrollTop += oldheight - newheight;
}