ComunicWeb/assets/3rdparty/wdt-emoji/wdt-emoji-bundle.js

1097 lines
337 KiB
JavaScript
Raw Normal View History

2018-04-20 13:40:09 +00:00
/*!
@package wdt-emoji-bundle - Slack like emoji selector with apple, twitter, google, emojione and custom emoji support.
@version version: 0.2.1
@contributors https://github.com/needim/wdt-emoji-bundle/graphs/contributors
@documentation Examples and Documentation - http://ned.im/wdt-emoji-bundle/
@license Licensed under the MIT licenses: http://www.opensource.org/licenses/mit-license.php
*/
;
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['emoji-js'], factory);
} else if (typeof exports === 'object') {
module.exports = factory(require('emoji-js'));
} else {
root.wdtEmojiBundle = factory(root.EmojiConvertor);
}
})(this, function (EmojiConvertor) {
var wdtEmojiBundle = {};
wdtEmojiBundle.defaults = {
pickerColors : ['green', 'pink', 'yellow', 'blue', 'gray'],
textMode : true,
disabledCategories: ['Skin Tones'],
sectionOrders: {
'Recent' : 10,
'Custom' : 9,
'People' : 8,
'Nature' : 7,
'Foods' : 6,
'Activity': 5,
'Places' : 4,
'Objects' : 3,
'Symbols' : 2,
'Flags' : 1
},
skinColor : 'skin-1',
allowNative : false,
emojiType : 'apple',
emojiSheets: {
'apple' : '/sheets/sheet_apple_64_indexed_128.png',
'google' : '/sheets/sheet_google_64_indexed_128.png',
'twitter' : '/sheets/sheet_twitter_64_indexed_128.png',
'emojione' : '/sheets/sheet_emojione_64_indexed_128.png',
'facebook' : '/sheets/sheet_facebook_64_indexed_128.png',
'messenger': '/sheets/sheet_messenger_64_indexed_128.png'
},
emojiData: {"Symbols":[{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"HEAVY BLACK HEART","short_name":"heart","short_names":["heart"],"sort_order":1},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"YELLOW HEART","short_name":"yellow_heart","short_names":["yellow_heart"],"sort_order":2},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"GREEN HEART","short_name":"green_heart","short_names":["green_heart"],"sort_order":3},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"BLUE HEART","short_name":"blue_heart","short_names":["blue_heart"],"sort_order":4},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"PURPLE HEART","short_name":"purple_heart","short_names":["purple_heart"],"sort_order":5},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"BROKEN HEART","short_name":"broken_heart","short_names":["broken_heart"],"sort_order":6},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false,"name":"HEAVY HEART EXCLAMATION MARK ORNAMENT","short_name":"heavy_heart_exclamation_mark_ornament","short_names":["heavy_heart_exclamation_mark_ornament"],"sort_order":7},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"TWO HEARTS","short_name":"two_hearts","short_names":["two_hearts"],"sort_order":8},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"REVOLVING HEARTS","short_name":"revolving_hearts","short_names":["revolving_hearts"],"sort_order":9},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"BEATING HEART","short_name":"heartbeat","short_names":["heartbeat"],"sort_order":10},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"GROWING HEART","short_name":"heartpulse","short_names":["heartpulse"],"sort_order":11},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"SPARKLING HEART","short_name":"sparkling_heart","short_names":["sparkling_heart"],"sort_order":12},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"HEART WITH ARROW","short_name":"cupid","short_names":["cupid"],"sort_order":13},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"HEART WITH RIBBON","short_name":"gift_heart","short_names":["gift_heart"],"sort_order":14},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":true,"name":"HEART DECORATION","short_name":"heart_decoration","short_names":["heart_decoration"],"sort_order":15},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false,"name":"PEACE SYMBOL","short_name":"peace_symbol","short_names":["peace_symbol"],"sort_order":16},{"has_img_apple":true,"has_img_google":true,"has_img_twitter":true,"has_img_emojione":true,"has_img_facebook":true,"has_img_messenger":false,"name":"LATIN CROSS","short_name":"latin_cross","short_names"
};
/**
* Init the bundle with selector, YAY!
*/
wdtEmojiBundle.init = function (selector) {
var self = this;
// emoji.js overrides
self.emoji = new EmojiConvertor();
self.emoji.allow_native = this.defaults.allowNative;
self.emoji.img_set = this.defaults.emojiType;
self.emoji.use_sheet = true;
self.emoji.supports_css = true;
self.emoji.img_sets['apple']['sheet'] = this.defaults.emojiSheets.apple;
self.emoji.img_sets['google']['sheet'] = this.defaults.emojiSheets.google;
self.emoji.img_sets['twitter']['sheet'] = this.defaults.emojiSheets.twitter;
self.emoji.img_sets['emojione']['sheet'] = this.defaults.emojiSheets.emojione;
self.emoji.img_sets['facebook']['sheet'] = this.defaults.emojiSheets.facebook;
self.emoji.img_sets['messenger']['sheet'] = this.defaults.emojiSheets.messenger;
self.selector = selector;
self.elements = document.querySelectorAll(selector);
self.popup = document.querySelector('.wdt-emoji-popup');
self.scroller = self.popup.querySelector('.wdt-emoji-scroll-wrapper');
self.searchInput = self.popup.querySelector('#wdt-emoji-search');
self.previewImg = self.popup.querySelector('#wdt-emoji-preview-img');
self.previewName = self.popup.querySelector('#wdt-emoji-preview-name');
self.previewAliases = self.popup.querySelector('#wdt-emoji-preview-aliases');
document.querySelector('body').dataset.wdtEmojiBundle = wdtEmojiBundle.defaults.emojiType;
var recent = self.popup.querySelector('[data-group-name="Recent"]');
if (recent)
recent.innerHTML = self.emoji.replace_colons(':clock3:');
var people = self.popup.querySelector('[data-group-name="People"]');
if (people)
people.innerHTML = self.emoji.replace_colons(':sunglasses:');
var nature = self.popup.querySelector('[data-group-name="Nature"]');
if (nature)
nature.innerHTML = self.emoji.replace_colons(':shamrock:');
var foods = self.popup.querySelector('[data-group-name="Foods"]');
if (foods)
foods.innerHTML = self.emoji.replace_colons(':pizza:');
var activity = self.popup.querySelector('[data-group-name="Activity"]');
if (activity)
activity.innerHTML = self.emoji.replace_colons(':football:');
var places = self.popup.querySelector('[data-group-name="Places"]');
if (places)
places.innerHTML = self.emoji.replace_colons(':airplane:');
var objects = self.popup.querySelector('[data-group-name="Objects"]');
if (objects)
objects.innerHTML = self.emoji.replace_colons(':bulb:');
var symbols = self.popup.querySelector('[data-group-name="Symbols"]');
if (symbols)
symbols.innerHTML = self.emoji.replace_colons(':heart:');
var flags = self.popup.querySelector('[data-group-name="Flags"]');
if (flags)
flags.innerHTML = self.emoji.replace_colons(':waving_white_flag:');
var custom = self.popup.querySelector('[data-group-name="Custom"]');
if (custom)
custom.innerHTML = self.emoji.replace_colons(':dark_sunglasses:');
// a trick for contenteditable blur range clear
self.ranges = {};
if (this.elements.length) {
for (var i = 0; i < self.elements.length; i++) {
var el = self.elements[i];
if (el.getAttribute('contenteditable')) {
el.dataset.rangeIndex = i;
wdtEmojiBundle.addRangeStore(el);
}
self.addPicker(self.elements[i]);
}
}
return self;
};
/**
*
* @param element
*/
wdtEmojiBundle.addPicker = function (element) {
var self = this;
if (!hasClass(element, 'wdt-emoji-picker-ready')) {
var p = document.createElement('div');
addClass(p, 'wdt-emoji-picker');
p.innerHTML = self.emoji.replace_colons(':smile:');
p.addEventListener('click', wdtEmojiBundle.openPicker);
var parent = element.parentNode;
addClass(parent, 'wdt-emoji-picker-parent');
parent.appendChild(p);
if (hasClass(element, 'wdt-emoji-open-on-colon')) {
parent.addEventListener('keyup', wdtEmojiBundle.onKeyup)
}
addClass(element, 'wdt-emoji-picker-ready');
}
};
/**
*
* @param ev
* @returns {void}
*/
wdtEmojiBundle.onKeyup = function (ev) {
var element = ev.target,
parent = findParent(element, 'wdt-emoji-picker-parent'),
emojiPicker = findChild(parent, 'wdt-emoji-picker'),
val = element.value,
selection = getSelection(element),
textBeforeCursor = val.substring(0, selection.start),
// `<space>:` OR `^:` followed by text
// text is captured
matches = textBeforeCursor.match(/(\s|^):(\S*)$/),
text = matches && matches[2];
wdtEmojiBundle.searchAfterColon(text, emojiPicker);
};
/**
*
* @param text
* @param emojiPicker
* @returns {void}
*/
wdtEmojiBundle.searchAfterColon = function (text, emojiPicker) {
// no text or not enough text after colon
if (!text || text.length < 2) {
wdtEmojiBundle.close();
return;
}
// is closed
if (!hasClass(emojiPicker, 'wdt-emoji-picker-open')) {
wdtEmojiBundle.openPicker.call(emojiPicker, {target: emojiPicker});
}
// execute the search
wdtEmojiBundle.fillSearch(text);
};
/**
*
* @param ev
* @returns {boolean}
*/
wdtEmojiBundle.openPicker = function (ev) {
var self = this;
var parent = findParent(ev.target, 'wdt-emoji-picker-parent');
wdtEmojiBundle.input = parent.querySelector(wdtEmojiBundle.selector);
// @todo - [needim] - popup must be visible in viewport calculate carefully
function findBestAvailablePosition(el) {
var bodyRect = document.body.getBoundingClientRect();
var elRect = el.getBoundingClientRect();
var popupRect = wdtEmojiBundle.popup.getBoundingClientRect();
var pos = {
left: (elRect.left - popupRect.width) + elRect.width,
top : elRect.top + Math.abs(bodyRect.top) + elRect.height
};
pos.left = pos.left < 0 ? 0 : pos.left;
if (bodyRect.width < 415) { // mobile specific @todo - [needim] - better mobile detection needed
addClass(wdtEmojiBundle.popup, 'wdt-emoji-mobile');
return {
left : '0px',
bottom : '0px',
top : 'auto',
width : '100%',
position: 'fixed'
}
}
//COMUNIC EDIT
var body = document.body,
html = document.documentElement;
var heigth = Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight);
if(pos.top + 358 > heigth)
pos.top = heigth - 358;
//END COMUNIC EDIT
//COMUNIC MOVE
pos.left += 'px';
pos.top += 'px';
//END COMUNIC MOVE
return pos;
}
css(wdtEmojiBundle.popup, findBestAvailablePosition(ev.target));
// On window resized
window.addEventListener('resize', function(new_event){
css(wdtEmojiBundle.popup, findBestAvailablePosition(ev.target));
});
addClass(wdtEmojiBundle.popup, 'open');
// fill with emoji
wdtEmojiBundle.fillPickerPopup();
if (hasClass(this, 'wdt-emoji-picker-open')) {
wdtEmojiBundle.closePicker(this);
removeClass(wdtEmojiBundle.popup, 'open');
return false;
}
wdtEmojiBundle.closePickers();
addClass(this, 'wdt-emoji-picker-open');
//this.innerHTML = wdtEmojiBundle.emoji.replace_colons(':sunglasses:'); //COMUNIC - EDIT
//COMUNIC EDIT
//Make the picker close automatically if the parent element is removed
var interval = setInterval(function(){
if(!parent.isConnected){
wdtEmojiBundle.close();
clearInterval(interval);
}
}, 2500);
//END COMUNIC EDIT
2018-04-20 13:40:09 +00:00
};
/**
*
* Main function to fill picker popup with emoji
*
* @returns void | boolean | mixed
*/
wdtEmojiBundle.fillPickerPopup = function () {
var self = this;
if (hasClass(this.popup, 'ready'))
return false;
// @todo - [needim] - Support for recent and custom emoji list
var sectionsContainer = this.popup.querySelector('.wdt-emoji-sections'),
sections = {'Recent': [], 'Custom': []},
sortedSections = [];
for (var category in wdtEmojiBundle.defaults.emojiData) {
if (wdtEmojiBundle.defaults.emojiData.hasOwnProperty(category)) {
if (inArray(category, wdtEmojiBundle.defaults.disabledCategories))
continue;
emojiList = wdtEmojiBundle.defaults.emojiData[category];
sections[category] = emojiList;
}
}
var sortedSectionsArray = Object.keys(sections).sort(function (a, b) {
return wdtEmojiBundle.defaults.sectionOrders[a] < wdtEmojiBundle.defaults.sectionOrders[b] ? 1 : -1;
});
for (var i = 0; i < sortedSectionsArray.length; i++) {
sortedSections[sortedSectionsArray[i]] = sections[sortedSectionsArray[i]];
}
for (var title in sortedSections) {
if (sortedSections.hasOwnProperty(title)) {
var emojiList = sortedSections[title];
if (emojiList.length) {
var emojiSection = document.createElement('div'),
emojiTitle = document.createElement('h3'),
emojiListDiv = document.createElement('div');
emojiTitle.innerHTML = title;
emojiTitle.dataset.emojiGroup = title;
emojiListDiv.dataset.emojiGroup = title;
addClass(emojiListDiv, 'wdt-emoji-list');
addClass(emojiSection, 'wdt-emoji-section');
for (i = 0; i < emojiList.length; i++) {
var em = emojiList[i];
if (em.has_img_apple || em.has_img_emojione || em.has_img_google || em.has_img_twitter || em.has_img_facebook || em.has_img_messenger) {
var emojiLink = document.createElement('a');
addClass(emojiLink, 'wdt-emoji');
addClass(emojiLink, wdtEmojiBundle.getRandomPickerColor());
emojiLink.dataset.hasImgApple = em.has_img_apple;
emojiLink.dataset.hasImgEmojione = em.has_img_emojione;
emojiLink.dataset.hasImgGoogle = em.has_img_google;
emojiLink.dataset.hasImgTwitter = em.has_img_twitter;
emojiLink.dataset.hasImgFacebook = em.has_img_facebook;
emojiLink.dataset.hasImgMessenger = em.has_img_messenger;
emojiLink.dataset.wdtEmojiName = em.name;
emojiLink.dataset.wdtEmojiShortnames = ':' + em.short_names.join(': :') + ':';
emojiLink.dataset.wdtEmojiShortname = em.short_name;
emojiLink.dataset.wdtEmojiOrder = em.sort_order;
emojiLink.innerHTML = self.emoji.replace_colons(':' + em.short_name + ':');
emojiListDiv.appendChild(emojiLink);
}
}
emojiSection.appendChild(emojiTitle);
emojiSection.appendChild(emojiListDiv);
sectionsContainer.appendChild(emojiSection);
}
}
}
addClass(this.popup, 'ready');
wdtEmojiBundle.bindEvents();
};
/**
* Random css class getter for picker hover colors
* @returns string
*/
wdtEmojiBundle.getRandomPickerColor = function () {
return wdtEmojiBundle.defaults.pickerColors[Math.floor(Math.random() * wdtEmojiBundle.defaults.pickerColors.length)]
};
/**
* Close the bundle popup
*/
wdtEmojiBundle.close = function () {
removeClass(wdtEmojiBundle.popup, 'open');
wdtEmojiBundle.closePickers();
};
/**
* Closes all the pickers
*/
wdtEmojiBundle.closePickers = function () {
var openPickers = document.querySelectorAll('.wdt-emoji-picker-open');
if (openPickers.length) {
for (var i = 0; i < openPickers.length; i++) {
wdtEmojiBundle.closePicker(openPickers[i]);
}
}
};
/**
*
* @param element
*/
wdtEmojiBundle.closePicker = function (element) {
removeClass(element, 'wdt-emoji-picker-open');
//element.innerHTML = this.emoji.replace_colons(':smile:'); //COMUNIC - EDIT
var parent = findParent(element, 'wdt-emoji-picker-parent');
if (wdtEmojiBundle.searchInput) {
wdtEmojiBundle.searchInput.value = "";
wdtEmojiBundle.search("");
}
};
/**
* void function binds some events for the bundle
*/
wdtEmojiBundle.bindEvents = function () {
var self = this;
var stickers = document.querySelectorAll('.wdt-emoji-section h3');
if (stickers.length) {
for (var i = 0; i < stickers.length; i++) {
sticky(stickers[i]);
}
}
live('click', '.wdt-emoji-list a.wdt-emoji', function (event) {
var selection = getSelection(wdtEmojiBundle.input);
replaceText(wdtEmojiBundle.input, selection, ':' + this.dataset.wdtEmojiShortname + ':');
fire('select', {el: wdtEmojiBundle.input, event: event, emoji: ':' + this.dataset.wdtEmojiShortname + ':'});
var ce = document.createEvent('Event');
ce.initEvent('input', true, true);
wdtEmojiBundle.input.dispatchEvent(ce);
wdtEmojiBundle.close();
fire('afterSelect', {el: wdtEmojiBundle.input, event: event, emoji: ':' + this.dataset.wdtEmojiShortname + ':'});
return false;
});
live('click', '.wdt-emoji-popup-mobile-closer', function (event) {
wdtEmojiBundle.close();
return false;
});
live('mouseover', '.wdt-emoji-list a.wdt-emoji', function (event) {
if (wdtEmojiBundle.previewTimer)
clearTimeout(wdtEmojiBundle.previewTimer);
if (wdtEmojiBundle.previewExitTimer)
clearTimeout(wdtEmojiBundle.previewExitTimer);
var emo = this;
wdtEmojiBundle.previewTimer = setTimeout(function () {
addClass(wdtEmojiBundle.popup, 'preview-mode');
wdtEmojiBundle.previewImg.innerHTML = self.emoji.replace_colons(':' + emo.dataset.wdtEmojiShortname + ':');
wdtEmojiBundle.previewName.innerHTML = emo.dataset.wdtEmojiShortname;
wdtEmojiBundle.previewAliases.innerHTML = emo.dataset.wdtEmojiShortnames;
}, 100);
return false;
});
live('mouseout', '.wdt-emoji-list a.wdt-emoji', function () {
if (wdtEmojiBundle.previewExitTimer)
clearTimeout(wdtEmojiBundle.previewExitTimer);
wdtEmojiBundle.previewExitTimer = setTimeout(function () {
removeClass(wdtEmojiBundle.popup, 'preview-mode');
}, 1000);
return false;
});
live('click', '.wdt-emoji-tab', function (e) {
var group = this.dataset.groupName,
groupHeader = wdtEmojiBundle.popup.querySelector('.wdt-emoji-section h3[data-emoji-group="' + group + '"]');
if (groupHeader) {
wdtEmojiBundle.setActiveTab(group);
wdtEmojiBundle.scroller.scrollTop = groupHeader.offsetTop - groupHeader.getBoundingClientRect().height - 2;
}
return false;
});
live('input', '#wdt-emoji-search', function (e) {
var input = this;
if (wdtEmojiBundle.searchTimer) {
clearTimeout(wdtEmojiBundle.searchTimer);
}
wdtEmojiBundle.searchTimer = setTimeout(function () {
wdtEmojiBundle.search(input.value);
}, 225);
});
addListenerMulti(wdtEmojiBundle.scroller, 'mousewheel DOMMouseScroll', function(e) {
var delta = e.wheelDelta || (e.originalEvent && e.originalEvent.wheelDelta) || -e.detail,
bottomOverflow = this.scrollTop + this.getBoundingClientRect().height - this.scrollHeight >= 0,
topOverflow = this.scrollTop <= 0;
if ((delta < 0 && bottomOverflow) || (delta > 0 && topOverflow)) {
e.preventDefault();
}
});
};
/**
*
* @param q
* @returns {boolean}
*/
wdtEmojiBundle.fillSearch = function (q) {
if (wdtEmojiBundle.searchInput) {
wdtEmojiBundle.searchInput.value = q;
return wdtEmojiBundle.search(q);
} else {
return false;
}
};
/**
*
* @param q
* @returns {boolean}
*/
wdtEmojiBundle.search = function (q) {
var sections = wdtEmojiBundle.popup.querySelector('.wdt-emoji-sections'),
searchResultH3 = wdtEmojiBundle.popup.querySelector('#wdt-emoji-search-result-title'),
emojiList = sections.querySelectorAll('.wdt-emoji'),
zeroText = wdtEmojiBundle.popup.querySelector('#wdt-emoji-no-result'),
found = 0;
if (q == '') {
removeClass(searchResultH3, 'wdt-show');
removeClass(zeroText, 'wdt-show');
removeClassAll('.wdt-emoji.not-matched', 'not-matched');
removeClassAll('.wdt-emoji-section', 'wdt-inline');
removeClassAll('.wdt-emoji-list', 'wdt-inline');
removeClassAll('.wdt-emoji-section h3', 'wdt-search-on');
return false;
}
for (var i = 0; i < emojiList.length; i++) {
var emo = emojiList[i];
var sst = emo.dataset.wdtEmojiName + ' ' + emo.dataset.wdtEmojiShortnames;
removeClass(emo, 'not-matched');
if (sst.match(new RegExp(q, "gi"))) {
found++;
} else {
addClass(emo, 'not-matched');
}
}
addClass(searchResultH3, 'wdt-show');
addClassAll('.wdt-emoji-section', 'wdt-inline');
addClassAll('.wdt-emoji-list', 'wdt-inline');
addClassAll('.wdt-emoji-section h3', 'wdt-search-on');
if (found) {
removeClass(zeroText, 'wdt-show');
} else {
addClass(zeroText, 'wdt-show');
}
};
/**
*
* @type {{select: Array, afterSelect: Array, afterPickerOpen: Array}}
*/
wdtEmojiBundle.dispatchHandlers = {
'select' : [],
'afterSelect' : [],
'afterPickerOpen': [] // not implemented
};
/**
*
* @param eventName
* @param handler
* @returns mixed
*/
wdtEmojiBundle.on = function (eventName, handler) {
switch (eventName) {
case "select":
return wdtEmojiBundle.dispatchHandlers.select.push(handler);
break;
case "afterSelect":
return wdtEmojiBundle.dispatchHandlers.afterSelect.push(handler);
break;
case "afterPickerOpen":
return wdtEmojiBundle.dispatchHandlers.afterPickerOpen.push(handler);
break;
default:
console.error('wdt-emoji-bundle - Not supported event type!', eventName);
break;
}
};
/**
* On the fly emoji type changer apple, google, twitter, emojione
* @param changeType
*/
wdtEmojiBundle.changeType = function (changeType) {
var nextSheet = wdtEmojiBundle.defaults.emojiSheets[changeType],
currentEmojiList = document.querySelectorAll('.emoji-inner'),
i;
for (i = 0; i < currentEmojiList.length; i++) {
var e = currentEmojiList[i];
css(e, {
'background-image': 'url(' + nextSheet + ')'
});
}
wdtEmojiBundle.defaults.emojiType = changeType;
document.querySelector('body').dataset.wdtEmojiBundle = changeType;
this.emoji.img_set = changeType;
};
/**
*
* @param color
*/
wdtEmojiBundle.changeSkinColor = function (color) {
// @todo - [needim] - support skin colors for apple emoji set
};
/**
*
* @param text
* @returns {string}
*/
wdtEmojiBundle.render = function (text) {
return this.emoji.replace_colons(this.emoji.replace_emoticons(this.emoji.replace_unified(text)));
};
/**
* A trick for contenteditable range clear on blur
* @param el
*/
wdtEmojiBundle.addRangeStore = function (el) {
el.addEventListener('focus', function () {
var s = window.getSelection();
if (!wdtEmojiBundle.ranges[this.dataset.rangeIndex]) {
wdtEmojiBundle.ranges[this.dataset.rangeIndex] = new Range();
} else if (s.rangeCount > 0) {
s.removeAllRanges();
s.addRange(wdtEmojiBundle.ranges[this.dataset.rangeIndex]);
}
});
addListenerMulti(el, 'mouseup keyup', function () {
wdtEmojiBundle.ranges[this.dataset.rangeIndex] = window.getSelection().getRangeAt(0);
});
addListenerMulti(el, 'mousedown click', function (e) {
if (document.activeElement != this) {
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
this.focus();
}
});
};
/**
*
* @param el
* @param events
* @param cb
*/
var addListenerMulti = function (el, events, cb) {
events = events.split(' ');
for (var i = 0; i < events.length; i++) {
el.addEventListener(events[i], cb, false);
}
};
/**
* Stick section header controls
* @param el
*/
var sticky = function (el) {
var scrollerRect = wdtEmojiBundle.scroller.getBoundingClientRect(),
elTop = el.getBoundingClientRect().top - scrollerRect.top,
tabHeaderHeight = wdtEmojiBundle.popup.querySelector('#wdt-emoji-menu-header').getBoundingClientRect().height;
wdtEmojiBundle.scroller.addEventListener("scroll", check);
function check() {
var scrollTop = wdtEmojiBundle.scroller.scrollTop;
if (hasClass(el, 'sticky') && scrollTop < elTop) {
removeClass(el, 'sticky');
css(el, {top: null});
css(el.parentNode, {'padding-top': null});
} else if (scrollTop > elTop && !hasClass(el, 'sticky')) {
var stickers = document.querySelectorAll('.wdt-emoji-section h3');
if (stickers.length) {
for (var i = 0; i < stickers.length; i++) {
removeClass(stickers[i], 'sticky');
css(stickers[i], {top: null});
css(stickers[i].parentNode, {'padding-top': null});
}
}
addClass(el, 'sticky');
css(el, {'top': tabHeaderHeight + 'px'});
css(el.parentNode, {'padding-top': el.getBoundingClientRect().height + 'px'});
wdtEmojiBundle.setActiveTab(el.dataset.emojiGroup);
}
}
};
/**
*
* @param group
*/
wdtEmojiBundle.setActiveTab = function (group) {
var tabs = document.querySelectorAll('.wdt-emoji-tab');
if (tabs.length) {
for (var t = 0; t < tabs.length; t++) {
removeClass(tabs[t], 'active');
}
}
var activeTab = wdtEmojiBundle.popup.querySelector('.wdt-emoji-tab[data-group-name="' + group + '"]');
addClass(activeTab, 'active');
};
/**
*
* @param el
* @param cls
* @returns {*}
*/
var findParent = function (el, cls) {
while ((el = el.parentElement) && !el.classList.contains(cls));
return el;
};
/**
*
* @param el
* @param cls
* @returns {*}
*/
var findChild = function (el, cls) {
var children = el.children;
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child.classList.contains(cls)) {
return child;
}
}
};
/**
*
* @param el
* @returns {*}
*/
var getSelection = function (el) {
var result = {};
if (el.getAttribute('contenteditable')) {
return {
el: el,
ce: true
}
}
if (window.getSelection) {
var val = el.value || el.innerHTML,
len = val.length,
start = el.selectionStart,
end = el.selectionEnd,
sel = val.substring(start, end);
result = {
"el" : el,
"start": start,
"end" : end,
"len" : len,
"sel" : sel
};
}
else if (document.selection) { // ie
var range = document.selection.createRange(),
value = el.value || el.innerHTML,
stored_range = range.duplicate();
stored_range.moveToElementText(el);
stored_range.setEndPoint('EndToEnd', range);
el.selectionStart = stored_range.text.length - range.text.length;
el.selectionEnd = el.selectionStart + range.text.length;
result = {
"el" : el,
"start": el.selectionStart,
"end" : el.selectionEnd,
"len" : value.length,
"sel" : range.text
};
}
return result;
};
/**
* Replace selection text for :input
*
* @param el
* @param selection
* @param emo
*/
var replaceText = function (el, selection, emo) {
var val = el.value || el.innerHTML || '';
emo = emo + ' '; //append a space
if (selection.ce) { // if contenteditable
el.focus();
document.execCommand('insertText', false, emo);
} else {
var textBefore = val.substring(0, selection.start);
textBefore = textBefore.replace(/:\S*$/, '')
el.value = textBefore + emo + val.substring(selection.end, selection.len);
// @todo - [needim] - check browser compatibilities
el.selectionStart = el.selectionEnd = (textBefore.length + emo.length);
el.focus();
}
};
/**
* Fire custom events
*
* @param eventName
* @param params
*/
var fire = function (eventName, params) {
var handler, i, len, ref;
ref = wdtEmojiBundle.dispatchHandlers[eventName];
for (i = 0, len = ref.length; i < len; i++) {
handler = ref[i];
handler(params);
}
};
/**
*
* @param eventType
* @param elementQuerySelector
* @param cb
*/
var live = function (eventType, elementQuerySelector, cb) {
document.addEventListener(eventType, function (event) {
var qs = document.querySelectorAll(elementQuerySelector);
if (qs) {
var el = event.target, index = -1;
while (el && ((index = Array.prototype.indexOf.call(qs, el)) === -1)) {
el = el.parentElement;
}
if (index > -1) {
cb.call(el, event);
}
}
});
};
/**
* Applies css properties to an element, similar to the jQuery
* css method.
*
* While this helper does assist with vendor prefixed property names, it
* does not perform any manipulation of values prior to setting styles.
*/
var css = (function () {
var cssPrefixes = ['Webkit', 'O', 'Moz', 'ms'],
cssProps = {};
function camelCase(string) {
return string.replace(/^-ms-/, 'ms-').replace(/-([\da-z])/gi, function (match, letter) {
return letter.toUpperCase();
});
}
function getVendorProp(name) {
var style = document.body.style;
if (name in style) return name;
var i = cssPrefixes.length,
capName = name.charAt(0).toUpperCase() + name.slice(1),
vendorName;
while (i--) {
vendorName = cssPrefixes[i] + capName;
if (vendorName in style) return vendorName;
}
return name;
}
function getStyleProp(name) {
name = camelCase(name);
return cssProps[name] || (cssProps[name] = getVendorProp(name));
}
function applyCss(element, prop, value) {
prop = getStyleProp(prop);
element.style[prop] = value;
}
return function (element, properties) {
var args = arguments,
prop,
value;
if (args.length == 2) {
for (prop in properties) {
value = properties[prop];
if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);
}
} else {
applyCss(element, args[1], args[2]);
}
}
})();
/**
*
* @param element
* @param name
* @returns {boolean}
*/
function hasClass(element, name) {
var list = typeof element == 'string' ? element : classList(element);
return list.indexOf(' ' + name + ' ') >= 0;
}
/**
*
* @param element
* @param name
*/
function addClass(element, name) {
var oldList = classList(element),
newList = oldList + name;
if (hasClass(oldList, name)) return;
// Trim the opening space.
element.className = newList.substring(1);
}
/**
*
* @param query
* @param name
*/
function addClassAll(query, name) {
var elements = document.querySelectorAll(query);
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
var oldList = classList(element),
newList = oldList + name;
if (hasClass(oldList, name)) return;
// Trim the opening space.
element.className = newList.substring(1);
}
}
/**
*
* @param element
* @param name
*/
function removeClass(element, name) {
var oldList = classList(element),
newList;
if (!hasClass(element, name)) return;
// Replace the class name.
newList = oldList.replace(' ' + name + ' ', ' ');
// Trim the opening and closing spaces.
element.className = newList.substring(1, newList.length - 1);
}
/**
*
* @param query
* @param name
*/
function removeClassAll(query, name) {
var elements = document.querySelectorAll(query);
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
var oldList = classList(element),
newList;
if (!hasClass(element, name)) return;
// Replace the class name.
newList = oldList.replace(' ' + name + ' ', ' ');
// Trim the opening and closing spaces.
element.className = newList.substring(1, newList.length - 1);
}
}
function inArray(needle, haystack) {
var length = haystack.length;
for(var i = 0; i < length; i++) {
if(haystack[i] == needle) return true;
}
return false;
}
/**
*
* @param element
* @returns {string}
*/
function classList(element) {
return (' ' + (element && element.className || '') + ' ').replace(/\s+/gi, ' ');
}
return wdtEmojiBundle;
});