Created
July 25, 2011 21:56
-
-
Save daviddahl/1105340 to your computer and use it in GitHub Desktop.
chatter.js
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
// Encrypt chat bookmarklet | |
// Author: David Dahl <[email protected]> | |
// (function (){ var e = document.createElement("script"); e.src = "https://raw.github.com/gist/1105340/88e82d098691fbc1d1ba37ca6ed7c9d5aef97c1c/chatter.js?t=" + Date.now(); document.body.appendChild(e);}()); | |
function Chatter() | |
{ | |
var DEBUG = false; | |
var self = this; | |
document.addEventListener("DOMNodeInserted", function nodeInserted(aEvent) { | |
console.log("...DOMNodeInserted..."); | |
console.log(aEvent.target); | |
self.discoverMessage(aEvent); | |
}); | |
if (DEBUG) { | |
document.getElementById("send").addEventListener("click", | |
// XXX: this event is for the demo only | |
function clickButton(aEvent) { | |
self.transformMessage(); | |
var node = document.createElement("div"); | |
node.setAttribute("class", "msg-node"); | |
node.innerHTML = new String(self.inputNode.value); | |
var parent = document.getElementById("messages"); | |
document.getElementById("messages").insertBefore(node, parent.childNodes[0]); | |
self.inputNode.value = ""; | |
}, false); | |
} | |
this.testMode = true; | |
this.launchUI(); | |
} | |
Chatter.prototype = { | |
chooseInputNodeEvent: function c_chooseInputNodeEvent() | |
{ | |
var self = this; | |
var attempts = 0; | |
window.addEventListener("click", function chooseNode(aEvent) { | |
attempts++; | |
if (self.chooseInputNode(aEvent)) { | |
window.removeEventListener("click", chooseNode, false); | |
} | |
else { | |
if (attempts > 3) { | |
alert("Apparently you do not understand what to do. Please read the docs at http://domcrypt.org"); | |
attempts = 0; | |
} | |
else { | |
alert("Please choose a chat input widget"); | |
} | |
} | |
}, false); | |
}, | |
uiMinimized: false, | |
uiVisible: false, | |
onscroll: function c_onscroll() | |
{ | |
var _scroll; | |
if (window.onscroll) { | |
window.onscroll = _scroll; | |
} | |
window.onscroll = function _chatterOnScroll(aEvent) { | |
// move the UI down or up on scroll... | |
var node = document.querySelector("#_chatter-writing-node"); | |
node.style.top = window.scrollY + "px"; | |
node = document.querySelector("#_chatter-minimized"); | |
node.style.top = window.scrollY + "px"; | |
console.log("adjusted position"); | |
if (_scroll) { | |
_scroll(aEvent); | |
} | |
}; | |
}, | |
showEncodingEditor: function c_showEncodingEditor() | |
{ | |
document.querySelector("#_chatter-message-encoder").style.display = "block"; | |
}, | |
hide: function c_hide() | |
{ | |
document.getElementById("_chatter-minimized").style.display = "block"; | |
document.getElementById("_chatter-writing-node").style.display = "none"; | |
}, | |
show: function c_show() | |
{ | |
document.getElementById("_chatter-writing-node").style.display = "block"; | |
document.getElementById("_chatter-minimized").style.display = "none"; | |
}, | |
launchUI: function c_launchUI() | |
{ | |
this.onscroll(); | |
this.uiVisible = true; | |
var nodeStr = '<div id="_chatter-minimized" onclick="_chatter.show();" ' | |
+ 'style="position:absolute; top: 0px; left: 0px; display:none; ' | |
+ 'cursor: pointer; width: 5%; ' | |
+ 'background-color: #ccc; border: 1px solid #999;">' | |
+ '<span>chatter</span></div>' | |
+ '<div class="max" id="_chatter-writing-node" ' | |
+ 'style="background-color: #eee; border: 1px solid #aaa; position:absolute; top: 0px; left: 0px;">' | |
+ '<div class="min" id="handle" ' | |
+ 'style="background-color: #eee; width:100%; ' | |
+ 'border: 1px solid #bbb;">' | |
+ ' <span style="font-size: 90%; font-weight: bold; text-transform: uppercase">Chatter</span> ' | |
+ '<button onclick="_chatter.chooseInputNodeEvent();" id="_chatter-choose-input">Select Chat Input</button>' | |
+ '<button id="_chatter-encode-message-ui-btn" onclick="_chatter.showEncodingEditor();">Message Pad</button>' | |
+ '<button id="_chatter-hide-btn" onclick="_chatter.hide();">Hide</button>' | |
+ ' </div>' | |
+ '<div id="_chatter-message-encoder" style="display: none;">' | |
+ '<textarea class="min" style="width: 70%; height:8em; margin:1em;"' | |
+ 'id="_chatter-writing-node-textarea">' | |
+ '</textarea> ' | |
+ '<button onclick="_chatter.encodeMessage();" class="min" style="margin: 1em;" id="_chatter-button">Make Message Private</button>' | |
+ '<button onclick="_chatter.hideEncodingEditor();" class="min" style="margin: 1em;" id="_chatter-cancel-btn">Cancel</button>' | |
+ '</div>' | |
+ '<div id="_chatter-console" style="font-family: monospace; font-size: 90%;"></div>' | |
+ '</div>'; | |
var wrapperNode = document.createElement("div"); | |
wrapperNode.innerHTML = nodeStr; | |
var body = document.querySelector("body"); | |
var node; | |
for (var i = 0; i < body.childNodes.length; i++) { | |
node = body.childNodes.item(i); | |
if (node.nodeType == 1) { | |
body.insertBefore(wrapperNode, node); | |
break; | |
} | |
} | |
}, | |
hideEncodingEditor: function c_hideEncodingEditor() | |
{ | |
document.querySelector("#_chatter-message-encoder").style.display = "none"; | |
}, | |
inputNode: null, | |
recipientPubKey: null, | |
init: function c_init() | |
{ | |
this.launchUI(); | |
}, | |
get writingNode() { | |
return document.getElementById("_chatter-writing-node-textarea"); | |
}, | |
verbose: false, | |
encodeMessage: function c_encodeMessage() | |
{ | |
var self = this; | |
var str = this.writingNode.value; | |
if (!str) { | |
alert("Please enter a message to encode"); | |
} | |
else { | |
if (!window.recipientPubKey) { | |
alert("Your chatting partner has not initiated private message sending"); | |
return; | |
} | |
window.mozCipher.pk.encrypt(str, window.recipientPubKey, | |
function callback(aCipherMsg) { | |
var cipherTxt = JSON.stringify(aCipherMsg); | |
self.inputNode.value = "chatter||||" + "Private Message" + "||||" + cipherTxt; | |
self.writingNode.value = ""; | |
self.hideMessagePad(); | |
if (self.verbose) | |
alert("Now you can send the private message"); | |
}); | |
} | |
}, | |
hideMessagePad: function c_hideMessagePad() | |
{ | |
document.getElementById("_chatter-message-encoder").style.display = "none"; | |
}, | |
transformMessage: function c_transformMessage(aEvent) | |
{ | |
var self = this; | |
var str = this.inputNode.value; | |
var data = str.split("||||"); | |
console.log(data); | |
if (data.length != 3 || !data[0]) { | |
// plain text message needs to be encrypted | |
window.mozCipher.pk.encrypt(str, window.recipientPubKey, | |
function callback(aCipherMsg) { | |
var cipherTxt = JSON.stringify(aCipherMsg); | |
self.inputNode.value = "chatter||||" + "Private Message" + "||||" + cipherTxt; | |
}); | |
} | |
}, | |
testMode: function c_testMode() | |
{ | |
window.mozCipher.pk.getPublicKey(function (aKey) { | |
window.recipientPubKey = aKey; | |
console.log("_chatter: test mode started"); | |
}); | |
}, | |
discoverMessage: function c_discoverMessage(aEvent) | |
{ | |
var self = this; | |
console.log(aEvent.target); | |
if (aEvent.target) { | |
var str = aEvent.target.innerHTML; | |
var data = str.split("||||"); | |
if (data[0] == "chatter") { | |
// switch through the commands, set pubkey or parse, decrypt message and display message | |
console.log(data[0]); | |
console.log(data[1]); | |
console.log(data[2]); | |
switch (data[1]) { | |
case "Private Message": | |
if (window.recipientPubKey) { | |
console.info("decrypting..."); | |
console.info("target: " + aEvent.target); | |
console.info("data[2]: " + data[2]); | |
try { | |
self.decryptMessage(data[2], window.recipientPubKey, aEvent.target); | |
} | |
catch (ex) { | |
console.log(ex); | |
console.log(ex.stack); | |
} | |
} | |
else { | |
console.error("Error: Configuration problem"); | |
} | |
break; | |
case "Initiate Private Message": | |
console.log("Initiate Private Message!!!!"); | |
console.log(data[2]); | |
window.recipientPubKey = data[2]; | |
default: | |
break; | |
} | |
} | |
else { | |
// not a recognized incoming message | |
} | |
} | |
}, | |
decryptMessage: function c_decryptMessage(aMsg, aPubKey, aNode) | |
{ | |
console.log("aMsg: "); | |
console.log(aMsg); | |
var msg = JSON.parse(aMsg); | |
console.log("message object: " + msg); | |
var self = this; | |
try { | |
window.mozCipher.pk.decrypt(msg, function decrypt(aPlainTxt) { | |
console.log(msg); | |
aNode.innerHTML = "<pre>" | |
+ aPlainTxt | |
+ "</pre>"; | |
}); | |
} | |
catch(ex) { | |
console.log(ex); | |
console.log(ex.stack); | |
} | |
}, | |
offerKey: function c_offerKey(aKey) | |
{ | |
this.inputNode.value = "chatter||||Initiate Private Message||||" + aKey; | |
}, | |
checkKey: function c_checkKey() | |
{ | |
// var self = this; | |
// var pubKey = localStorage.getItem("_chatter_pubkey"); | |
// if (pubKey != "" && pubKey != null && pubKey != undefined) { | |
// self.offerKey(pubKey); | |
// return; | |
// } | |
var self = this; | |
// check if we have a pubKey | |
window.mozCipher.pk.getPublicKey(function callback(aKey) { | |
if (aKey) { | |
console.log("getPubKey"); | |
// localStorage.setItem("_chatter_pubkey", aKey); | |
self.offerKey(aKey); | |
} | |
else { | |
// generate a keyPair | |
console.log("generatePubKey"); | |
window.mozCipher.pk.generateKeypair(function callback (aNewKey) { | |
// localStorage.setItem("_chatter_pubkey", aNewKey); | |
self.offerKey(aNewKey); | |
}); | |
} | |
}); | |
}, | |
chooseInputNode: function c_chooseInputNode(aEvent) | |
{ | |
var tagName = aEvent.target.tagName; | |
if (!(aEvent.target.getAttribute("contenteditable") || | |
tagName == "TEXTAREA" || tagName == "INPUT")) { | |
return false; | |
} | |
this.inputNode = aEvent.target; | |
this.checkKey(); | |
console.log("chooseInputNode: editable node found"); | |
alert("Please send the current *unedited* chat message to begin using Chatter"); | |
return true; | |
} | |
}; | |
function _chatter_toggle(aNode) | |
{ | |
if (!_chatter.uiMinimized) { | |
aNode.parentNode.parentNode.style.width = "1em"; | |
aNode.parentNode.parentNode.style.height = "1em"; | |
var nodes = document.querySelectorAll(".min"); | |
for (var node in nodes) { | |
if (nodes[node].style) { | |
nodes[node].style.display = "none"; | |
} | |
} | |
document.querySelector("#_chatter-writing-node"). | |
addEventListener("click", function _chatterMax(aEvent) { | |
document.querySelector("#_chatter-writing-node"). | |
removeEventListener("click", _chatterMax, false); | |
_chatter_toggle(document.querySelector("#_chatter-toggle-btn")); | |
}, false); | |
} | |
else { | |
aNode.parentNode.parentNode.style.width = "400px"; | |
aNode.parentNode.parentNode.style.height = "8em"; | |
var nodes = document.querySelectorAll(".min"); | |
for (var node in nodes) { | |
if (nodes[node].style) { | |
nodes[node].style.display = "block"; | |
} | |
} | |
} | |
} | |
window._chatter = new Chatter(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
jhkjhh