jquery-emojiarea-rails 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +76 -0
- data/lib/jquery/emojiarea/rails.rb +10 -0
- data/lib/jquery/emojiarea/rails/version.rb +7 -0
- data/vendor/assets/javascripts/jquery.emojiarea.js +458 -0
- data/vendor/assets/javascripts/jquery.emojiarea.min.js +14 -0
- data/vendor/assets/javascripts/packs/basic/angry.png +0 -0
- data/vendor/assets/javascripts/packs/basic/emojis.js +8 -0
- data/vendor/assets/javascripts/packs/basic/flushed.png +0 -0
- data/vendor/assets/javascripts/packs/basic/laughing.png +0 -0
- data/vendor/assets/javascripts/packs/basic/neckbeard.png +0 -0
- data/vendor/assets/javascripts/packs/basic/smile.png +0 -0
- data/vendor/assets/javascripts/packs/basic/sunglasses.png +0 -0
- data/vendor/assets/stylesheets/jquery.emojiarea.css +59 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -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
|
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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,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, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
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,"&").replace(/</g,"<").replace(/>/g,
|
6
|
+
">").replace(/"/g,""")};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);
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -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: []
|