Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ryan778
GitHub Repository: Ryan778/Ryan778.github.io
Path: blob/master/emojionearea/dist/emojionearea.js
572 views
1
/*!
2
* EmojioneArea v3.1.5
3
* https://github.com/mervick/emojionearea
4
* Copyright Andrey Izman and other contributors
5
* Released under the MIT license
6
* Date: 2017-01-20T14:56Z
7
*/
8
(function(document, window, $) {
9
'use strict';
10
11
var unique = 0;
12
var eventStorage = {};
13
var possibleEvents = {};
14
var emojione = window.emojione;
15
var readyCallbacks = [];
16
function emojioneReady (fn) {
17
if (emojione) {
18
fn();
19
} else {
20
readyCallbacks.push(fn);
21
}
22
};
23
var blankImg = 'data:image/gif;base64,R0lGODlhAQABAJH/AP///wAAAMDAwAAAACH5BAEAAAIALAAAAAABAAEAAAICVAEAOw==';
24
var slice = [].slice;
25
var css_class = "emojionearea";
26
var emojioneSupportMode = 0;
27
var invisibleChar = '​';
28
function trigger(self, event, args) {
29
var result = true, j = 1;
30
if (event) {
31
event = event.toLowerCase();
32
do {
33
var _event = j==1 ? '@' + event : event;
34
if (eventStorage[self.id][_event] && eventStorage[self.id][_event].length) {
35
$.each(eventStorage[self.id][_event], function (i, fn) {
36
return result = fn.apply(self, args|| []) !== false;
37
});
38
}
39
} while (result && !!j--);
40
}
41
return result;
42
}
43
function attach(self, element, events, target) {
44
target = target || function (event, callerEvent) { return $(callerEvent.currentTarget) };
45
$.each(events, function(event, link) {
46
event = $.isArray(events) ? link : event;
47
(possibleEvents[self.id][link] || (possibleEvents[self.id][link] = []))
48
.push([element, event, target]);
49
});
50
}
51
function getTemplate(template, unicode, shortname) {
52
var imageType = emojione.imageType, imagePath;
53
if (imageType=='svg'){
54
imagePath = emojione.imagePathSVG;
55
} else {
56
imagePath = emojione.imagePathPNG;
57
}
58
return template
59
.replace('{name}', shortname || '')
60
.replace('{img}', imagePath + (emojioneSupportMode < 2 ? unicode.toUpperCase() : unicode) + '.' + imageType)
61
.replace('{uni}', unicode)
62
.replace('{alt}', emojione.convert(unicode));
63
};
64
function shortnameTo(str, template, clear) {
65
return str.replace(/:?\+?[\w_\-]+:?/g, function(shortname) {
66
shortname = ":" + shortname.replace(/:$/,'').replace(/^:/,'') + ":";
67
var unicode = emojione.emojioneList[shortname];
68
if (unicode) {
69
if (emojioneSupportMode > 3) unicode = unicode.unicode;
70
return getTemplate(template, unicode[unicode.length-1], shortname);
71
}
72
return clear ? '' : shortname;
73
});
74
};
75
function pasteHtmlAtCaret(html) {
76
var sel, range;
77
if (window.getSelection) {
78
sel = window.getSelection();
79
if (sel.getRangeAt && sel.rangeCount) {
80
range = sel.getRangeAt(0);
81
range.deleteContents();
82
var el = document.createElement("div");
83
el.innerHTML = html;
84
var frag = document.createDocumentFragment(), node, lastNode;
85
while ( (node = el.firstChild) ) {
86
lastNode = frag.appendChild(node);
87
}
88
range.insertNode(frag);
89
if (lastNode) {
90
range = range.cloneRange();
91
range.setStartAfter(lastNode);
92
range.collapse(true);
93
sel.removeAllRanges();
94
sel.addRange(range);
95
}
96
}
97
} else if (document.selection && document.selection.type != "Control") {
98
document.selection.createRange().pasteHTML(html);
99
}
100
}
101
var getDefaultOptions = function () {
102
return $.fn.emojioneArea && $.fn.emojioneArea.defaults ? $.fn.emojioneArea.defaults : {
103
attributes: {
104
dir : "ltr",
105
spellcheck : false,
106
autocomplete : "off",
107
autocorrect : "off",
108
autocapitalize : "off",
109
},
110
placeholder : null,
111
emojiPlaceholder : ":smiley:",
112
container : null,
113
hideSource : true,
114
shortnames : true,
115
sprite : true,
116
pickerPosition : "top", // top | bottom | right
117
filtersPosition : "top", // top | bottom
118
hidePickerOnBlur : true,
119
buttonTitle : "Use the TAB key to insert emoji faster",
120
tones : true,
121
tonesStyle : "bullet", // bullet | radio | square | checkbox
122
inline : null, // null - auto
123
saveEmojisAs : "unicode", // unicode | shortname | image
124
shortcuts : true,
125
autocomplete : true,
126
autocompleteTones : false,
127
standalone : false,
128
useInternalCDN : true, // Use the self loading mechanism
129
imageType : "png", // Default image type used by internal CDN
130
recentEmojis : true,
131
textcomplete: {
132
maxCount : 15,
133
placement : null // null - default | top | absleft | absright
134
},
135
136
filters: {
137
tones: {
138
title: "Diversity",
139
emoji: "santa runner surfer swimmer lifter ear nose point_up_2 point_down point_left point_right punch " +
140
"wave ok_hand thumbsup thumbsdown clap open_hands boy girl man woman cop bride_with_veil person_with_blond_hair " +
141
"man_with_gua_pi_mao man_with_turban older_man grandma baby construction_worker princess angel " +
142
"information_desk_person guardsman dancer nail_care massage haircut muscle spy hand_splayed middle_finger " +
143
"vulcan no_good ok_woman bow raising_hand raised_hands person_frowning person_with_pouting_face pray rowboat " +
144
"bicyclist mountain_bicyclist walking bath metal point_up basketball_player fist raised_hand v writing_hand"
145
},
146
147
recent: {
148
icon: "clock3",
149
title: "Recent",
150
emoji: ""
151
},
152
153
smileys_people: {
154
icon: "yum",
155
title: "Smileys & People",
156
emoji: "grinning grimacing grin joy smiley smile sweat_smile laughing innocent wink blush slight_smile " +
157
"upside_down relaxed yum relieved heart_eyes kissing_heart kissing kissing_smiling_eyes " +
158
"kissing_closed_eyes stuck_out_tongue_winking_eye stuck_out_tongue_closed_eyes stuck_out_tongue " +
159
"money_mouth nerd sunglasses hugging smirk no_mouth neutral_face expressionless unamused rolling_eyes " +
160
"thinking flushed disappointed worried angry rage pensive confused slight_frown frowning2 persevere " +
161
"confounded tired_face weary triumph open_mouth scream fearful cold_sweat hushed frowning anguished " +
162
"cry disappointed_relieved sleepy sweat sob dizzy_face astonished zipper_mouth mask thermometer_face " +
163
"head_bandage sleeping zzz poop smiling_imp imp japanese_ogre japanese_goblin skull ghost alien robot " +
164
"smiley_cat smile_cat joy_cat heart_eyes_cat smirk_cat kissing_cat scream_cat crying_cat_face " +
165
"pouting_cat raised_hands clap wave thumbsup thumbsdown punch fist v ok_hand raised_hand open_hands " +
166
"muscle pray point_up point_up_2 point_down point_left point_right middle_finger hand_splayed metal " +
167
"vulcan writing_hand nail_care lips tongue ear nose eye eyes bust_in_silhouette busts_in_silhouette " +
168
"speaking_head baby boy girl man woman person_with_blond_hair older_man older_woman man_with_gua_pi_mao " +
169
"man_with_turban cop construction_worker guardsman spy santa angel princess bride_with_veil walking " +
170
"runner dancer dancers couple two_men_holding_hands two_women_holding_hands bow information_desk_person " +
171
"no_good ok_woman raising_hand person_with_pouting_face person_frowning haircut massage couple_with_heart " +
172
"couple_ww couple_mm couplekiss kiss_ww kiss_mm family family_mwg family_mwgb family_mwbb family_mwgg " +
173
"family_wwb family_wwg family_wwgb family_wwbb family_wwgg family_mmb family_mmg family_mmgb family_mmbb " +
174
"family_mmgg womans_clothes shirt jeans necktie dress bikini kimono lipstick kiss footprints high_heel " +
175
"sandal boot mans_shoe athletic_shoe womans_hat tophat helmet_with_cross mortar_board crown school_satchel " +
176
"pouch purse handbag briefcase eyeglasses dark_sunglasses ring closed_umbrella"
177
},
178
179
animals_nature: {
180
icon: "hamster",
181
title: "Animals & Nature",
182
emoji: "dog cat mouse hamster rabbit bear panda_face koala tiger lion_face cow pig pig_nose frog " +
183
"octopus monkey_face see_no_evil hear_no_evil speak_no_evil monkey chicken penguin bird baby_chick " +
184
"hatching_chick hatched_chick wolf boar horse unicorn bee bug snail beetle ant spider scorpion crab " +
185
"snake turtle tropical_fish fish blowfish dolphin whale whale2 crocodile leopard tiger2 water_buffalo " +
186
"ox cow2 dromedary_camel camel elephant goat ram sheep racehorse pig2 rat mouse2 rooster turkey dove " +
187
"dog2 poodle cat2 rabbit2 chipmunk feet dragon dragon_face cactus christmas_tree evergreen_tree " +
188
"deciduous_tree palm_tree seedling herb shamrock four_leaf_clover bamboo tanabata_tree leaves " +
189
"fallen_leaf maple_leaf ear_of_rice hibiscus sunflower rose tulip blossom cherry_blossom bouquet " +
190
"mushroom chestnut jack_o_lantern shell spider_web earth_americas earth_africa earth_asia full_moon " +
191
"waning_gibbous_moon last_quarter_moon waning_crescent_moon new_moon waxing_crescent_moon " +
192
"first_quarter_moon waxing_gibbous_moon new_moon_with_face full_moon_with_face first_quarter_moon_with_face " +
193
"last_quarter_moon_with_face sun_with_face crescent_moon star star2 dizzy sparkles comet sunny " +
194
"white_sun_small_cloud partly_sunny white_sun_cloud white_sun_rain_cloud cloud cloud_rain " +
195
"thunder_cloud_rain cloud_lightning zap fire boom snowflake cloud_snow snowman2 snowman wind_blowing_face " +
196
"dash cloud_tornado fog umbrella2 umbrella droplet sweat_drops ocean"
197
},
198
199
food_drink: {
200
icon: "pizza",
201
title: "Food & Drink",
202
emoji: "green_apple apple pear tangerine lemon banana watermelon grapes strawberry melon cherries peach " +
203
"pineapple tomato eggplant hot_pepper corn sweet_potato honey_pot bread cheese poultry_leg meat_on_bone " +
204
"fried_shrimp egg hamburger fries hotdog pizza spaghetti taco burrito ramen stew fish_cake sushi bento " +
205
"curry rice_ball rice rice_cracker oden dango shaved_ice ice_cream icecream cake birthday custard candy " +
206
"lollipop chocolate_bar popcorn doughnut cookie beer beers wine_glass cocktail tropical_drink champagne " +
207
"sake tea coffee baby_bottle fork_and_knife fork_knife_plate"
208
},
209
210
activity: {
211
icon: "basketball",
212
title: "Activity",
213
emoji: "soccer basketball football baseball tennis volleyball rugby_football 8ball golf golfer ping_pong " +
214
"badminton hockey field_hockey cricket ski skier snowboarder ice_skate bow_and_arrow fishing_pole_and_fish " +
215
"rowboat swimmer surfer bath basketball_player lifter bicyclist mountain_bicyclist horse_racing levitate " +
216
"trophy running_shirt_with_sash medal military_medal reminder_ribbon rosette ticket tickets performing_arts " +
217
"art circus_tent microphone headphones musical_score musical_keyboard saxophone trumpet guitar violin " +
218
"clapper video_game space_invader dart game_die slot_machine bowling"
219
},
220
221
travel_places: {
222
icon: "rocket",
223
title: "Travel & Places",
224
emoji: "red_car taxi blue_car bus trolleybus race_car police_car ambulance fire_engine minibus truck " +
225
"articulated_lorry tractor motorcycle bike rotating_light oncoming_police_car oncoming_bus " +
226
"oncoming_automobile oncoming_taxi aerial_tramway mountain_cableway suspension_railway railway_car " +
227
"train monorail bullettrain_side bullettrain_front light_rail mountain_railway steam_locomotive train2 " +
228
"metro tram station helicopter airplane_small airplane airplane_departure airplane_arriving sailboat " +
229
"motorboat speedboat ferry cruise_ship rocket satellite_orbital seat anchor construction fuelpump busstop " +
230
"vertical_traffic_light traffic_light checkered_flag ship ferris_wheel roller_coaster carousel_horse " +
231
"construction_site foggy tokyo_tower factory fountain rice_scene mountain mountain_snow mount_fuji volcano " +
232
"japan camping tent park motorway railway_track sunrise sunrise_over_mountains desert beach island " +
233
"city_sunset city_dusk cityscape night_with_stars bridge_at_night milky_way stars sparkler fireworks " +
234
"rainbow homes european_castle japanese_castle stadium statue_of_liberty house house_with_garden " +
235
"house_abandoned office department_store post_office european_post_office hospital bank hotel " +
236
"convenience_store school love_hotel wedding classical_building church mosque synagogue kaaba shinto_shrine"
237
},
238
239
objects: {
240
icon: "bulb",
241
title: "Objects",
242
emoji: "watch iphone calling computer keyboard desktop printer mouse_three_button trackball joystick " +
243
"compression minidisc floppy_disk cd dvd vhs camera camera_with_flash video_camera movie_camera projector " +
244
"film_frames telephone_receiver telephone pager fax tv radio microphone2 level_slider control_knobs " +
245
"stopwatch timer alarm_clock clock hourglass_flowing_sand hourglass satellite battery electric_plug bulb " +
246
"flashlight candle wastebasket oil money_with_wings dollar yen euro pound moneybag credit_card gem scales " +
247
"wrench hammer hammer_pick tools pick nut_and_bolt gear chains gun bomb knife dagger crossed_swords shield " +
248
"smoking skull_crossbones coffin urn amphora crystal_ball prayer_beads barber alembic telescope microscope " +
249
"hole pill syringe thermometer label bookmark toilet shower bathtub key key2 couch sleeping_accommodation " +
250
"bed door bellhop frame_photo map beach_umbrella moyai shopping_bags balloon flags ribbon gift confetti_ball " +
251
"tada dolls wind_chime crossed_flags izakaya_lantern envelope envelope_with_arrow incoming_envelope e-mail " +
252
"love_letter postbox mailbox_closed mailbox mailbox_with_mail mailbox_with_no_mail package postal_horn " +
253
"inbox_tray outbox_tray scroll page_with_curl bookmark_tabs bar_chart chart_with_upwards_trend " +
254
"chart_with_downwards_trend page_facing_up date calendar calendar_spiral card_index card_box ballot_box " +
255
"file_cabinet clipboard notepad_spiral file_folder open_file_folder dividers newspaper2 newspaper notebook " +
256
"closed_book green_book blue_book orange_book notebook_with_decorative_cover ledger books book link " +
257
"paperclip paperclips scissors triangular_ruler straight_ruler pushpin round_pushpin triangular_flag_on_post " +
258
"flag_white flag_black closed_lock_with_key lock unlock lock_with_ink_pen pen_ballpoint pen_fountain " +
259
"black_nib pencil pencil2 crayon paintbrush mag mag_right"
260
},
261
262
symbols: {
263
icon: "heartpulse",
264
title: "Symbols",
265
emoji: "heart yellow_heart green_heart blue_heart purple_heart broken_heart heart_exclamation two_hearts " +
266
"revolving_hearts heartbeat heartpulse sparkling_heart cupid gift_heart heart_decoration peace cross " +
267
"star_and_crescent om_symbol wheel_of_dharma star_of_david six_pointed_star menorah yin_yang orthodox_cross " +
268
"place_of_worship ophiuchus aries taurus gemini cancer leo virgo libra scorpius sagittarius capricorn " +
269
"aquarius pisces id atom u7a7a u5272 radioactive biohazard mobile_phone_off vibration_mode u6709 u7121 " +
270
"u7533 u55b6 u6708 eight_pointed_black_star vs accept white_flower ideograph_advantage secret congratulations " +
271
"u5408 u6e80 u7981 a b ab cl o2 sos no_entry name_badge no_entry_sign x o anger hotsprings no_pedestrians " +
272
"do_not_litter no_bicycles non-potable_water underage no_mobile_phones exclamation grey_exclamation question " +
273
"grey_question bangbang interrobang 100 low_brightness high_brightness trident fleur-de-lis part_alternation_mark " +
274
"warning children_crossing beginner recycle u6307 chart sparkle eight_spoked_asterisk negative_squared_cross_mark " +
275
"white_check_mark diamond_shape_with_a_dot_inside cyclone loop globe_with_meridians m atm sa passport_control " +
276
"customs baggage_claim left_luggage wheelchair no_smoking wc parking potable_water mens womens baby_symbol " +
277
"restroom put_litter_in_its_place cinema signal_strength koko ng ok up cool new free zero one two three four " +
278
"five six seven eight nine ten 1234 arrow_forward pause_button play_pause stop_button record_button track_next " +
279
"track_previous fast_forward rewind twisted_rightwards_arrows repeat repeat_one arrow_backward arrow_up_small " +
280
"arrow_down_small arrow_double_up arrow_double_down arrow_right arrow_left arrow_up arrow_down arrow_upper_right " +
281
"arrow_lower_right arrow_lower_left arrow_upper_left arrow_up_down left_right_arrow arrows_counterclockwise " +
282
"arrow_right_hook leftwards_arrow_with_hook arrow_heading_up arrow_heading_down hash asterisk information_source " +
283
"abc abcd capital_abcd symbols musical_note notes wavy_dash curly_loop heavy_check_mark arrows_clockwise " +
284
"heavy_plus_sign heavy_minus_sign heavy_division_sign heavy_multiplication_x heavy_dollar_sign currency_exchange " +
285
"copyright registered tm end back on top soon ballot_box_with_check radio_button white_circle black_circle " +
286
"red_circle large_blue_circle small_orange_diamond small_blue_diamond large_orange_diamond large_blue_diamond " +
287
"small_red_triangle black_small_square white_small_square black_large_square white_large_square small_red_triangle_down " +
288
"black_medium_square white_medium_square black_medium_small_square white_medium_small_square black_square_button " +
289
"white_square_button speaker sound loud_sound mute mega loudspeaker bell no_bell black_joker mahjong spades " +
290
"clubs hearts diamonds flower_playing_cards thought_balloon anger_right speech_balloon clock1 clock2 clock3 " +
291
"clock4 clock5 clock6 clock7 clock8 clock9 clock10 clock11 clock12 clock130 clock230 clock330 clock430 " +
292
"clock530 clock630 clock730 clock830 clock930 clock1030 clock1130 clock1230 eye_in_speech_bubble"
293
},
294
295
flags: {
296
icon: "flag_gb",
297
title: "Flags",
298
emoji: "ac af al dz ad ao ai ag ar am aw au at az bs bh bd bb by be bz bj bm bt bo ba bw br bn bg bf bi " +
299
"cv kh cm ca ky cf td flag_cl cn co km cg flag_cd cr hr cu cy cz dk dj dm do ec eg sv gq er ee et fk fo " +
300
"fj fi fr pf ga gm ge de gh gi gr gl gd gu gt gn gw gy ht hn hk hu is in flag_id ir iq ie il it ci jm jp " +
301
"je jo kz ke ki xk kw kg la lv lb ls lr ly li lt lu mo mk mg mw my mv ml mt mh mr mu mx fm md mc mn me " +
302
"ms ma mz mm na nr np nl nc nz ni ne flag_ng nu kp no om pk pw ps pa pg py pe ph pl pt pr qa ro ru rw " +
303
"sh kn lc vc ws sm st flag_sa sn rs sc sl sg sk si sb so za kr es lk sd sr sz se ch sy tw tj tz th tl " +
304
"tg to tt tn tr flag_tm flag_tm ug ua ae gb us vi uy uz vu va ve vn wf eh ye zm zw re ax ta io bq cx " +
305
"cc gg im yt nf pn bl pm gs tk bv hm sj um ic ea cp dg as aq vg ck cw eu gf tf gp mq mp sx ss tc "
306
}
307
}
308
};
309
};
310
function isObject(variable) {
311
return typeof variable === 'object';
312
};
313
function getOptions(options) {
314
var default_options = getDefaultOptions();
315
if (options && options['filters']) {
316
var filters = default_options.filters;
317
$.each(options['filters'], function(filter, data) {
318
if (!isObject(data) || $.isEmptyObject(data)) {
319
delete filters[filter];
320
return;
321
}
322
$.each(data, function(key, val) {
323
filters[filter][key] = val;
324
});
325
});
326
options['filters'] = filters;
327
}
328
return $.extend({}, default_options, options);
329
};
330
331
var saveSelection, restoreSelection;
332
if (window.getSelection && document.createRange) {
333
saveSelection = function(el) {
334
var sel = window.getSelection && window.getSelection();
335
if (sel && sel.rangeCount > 0) {
336
var range = sel.getRangeAt(0);
337
var preSelectionRange = range.cloneRange();
338
preSelectionRange.selectNodeContents(el);
339
preSelectionRange.setEnd(range.startContainer, range.startOffset);
340
return preSelectionRange.toString().length;
341
}
342
};
343
344
restoreSelection = function(el, sel) {
345
var charIndex = 0, range = document.createRange();
346
range.setStart(el, 0);
347
range.collapse(true);
348
var nodeStack = [el], node, foundStart = false, stop = false;
349
350
while (!stop && (node = nodeStack.pop())) {
351
if (node.nodeType == 3) {
352
var nextCharIndex = charIndex + node.length;
353
if (!foundStart && sel >= charIndex && sel <= nextCharIndex) {
354
range.setStart(node, sel - charIndex);
355
range.setEnd(node, sel - charIndex);
356
stop = true;
357
}
358
charIndex = nextCharIndex;
359
} else {
360
var i = node.childNodes.length;
361
while (i--) {
362
nodeStack.push(node.childNodes[i]);
363
}
364
}
365
}
366
367
sel = window.getSelection();
368
sel.removeAllRanges();
369
sel.addRange(range);
370
}
371
} else if (document.selection && document.body.createTextRange) {
372
saveSelection = function(el) {
373
var selectedTextRange = document.selection.createRange(),
374
preSelectionTextRange = document.body.createTextRange();
375
preSelectionTextRange.moveToElementText(el);
376
preSelectionTextRange.setEndPoint("EndToStart", selectedTextRange);
377
var start = preSelectionTextRange.text.length;
378
return start + selectedTextRange.text.length;
379
};
380
381
restoreSelection = function(el, sel) {
382
var textRange = document.body.createTextRange();
383
textRange.moveToElementText(el);
384
textRange.collapse(true);
385
textRange.moveEnd("character", sel);
386
textRange.moveStart("character", sel);
387
textRange.select();
388
};
389
}
390
391
392
var uniRegexp;
393
function unicodeTo(str, template) {
394
return str.replace(uniRegexp, function(unicodeChar) {
395
var map = emojione[(emojioneSupportMode === 0 ? 'jsecapeMap' : 'jsEscapeMap')];
396
if (typeof unicodeChar !== 'undefined' && unicodeChar in map) {
397
return getTemplate(template, map[unicodeChar]);
398
}
399
return unicodeChar;
400
});
401
}
402
function htmlFromText(str, self) {
403
str = str
404
.replace(/&/g, '&amp;')
405
.replace(/</g, '&lt;')
406
.replace(/>/g, '&gt;')
407
.replace(/"/g, '&quot;')
408
.replace(/'/g, '&#x27;')
409
.replace(/`/g, '&#x60;')
410
.replace(/(?:\r\n|\r|\n)/g, '\n')
411
.replace(/(\n+)/g, '<div>$1</div>')
412
.replace(/\n/g, '<br/>')
413
.replace(/<br\/><\/div>/g, '</div>');
414
if (self.shortnames) {
415
str = emojione.shortnameToUnicode(str);
416
}
417
return unicodeTo(str, self.emojiTemplate)
418
.replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;')
419
.replace(/ /g, '&nbsp;&nbsp;');
420
}
421
function textFromHtml(str, self) {
422
str = str
423
.replace(/<img[^>]*alt="([^"]+)"[^>]*>/ig, '$1')
424
.replace(/\n|\r/g, '')
425
.replace(/<br[^>]*>/ig, '\n')
426
.replace(/(?:<(?:div|p|ol|ul|li|pre|code|object)[^>]*>)+/ig, '<div>')
427
.replace(/(?:<\/(?:div|p|ol|ul|li|pre|code|object)>)+/ig, '</div>')
428
.replace(/\n<div><\/div>/ig, '\n')
429
.replace(/<div><\/div>\n/ig, '\n')
430
.replace(/(?:<div>)+<\/div>/ig, '\n')
431
.replace(/([^\n])<\/div><div>/ig, '$1\n')
432
.replace(/(?:<\/div>)+/ig, '</div>')
433
.replace(/([^\n])<\/div>([^\n])/ig, '$1\n$2')
434
.replace(/<\/div>/ig, '')
435
.replace(/([^\n])<div>/ig, '$1\n')
436
.replace(/\n<div>/ig, '\n')
437
.replace(/<div>\n/ig, '\n\n')
438
.replace(/<(?:[^>]+)?>/g, '')
439
.replace(new RegExp(invisibleChar, 'g'), '')
440
.replace(/&nbsp;/g, ' ')
441
.replace(/&lt;/g, '<')
442
.replace(/&gt;/g, '>')
443
.replace(/&quot;/g, '"')
444
.replace(/&#x27;/g, "'")
445
.replace(/&#x60;/g, '`')
446
.replace(/&amp;/g, '&');
447
448
switch (self.saveEmojisAs) {
449
case 'image':
450
str = unicodeTo(str, self.emojiTemplate);
451
break;
452
case 'shortname':
453
str = emojione.toShort(str);
454
}
455
return str;
456
}
457
function calcButtonPosition() {
458
var self = this,
459
offset = self.editor[0].offsetWidth - self.editor[0].clientWidth,
460
current = parseInt(self.button.css('marginRight'));
461
if (current !== offset) {
462
self.button.css({marginRight: offset});
463
if (self.floatingPicker) {
464
self.picker.css({right: parseInt(self.picker.css('right')) - current + offset});
465
}
466
}
467
}
468
function lazyLoading() {
469
var self = this;
470
if (!self.sprite && self.lasyEmoji[0]) {
471
var pickerTop = self.picker.offset().top,
472
pickerBottom = pickerTop + self.picker.height() + 20;
473
self.lasyEmoji.each(function() {
474
var e = $(this), top = e.offset().top;
475
if (top > pickerTop && top < pickerBottom) {
476
e.attr("src", e.data("src")).removeClass("lazy-emoji");
477
}
478
})
479
self.lasyEmoji = self.lasyEmoji.filter(".lazy-emoji");
480
}
481
}
482
function selector (prefix, skip_dot) {
483
return (skip_dot ? '' : '.') + css_class + (prefix ? ("-" + prefix) : "");
484
}
485
function div(prefix) {
486
var parent = $('<div/>', isObject(prefix) ? prefix : {"class" : selector(prefix, true)});
487
$.each(slice.call(arguments).slice(1), function(i, child) {
488
if ($.isFunction(child)) {
489
child = child.call(parent);
490
}
491
if (child) {
492
$(child).appendTo(parent);
493
}
494
});
495
return parent;
496
}
497
function getRecent () {
498
return localStorage.getItem("recent_emojis") || "";
499
}
500
function updateRecent(self) {
501
var emojis = getRecent();
502
if (!self.recent || self.recent !== emojis) {
503
if (emojis.length) {
504
var skinnable = self.scrollArea.is(".skinnable"),
505
scrollTop, height;
506
507
if (!skinnable) {
508
scrollTop = self.scrollArea.scrollTop();
509
height = self.recentCategory.is(":visible") ? self.recentCategory.height() : 0;
510
}
511
512
var items = shortnameTo(emojis, self.emojiBtnTemplate, true).split('|').join('');
513
self.recentCategory.children(".emojibtn").remove();
514
$(items).insertAfter(self.recentCategory.children("h1"));
515
516
517
self.recentCategory.children(".emojibtn").on("click", function() {
518
self.trigger("emojibtn.click", $(this));
519
});
520
521
self.recentFilter.show();
522
523
if (!skinnable) {
524
self.recentCategory.show();
525
526
var height2 = self.recentCategory.height();
527
528
if (height !== height2) {
529
self.scrollArea.scrollTop(scrollTop + height2 - height);
530
}
531
}
532
} else {
533
if (self.recentFilter.hasClass("active")) {
534
self.recentFilter.removeClass("active").next().addClass("active");
535
}
536
self.recentCategory.hide();
537
self.recentFilter.hide();
538
}
539
self.recent = emojis;
540
}
541
};
542
function setRecent(self, emoji) {
543
var recent = getRecent();
544
var emojis = recent.split("|");
545
546
var index = emojis.indexOf(emoji);
547
if (index !== -1) {
548
emojis.splice(index, 1);
549
}
550
emojis.unshift(emoji);
551
552
if (emojis.length > 9) {
553
emojis.pop();
554
}
555
556
localStorage.setItem("recent_emojis", emojis.join("|"));
557
558
updateRecent(self);
559
};
560
// see https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js
561
function supportsLocalStorage () {
562
var test = 'test';
563
try {
564
localStorage.setItem(test, test);
565
localStorage.removeItem(test);
566
return true;
567
} catch(e) {
568
return false;
569
}
570
}
571
function init(self, source, options) {
572
//calcElapsedTime('init', function() {
573
options = getOptions(options);
574
self.sprite = options.sprite && emojioneSupportMode < 3;
575
self.inline = options.inline === null ? source.is("INPUT") : options.inline;
576
self.shortnames = options.shortnames;
577
self.saveEmojisAs = options.saveEmojisAs;
578
self.standalone = options.standalone;
579
self.emojiTemplate = '<img alt="{alt}" class="emojione' + (self.sprite ? '-{uni}" src="' + blankImg + '"/>' : 'emoji" src="{img}"/>');
580
self.emojiTemplateAlt = self.sprite ? '<i class="emojione-{uni}"/>' : '<img class="emojioneemoji" src="{img}"/>';
581
self.emojiBtnTemplate = '<i class="emojibtn" role="button" data-name="{name}">' + self.emojiTemplateAlt + '</i>';
582
self.recentEmojis = options.recentEmojis && supportsLocalStorage();
583
584
var pickerPosition = options.pickerPosition;
585
self.floatingPicker = pickerPosition === 'top' || pickerPosition === 'bottom';
586
587
var sourceValFunc = source.is("TEXTAREA") || source.is("INPUT") ? "val" : "text",
588
editor, button, picker, tones, filters, filtersBtns, emojisList, categories, scrollArea,
589
app = div({
590
"class" : css_class + ((self.standalone) ? " " + css_class + "-standalone " : " ") + (source.attr("class") || ""),
591
role: "application"
592
},
593
editor = self.editor = div("editor").attr({
594
contenteditable: (self.standalone) ? false : true,
595
placeholder: options["placeholder"] || source.data("placeholder") || source.attr("placeholder") || "",
596
tabindex: 0
597
}),
598
button = self.button = div('button',
599
div('button-open'),
600
div('button-close')
601
).attr('title', options.buttonTitle),
602
picker = self.picker = div('picker',
603
div('wrapper',
604
filters = div('filters'),
605
scrollArea = div('scroll-area',
606
emojisList = div('emojis-list'),
607
tones = div('tones',
608
function() {
609
if (options.tones) {
610
this.addClass(selector('tones-' + options.tonesStyle, true));
611
for (var i = 0; i <= 5; i++) {
612
this.append($("<i/>", {
613
"class": "btn-tone btn-tone-" + i + (!i ? " active" : ""),
614
"data-skin": i,
615
role: "button"
616
}));
617
}
618
}
619
}
620
)
621
)
622
)
623
).addClass(selector('picker-position-' + options.pickerPosition, true))
624
.addClass(selector('filters-position-' + options.filtersPosition, true))
625
.addClass('hidden')
626
);
627
628
editor.data(source.data());
629
630
$.each(options.attributes, function(attr, value) {
631
editor.attr(attr, value);
632
});
633
634
$.each(options.filters, function(filter, params) {
635
var skin = 0;
636
if (filter === 'recent' && !self.recentEmojis) {
637
return;
638
}
639
if (filter !== 'tones') {
640
$("<i/>", {
641
"class": selector("filter", true) + " " + selector("filter-" + filter, true),
642
"data-filter": filter,
643
title: params.title
644
})
645
.wrapInner(shortnameTo(params.icon, self.emojiTemplateAlt))
646
.appendTo(filters);
647
} else if (options.tones) {
648
skin = 5;
649
} else {
650
return;
651
}
652
do {
653
var category = div('category').attr({name: filter, "data-tone": skin}).appendTo(emojisList),
654
items = params.emoji.replace(/[\s,;]+/g, '|');
655
if (skin > 0) {
656
category.hide();
657
items = items.split('|').join('_tone' + skin + '|') + '_tone' + skin;
658
}
659
660
if (filter === 'recent') {
661
items = getRecent();
662
}
663
664
items = shortnameTo(items,
665
self.sprite ?
666
'<i class="emojibtn" role="button" data-name="{name}"><i class="emojione-{uni}"></i></i>' :
667
'<i class="emojibtn" role="button" data-name="{name}"><img class="emojioneemoji lazy-emoji" data-src="{img}"/></i>',
668
true).split('|').join('');
669
670
category.html(items);
671
$('<h1/>').text(params.title).prependTo(category);
672
} while (--skin > 0);
673
});
674
675
options.filters = null;
676
if (!self.sprite) {
677
self.lasyEmoji = emojisList.find(".lazy-emoji");
678
}
679
680
filtersBtns = filters.find(selector("filter"));
681
filtersBtns.eq(0).addClass("active");
682
categories = emojisList.find(selector("category"));
683
684
self.recentFilter = filtersBtns.filter('[data-filter="recent"]');
685
self.recentCategory = categories.filter("[name=recent]");
686
687
self.scrollArea = scrollArea;
688
689
if (options.container) {
690
$(options.container).wrapInner(app);
691
} else {
692
app.insertAfter(source);
693
}
694
695
if (options.hideSource) {
696
source.hide();
697
}
698
699
self.setText(source[sourceValFunc]());
700
source[sourceValFunc](self.getText());
701
calcButtonPosition.apply(self);
702
703
// if in standalone mode and no value is set, initialise with a placeholder
704
if (self.standalone && !self.getText().length) {
705
var placeholder = $(source).data("emoji-placeholder") || options.emojiPlaceholder;
706
self.setText(placeholder);
707
editor.addClass("has-placeholder");
708
}
709
710
// attach() must be called before any .on() methods !!!
711
// 1) attach() stores events into possibleEvents{},
712
// 2) .on() calls bindEvent() and stores handlers into eventStorage{},
713
// 3) bindEvent() finds events in possibleEvents{} and bind founded via jQuery.on()
714
// 4) attached events via jQuery.on() calls trigger()
715
// 5) trigger() calls handlers stored into eventStorage{}
716
717
attach(self, emojisList.find(".emojibtn"), {click: "emojibtn.click"});
718
attach(self, window, {resize: "!resize"});
719
attach(self, tones.children(), {click: "tone.click"});
720
attach(self, [picker, button], {mousedown: "!mousedown"}, editor);
721
attach(self, button, {click: "button.click"});
722
attach(self, editor, {paste :"!paste"}, editor);
723
attach(self, editor, ["focus", "blur"], function() { return self.stayFocused ? false : editor; });
724
attach(self, picker, {mousedown: "picker.mousedown", mouseup: "picker.mouseup", click: "picker.click",
725
keyup: "picker.keyup", keydown: "picker.keydown", keypress: "picker.keypress"});
726
attach(self, editor, ["mousedown", "mouseup", "click", "keyup", "keydown", "keypress"]);
727
attach(self, picker.find(".emojionearea-filter"), {click: "filter.click"});
728
729
var noListenScroll = false;
730
scrollArea.on('scroll', function () {
731
if (!noListenScroll) {
732
lazyLoading.call(self);
733
if (scrollArea.is(":not(.skinnable)")) {
734
var item = categories.eq(0), scrollTop = scrollArea.offset().top;
735
categories.each(function (i, e) {
736
if ($(e).offset().top - scrollTop >= 10) {
737
return false;
738
}
739
item = $(e);
740
});
741
var filter = filtersBtns.filter('[data-filter="' + item.attr("name") + '"]');
742
if (filter[0] && !filter.is(".active")) {
743
filtersBtns.removeClass("active");
744
filter.addClass("active");
745
}
746
}
747
}
748
});
749
750
self.on("@filter.click", function(filter) {
751
var isActive = filter.is(".active");
752
if (scrollArea.is(".skinnable")) {
753
if (isActive) return;
754
tones.children().eq(0).click();
755
}
756
noListenScroll = true;
757
if (!isActive) {
758
filtersBtns.filter(".active").removeClass("active");
759
filter.addClass("active");
760
}
761
var headerOffset = categories.filter('[name="' + filter.data('filter') + '"]').offset().top,
762
scroll = scrollArea.scrollTop(),
763
offsetTop = scrollArea.offset().top;
764
scrollArea.stop().animate({
765
scrollTop: headerOffset + scroll - offsetTop - 2
766
}, 200, 'swing', function () {
767
lazyLoading.call(self);
768
noListenScroll = false;
769
});
770
})
771
772
.on("@picker.show", function() {
773
if (self.recentEmojis) {
774
updateRecent(self);
775
}
776
lazyLoading.call(self);
777
})
778
779
.on("@tone.click", function(tone) {
780
tones.children().removeClass("active");
781
var skin = tone.addClass("active").data("skin");
782
if (skin) {
783
scrollArea.addClass("skinnable");
784
categories.hide().filter("[data-tone=" + skin + "]").show();
785
if (filtersBtns.eq(0).is('.active[data-filter="recent"]')) {
786
filtersBtns.eq(0).removeClass("active").next().addClass("active");
787
}
788
} else {
789
scrollArea.removeClass("skinnable");
790
categories.hide().filter("[data-tone=0]").show();
791
filtersBtns.eq(0).click();
792
}
793
lazyLoading.call(self);
794
})
795
796
.on("@button.click", function(button) {
797
if (button.is(".active")) {
798
self.hidePicker();
799
} else {
800
self.showPicker();
801
}
802
})
803
804
.on("@!paste", function(editor, event) {
805
806
var pasteText = function(text) {
807
var caretID = "caret-" + (new Date()).getTime();
808
var html = htmlFromText(text, self);
809
pasteHtmlAtCaret(html);
810
pasteHtmlAtCaret('<i id="' + caretID +'"></i>');
811
editor.scrollTop(editorScrollTop);
812
var caret = $("#" + caretID),
813
top = caret.offset().top - editor.offset().top,
814
height = editor.height();
815
if (editorScrollTop + top >= height || editorScrollTop > top) {
816
editor.scrollTop(editorScrollTop + top - 2 * height/3);
817
}
818
caret.remove();
819
self.stayFocused = false;
820
calcButtonPosition.apply(self);
821
trigger(self, 'paste', [editor, text, html]);
822
}
823
824
if (event.originalEvent.clipboardData) {
825
var text = event.originalEvent.clipboardData.getData('text/plain');
826
pasteText(text);
827
828
if (event.preventDefault){
829
event.preventDefault();
830
} else {
831
event.stop();
832
};
833
834
event.returnValue = false;
835
event.stopPropagation();
836
return false;
837
}
838
839
self.stayFocused = true;
840
// insert invisible character for fix caret position
841
pasteHtmlAtCaret('<span>' + invisibleChar + '</span>');
842
843
var sel = saveSelection(editor[0]),
844
editorScrollTop = editor.scrollTop(),
845
clipboard = $("<div/>", {contenteditable: true})
846
.css({position: "fixed", left: "-999px", width: "1px", height: "1px", top: "20px", overflow: "hidden"})
847
.appendTo($("BODY"))
848
.focus();
849
850
window.setTimeout(function() {
851
editor.focus();
852
restoreSelection(editor[0], sel);
853
var text = textFromHtml(clipboard.html().replace(/\r\n|\n|\r/g, '<br>'), self);
854
clipboard.remove();
855
pasteText(text);
856
}, 200);
857
})
858
859
.on("@emojibtn.click", function(emojibtn) {
860
editor.removeClass("has-placeholder");
861
if (!app.is(".focused")) {
862
editor.focus();
863
}
864
if (self.standalone) {
865
editor.html(shortnameTo(emojibtn.data("name"), self.emojiTemplate));
866
self.trigger("blur");
867
} else {
868
saveSelection(editor[0]);
869
pasteHtmlAtCaret(shortnameTo(emojibtn.data("name"), self.emojiTemplate));
870
}
871
872
if (self.recentEmojis) {
873
setRecent(self, emojibtn.data("name"));
874
}
875
})
876
877
.on("@!resize @keyup @emojibtn.click", calcButtonPosition)
878
879
.on("@!mousedown", function(editor, event) {
880
if (!app.is(".focused")) {
881
editor.focus();
882
}
883
event.preventDefault();
884
return false;
885
})
886
887
.on("@change", function() {
888
var html = self.editor.html().replace(/<\/?(?:div|span|p)[^>]*>/ig, '');
889
// clear input: chrome adds <br> when contenteditable is empty
890
if (!html.length || /^<br[^>]*>$/i.test(html)) {
891
self.editor.html(self.content = '');
892
}
893
source[sourceValFunc](self.getText());
894
})
895
896
.on("@focus", function() {
897
app.addClass("focused");
898
})
899
900
.on("@blur", function() {
901
app.removeClass("focused");
902
903
if (options.hidePickerOnBlur) {
904
self.hidePicker();
905
}
906
907
var content = self.editor.html();
908
if (self.content !== content) {
909
self.content = content;
910
trigger(self, 'change', [self.editor]);
911
source.blur().trigger("change");
912
} else {
913
source.blur();
914
}
915
});
916
917
if (options.shortcuts) {
918
self.on("@keydown", function(_, e) {
919
if (!e.ctrlKey) {
920
if (e.which == 9) {
921
e.preventDefault();
922
button.click();
923
}
924
else if (e.which == 27) {
925
e.preventDefault();
926
if (button.is(".active")) {
927
self.hidePicker();
928
}
929
}
930
}
931
});
932
}
933
934
if (isObject(options.events) && !$.isEmptyObject(options.events)) {
935
$.each(options.events, function(event, handler) {
936
self.on(event.replace(/_/g, '.'), handler);
937
});
938
}
939
940
if (options.autocomplete) {
941
var autocomplete = function() {
942
var textcompleteOptions = {
943
maxCount: options.textcomplete.maxCount,
944
placement: options.textcomplete.placement
945
};
946
947
if (options.shortcuts) {
948
textcompleteOptions.onKeydown = function (e, commands) {
949
if (!e.ctrlKey && e.which == 13) {
950
return commands.KEY_ENTER;
951
}
952
};
953
}
954
955
var map = $.map(emojione.emojioneList, function (_, emoji) {
956
return !options.autocompleteTones ? /_tone[12345]/.test(emoji) ? null : emoji : emoji;
957
});
958
map.sort();
959
editor.textcomplete([
960
{
961
id: css_class,
962
match: /\B(:[\-+\w]*)$/,
963
search: function (term, callback) {
964
callback($.map(map, function (emoji) {
965
return emoji.indexOf(term) === 0 ? emoji : null;
966
}));
967
},
968
template: function (value) {
969
return shortnameTo(value, self.emojiTemplate) + " " + value.replace(/:/g, '');
970
},
971
replace: function (value) {
972
return shortnameTo(value, self.emojiTemplate);
973
},
974
cache: true,
975
index: 1
976
}
977
], textcompleteOptions);
978
979
if (options.textcomplete.placement) {
980
// Enable correct positioning for textcomplete
981
if ($(editor.data('textComplete').option.appendTo).css("position") == "static") {
982
$(editor.data('textComplete').option.appendTo).css("position", "relative");
983
}
984
}
985
};
986
if ($.fn.textcomplete) {
987
autocomplete();
988
} else {
989
$.getScript("https://cdn.rawgit.com/yuku-t/jquery-textcomplete/v1.3.4/dist/jquery.textcomplete.js",
990
autocomplete);
991
}
992
}
993
994
if (self.inline) {
995
app.addClass(selector('inline', true));
996
self.on("@keydown", function(_, e) {
997
if (e.which == 13) {
998
e.preventDefault();
999
}
1000
});
1001
}
1002
1003
if (/firefox/i.test(navigator.userAgent)) {
1004
// disabling resize images on Firefox
1005
document.execCommand("enableObjectResizing", false, false);
1006
}
1007
1008
//}, self.id === 1); // calcElapsedTime()
1009
};
1010
var emojioneVersion = window.emojioneVersion || '2.1.4';
1011
var cdn = {
1012
defaultBase: "https://cdnjs.cloudflare.com/ajax/libs/emojione/",
1013
base: null,
1014
isLoading: false
1015
};
1016
function loadEmojione(options) {
1017
1018
function detectVersion(emojione) {
1019
var version = emojione.cacheBustParam;
1020
if (!isObject(emojione['jsEscapeMap'])) return '1.5.2';
1021
if (version === "?v=1.2.4") return '2.0.0';
1022
if (version === "?v=2.0.1") return '2.1.0'; // v2.0.1 || v2.1.0
1023
if (version === "?v=2.1.1") return '2.1.1';
1024
if (version === "?v=2.1.2") return '2.1.2';
1025
if (version === "?v=2.1.3") return '2.1.3';
1026
if (version === "?v=2.1.4") return '2.1.4';
1027
if (version === "?v=2.2.7") return '2.2.7';
1028
return '2.2.7';
1029
}
1030
1031
function getSupportMode(version) {
1032
switch (version) {
1033
case '1.5.2': return 0;
1034
case '2.0.0': return 1;
1035
case '2.1.0':
1036
case '2.1.1': return 2;
1037
case '2.1.2': return 3;
1038
case '2.1.3':
1039
case '2.1.4':
1040
case '2.2.7':
1041
default: return 4;
1042
}
1043
}
1044
options = getOptions(options);
1045
1046
if (!cdn.isLoading) {
1047
if (!emojione || getSupportMode(detectVersion(emojione)) < 2) {
1048
cdn.isLoading = true;
1049
$.getScript(cdn.defaultBase + emojioneVersion + "/lib/js/emojione.min.js", function () {
1050
emojione = window.emojione;
1051
emojioneVersion = detectVersion(emojione);
1052
emojioneSupportMode = getSupportMode(emojioneVersion);
1053
cdn.base = cdn.defaultBase + emojioneVersion + "/assets";
1054
if (options.sprite) {
1055
var sprite = cdn.base + "/sprites/emojione.sprites.css";
1056
if (document.createStyleSheet) {
1057
document.createStyleSheet(sprite);
1058
} else {
1059
$('<link/>', {rel: 'stylesheet', href: sprite}).appendTo('head');
1060
}
1061
}
1062
while (readyCallbacks.length) {
1063
readyCallbacks.shift().call();
1064
}
1065
cdn.isLoading = false;
1066
});
1067
} else {
1068
emojioneVersion = detectVersion(emojione);
1069
emojioneSupportMode = getSupportMode(emojioneVersion);
1070
cdn.base = cdn.defaultBase + emojioneVersion + "/assets";
1071
}
1072
}
1073
1074
emojioneReady(function() {
1075
if (options.useInternalCDN) {
1076
emojione.imagePathPNG = cdn.base + "/png/";
1077
emojione.imagePathSVG = cdn.base + "/svg/";
1078
emojione.imagePathSVGSprites = cdn.base + "/sprites/emojione.sprites.svg";
1079
emojione.imageType = options.imageType;
1080
}
1081
1082
uniRegexp = new RegExp("<object[^>]*>.*?<\/object>|<span[^>]*>.*?<\/span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|(" + emojione.unicodeRegexp + ")", "gi");
1083
});
1084
};
1085
var EmojioneArea = function(element, options) {
1086
var self = this;
1087
loadEmojione(options);
1088
eventStorage[self.id = ++unique] = {};
1089
possibleEvents[self.id] = {};
1090
emojioneReady(function() {
1091
init(self, element, options);
1092
});
1093
};
1094
function bindEvent(self, event) {
1095
event = event.replace(/^@/, '');
1096
var id = self.id;
1097
if (possibleEvents[id][event]) {
1098
$.each(possibleEvents[id][event], function(i, ev) {
1099
// ev[0] = element
1100
// ev[1] = event
1101
// ev[2] = target
1102
$.each($.isArray(ev[0]) ? ev[0] : [ev[0]], function(i, el) {
1103
$(el).on(ev[1], function() {
1104
var args = slice.call(arguments),
1105
target = $.isFunction(ev[2]) ? ev[2].apply(self, [event].concat(args)) : ev[2];
1106
if (target) {
1107
trigger(self, event, [target].concat(args));
1108
}
1109
});
1110
});
1111
});
1112
possibleEvents[id][event] = null;
1113
}
1114
}
1115
1116
EmojioneArea.prototype.on = function(events, handler) {
1117
if (events && $.isFunction(handler)) {
1118
var self = this;
1119
$.each(events.toLowerCase().split(' '), function(i, event) {
1120
bindEvent(self, event);
1121
(eventStorage[self.id][event] || (eventStorage[self.id][event] = [])).push(handler);
1122
});
1123
}
1124
return this;
1125
};
1126
1127
EmojioneArea.prototype.off = function(events, handler) {
1128
if (events) {
1129
var id = this.id;
1130
$.each(events.toLowerCase().replace(/_/g, '.').split(' '), function(i, event) {
1131
if (eventStorage[id][event] && !/^@/.test(event)) {
1132
if (handler) {
1133
$.each(eventStorage[id][event], function(j, fn) {
1134
if (fn === handler) {
1135
eventStorage[id][event] = eventStorage[id][event].splice(j, 1);
1136
}
1137
});
1138
} else {
1139
eventStorage[id][event] = [];
1140
}
1141
}
1142
});
1143
}
1144
return this;
1145
};
1146
1147
EmojioneArea.prototype.trigger = function() {
1148
var args = slice.call(arguments),
1149
call_args = [this].concat(args.slice(0,1));
1150
call_args.push(args.slice(1));
1151
return trigger.apply(this, call_args);
1152
};
1153
1154
EmojioneArea.prototype.setFocus = function () {
1155
var self = this;
1156
emojioneReady(function () {
1157
self.editor.focus();
1158
});
1159
return self;
1160
};
1161
1162
EmojioneArea.prototype.setText = function (str) {
1163
var self = this;
1164
emojioneReady(function () {
1165
self.editor.html(htmlFromText(str, self));
1166
self.content = self.editor.html();
1167
trigger(self, 'change', [self.editor]);
1168
calcButtonPosition.apply(self);
1169
});
1170
return self;
1171
}
1172
1173
EmojioneArea.prototype.getText = function() {
1174
return textFromHtml(this.editor.html(), this);
1175
}
1176
1177
EmojioneArea.prototype.showPicker = function () {
1178
var self = this;
1179
if (self._sh_timer) {
1180
window.clearTimeout(self._sh_timer);
1181
}
1182
self.picker.removeClass("hidden");
1183
self._sh_timer = window.setTimeout(function() {
1184
self.button.addClass("active");
1185
}, 50);
1186
trigger(self, "picker.show", [self.picker]);
1187
return self;
1188
}
1189
1190
EmojioneArea.prototype.hidePicker = function () {
1191
var self = this;
1192
if (self._sh_timer) {
1193
window.clearTimeout(self._sh_timer);
1194
}
1195
self.button.removeClass("active");
1196
self._sh_timer = window.setTimeout(function() {
1197
self.picker.addClass("hidden");
1198
}, 500);
1199
trigger(self, "picker.hide", [self.picker]);
1200
return self;
1201
}
1202
1203
$.fn.emojioneArea = function(options) {
1204
return this.each(function() {
1205
if (!!this.emojioneArea) return this.emojioneArea;
1206
$.data(this, 'emojioneArea', this.emojioneArea = new EmojioneArea($(this), options));
1207
return this.emojioneArea;
1208
});
1209
};
1210
1211
$.fn.emojioneArea.defaults = getDefaultOptions();
1212
1213
}) (document, window, jQuery);
1214
1215