| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- /* jshint sub: true */
- 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: {}},
- emojiDetail = document.createElement("div"),
- emojiDetailImg = document.createElement("span"),
- emojiDetailName = document.createElement("span"),
- /** @type {function((string|null))|undefined} */
- emojiSelectedHandler,
- /** @type {ChatContext} */
- context,
- /** @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, string):{dom:Element,visible:boolean}} */
- makeCustomEmoji = function(emojiName, emojiSrc) {
- var domEmoji = document.createElement("span"),
- domParent = document.createElement("span");
- domEmoji.className = R.klass.emoji.emoji +' ' +R.klass.emoji.custom;
- domEmoji.style.backgroundImage = 'url("' +emojiSrc +'")';
- domEmoji.textContent = ':' +emojiName +':';
- domEmoji.title = emojiName;
- domParent.appendChild(domEmoji);
- domParent.className = R.klass.emoji.medium;
- return wrapEmojiLi(emojiName, domParent);
- },
- /** @type {function(Object.<string,*>, Object.<string, number>):Array.<{name:string, pos:number, count:number}>} */
- sortEmojis = function(emojiObj, favoriteEmojis) {
- var names = [],
- index = 0;
- for (var i in emojiObj) {
- var obj = {
- name: i,
- pos: index,
- count: 0
- };
- if (emojiObj[i].names)
- for (var nameI =0, nbNames = emojiObj[i].names.length; nameI < nbNames; nameI++)
- obj.count += (favoriteEmojis[emojiObj[i].names[nameI]] || 0);
- names.push(obj);
- }
- names = names.sort(function(a, b) {
- var diff = b.count -a.count;
- if (diff) return diff;
- return a.pos -b.pos;
- });
- return names;
- },
- /** @type {function(string):number} */
- searchFromService = function(queryString) {
- var emojiCount =0,
- /** @type {Object.<string, *>} */
- foundEmojis = window['searchEmojis'](queryString),
- /** @type {Array.<{name:string, pos:number, count:number}>} */
- sortedEmojiNames = sortEmojis(foundEmojis, context ? context.self.prefs.favoriteEmojis : []),
- i,
- nbEmojis;
- for (i in emojiCache.unicode) {
- if (emojiCache.unicode[i].visible) {
- // We remove every item to reorder them (add them in order)
- emojiCache.unicode[i].visible = false;
- unicodeEmojis.removeChild(emojiCache.unicode[i].dom);
- }
- }
- for (i =0, nbEmojis = sortedEmojiNames.length; i < nbEmojis; i++) {
- var emojiName = sortedEmojiNames[i].name,
- e = emojiCache.unicode[emojiName];
- if (!e)
- e = emojiCache.unicode[emojiName] = makeUnicodeEmojiLi(emojiName, foundEmojis[emojiName]);
- if (!e.visible) {
- e.visible = true;
- unicodeEmojis.appendChild(e.dom);
- }
- emojiCount++;
- }
- return emojiCount;
- },
- /** @type {function(string):number} */
- searchFromCustom = function(queryString) {
- var i,
- nbEmojis,
- emojiCount = 0;
- for (i in emojiCache.custom) {
- if (emojiCache.custom[i].visible) {
- emojiCache.custom[i].visible = false;
- customEmojis.removeChild(emojiCache.custom[i].dom);
- }
- }
- if (!context)
- return 0;
- /** @type {Array.<{name:string, pos:number, count:number}>} */
- var sortedEmojiNames = sortEmojis(context.emojis.data, context ? context.self.prefs.favoriteEmojis : []);
- for (i =0, nbEmojis = sortedEmojiNames.length; i < nbEmojis; i++) {
- var emojiName = sortedEmojiNames[i].name;
- if ((queryString === '' || emojiName.substr(0, queryString.length) === queryString) && context.emojis.data[emojiName].substr(0, 6) !== 'alias:') {
- var e = emojiCache.custom[emojiName];
- if (!e)
- e = emojiCache.custom[emojiName] = makeCustomEmoji(emojiName, context.emojis.data[emojiName]);
- if (!e.visible) {
- e.visible = true;
- customEmojis.appendChild(e.dom);
- }
- emojiCount++;
- }
- }
- return emojiCount;
- },
- /** @type function(string=):number */
- search = function(queryString) {
- var emojiCount = 0;
- queryString = (queryString === undefined) ? searchBar.value : queryString;
- // Service emojis
- if (isSupported()) {
- emojiCount += searchFromService(queryString);
- }
- emojiCount += searchFromCustom(queryString);
- // Custom emojis
- return emojiCount;
- },
- /** @type function(Element, ChatContext, function((string|null))=):boolean */
- spawn = function(domParent, ctx, handler) {
- if (isSupported()) {
- context = ctx;
- 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);
- },
- reset = function() {
- emojiCache.unicode = {};
- emojisDom.textContent = "";
- if (window['emojiProviderHeader']) {
- emojisDom.appendChild(makeHeader(window['emojiProviderHeader']));
- unicodeEmojis.textContent = "";
- emojisDom.appendChild(unicodeEmojis);
- }
- emojisDom.appendChild(makeHeader("emojicustom.png"));
- emojisDom.appendChild(customEmojis);
- }
- ;
- 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;
- emojiDetail.className = R.klass.emojibar.detail.container;
- emojiDetailImg.className = R.klass.emojibar.detail.img;
- emojiDetailName.className = R.klass.emojibar.detail.name;
- emojiDetail.appendChild(emojiDetailImg);
- emojiDetail.appendChild(emojiDetailName);
- reset();
- dom.appendChild(emojisDom);
- dom.appendChild(emojiDetail);
- dom.appendChild(searchBar);
- searchBar.addEventListener("keyup", function() {
- search();
- });
- var makeDelegate = function(e, cb) {
- 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);
- return cb(emojiId);
- }
- cb(null);
- };
- dom.addEventListener("mousemove", function(e) {
- makeDelegate(e, function(emoji) {
- var emojiCached = emoji ? (emojiCache.unicode[emoji] || emojiCache.custom[emoji]) : null;
- if (emojiCached) {
- emojiDetailImg.innerHTML = emojiCached.dom.outerHTML;
- emojiDetailName.textContent = ':' +emoji +':';
- } else {
- emojiDetailImg.textContent = "";
- emojiDetailName.textContent = "";
- }
- });
- });
- dom.addEventListener("click", function(e) {
- makeDelegate(e, function(emoji) {
- if (emoji) onEmojiSelected(emoji);
- });
- });
- return {
- isSupported: isSupported,
- spawn: spawn,
- search: search,
- close: close,
- reset: function() {
- reset();
- search();
- }
- };
- })();
|