var EMOJI_BAR = (function() { var dom = document.createElement("div") ,overlay = document.createElement("div") ,emojisDom = document.createElement("div") ,unicodeEmojis = document.createElement("ul") ,customEmojis = document.createElement("ul") ,searchBar = document.createElement("input") ,emojiCache = { unicode: {}, custom: {}} /** @type {function((string|null))|undefined} */ ,emojiSelectedHandler /** @type {function():boolean} */ ,isSupported = function() { return ("searchEmojis" in window); } ,makeHeader = function(imgSrc) { var img = document.createElement("img") ,dom = document.createElement("div"); img.src = imgSrc; dom.appendChild(img); dom.className = R.klass.emojibar.header; return dom; } /** @type {function(string, Element):{dom:Element,visible:boolean}} */ ,wrapEmojiLi = function(emojiName, emojiDom) { var dom = document.createElement("li"); dom.appendChild(emojiDom); dom.className = R.klass.emojibar.item; dom.id = "emojibar-" +emojiName; return { visible: false ,dom: dom }; } /** @type {function(string, *):{dom:Element,visible:boolean}} */ ,makeUnicodeEmojiLi = function(emojiName, emoji) { var domEmoji = window['makeEmoji'](emoji) ,domParent = document.createElement("span"); domParent.appendChild(domEmoji); domParent.className = R.klass.emoji.medium; return wrapEmojiLi(emojiName, domParent); } /** @type function(string=):number */ ,search = function(queryString) { var emojiCount = 0 ,toRemove = []; queryString = queryString === undefined ? searchBar.value : queryString; if (isSupported()) { /** @type {Object.} */ var emojis = window['searchEmojis'](queryString); for (var i in emojiCache.unicode) { if (emojiCache.unicode[i].visible && !emojis[i]) { emojiCache.unicode[i].visible = false; unicodeEmojis.removeChild(emojiCache.unicode[i].dom); } } for (var i in emojis) { var e = emojiCache.unicode[i]; if (!e) e = emojiCache.unicode[i] = makeUnicodeEmojiLi(i, emojis[i]); if (!e.visible) { e.visible = true; unicodeEmojis.appendChild(e.dom); } emojiCount++; } } //TODO custom return emojiCount; } /** @type function(Element, function((string|null))=):boolean */ ,spawn = function(domParent, handler) { if (isSupported()) { emojiSelectedHandler = handler; domParent.appendChild(overlay); domParent.appendChild(dom); searchBar.value = ""; search(); searchBar.focus(); return true; } return false; } /** @type {function():boolean} */ ,doClose = function() { if (dom.parentElement) { dom.parentElement.removeChild(overlay); dom.parentElement.removeChild(dom); return true; } return false; } /** @type {function():boolean} */ ,close = function() { var closed = doClose(); if (!closed) return false; if (emojiSelectedHandler) emojiSelectedHandler(null); return true; } ,onEmojiSelected = function(emojiName) { if (doClose() && emojiSelectedHandler) emojiSelectedHandler(emojiName); } ; overlay.addEventListener("click", function(e) { var bounds = dom.getBoundingClientRect(); if (e.screenY < bounds.top || e.screenY > bounds.bottom || e.screenX < bounds.left || e.screenX > bounds.right) close(); }); overlay.className = R.klass.emojibar.overlay; dom.className = R.klass.emojibar.container; emojisDom.className = R.klass.emojibar.emojis; unicodeEmojis.className = customEmojis.className = R.klass.emojibar.list; searchBar.className = R.klass.emojibar.search; emojisDom.appendChild(makeHeader(window['emojiProviderHeader'])); emojisDom.appendChild(unicodeEmojis); emojisDom.appendChild(makeHeader("emojicustom.png")); emojisDom.appendChild(customEmojis); dom.appendChild(emojisDom); dom.appendChild(searchBar); searchBar.addEventListener("keyup", function() { search(); }); dom.addEventListener("click", function(e) { var target = e.target; while (target !== dom && target && target.nodeName !== "LI") target = target.parentElement; if (target && target.nodeName === "LI" && target.id && target.id.substr(0, "emojibar-".length) === "emojibar-") { var emojiId = target.id.substr("emojibar-".length); onEmojiSelected(emojiId); } }); return { isSupported: isSupported ,spawn: spawn ,search: search ,close: close }; })();