Skip to content

Commit

Permalink
WIP of contenteditable support
Browse files Browse the repository at this point in the history
  • Loading branch information
makenai committed Apr 6, 2015
1 parent 07a8776 commit 7877712
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 19 deletions.
8 changes: 8 additions & 0 deletions css/jquery.emojipicker.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
$(document).ready(function(e) {

$('.emojiable-question').emojiPicker({
width: '300px',
height: '200px',
width: '260px',
height: '170px',
button: false
});

$('.emojiable-option').emojiPicker({
width: '200px',
height: '100px'
height: '140px'
});

$('#trigger').click(function(e) {
Expand All @@ -34,7 +34,7 @@

<style type="text/css">
body {background:#888;}
form {margin:200px 0 0 0; text-align:center;}
form {margin:150px 0 0 0; text-align:center;}
input {width:400px; height:30px;}
input,textarea,button {padding:5px 10px; font-family:"Helvetica Neue", "Helvetica", "Arial", sans-serif; font-size:24px; font-weight:300; outline:none; border:none;}
#emojiPickerWrap {margin:10px 0 0 0;}
Expand Down
140 changes: 125 additions & 15 deletions js/jquery.emojipicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
iconColor: 'black',
iconBackgroundColor: '#eee',
container: 'body',
button: true
button: true,
richInput: true
};

var MIN_WIDTH = 200,
Expand All @@ -23,6 +24,9 @@
this.element = element;
this.$el = $(element);

// This will either be the element or the rich text area.
this.$input = this.$el;

this.settings = $.extend( {}, defaults, options );

this.$container = $(this.settings.container);
Expand Down Expand Up @@ -54,21 +58,49 @@

init: function() {
this.active = false;
if (this.settings.richInput) {
this.emojifyInput();
}
this.addPickerIcon();
this.createPicker();
this.listen();
},

// TODO : Placeholder http://stackoverflow.com/questions/20726174/placeholder-for-contenteditable-div

emojifyInput: function() {
this.$emojiArea = $('<div>', {
class: 'emojiArea',
contenteditable: 'true'
})

this.$emojiArea.width( this.$el.width() );
this.$emojiArea.height( this.$el.height() );

this.$emojiArea.copyCSS( this.$el, [
/^(padding|font|color|background|border|margin)/
]);

// TODO : remove visual debugging aid
this.$emojiArea.css( 'background-color', '#c8fccf' );

// Replace the textarea
this.$el.hide()
.after(this.$emojiArea);

this.$input = this.$emojiArea;
},

addPickerIcon: function() {
var elementHeight = this.$el.outerHeight();
var elementHeight = this.$input.outerHeight();
var iconHeight = elementHeight > MAX_ICON_HEIGHT ?
MAX_ICON_HEIGHT :
elementHeight;
var objectWidth = this.$el.width();
var objectWidth = this.$input.width();

this.$el.width(objectWidth)
this.$input.width(objectWidth)

this.$wrapper = this.$el
this.$wrapper = this.$input
.wrap("<div class='emojiPickerIconWrap'></div>")
.parent()

Expand Down Expand Up @@ -117,20 +149,22 @@
this.$picker.find('nav .tab')
.click( $.proxy(this.emojiCategoryClicked, this) );

this.$picker.click( $.proxy(this.pickerClicked, this) );

$(document.body).click( $.proxy(this.clickOutside, this) );
// Clicking inside and outside of the picker
this.$picker
.click( $.proxy(this.pickerClicked, this) );
$(document.body)
.click( $.proxy(this.clickOutside, this) );
},

updatePosition: function() {
var top, left;
if (this.settings.container === 'body') {
top = this.$el.offset().top + this.$el.height();
left = this.$el.offset().left;
top = this.$input.offset().top + this.$input.height();
left = this.$input.offset().left;
}
else {
top = this.$el.position().top + this.$el.height();
left = this.$el.position().left;
top = this.$input.position().top + this.$input.height();
left = this.$input.position().left;
}

// Picker position
Expand All @@ -154,7 +188,7 @@

this.$picker.css({
top: top + 15,
left: left + this.$el.outerWidth() - this.settings.width
left: left + this.$input.outerWidth() - this.settings.width
});
return this;
},
Expand All @@ -166,7 +200,7 @@
},

show: function() {
this.$el.focus();
this.$input.focus();
this.updatePosition();
this.$picker.show(this.settings.fadeTime, 'linear', function() {
this.active = true;
Expand All @@ -189,7 +223,15 @@
var emojiShortcode = $(e.target).attr('class').split('emoji-')[1];
var emojiUnicode = toUnicode(findEmoji(emojiShortcode).unicode);

insertAtCaret(this.element, emojiUnicode);
if (this.settings.richInput) {

var emoji = $(emojiHTML( emojiShortcode, emojiUnicode ));
this.$input.focus();
insertTextAtCursor( emojiUnicode );

} else {
insertAtCaret(this.element, emojiUnicode);
}
},

emojiCategoryClicked: function(e) {
Expand Down Expand Up @@ -248,6 +290,58 @@

/* ---------------------------------------------------------------------- */

/*
* getStyleObject Plugin for jQuery JavaScript Library
* From: http://upshots.org/?p=112
*/
$.fn.getStyleObject = function(){
var dom = this.get(0);
var style;
var returns = {};
if(window.getComputedStyle){
var camelize = function(a,b){
return b.toUpperCase();
};
style = window.getComputedStyle(dom, null);
for(var i = 0, l = style.length; i < l; i++){
var prop = style[i];
var camel = prop.replace(/\-([a-z])/g, camelize);
var val = style.getPropertyValue(prop);
returns[camel] = val;
};
return returns;
};
if(style = dom.currentStyle){
for(var prop in style){
returns[prop] = style[prop];
};
return returns;
};
return this.css();
}

$.fn.copyCSS = function(source, attributes){
var styles = $(source).getStyleObject();
var copiedStyles = {};
for (var i in attributes) {
var attr = attributes[i];
if ( attr instanceof RegExp ) {
for (prop in styles) {
if (prop.match(attr))
copiedStyles[ prop ] = styles[ prop ];
}
} else {
if (attr in styles)
copiedStyles[ attr ] = styles[ attr ];
}
};
this.css(copiedStyles);
}

function emojiHTML(shortcode,unicode) {
return '<span class="emoji emoji-' + shortcode + '">' + unicode + '</span>';
}

function getPickerHTML() {
var nodes = [];
var categories = [
Expand Down Expand Up @@ -308,6 +402,22 @@
}
}

// For contenteditable
function insertTextAtCursor(text) {
var sel, range, html;
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
range.insertNode( document.createTextNode(text) );
}
} else if (document.selection && document.selection.createRange) {
document.selection.createRange().text = text;
}
}

// For text area
function insertAtCaret(inputField, myValue) {
if (document.selection) {
//For browsers like Internet Explorer
Expand Down

0 comments on commit 7877712

Please sign in to comment.