diff --git a/plugins/emoji/assets/javascripts/emoji-autocomplete.js b/plugins/emoji/assets/javascripts/emoji-autocomplete.js
new file mode 100644
index 00000000000..977d8ccebeb
--- /dev/null
+++ b/plugins/emoji/assets/javascripts/emoji-autocomplete.js
@@ -0,0 +1,46 @@
+
+// TODO: Make this a proper ES6 import
+var ComposerView = require('discourse/views/composer').default;
+ComposerView.on("initWmdEditor", function(){
+ if (!Discourse.SiteSettings.enable_emoji) { return; }
+
+ var template = Handlebars.compile("
");
+
+ $('#wmd-input').autocomplete({
+ template: template,
+ key: ":",
+ transformComplete: function(v){ return v.code + ":"; },
+ dataSource: function(term){
+ return new Ember.RSVP.Promise(function(resolve) {
+ var full = ":" + term;
+ term = term.toLowerCase();
+
+ if (term === "") {
+ return resolve(["smile", "smiley", "wink", "sunny", "blush"]);
+ }
+
+ if (Discourse.Emoji.translations[full]) {
+ return resolve([Discourse.Emoji.translations[full]]);
+ }
+
+ var options = Discourse.Emoji.search(term, {maxResults: 5});
+
+ return resolve(options);
+ }).then(function(list) {
+ return list.map(function(i) {
+ return {code: i, src: Discourse.Emoji.urlFor(i)};
+ });
+ });
+ }
+ });
+});
diff --git a/plugins/emoji/assets/javascripts/emoji-toolbar.js b/plugins/emoji/assets/javascripts/emoji-toolbar.js
new file mode 100644
index 00000000000..e3b38407168
--- /dev/null
+++ b/plugins/emoji/assets/javascripts/emoji-toolbar.js
@@ -0,0 +1,71 @@
+
+var groups = [
+{
+ name: "emoticons",
+ icons: ["smile","smiley","grinning","blush","relaxed","wink","heart_eyes","kissing_heart","kissing_closed_eyes","kissing","kissing_smiling_eyes","stuck_out_tongue_winking_eye","stuck_out_tongue_closed_eyes","stuck_out_tongue","flushed","grin","pensive","relieved","unamused","disappointed","persevere","cry","joy","sob","sleepy","disappointed_relieved","cold_sweat","sweat_smile","sweat","weary","tired_face","fearful","scream","angry","rage","triumph","confounded","laughing","yum","mask","sunglasses","sleeping","dizzy_face","astonished","worried","frowning","anguished","smiling_imp","imp","open_mouth","grimacing","neutral_face","confused","hushed","no_mouth","innocent","smirk","expressionless","man_with_gua_pi_mao","man_with_turban","cop","construction_worker","guardsman","baby","boy","girl","man","woman","older_man","older_woman","person_with_blond_hair","angel","princess","smiley_cat","smile_cat","heart_eyes_cat","kissing_cat","smirk_cat","scream_cat","crying_cat_face","joy_cat","pouting_cat","japanese_ogre","japanese_goblin","see_no_evil","hear_no_evil","speak_no_evil","skull","alien","poop","fire","sparkles","star2","dizzy","boom","anger","sweat_drops","droplet","zzz","dash","ear","eyes","nose","tongue","lips","thumbsup","thumbsdown","ok_hand","punch","fist","v","wave","raised_hand","open_hands","point_up_2","point_down","point_right","point_left","raised_hands","pray","point_up","clap","muscle","walking","runner","dancer","couple","family","two_men_holding_hands","two_women_holding_hands","couplekiss","couple_with_heart","dancers","ok_woman","no_good","information_desk_person","raising_hand","massage","haircut","nail_care","bride_with_veil","person_with_pouting_face","person_frowning","bow","tophat","crown","womans_hat","athletic_shoe","mans_shoe","sandal","high_heel","boot","shirt","necktie","womans_clothes","dress","running_shirt_with_sash","jeans","kimono","bikini","briefcase","handbag","pouch","purse","eyeglasses","ribbon","closed_umbrella","lipstick","yellow_heart","blue_heart","purple_heart","green_heart","heart","broken_heart","heartpulse","heartbeat","two_hearts","sparkling_heart","revolving_hearts","cupid","love_letter","kiss","ring","gem","bust_in_silhouette","busts_in_silhouette","speech_balloon","footprints","thought_balloon"]
+},
+{
+ name: "nature",
+ icons: ["dog","wolf","cat","mouse","hamster","rabbit","frog","tiger","koala","bear","pig","pig_nose","cow","boar","monkey_face","monkey","horse","sheep","elephant","panda_face","penguin","bird","baby_chick","hatched_chick","hatching_chick","chicken","snake","turtle","bug","bee","ant","beetle","snail","octopus","shell","tropical_fish","fish","dolphin","whale","whale2","cow2","ram","rat","water_buffalo","tiger2","rabbit2","dragon","racehorse","goat","rooster","dog2","pig2","mouse2","ox","dragon_face","blowfish","crocodile","camel","dromedary_camel","leopard","cat2","poodle","feet","bouquet","cherry_blossom","tulip","four_leaf_clover","rose","sunflower","hibiscus","maple_leaf","leaves","fallen_leaf","herb","ear_of_rice","mushroom","cactus","palm_tree","evergreen_tree","deciduous_tree","chestnut","seedling","blossom","globe_with_meridians","sun_with_face","full_moon_with_face","new_moon_with_face","new_moon","waxing_crescent_moon","first_quarter_moon","waxing_gibbous_moon","full_moon","waning_gibbous_moon","last_quarter_moon","waning_crescent_moon","last_quarter_moon_with_face","first_quarter_moon_with_face","crescent_moon","earth_africa","earth_americas","earth_asia","volcano","milky_way","stars","star","sunny","partly_sunny","cloud","zap","umbrella","snowflake","snowman","cyclone","foggy","rainbow","ocean"]
+},
+{
+ name: "objects",
+ icons: ["dog","wolf","cat","mouse","hamster","rabbit","frog","tiger","koala","bear","pig","pig_nose","cow","boar","monkey_face","monkey","horse","sheep","elephant","panda_face","penguin","bird","baby_chick","hatched_chick","hatching_chick","chicken","snake","turtle","bug","bee","ant","beetle","snail","octopus","shell","tropical_fish","fish","dolphin","whale","whale2","cow2","ram","rat","water_buffalo","tiger2","rabbit2","dragon","racehorse","goat","rooster","dog2","pig2","mouse2","ox","dragon_face","blowfish","crocodile","camel","dromedary_camel","leopard","cat2","poodle","feet","bouquet","cherry_blossom","tulip","four_leaf_clover","rose","sunflower","hibiscus","maple_leaf","leaves","fallen_leaf","herb","ear_of_rice","mushroom","cactus","palm_tree","evergreen_tree","deciduous_tree","chestnut","seedling","blossom","globe_with_meridians","sun_with_face","full_moon_with_face","new_moon_with_face","new_moon","waxing_crescent_moon","first_quarter_moon","waxing_gibbous_moon","full_moon","waning_gibbous_moon","last_quarter_moon","waning_crescent_moon","last_quarter_moon_with_face","first_quarter_moon_with_face","crescent_moon","earth_africa","earth_americas","earth_asia","volcano","milky_way","stars","star","sunny","partly_sunny","cloud","zap","umbrella","snowflake","snowman","cyclone","foggy","rainbow","ocean"]
+},
+{
+ name: "places",
+ icons: ["house","house_with_garden","school","office","post_office","hospital","bank","convenience_store","love_hotel","hotel","wedding","church","department_store","european_post_office","city_sunset","city_dusk","japanese_castle","european_castle","tent","factory","tokyo_tower","japan","mount_fuji","sunrise_over_mountains","sunrise","night_with_stars","statue_of_liberty","bridge_at_night","carousel_horse","ferris_wheel","fountain","roller_coaster","ship","sailboat","speedboat","rowboat","anchor","rocket","airplane","seat","helicopter","steam_locomotive","tram","station","mountain_railway","train2","bullettrain_side","bullettrain_front","light_rail","metro","monorail","train","railway_car","trolleybus","bus","oncoming_bus","blue_car","oncoming_automobile","red_car","taxi","oncoming_taxi","articulated_lorry","truck","rotating_light","police_car","oncoming_police_car","fire_engine","ambulance","minibus","bike","aerial_tramway","suspension_railway","mountain_cableway","tractor","barber","busstop","ticket","vertical_traffic_light","traffic_light","warning","construction","beginner","fuelpump","izakaya_lantern","slot_machine","hotsprings","moyai","circus_tent","performing_arts","round_pushpin","triangular_flag_on_post","cn","us","in","jp","br","ru","de","ng","gb","fr","mx","kr","id","ph","eg","vn","tr","it","es","ca","pl","ar","co","ir","za","my","pk","au","th","ma","tw","nl","ua","sa","ke","ve","pe","ro","cl","uz","bd","kz","be","se","cz","sd","hu","pt","ch","at","tz"]
+},
+{
+ name: "symbols",
+ icons: ["hash","one","two","three","four","five","six","seven","eight","nine","zero","keycap_ten","1234","symbols","arrow_up","arrow_down","arrow_left","arrow_right","capital_abcd","abcd","abc","arrow_upper_right","arrow_upper_left","arrow_lower_right","arrow_lower_left","left_right_arrow","arrow_up_down","arrows_counterclockwise","arrow_backward","arrow_forward","arrow_up_small","arrow_down_small","leftwards_arrow_with_hook","arrow_right_hook","information_source","rewind","fast_forward","arrow_double_up","arrow_double_down","arrow_heading_down","arrow_heading_up","ok","twisted_rightwards_arrows","repeat","repeat_one","new","up","cool","free","ng","signal_strength","cinema","koko","u6307","u7a7a","u6e80","u5408","u7981","ideograph_advantage","u5272","u55b6","u6709","u7121","restroom","mens","womens","baby_symbol","wc","potable_water","put_litter_in_its_place","parking","wheelchair","no_smoking","u6708","u7533","sa","m","passport_control","baggage_claim","left_luggage","customs","accept","secret","congratulations","cl","sos","id","no_entry_sign","underage","no_mobile_phones","do_not_litter","non-potable_water","no_bicycles","no_pedestrians","children_crossing","no_entry","eight_spoked_asterisk","sparkle","negative_squared_cross_mark","white_check_mark","eight_pointed_black_star","heart_decoration","vs","vibration_mode","mobile_phone_off","a","b","ab","o2","diamond_shape_with_a_dot_inside","loop","recycle","aries","taurus","gemini","cancer","leo","virgo","libra","scorpius","sagittarius","capricorn","aquarius","pisces","ophiuchus","six_pointed_star","atm","chart","heavy_dollar_sign","currency_exchange","copyright","registered","tm","part_alternation_mark","wavy_dash","top","end","back","on","soon","x","o","exclamation","question","grey_exclamation","grey_question","bangbang","interrobang","arrows_clockwise","clock12","clock1230","clock1","clock130","clock2","clock230","clock3","clock330","clock4","clock430","clock5","clock530","clock6","clock7","clock8","clock9","clock10","clock11","clock630","clock730","clock830","clock930","clock1030","clock1130","heavy_multiplication_x","heavy_plus_sign","heavy_minus_sign","heavy_division_sign","spades","hearts","clubs","diamonds","white_flower","100","heavy_check_mark","ballot_box_with_check","radio_button","link","curly_loop","trident","black_square_button","white_square_button","black_medium_square","white_medium_square","black_medium_small_square","white_medium_small_square","black_small_square","white_small_square","small_red_triangle","white_large_square","black_large_square","black_circle","white_circle","red_circle","large_blue_circle","small_red_triangle_down","large_orange_diamond","large_blue_diamond","small_orange_diamond","small_blue_diamond"]
+}];
+
+var renderPage = Handlebars.compile(
+ "" +
+ "{{#each this}}"+
+ "{{#each this}}" +
+ " | " +
+ "{{/each}}
" +
+ "{{/each}}"+
+ "
");
+
+var closeSelector = function(){
+ $('.emoji-modal, .emoji-modal-wrapper').remove();
+};
+
+var showSelector = function(){
+
+ $('body').append('');
+
+ $('.emoji-modal-wrapper').click(function(){
+ closeSelector();
+ });
+
+ var rows = [];
+ var row = [];
+ var icons = groups[0].icons;
+
+ for(var i=0; i<50; i++){
+ if(row.length === 10){
+ rows.push(row);
+ row = [];
+ }
+ row.push({src: Discourse.Emoji.urlFor(icons[i]), title: icons[i]});
+ }
+ rows.push(row);
+
+ $('body').append('' + renderPage(rows) + '
');
+
+ var composerController = Discourse.__container__.lookup('controller:composer');
+ $('.emoji-page a').click(function(){
+ composerController.appendText(":" + $(this).attr('title') + ":", {space: true});
+ closeSelector();
+ });
+};
+
+window.PagedownCustom.appendButtons.push({
+ id: 'wmd-emoji-button',
+ description: I18n.t("composer.emoji"),
+ execute: showSelector
+});
diff --git a/plugins/emoji/assets/javascripts/emoji.js.erb b/plugins/emoji/assets/javascripts/emoji.js.erb
index 2133626cdd3..9a029375b00 100644
--- a/plugins/emoji/assets/javascripts/emoji.js.erb
+++ b/plugins/emoji/assets/javascripts/emoji.js.erb
@@ -1,262 +1,162 @@
-(function() {
- var emoji = <%= Dir.glob(File.expand_path("../../../public/images/*.png", __FILE__)).map{|f| File.basename(f).split(".")[0]}.inspect %>;
+var emoji = <%= Dir.glob(File.expand_path("../../../public/images/*.png", __FILE__)).map{|f| File.basename(f).split(".")[0]}.inspect %>;
- var _extendedEmoji = {};
- Discourse.Dialect.registerEmoji = function(code, url) {
- _extendedEmoji[code] = url;
- };
+// TODO @robin to move this whole thing to es6
+Discourse.Emoji = {};
- function urlFor(code) {
- var url = _extendedEmoji[code];
- if (!url && emoji.indexOf(code) !== -1) {
- url = Discourse.getURL('/plugins/emoji/images/' + code + '.png');
- }
- return url;
+var _extendedEmoji = {};
+Discourse.Dialect.registerEmoji = function(code, url) {
+ _extendedEmoji[code] = url;
+};
+
+var toSearch;
+
+var search = function(term, options) {
+ var maxResults = (options && options["maxResults"]) || -1;
+
+ toSearch = toSearch || emoji.concat(Object.keys(_extendedEmoji));
+
+ if(maxResults === 0) {
+ return [];
}
- function imageFor(code) {
- var url = urlFor(code);
- if (url) {
- return ['img', {href: url, title: ':' + code + ':', 'class': 'emoji', alt: code}];
+ var results = [];
+
+ var done = function(){
+ return maxResults > 0 && results.length >= maxResults;
+ }
+
+ for (i=0; i < toSearch.length; i++) {
+ if (toSearch[i].indexOf(term) === 0) {
+ results.push(toSearch[i]);
+ if(done()) { break; }
}
}
- // Also support default emotions
- var translations = {
- ':)' : 'smile',
- ':-)' : 'smile',
- ':(' : 'frowning',
- ':-(' : 'frowning',
- ';)' : 'wink',
- ';-)' : 'wink',
- ':\'(' : 'cry',
- ':\'-(' : 'cry',
- ':-\'(' : 'cry',
- ':p' : 'stuck_out_tongue',
- ':P' : 'stuck_out_tongue',
- ':-P' : 'stuck_out_tongue',
- ':O' : 'open_mouth',
- ':-O' : 'open_mouth',
- ':D' : 'smiley',
- ':-D' : 'smiley',
- ':|' : 'expressionless',
- ':-|' : 'expressionless',
- ";P" : 'stuck_out_tongue_winking_eye',
- ";-P" : 'stuck_out_tongue_winking_eye',
- ';)' : 'wink',
- ';-)' : 'wink',
- ":$" : 'blush',
- ":-$" : 'blush'
- };
-
- var groups = [
- {
- name: "emoticons",
- icons: ["smile","smiley","grinning","blush","relaxed","wink","heart_eyes","kissing_heart","kissing_closed_eyes","kissing","kissing_smiling_eyes","stuck_out_tongue_winking_eye","stuck_out_tongue_closed_eyes","stuck_out_tongue","flushed","grin","pensive","relieved","unamused","disappointed","persevere","cry","joy","sob","sleepy","disappointed_relieved","cold_sweat","sweat_smile","sweat","weary","tired_face","fearful","scream","angry","rage","triumph","confounded","laughing","yum","mask","sunglasses","sleeping","dizzy_face","astonished","worried","frowning","anguished","smiling_imp","imp","open_mouth","grimacing","neutral_face","confused","hushed","no_mouth","innocent","smirk","expressionless","man_with_gua_pi_mao","man_with_turban","cop","construction_worker","guardsman","baby","boy","girl","man","woman","older_man","older_woman","person_with_blond_hair","angel","princess","smiley_cat","smile_cat","heart_eyes_cat","kissing_cat","smirk_cat","scream_cat","crying_cat_face","joy_cat","pouting_cat","japanese_ogre","japanese_goblin","see_no_evil","hear_no_evil","speak_no_evil","skull","alien","poop","fire","sparkles","star2","dizzy","boom","anger","sweat_drops","droplet","zzz","dash","ear","eyes","nose","tongue","lips","thumbsup","thumbsdown","ok_hand","punch","fist","v","wave","raised_hand","open_hands","point_up_2","point_down","point_right","point_left","raised_hands","pray","point_up","clap","muscle","walking","runner","dancer","couple","family","two_men_holding_hands","two_women_holding_hands","couplekiss","couple_with_heart","dancers","ok_woman","no_good","information_desk_person","raising_hand","massage","haircut","nail_care","bride_with_veil","person_with_pouting_face","person_frowning","bow","tophat","crown","womans_hat","athletic_shoe","mans_shoe","sandal","high_heel","boot","shirt","necktie","womans_clothes","dress","running_shirt_with_sash","jeans","kimono","bikini","briefcase","handbag","pouch","purse","eyeglasses","ribbon","closed_umbrella","lipstick","yellow_heart","blue_heart","purple_heart","green_heart","heart","broken_heart","heartpulse","heartbeat","two_hearts","sparkling_heart","revolving_hearts","cupid","love_letter","kiss","ring","gem","bust_in_silhouette","busts_in_silhouette","speech_balloon","footprints","thought_balloon"]
- },
- {
- name: "nature",
- icons: ["dog","wolf","cat","mouse","hamster","rabbit","frog","tiger","koala","bear","pig","pig_nose","cow","boar","monkey_face","monkey","horse","sheep","elephant","panda_face","penguin","bird","baby_chick","hatched_chick","hatching_chick","chicken","snake","turtle","bug","bee","ant","beetle","snail","octopus","shell","tropical_fish","fish","dolphin","whale","whale2","cow2","ram","rat","water_buffalo","tiger2","rabbit2","dragon","racehorse","goat","rooster","dog2","pig2","mouse2","ox","dragon_face","blowfish","crocodile","camel","dromedary_camel","leopard","cat2","poodle","feet","bouquet","cherry_blossom","tulip","four_leaf_clover","rose","sunflower","hibiscus","maple_leaf","leaves","fallen_leaf","herb","ear_of_rice","mushroom","cactus","palm_tree","evergreen_tree","deciduous_tree","chestnut","seedling","blossom","globe_with_meridians","sun_with_face","full_moon_with_face","new_moon_with_face","new_moon","waxing_crescent_moon","first_quarter_moon","waxing_gibbous_moon","full_moon","waning_gibbous_moon","last_quarter_moon","waning_crescent_moon","last_quarter_moon_with_face","first_quarter_moon_with_face","crescent_moon","earth_africa","earth_americas","earth_asia","volcano","milky_way","stars","star","sunny","partly_sunny","cloud","zap","umbrella","snowflake","snowman","cyclone","foggy","rainbow","ocean"]
- },
- {
- name: "objects",
- icons: ["dog","wolf","cat","mouse","hamster","rabbit","frog","tiger","koala","bear","pig","pig_nose","cow","boar","monkey_face","monkey","horse","sheep","elephant","panda_face","penguin","bird","baby_chick","hatched_chick","hatching_chick","chicken","snake","turtle","bug","bee","ant","beetle","snail","octopus","shell","tropical_fish","fish","dolphin","whale","whale2","cow2","ram","rat","water_buffalo","tiger2","rabbit2","dragon","racehorse","goat","rooster","dog2","pig2","mouse2","ox","dragon_face","blowfish","crocodile","camel","dromedary_camel","leopard","cat2","poodle","feet","bouquet","cherry_blossom","tulip","four_leaf_clover","rose","sunflower","hibiscus","maple_leaf","leaves","fallen_leaf","herb","ear_of_rice","mushroom","cactus","palm_tree","evergreen_tree","deciduous_tree","chestnut","seedling","blossom","globe_with_meridians","sun_with_face","full_moon_with_face","new_moon_with_face","new_moon","waxing_crescent_moon","first_quarter_moon","waxing_gibbous_moon","full_moon","waning_gibbous_moon","last_quarter_moon","waning_crescent_moon","last_quarter_moon_with_face","first_quarter_moon_with_face","crescent_moon","earth_africa","earth_americas","earth_asia","volcano","milky_way","stars","star","sunny","partly_sunny","cloud","zap","umbrella","snowflake","snowman","cyclone","foggy","rainbow","ocean"]
- },
- {
- name: "places",
- icons: ["house","house_with_garden","school","office","post_office","hospital","bank","convenience_store","love_hotel","hotel","wedding","church","department_store","european_post_office","city_sunset","city_dusk","japanese_castle","european_castle","tent","factory","tokyo_tower","japan","mount_fuji","sunrise_over_mountains","sunrise","night_with_stars","statue_of_liberty","bridge_at_night","carousel_horse","ferris_wheel","fountain","roller_coaster","ship","sailboat","speedboat","rowboat","anchor","rocket","airplane","seat","helicopter","steam_locomotive","tram","station","mountain_railway","train2","bullettrain_side","bullettrain_front","light_rail","metro","monorail","train","railway_car","trolleybus","bus","oncoming_bus","blue_car","oncoming_automobile","red_car","taxi","oncoming_taxi","articulated_lorry","truck","rotating_light","police_car","oncoming_police_car","fire_engine","ambulance","minibus","bike","aerial_tramway","suspension_railway","mountain_cableway","tractor","barber","busstop","ticket","vertical_traffic_light","traffic_light","warning","construction","beginner","fuelpump","izakaya_lantern","slot_machine","hotsprings","moyai","circus_tent","performing_arts","round_pushpin","triangular_flag_on_post","cn","us","in","jp","br","ru","de","ng","gb","fr","mx","kr","id","ph","eg","vn","tr","it","es","ca","pl","ar","co","ir","za","my","pk","au","th","ma","tw","nl","ua","sa","ke","ve","pe","ro","cl","uz","bd","kz","be","se","cz","sd","hu","pt","ch","at","tz"]
- },
- {
- name: "symbols",
- icons: ["hash","one","two","three","four","five","six","seven","eight","nine","zero","keycap_ten","1234","symbols","arrow_up","arrow_down","arrow_left","arrow_right","capital_abcd","abcd","abc","arrow_upper_right","arrow_upper_left","arrow_lower_right","arrow_lower_left","left_right_arrow","arrow_up_down","arrows_counterclockwise","arrow_backward","arrow_forward","arrow_up_small","arrow_down_small","leftwards_arrow_with_hook","arrow_right_hook","information_source","rewind","fast_forward","arrow_double_up","arrow_double_down","arrow_heading_down","arrow_heading_up","ok","twisted_rightwards_arrows","repeat","repeat_one","new","up","cool","free","ng","signal_strength","cinema","koko","u6307","u7a7a","u6e80","u5408","u7981","ideograph_advantage","u5272","u55b6","u6709","u7121","restroom","mens","womens","baby_symbol","wc","potable_water","put_litter_in_its_place","parking","wheelchair","no_smoking","u6708","u7533","sa","m","passport_control","baggage_claim","left_luggage","customs","accept","secret","congratulations","cl","sos","id","no_entry_sign","underage","no_mobile_phones","do_not_litter","non-potable_water","no_bicycles","no_pedestrians","children_crossing","no_entry","eight_spoked_asterisk","sparkle","negative_squared_cross_mark","white_check_mark","eight_pointed_black_star","heart_decoration","vs","vibration_mode","mobile_phone_off","a","b","ab","o2","diamond_shape_with_a_dot_inside","loop","recycle","aries","taurus","gemini","cancer","leo","virgo","libra","scorpius","sagittarius","capricorn","aquarius","pisces","ophiuchus","six_pointed_star","atm","chart","heavy_dollar_sign","currency_exchange","copyright","registered","tm","part_alternation_mark","wavy_dash","top","end","back","on","soon","x","o","exclamation","question","grey_exclamation","grey_question","bangbang","interrobang","arrows_clockwise","clock12","clock1230","clock1","clock130","clock2","clock230","clock3","clock330","clock4","clock430","clock5","clock530","clock6","clock7","clock8","clock9","clock10","clock11","clock630","clock730","clock830","clock930","clock1030","clock1130","heavy_multiplication_x","heavy_plus_sign","heavy_minus_sign","heavy_division_sign","spades","hearts","clubs","diamonds","white_flower","100","heavy_check_mark","ballot_box_with_check","radio_button","link","curly_loop","trident","black_square_button","white_square_button","black_medium_square","white_medium_square","black_medium_small_square","white_medium_small_square","black_small_square","white_small_square","small_red_triangle","white_large_square","black_large_square","black_circle","white_circle","red_circle","large_blue_circle","small_red_triangle_down","large_orange_diamond","large_blue_diamond","small_orange_diamond","small_blue_diamond"]
- }];
-
- function checkPrev(prev) {
- if (prev && prev.length) {
- var lastToken = prev[prev.length-1];
- if (lastToken && lastToken.charAt) {
- var lastChar = lastToken.charAt(lastToken.length-1);
- if (lastChar !== ' ' && lastChar !== "\n") return false;
+ if(!done()){
+ for (i=0; i < toSearch.length; i++) {
+ if (toSearch[i].indexOf(term) > 0) {
+ results.push(toSearch[i]);
+ if(done()) { break; }
}
}
- return true;
}
- var translationsWithColon = {};
- Object.keys(translations).forEach(function (t) {
- if (t[0] === ':') {
- translationsWithColon[t] = translations[t];
- } else {
- var replacement = translations[t];
- Discourse.Dialect.inlineReplace(t, function (token, match, prev) {
- if (!Discourse.SiteSettings.enable_emoji) { return token; }
- return checkPrev(prev) ? imageFor(replacement) : token;
- });
- }
- });
+ return results;
+}
- function escapeRegExp(s) {
- return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
+Discourse.Emoji.search = search;
+
+var urlFor = function(code) {
+ var url = _extendedEmoji[code];
+ if (!url && emoji.indexOf(code) !== -1) {
+ url = Discourse.getURL('/plugins/emoji/images/' + code + '.png');
}
+ return url;
+}
- var translationColonRegexp = new RegExp(Object.keys(translationsWithColon).map(function (t) {
- return "(" + escapeRegExp(t) + ")";
- }).join("|"));
+Discourse.Emoji.urlFor = urlFor;
- Discourse.Dialect.registerInline(':', function(text, match, prev) {
- if (!Discourse.SiteSettings.enable_emoji) { return; }
+function imageFor(code) {
+ var url = urlFor(code);
+ if (url) {
+ return ['img', {href: url, title: ':' + code + ':', 'class': 'emoji', alt: code}];
+ }
+}
- var endPos = text.indexOf(':', 1),
- firstSpace = text.search(/\s/),
- contents;
+// Also support default emotions
+var translations = {
+ ':)' : 'smile',
+ ':-)' : 'smile',
+ ':(' : 'frowning',
+ ':-(' : 'frowning',
+ ';)' : 'wink',
+ ';-)' : 'wink',
+ ':\'(' : 'cry',
+ ':\'-(' : 'cry',
+ ':-\'(' : 'cry',
+ ':p' : 'stuck_out_tongue',
+ ':P' : 'stuck_out_tongue',
+ ':-P' : 'stuck_out_tongue',
+ ':O' : 'open_mouth',
+ ':-O' : 'open_mouth',
+ ':D' : 'smiley',
+ ':-D' : 'smiley',
+ ':|' : 'expressionless',
+ ':-|' : 'expressionless',
+ ";P" : 'stuck_out_tongue_winking_eye',
+ ";-P" : 'stuck_out_tongue_winking_eye',
+ ":$" : 'blush',
+ ":-$" : 'blush'
+};
- if (!checkPrev(prev)) { return; }
+Discourse.Emoji.translations = translations;
- // If there is no trailing colon, check our translations that begin with colons
- if (endPos === -1 || (firstSpace !== -1 && endPos > firstSpace)) {
- translationColonRegexp.lastIndex = 0;
- var m = translationColonRegexp.exec(text);
- if (m && m[0] && text.indexOf(m[0]) === 0) {
-
- // Check outer edge
- var lastChar = text.charAt(m[0].length);
- if (lastChar && (lastChar !== ' ' && lastChar !== "\n")) return;
- contents = imageFor(translationsWithColon[m[0]]);
- if (contents) {
- return [m[0].length, contents];
- }
- }
- return;
+function checkPrev(prev) {
+ if (prev && prev.length) {
+ var lastToken = prev[prev.length-1];
+ if (lastToken && lastToken.charAt) {
+ var lastChar = lastToken.charAt(lastToken.length-1);
+ if (lastChar !== ' ' && lastChar !== "\n") return false;
}
+ }
+ return true;
+}
- // Simple find and replace from our array
- var between = text.slice(1, endPos);
- contents = imageFor(between);
- if (contents) {
- return [endPos+1, contents];
- }
- });
-
-
- if(window.PagedownCustom) {
- var renderPage = Handlebars.compile(
- "" +
- "{{#each this}}"+
- "{{#each this}}" +
- " | " +
- "{{/each}}
" +
- "{{/each}}"+
- "
");
-
- var closeSelector = function(){
- $('.emoji-modal, .emoji-modal-wrapper').remove();
- };
-
- var showSelector = function(){
-
- $('body').append('');
-
- $('.emoji-modal-wrapper').click(function(){
- closeSelector();
- });
-
- var rows = [];
- var row = [];
- var icons = groups[0].icons;
-
- for(var i=0; i<50; i++){
- if(row.length === 10){
- rows.push(row);
- row = [];
- }
- row.push({src: urlFor(icons[i]), title: icons[i]});
- }
- rows.push(row);
-
- $('body').append('' + renderPage(rows) + '
');
-
- var composerController = Discourse.__container__.lookup('controller:composer');
- $('.emoji-page a').click(function(){
- composerController.appendText(":" + $(this).attr('title') + ":", {space: true});
- closeSelector();
- });
- };
-
- window.PagedownCustom.appendButtons.push({
- id: 'wmd-emoji-button',
- description: I18n.t("composer.emoji"),
- execute: showSelector
+var translationsWithColon = {};
+Object.keys(translations).forEach(function (t) {
+ if (t[0] === ':') {
+ translationsWithColon[t] = translations[t];
+ } else {
+ var replacement = translations[t];
+ Discourse.Dialect.inlineReplace(t, function (token, match, prev) {
+ if (!Discourse.SiteSettings.enable_emoji) { return token; }
+ return checkPrev(prev) ? imageFor(replacement) : token;
});
}
+});
- // TODO: Make this a proper ES6 import
- var ComposerView = (Discourse && Discourse.ComposerView) || (typeof require !== "undefined" && require('discourse/views/composer').default);
- if (ComposerView) {
- ComposerView.on("initWmdEditor", function(event){
- if (!Discourse.SiteSettings.enable_emoji) { return; }
+function escapeRegExp(s) {
+ return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
+}
- var baseUrl = Discourse.getURL("/");
+var translationColonRegexp = new RegExp(Object.keys(translationsWithColon).map(function (t) {
+ return "(" + escapeRegExp(t) + ")";
+ }).join("|"));
- template = Handlebars.compile("");
+Discourse.Dialect.registerInline(':', function(text, match, prev) {
+ if (!Discourse.SiteSettings.enable_emoji) { return; }
- var toSearch = emoji.concat(Object.keys(_extendedEmoji));
+ var endPos = text.indexOf(':', 1),
+ firstSpace = text.search(/\s/),
+ contents;
- $('#wmd-input').autocomplete({
- template: template,
- key: ":",
- transformComplete: function(v){ return v.code + ":"; },
- dataSource: function(term){
- return new Ember.RSVP.Promise(function(resolve) {
- var full = ":" + term;
- term = term.toLowerCase();
+ if (!checkPrev(prev)) { return; }
- if (term === "") {
- return resolve(["smile", "smiley", "wink", "sunny", "blush"]);
- }
+ // If there is no trailing colon, check our translations that begin with colons
+ if (endPos === -1 || (firstSpace !== -1 && endPos > firstSpace)) {
+ translationColonRegexp.lastIndex = 0;
+ var m = translationColonRegexp.exec(text);
+ if (m && m[0] && text.indexOf(m[0]) === 0) {
- if (translations[full]) {
- return resolve([translations[full]]);
- }
-
- var options = [];
- var i;
- for (i=0; i < toSearch.length; i++) {
- if (toSearch[i].indexOf(term) === 0) {
- options.push(toSearch[i]);
- if(options.length > 4) { break; }
- }
- }
-
- if (options.length <= 4) {
- for (i=0; i < toSearch.length; i++) {
- if (toSearch[i].indexOf(term) > 0) {
- options.push(toSearch[i]);
- if(options.length > 4) { break; }
- }
- }
- }
-
- return resolve(options);
- }).then(function(list) {
- return list.map(function(i) {
- return {code: i, src: urlFor(i)};
- });
- });
- }
- });
- });
+ // Check outer edge
+ var lastChar = text.charAt(m[0].length);
+ if (lastChar && (lastChar !== ' ' && lastChar !== "\n")) return;
+ contents = imageFor(translationsWithColon[m[0]]);
+ if (contents) {
+ return [m[0].length, contents];
+ }
+ }
+ return;
}
- Discourse.Markdown.whiteListTag('img', 'class', 'emoji');
+ // Simple find and replace from our array
+ var between = text.slice(1, endPos);
+ contents = imageFor(between);
+ if (contents) {
+ return [endPos+1, contents];
+ }
+});
+
+
+Discourse.Markdown.whiteListTag('img', 'class', 'emoji');
-}).call(this);
diff --git a/plugins/emoji/plugin.rb b/plugins/emoji/plugin.rb
index 261b6686343..9209cca369d 100644
--- a/plugins/emoji/plugin.rb
+++ b/plugins/emoji/plugin.rb
@@ -4,6 +4,8 @@
# authors: Sam Saffron, Robin Ward
register_asset('javascripts/emoji.js.erb', :server_side)
+register_asset('javascripts/emoji-autocomplete.js', :composer)
+register_asset('javascripts/emoji-toolbar.js', :composer)
register_asset('stylesheets/emoji.css')
after_initialize do