Created
July 12, 2013 15:01
-
-
Save Zirak/5985141 to your computer and use it in GitHub Desktop.
SO-Chat onebox utility and example
This file contains hidden or 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
| Array.some = function (arr) { | |
| return [].some.apply(arr, [].slice.call(arguments, 1)); | |
| }; | |
| //not a good idea later on, but in dev, it's priceless when chaining | |
| Object.defineProperty(Object.prototype, 'log', { | |
| value : function log () { | |
| console.log(this); | |
| return this; | |
| }, | |
| writable : true, | |
| configurable : true | |
| }); | |
| var obox = window.obox = { | |
| listeners : [], | |
| init : function () { | |
| this.chatElem = document.getElementById('chat'); | |
| var observer = | |
| this.observer = | |
| new MutationObserver(this.onmutations.bind(this)); | |
| observer.observe(this.chatElem, { childList : true, subtree : true }); | |
| }, | |
| //why is this useful? | |
| destroy : function () { | |
| this.observer.disconnect(); | |
| }, | |
| runOnAllMessages : function (listener) { | |
| var fun = listener ? | |
| this.callListener.bind(this, listener) : | |
| this.callListeners.bind(this); | |
| return [].forEach.call( | |
| this.chatElem.getElementsByClassName('content'), fun); | |
| }, | |
| cond : function (predicate, callback) { | |
| var ret = { pred : predicate, fun : callback }; | |
| this.listeners.push(ret); | |
| return ret; | |
| }, | |
| condAndRun : function (predicate, callback) { | |
| var listener = this.cond(predicate, callback); | |
| this.runOnAllMessages(listener); | |
| return listener; | |
| }, | |
| onmutations : function (mutations) { | |
| mutations | |
| .filter(mutationFilterer) | |
| .map(mutationMapper) | |
| .forEach(this.callListeners, this); | |
| function mutationMapper (mutation) { | |
| //console.log(mutation, 'mutationMapper'); | |
| return mutation | |
| .addedNodes[0] | |
| .getElementsByClassName('content')[0]; | |
| } | |
| function mutationFilterer (mutation) { | |
| //console.log(mutation, 'mutationFilterer'); | |
| return mutation.addedNodes.length && | |
| Array.some(mutation.addedNodes, nodeFilterer); | |
| } | |
| function nodeFilterer (node) { | |
| return node.classList && | |
| node.classList.contains('message') && | |
| //chat adds a class for what you just posted, but hasn't been | |
| // received by a server yet, or something of the sorts. some | |
| // classes aren't always there, so we check for 'em all | |
| !node.classList.contains('pending') && | |
| !node.classList.contains('posted'); | |
| } | |
| }, | |
| callListener : function (listener, node) { | |
| var match, res = false; | |
| if (match = listener.pred(node)) { | |
| res = listener.fun(node, match); | |
| if (res !== false) { | |
| this.handleListenerReturn(res, node); | |
| } | |
| } | |
| return !!match && res !== false; | |
| }, | |
| callListeners : function (node) { | |
| console.log(node, 'callListeners'); | |
| var self = this; | |
| this.listeners.some(function (listener) { | |
| return self.callListener(listener, node); | |
| }); | |
| }, | |
| //this allows you to return an element from a listener, and the element will | |
| // automatically replace the content | |
| handleListenerReturn : function (ret, container) { | |
| console.log(ret, container, 'handleListenerReturn'); | |
| if (!ret || !ret.nodeType) { | |
| return; | |
| } | |
| container.textContent = ''; //h4x for clearing the element | |
| container.appendChild(ret); | |
| }, | |
| createElement : function () { | |
| var ret = document.createElement('div'); | |
| ret.classList.add('onebox'); | |
| return ret; | |
| } | |
| }; | |
| obox.init(); | |
| (function () { | |
| var extensions = { | |
| oga : { | |
| type : 'audio', | |
| codec : 'audio/ogg; codecs="vorbis"' | |
| }, | |
| mp3 : { | |
| type : 'audio', | |
| codec : 'audio/mpeg; codecs="mp3"' | |
| }, | |
| wav : { | |
| type : 'audio', | |
| codec : 'audio/wav; codecs="1"' | |
| }, | |
| webma : { | |
| type : 'audio', | |
| codec : 'audio/webm; codecs="vorbis"' | |
| }, | |
| ogv : { | |
| type : 'video', | |
| codec : 'video/ogg; codecs="theora, vorbis"' | |
| }, | |
| mp4 : { | |
| type : 'video', | |
| codec : 'video/mp4' //I can't find the exact codec... | |
| }, | |
| webmv : { | |
| type : 'video', | |
| codec : 'video/webm; codecs="vorbis, vp8"' | |
| } | |
| }; | |
| extensions.webm = extensions.webmv; | |
| var re = new RegExp( | |
| 'https?.+\\.(' + Object.keys(extensions).join('|') + ')$', | |
| 'i'); | |
| obox.condAndRun( | |
| function check_audio_video (node) { | |
| var first = node.firstElementChild; | |
| return first && | |
| !first.nextSibling && //make sure there isn't any other content | |
| first.tagName === 'A' && | |
| re.exec(first.href); | |
| }, | |
| function audio_video (content, match) { | |
| console.log(content, match, 'audio_video'); | |
| var ext = extensions[match[1].toLowerCase()], | |
| box = obox.createElement(), | |
| elem = document.createElement(ext.type); | |
| console.log(ext, elem, elem.canPlayType(ext.codec)); | |
| if (!elem.canPlayType(ext.codec)) { | |
| return false; | |
| } | |
| elem.src = match[0]; | |
| elem.controls = "controls"; | |
| box.appendChild(elem); | |
| return box; | |
| }); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment