jquery-emojiarea-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8bfbc0275921ae25575c47096eec45a5c97d3203
4
+ data.tar.gz: d658748fd242fa831353b48626bb3c70ba314cd2
5
+ SHA512:
6
+ metadata.gz: a5ea60ce6eafba1dec75d403600984a221ca90aa4e816c23f5232d8e44af3476f70757fbbd559a32abcbf44f03c424e63ffc6bdb98b72e69c0e766e421040286
7
+ data.tar.gz: c542bcccea39e66b71035e6cb50737518f5a27c54dce92bef89cdb5b9b1fae4bb98ab52ef4402fd6ed25584f40780424c2863efa6d39d340c52283b61b2187c9
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2017 Lucius Choi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,76 @@
1
+ # Jquery::Emojiarea::Rails
2
+
3
+ jquery.emojiarea.js plugin is wrapped with a gem for Rails asset pipeline.
4
+
5
+ https://github.com/diy/jquery-emojiarea
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'jquery-emojiarea-rails'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install jquery-emojiarea-rails
22
+
23
+ ## Usage
24
+
25
+ `assets/javascripts/application.js` :
26
+
27
+ ```javascript
28
+ ...
29
+
30
+ // alternatively, jquery.emojiarea.min
31
+ //= require jquery.emojiarea
32
+ //= require packs/basic/emojis
33
+ ...
34
+
35
+ ```
36
+
37
+ `assets/javascripts/emojiarea_init.coffee` ;
38
+
39
+ ```coffee
40
+ $(document).on "turbolinks:load", ->
41
+ $('.emojiarea').emojiarea
42
+ wysiwyg: true
43
+ ```
44
+
45
+
46
+ `assets/stylesheets/application.scss` :
47
+
48
+ ```css
49
+
50
+ @import 'jquery.emojiarea';
51
+ @import 'emojiarea_init';
52
+
53
+ ```
54
+
55
+ `_form.html.erb` :
56
+
57
+ ```rb
58
+ <%= simple_form_for @message, remote: true do | f | %>
59
+ <%= f.input :content, as: :text, label: false, input_html: { class: 'emojiarea', rows: 5 } %>
60
+ <%= f.submit class: 'btn btn-outline-primary' %>
61
+ <% end %>
62
+ ```
63
+
64
+ ## Development
65
+
66
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
67
+
68
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
69
+
70
+ ## Contributing
71
+
72
+ 1. Fork it ( https://github.com/[my-github-username]/jquery-emojiarea-rails/fork )
73
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
74
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
75
+ 4. Push to the branch (`git push origin my-new-feature`)
76
+ 5. Create a new Pull Request
@@ -0,0 +1,10 @@
1
+ require "jquery/emojiarea/rails/version"
2
+
3
+ module Jquery
4
+ module Emojiarea
5
+ module Rails
6
+ class Engine < ::Rails::Engine
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ module Jquery
2
+ module Emojiarea
3
+ module Rails
4
+ VERSION = "0.1.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,458 @@
1
+ /**
2
+ * emojiarea - A rich textarea control that supports emojis, WYSIWYG-style.
3
+ * Copyright (c) 2012 DIY Co
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
6
+ * file except in compliance with the License. You may obtain a copy of the License at:
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software distributed under
10
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ * ANY KIND, either express or implied. See the License for the specific language
12
+ * governing permissions and limitations under the License.
13
+ *
14
+ * @author Brian Reavis <brian@diy.org>
15
+ */
16
+
17
+ (function($, window, document) {
18
+
19
+ var ELEMENT_NODE = 1;
20
+ var TEXT_NODE = 3;
21
+ var TAGS_BLOCK = ['p', 'div', 'pre', 'form'];
22
+ var KEY_ESC = 27;
23
+ var KEY_TAB = 9;
24
+
25
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
26
+
27
+ $.emojiarea = {
28
+ path: '',
29
+ icons: {},
30
+ defaults: {
31
+ button: null,
32
+ buttonLabel: 'Emojis',
33
+ buttonPosition: 'after'
34
+ }
35
+ };
36
+
37
+ $.fn.emojiarea = function(options) {
38
+ options = $.extend({}, $.emojiarea.defaults, options);
39
+ return this.each(function() {
40
+ var $textarea = $(this);
41
+ if ('contentEditable' in document.body && options.wysiwyg !== false) {
42
+ new EmojiArea_WYSIWYG($textarea, options);
43
+ } else {
44
+ new EmojiArea_Plain($textarea, options);
45
+ }
46
+ });
47
+ };
48
+
49
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
50
+
51
+ var util = {};
52
+
53
+ util.restoreSelection = (function() {
54
+ if (window.getSelection) {
55
+ return function(savedSelection) {
56
+ var sel = window.getSelection();
57
+ sel.removeAllRanges();
58
+ for (var i = 0, len = savedSelection.length; i < len; ++i) {
59
+ sel.addRange(savedSelection[i]);
60
+ }
61
+ };
62
+ } else if (document.selection && document.selection.createRange) {
63
+ return function(savedSelection) {
64
+ if (savedSelection) {
65
+ savedSelection.select();
66
+ }
67
+ };
68
+ }
69
+ })();
70
+
71
+ util.saveSelection = (function() {
72
+ if (window.getSelection) {
73
+ return function() {
74
+ var sel = window.getSelection(), ranges = [];
75
+ if (sel.rangeCount) {
76
+ for (var i = 0, len = sel.rangeCount; i < len; ++i) {
77
+ ranges.push(sel.getRangeAt(i));
78
+ }
79
+ }
80
+ return ranges;
81
+ };
82
+ } else if (document.selection && document.selection.createRange) {
83
+ return function() {
84
+ var sel = document.selection;
85
+ return (sel.type.toLowerCase() !== 'none') ? sel.createRange() : null;
86
+ };
87
+ }
88
+ })();
89
+
90
+ util.replaceSelection = (function() {
91
+ if (window.getSelection) {
92
+ return function(content) {
93
+ var range, sel = window.getSelection();
94
+ var node = typeof content === 'string' ? document.createTextNode(content) : content;
95
+ if (sel.getRangeAt && sel.rangeCount) {
96
+ range = sel.getRangeAt(0);
97
+ range.deleteContents();
98
+ range.insertNode(document.createTextNode(' '));
99
+ range.insertNode(node);
100
+ range.setStart(node, 0);
101
+
102
+ window.setTimeout(function() {
103
+ range = document.createRange();
104
+ range.setStartAfter(node);
105
+ range.collapse(true);
106
+ sel.removeAllRanges();
107
+ sel.addRange(range);
108
+ }, 0);
109
+ }
110
+ }
111
+ } else if (document.selection && document.selection.createRange) {
112
+ return function(content) {
113
+ var range = document.selection.createRange();
114
+ if (typeof content === 'string') {
115
+ range.text = content;
116
+ } else {
117
+ range.pasteHTML(content.outerHTML);
118
+ }
119
+ }
120
+ }
121
+ })();
122
+
123
+ util.insertAtCursor = function(text, el) {
124
+ text = ' ' + text;
125
+ var val = el.value, endIndex, startIndex, range;
126
+ if (typeof el.selectionStart != 'undefined' && typeof el.selectionEnd != 'undefined') {
127
+ startIndex = el.selectionStart;
128
+ endIndex = el.selectionEnd;
129
+ el.value = val.substring(0, startIndex) + text + val.substring(el.selectionEnd);
130
+ el.selectionStart = el.selectionEnd = startIndex + text.length;
131
+ } else if (typeof document.selection != 'undefined' && typeof document.selection.createRange != 'undefined') {
132
+ el.focus();
133
+ range = document.selection.createRange();
134
+ range.text = text;
135
+ range.select();
136
+ }
137
+ };
138
+
139
+ util.extend = function(a, b) {
140
+ if (typeof a === 'undefined' || !a) { a = {}; }
141
+ if (typeof b === 'object') {
142
+ for (var key in b) {
143
+ if (b.hasOwnProperty(key)) {
144
+ a[key] = b[key];
145
+ }
146
+ }
147
+ }
148
+ return a;
149
+ };
150
+
151
+ util.escapeRegex = function(str) {
152
+ return (str + '').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
153
+ };
154
+
155
+ util.htmlEntities = function(str) {
156
+ return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
157
+ };
158
+
159
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
160
+
161
+ var EmojiArea = function() {};
162
+
163
+ EmojiArea.prototype.setup = function() {
164
+ var self = this;
165
+
166
+ this.$editor.on('focus', function() { self.hasFocus = true; });
167
+ this.$editor.on('blur', function() { self.hasFocus = false; });
168
+
169
+ this.setupButton();
170
+ };
171
+
172
+ EmojiArea.prototype.setupButton = function() {
173
+ var self = this;
174
+ var $button;
175
+
176
+ if (this.options.button) {
177
+ $button = $(this.options.button);
178
+ } else if (this.options.button !== false) {
179
+ $button = $('<a href="javascript:void(0)">');
180
+ $button.html(this.options.buttonLabel);
181
+ $button.addClass('emoji-button');
182
+ $button.attr({title: this.options.buttonLabel});
183
+ this.$editor[this.options.buttonPosition]($button);
184
+ } else {
185
+ $button = $('');
186
+ }
187
+
188
+ $button.on('click', function(e) {
189
+ EmojiMenu.show(self);
190
+ e.stopPropagation();
191
+ });
192
+
193
+ this.$button = $button;
194
+ };
195
+
196
+ EmojiArea.createIcon = function(emoji) {
197
+ var filename = $.emojiarea.icons[emoji];
198
+ var path = $.emojiarea.path || '';
199
+ if (path.length && path.charAt(path.length - 1) !== '/') {
200
+ path += '/';
201
+ }
202
+ return '<img src="' + path + filename + '" alt="' + util.htmlEntities(emoji) + '">';
203
+ };
204
+
205
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
206
+
207
+ /**
208
+ * Editor (plain-text)
209
+ *
210
+ * @constructor
211
+ * @param {object} $textarea
212
+ * @param {object} options
213
+ */
214
+
215
+ var EmojiArea_Plain = function($textarea, options) {
216
+ this.options = options;
217
+ this.$textarea = $textarea;
218
+ this.$editor = $textarea;
219
+ this.setup();
220
+ };
221
+
222
+ EmojiArea_Plain.prototype.insert = function(emoji) {
223
+ if (!$.emojiarea.icons.hasOwnProperty(emoji)) return;
224
+ util.insertAtCursor(emoji, this.$textarea[0]);
225
+ this.$textarea.trigger('change');
226
+ };
227
+
228
+ EmojiArea_Plain.prototype.val = function() {
229
+ return this.$textarea.val();
230
+ };
231
+
232
+ util.extend(EmojiArea_Plain.prototype, EmojiArea.prototype);
233
+
234
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
235
+
236
+ /**
237
+ * Editor (rich)
238
+ *
239
+ * @constructor
240
+ * @param {object} $textarea
241
+ * @param {object} options
242
+ */
243
+
244
+ var EmojiArea_WYSIWYG = function($textarea, options) {
245
+ var self = this;
246
+
247
+ this.options = options;
248
+ this.$textarea = $textarea;
249
+ this.$editor = $('<div>').addClass('emoji-wysiwyg-editor');
250
+ this.$editor.text($textarea.val());
251
+ this.$editor.attr({contenteditable: 'true'});
252
+ this.$editor.on('blur keyup paste', function() { return self.onChange.apply(self, arguments); });
253
+ this.$editor.on('mousedown focus', function() { document.execCommand('enableObjectResizing', false, false); });
254
+ this.$editor.on('blur', function() { document.execCommand('enableObjectResizing', true, true); });
255
+
256
+ var html = this.$editor.text();
257
+ var emojis = $.emojiarea.icons;
258
+ for (var key in emojis) {
259
+ if (emojis.hasOwnProperty(key)) {
260
+ html = html.replace(new RegExp(util.escapeRegex(key), 'g'), EmojiArea.createIcon(key));
261
+ }
262
+ }
263
+ this.$editor.html(html);
264
+
265
+ $textarea.hide().after(this.$editor);
266
+
267
+ this.setup();
268
+
269
+ this.$button.on('mousedown', function() {
270
+ if (self.hasFocus) {
271
+ self.selection = util.saveSelection();
272
+ }
273
+ });
274
+ };
275
+
276
+ EmojiArea_WYSIWYG.prototype.onChange = function() {
277
+ this.$textarea.val(this.val()).trigger('change');
278
+ };
279
+
280
+ EmojiArea_WYSIWYG.prototype.insert = function(emoji) {
281
+ var content;
282
+ var $img = $(EmojiArea.createIcon(emoji));
283
+ if ($img[0].attachEvent) {
284
+ $img[0].attachEvent('onresizestart', function(e) { e.returnValue = false; }, false);
285
+ }
286
+
287
+ this.$editor.trigger('focus');
288
+ if (this.selection) {
289
+ util.restoreSelection(this.selection);
290
+ }
291
+ try { util.replaceSelection($img[0]); } catch (e) {}
292
+ this.onChange();
293
+ };
294
+
295
+ EmojiArea_WYSIWYG.prototype.val = function() {
296
+ var lines = [];
297
+ var line = [];
298
+
299
+ var flush = function() {
300
+ lines.push(line.join(''));
301
+ line = [];
302
+ };
303
+
304
+ var sanitizeNode = function(node) {
305
+ if (node.nodeType === TEXT_NODE) {
306
+ line.push(node.nodeValue);
307
+ } else if (node.nodeType === ELEMENT_NODE) {
308
+ var tagName = node.tagName.toLowerCase();
309
+ var isBlock = TAGS_BLOCK.indexOf(tagName) !== -1;
310
+
311
+ if (isBlock && line.length) flush();
312
+
313
+ if (tagName === 'img') {
314
+ var alt = node.getAttribute('alt') || '';
315
+ if (alt) line.push(alt);
316
+ return;
317
+ } else if (tagName === 'br') {
318
+ flush();
319
+ }
320
+
321
+ var children = node.childNodes;
322
+ for (var i = 0; i < children.length; i++) {
323
+ sanitizeNode(children[i]);
324
+ }
325
+
326
+ if (isBlock && line.length) flush();
327
+ }
328
+ };
329
+
330
+ var children = this.$editor[0].childNodes;
331
+ for (var i = 0; i < children.length; i++) {
332
+ sanitizeNode(children[i]);
333
+ }
334
+
335
+ if (line.length) flush();
336
+
337
+ return lines.join('\n');
338
+ };
339
+
340
+ util.extend(EmojiArea_WYSIWYG.prototype, EmojiArea.prototype);
341
+
342
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
343
+
344
+ /**
345
+ * Emoji Dropdown Menu
346
+ *
347
+ * @constructor
348
+ * @param {object} emojiarea
349
+ */
350
+ var EmojiMenu = function() {
351
+ var self = this;
352
+ var $body = $(document.body);
353
+ var $window = $(window);
354
+
355
+ this.visible = false;
356
+ this.emojiarea = null;
357
+ this.$menu = $('<div>');
358
+ this.$menu.addClass('emoji-menu');
359
+ this.$menu.hide();
360
+ this.$items = $('<div>').appendTo(this.$menu);
361
+
362
+ $body.append(this.$menu);
363
+
364
+ $body.on('keydown', function(e) {
365
+ if (e.keyCode === KEY_ESC || e.keyCode === KEY_TAB) {
366
+ self.hide();
367
+ }
368
+ });
369
+
370
+ $body.on('mouseup', function() {
371
+ self.hide();
372
+ });
373
+
374
+ $window.on('resize', function() {
375
+ if (self.visible) self.reposition();
376
+ });
377
+
378
+ this.$menu.on('mouseup', 'a', function(e) {
379
+ e.stopPropagation();
380
+ return false;
381
+ });
382
+
383
+ this.$menu.on('click', 'a', function(e) {
384
+ var emoji = $('.label', $(this)).text();
385
+ window.setTimeout(function() {
386
+ self.onItemSelected.apply(self, [emoji]);
387
+ }, 0);
388
+ e.stopPropagation();
389
+ return false;
390
+ });
391
+
392
+ this.load();
393
+ };
394
+
395
+ EmojiMenu.prototype.onItemSelected = function(emoji) {
396
+ this.emojiarea.insert(emoji);
397
+ this.hide();
398
+ };
399
+
400
+ EmojiMenu.prototype.load = function() {
401
+ var html = [];
402
+ var options = $.emojiarea.icons;
403
+ var path = $.emojiarea.path;
404
+ if (path.length && path.charAt(path.length - 1) !== '/') {
405
+ path += '/';
406
+ }
407
+
408
+ for (var key in options) {
409
+ if (options.hasOwnProperty(key)) {
410
+ var filename = options[key];
411
+ html.push('<a href="javascript:void(0)" title="' + util.htmlEntities(key) + '">' + EmojiArea.createIcon(key) + '<span class="label">' + util.htmlEntities(key) + '</span></a>');
412
+ }
413
+ }
414
+
415
+ this.$items.html(html.join(''));
416
+ };
417
+
418
+ EmojiMenu.prototype.reposition = function() {
419
+ var $button = this.emojiarea.$button;
420
+ var offset = $button.offset();
421
+ offset.top += $button.outerHeight();
422
+ offset.left += Math.round($button.outerWidth() / 2);
423
+
424
+ this.$menu.css({
425
+ top: offset.top,
426
+ left: offset.left
427
+ });
428
+ };
429
+
430
+ EmojiMenu.prototype.hide = function(callback) {
431
+ if (this.emojiarea) {
432
+ this.emojiarea.menu = null;
433
+ this.emojiarea.$button.removeClass('on');
434
+ this.emojiarea = null;
435
+ }
436
+ this.visible = false;
437
+ this.$menu.hide();
438
+ };
439
+
440
+ EmojiMenu.prototype.show = function(emojiarea) {
441
+ if (this.emojiarea && this.emojiarea === emojiarea) return;
442
+ this.emojiarea = emojiarea;
443
+ this.emojiarea.menu = this;
444
+
445
+ this.reposition();
446
+ this.$menu.show();
447
+ this.visible = true;
448
+ };
449
+
450
+ EmojiMenu.show = (function() {
451
+ var menu = null;
452
+ return function(emojiarea) {
453
+ menu = menu || new EmojiMenu();
454
+ menu.show(emojiarea);
455
+ };
456
+ })();
457
+
458
+ })(jQuery, window, document);
@@ -0,0 +1,14 @@
1
+ /*! jquery.emojiarea.js | https://github.com/diy/jquery-emojiarea | Apache License (v2) */
2
+ (function(d,i,e){var p=["p","div","pre","form"];d.emojiarea={path:"",icons:{},defaults:{button:null,buttonLabel:"Emojis",buttonPosition:"after"}};d.fn.emojiarea=function(a){a=d.extend({},d.emojiarea.defaults,a);return this.each(function(){var b=d(this);"contentEditable"in e.body&&!1!==a.wysiwyg?new l(b,a):new m(b,a)})};var g={},k;k=i.getSelection?function(a){var b=i.getSelection();b.removeAllRanges();for(var c=0,f=a.length;c<f;++c)b.addRange(a[c])}:e.selection&&e.selection.createRange?function(a){a&&
3
+ a.select()}:void 0;g.restoreSelection=k;k=i.getSelection?function(){var a=i.getSelection(),b=[];if(a.rangeCount)for(var c=0,f=a.rangeCount;c<f;++c)b.push(a.getRangeAt(c));return b}:e.selection&&e.selection.createRange?function(){var a=e.selection;return"none"!==a.type.toLowerCase()?a.createRange():null}:void 0;g.saveSelection=k;k=i.getSelection?function(a){var b,c=i.getSelection(),f="string"===typeof a?e.createTextNode(a):a;c.getRangeAt&&c.rangeCount&&(b=c.getRangeAt(0),b.deleteContents(),b.insertNode(e.createTextNode(" ")),
4
+ b.insertNode(f),b.setStart(f,0),i.setTimeout(function(){b=e.createRange();b.setStartAfter(f);b.collapse(!0);c.removeAllRanges();c.addRange(b)},0))}:e.selection&&e.selection.createRange?function(a){var b=e.selection.createRange();"string"===typeof a?b.text=a:b.pasteHTML(a.outerHTML)}:void 0;g.replaceSelection=k;g.insertAtCursor=function(a,b){var a=" "+a,c=b.value,f;"undefined"!=typeof b.selectionStart&&"undefined"!=typeof b.selectionEnd?(f=b.selectionStart,b.value=c.substring(0,f)+a+c.substring(b.selectionEnd),
5
+ b.selectionStart=b.selectionEnd=f+a.length):"undefined"!=typeof e.selection&&"undefined"!=typeof e.selection.createRange&&(b.focus(),c=e.selection.createRange(),c.text=a,c.select())};g.extend=function(a,b){if("undefined"===typeof a||!a)a={};if("object"===typeof b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a};g.escapeRegex=function(a){return(a+"").replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")};g.htmlEntities=function(a){return String(a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,
6
+ "&gt;").replace(/"/g,"&quot;")};var j=function(){};j.prototype.setup=function(){var a=this;this.$editor.on("focus",function(){a.hasFocus=!0});this.$editor.on("blur",function(){a.hasFocus=!1});this.setupButton()};j.prototype.setupButton=function(){var a=this,b;this.options.button?b=d(this.options.button):!1!==this.options.button?(b=d('<a href="javascript:void(0)">'),b.html(this.options.buttonLabel),b.addClass("emoji-button"),b.attr({title:this.options.buttonLabel}),this.$editor[this.options.buttonPosition](b)):
7
+ b=d("");b.on("click",function(b){h.show(a);b.stopPropagation()});this.$button=b};j.createIcon=function(a){var b=d.emojiarea.icons[a],c=d.emojiarea.path||"";c.length&&"/"!==c.charAt(c.length-1)&&(c+="/");return'<img src="'+c+b+'" alt="'+g.htmlEntities(a)+'">'};var m=function(a,b){this.options=b;this.$editor=this.$textarea=a;this.setup()};m.prototype.insert=function(a){d.emojiarea.icons.hasOwnProperty(a)&&(g.insertAtCursor(a,this.$textarea[0]),this.$textarea.trigger("change"))};m.prototype.val=function(){return this.$textarea.val()};
8
+ g.extend(m.prototype,j.prototype);var l=function(a,b){var c=this;this.options=b;this.$textarea=a;this.$editor=d("<div>").addClass("emoji-wysiwyg-editor");this.$editor.text(a.val());this.$editor.attr({contenteditable:"true"});this.$editor.on("blur keyup paste",function(){return c.onChange.apply(c,arguments)});this.$editor.on("mousedown focus",function(){e.execCommand("enableObjectResizing",!1,!1)});this.$editor.on("blur",function(){e.execCommand("enableObjectResizing",!0,!0)});var f=this.$editor.text(),
9
+ i=d.emojiarea.icons,h;for(h in i)i.hasOwnProperty(h)&&(f=f.replace(RegExp(g.escapeRegex(h),"g"),j.createIcon(h)));this.$editor.html(f);a.hide().after(this.$editor);this.setup();this.$button.on("mousedown",function(){c.hasFocus&&(c.selection=g.saveSelection())})};l.prototype.onChange=function(){this.$textarea.val(this.val()).trigger("change")};l.prototype.insert=function(a){a=d(j.createIcon(a));a[0].attachEvent&&a[0].attachEvent("onresizestart",function(a){a.returnValue=!1},!1);this.$editor.trigger("focus");
10
+ this.selection&&g.restoreSelection(this.selection);try{g.replaceSelection(a[0])}catch(b){}this.onChange()};l.prototype.val=function(){for(var a=[],b=[],c=function(){a.push(b.join(""));b=[]},f=function(a){if(3===a.nodeType)b.push(a.nodeValue);else if(1===a.nodeType){var d=a.tagName.toLowerCase(),e=-1!==p.indexOf(d);e&&b.length&&c();if("img"===d)(e=a.getAttribute("alt")||"")&&b.push(e);else{"br"===d&&c();a=a.childNodes;for(d=0;d<a.length;d++)f(a[d]);e&&b.length&&c()}}},d=this.$editor[0].childNodes,
11
+ e=0;e<d.length;e++)f(d[e]);b.length&&c();return a.join("\n")};g.extend(l.prototype,j.prototype);var h=function(){var a=this,b=d(e.body),c=d(i);this.visible=!1;this.emojiarea=null;this.$menu=d("<div>");this.$menu.addClass("emoji-menu");this.$menu.hide();this.$items=d("<div>").appendTo(this.$menu);b.append(this.$menu);b.on("keydown",function(b){(27===b.keyCode||9===b.keyCode)&&a.hide()});b.on("mouseup",function(){a.hide()});c.on("resize",function(){a.visible&&a.reposition()});this.$menu.on("mouseup",
12
+ "a",function(a){a.stopPropagation();return!1});this.$menu.on("click","a",function(b){var c=d(".label",d(this)).text();i.setTimeout(function(){a.onItemSelected.apply(a,[c])},0);b.stopPropagation();return!1});this.load()};h.prototype.onItemSelected=function(a){this.emojiarea.insert(a);this.hide()};h.prototype.load=function(){var a=[],b=d.emojiarea.icons,c=d.emojiarea.path;c.length&&c.charAt(c.length-1);for(var e in b)b.hasOwnProperty(e)&&a.push('<a href="javascript:void(0)" title="'+g.htmlEntities(e)+
13
+ '">'+j.createIcon(e)+'<span class="label">'+g.htmlEntities(e)+"</span></a>");this.$items.html(a.join(""))};h.prototype.reposition=function(){var a=this.emojiarea.$button,b=a.offset();b.top+=a.outerHeight();b.left+=Math.round(a.outerWidth()/2);this.$menu.css({top:b.top,left:b.left})};h.prototype.hide=function(){this.emojiarea&&(this.emojiarea.menu=null,this.emojiarea.$button.removeClass("on"),this.emojiarea=null);this.visible=!1;this.$menu.hide()};h.prototype.show=function(a){this.emojiarea&&this.emojiarea===
14
+ a||(this.emojiarea=a,this.emojiarea.menu=this,this.reposition(),this.$menu.show(),this.visible=!0)};var n=null;h.show=function(a){n=n||new h;n.show(a)}})(jQuery,window,document);
@@ -0,0 +1,8 @@
1
+ $.emojiarea.path = 'assets/packs/basic';
2
+ $.emojiarea.icons = {
3
+ ':smile:' : 'smile.png',
4
+ ':angry:' : 'angry.png',
5
+ ':flushed:' : 'flushed.png',
6
+ ':neckbeard:' : 'neckbeard.png',
7
+ ':laughing:' : 'laughing.png'
8
+ };
@@ -0,0 +1,59 @@
1
+ .emoji-wysiwyg-editor {
2
+ border: 1px solid #d0d0d0;
3
+ overflow: auto;
4
+ outline: none;
5
+ }
6
+ .emoji-wysiwyg-editor img {
7
+ width: 20px;
8
+ height: 20px;
9
+ vertical-align: middle;
10
+ margin: -3px 0 0 0;
11
+ }
12
+ .emoji-menu {
13
+ position: absolute;
14
+ z-index: 999;
15
+ width: 180px;
16
+ margin-left: -100px;
17
+ padding: 0;
18
+ -webkit-box-sizing: border-box;
19
+ -moz-box-sizing: border-box;
20
+ box-sizing: border-box;
21
+ }
22
+ .emoji-menu > div {
23
+ max-height: 200px;
24
+ overflow: hidden;
25
+ background: #fff;
26
+ -webkit-border-radius: 3px;
27
+ -moz-border-radius: 3px;
28
+ border-radius: 3px;
29
+ -webkit-box-sizing: border-box;
30
+ -moz-box-sizing: border-box;
31
+ box-sizing: border-box;
32
+ -webkit-box-shadow: 0 1px 5px rgba(0,0,0,0.3);
33
+ -moz-box-shadow: 0 1px 5px rgba(0,0,0,0.3);
34
+ box-shadow: 0 1px 5px rgba(0,0,0,0.3);
35
+ }
36
+ .emoji-menu img {
37
+ width: 25px;
38
+ height: 25px;
39
+ vertical-align: middle;
40
+ border: 0 none;
41
+ }
42
+ .emoji-menu a {
43
+ margin: -1px 0 0 -1px;
44
+ border: 1px solid #f2f2f2;
45
+ padding: 5px;
46
+ display: block;
47
+ float: left;
48
+ }
49
+ .emoji-menu a:hover {
50
+ background-color: #fffae7;
51
+ }
52
+ .emoji-menu:after {
53
+ content: ' ';
54
+ display: block;
55
+ clear: left;
56
+ }
57
+ .emoji-menu a .label {
58
+ display: none;
59
+ }
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jquery-emojiarea-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Lucius Choi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Wrap jquery-emojiarea plugin for Rails asset pipeline.
42
+ email:
43
+ - lucius.choi@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - LICENSE.txt
49
+ - README.md
50
+ - lib/jquery/emojiarea/rails.rb
51
+ - lib/jquery/emojiarea/rails/version.rb
52
+ - vendor/assets/javascripts/jquery.emojiarea.js
53
+ - vendor/assets/javascripts/jquery.emojiarea.min.js
54
+ - vendor/assets/javascripts/packs/basic/angry.png
55
+ - vendor/assets/javascripts/packs/basic/emojis.js
56
+ - vendor/assets/javascripts/packs/basic/flushed.png
57
+ - vendor/assets/javascripts/packs/basic/laughing.png
58
+ - vendor/assets/javascripts/packs/basic/neckbeard.png
59
+ - vendor/assets/javascripts/packs/basic/smile.png
60
+ - vendor/assets/javascripts/packs/basic/sunglasses.png
61
+ - vendor/assets/stylesheets/jquery.emojiarea.css
62
+ homepage: https://github.com/lucius/jquery-emojiarea-rails
63
+ licenses: []
64
+ metadata:
65
+ allowed_push_host: https://rubygems.org
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 2.4.5
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: Wrap jquery-emojiarea plugin with a gem.
86
+ test_files: []