(function($){
function saveRange(target){
var opts = $.data(target, 'texteditor').options;
opts.selectedRange = null;
if (window.getSelection){
var sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount){
var range = sel.getRangeAt(0);
var pnode = range.commonAncestorContainer.parentNode;
if ($(pnode).closest('.texteditor')[0] == $(target).parent()[0]){
opts.selectedRange = range;
}
}
} else if (document.selection && document.selection.createRange){
var range = document.selection.createRange();
var pnode = range.parentElement();
if ($(pnode).closest('.texteditor')[0] == $(target).parent()[0]){
opts.selectedRange = range;
}
}
}
function restoreRange(target){
var opts = $.data(target, 'texteditor').options;
var range = opts.selectedRange;
if (window.getSelection){
var sel = window.getSelection();
sel.removeAllRanges();
if (range){
sel.addRange(range);
}
} else if (document.selection){
document.selection.empty();
if (range && range.select){
range.select();
}
}
}
function insertContent(target, html){
var opts = $.data(target, 'texteditor').options;
if (opts.selectedRange){
if (window.getSelection){
opts.selectedRange.collapse(false);
opts.selectedRange.insertNode($(html)[0]);
} else if (document.selection && opts.selectedRange.select){
opts.selectedRange.collapse(false);
opts.selectedRange.pasteHTML($(html)[0]);
}
}
}
function updateToolbar(target){
var opts = $.data(target, 'texteditor').options;
opts.dlgToolbar.find('.l-btn').each(function(){
var cmd = $(this).attr('cmd');
if (document.queryCommandState(cmd)){
$(this).linkbutton('select');
} else {
$(this).linkbutton('unselect');
}
});
opts.dlgToolbar.find('.combobox-f').each(function(){
var cmd = $(this).attr('cmd');
var value = String(document.queryCommandValue(cmd)||'');
value = value.replace(/['"]/g,'').toLowerCase();
var copts = $(this).combo('options');
var onChange = copts.onChange;
copts.onChange = function(){};
var data = $(this).combobox('getData');
if ($.easyui.indexOfArray(data, copts.valueField, value) >= 0){
$(this).combobox('setValue', value);
} else {
$(this).combobox('clear');
}
copts.onChange = onChange;
});
}
function buildEditor(target){
var opts = $.data(target, 'texteditor').options;
$(opts.dlgToolbar).panel('clear').remove();
opts.dlgToolbar = $('
');
for(var i=0; i').appendTo(opts.dlgToolbar);
} else {
var cmd = opts.commands[tool];
if (cmd){
cmd.type = cmd.type || 'linkbutton';
cmd.plain = cmd.plain || true;
var btn = $('').appendTo(opts.dlgToolbar);
btn.attr('cmd', tool);
btn[cmd.type](cmd);
if (cmd.onInit){
cmd.onInit.call(btn[0]);
}
}
}
}
$(target).dialog($.extend({}, opts, {
toolbar: opts.dlgToolbar
}));
$(target).attr('contenteditable', true);
var input = $(target).dialog('dialog').children('.texteditor-value');
if (!input.length){
input = $('').insertAfter(target);
}
input.attr('name', opts.name || $(target).attr('name'));
$(target).unbind('.texteditor').bind('mouseup.texteditor keyup.texteditor',function(){
saveRange(target);
updateToolbar(target);
}).bind('blur.texteditor', function(e){
input.val($(target).html());
});
input.val($(target).html());
}
function buildColorPanel(mb){
var opts = $(mb).menubutton('options');
if (!opts.menu){
opts.menu = $('');
}
opts.menu.menu({
onShow: function(){
if ($(this).is(':empty')){
var colors = [
"0,0,0","68,68,68","102,102,102","153,153,153","204,204,204","238,238,238","243,243,243","255,255,255",
"244,204,204","252,229,205","255,242,204","217,234,211","208,224,227","207,226,243","217,210,233","234,209,220",
"234,153,153","249,203,156","255,229,153","182,215,168","162,196,201","159,197,232","180,167,214","213,166,189",
"224,102,102","246,178,107","255,217,102","147,196,125","118,165,175","111,168,220","142,124,195","194,123,160",
"204,0,0","230,145,56","241,194,50","106,168,79","69,129,142","61,133,198","103,78,167","166,77,121",
"153,0,0","180,95,6","191,144,0","56,118,29","19,79,92","11,83,148","53,28,117","116,27,71",
"102,0,0","120,63,4","127,96,0","39,78,19","12,52,61","7,55,99","32,18,77","76,17,48"
];
for(var i=0; i').appendTo(this);
a.css('backgroundColor', 'rgb('+colors[i]+')');
}
}
}
});
opts.menu.bind('click', function(e){
if ($(e.target).hasClass('texteditor-colorcell')){
var color = $(e.target).css('backgroundColor');
opts.onClick.call(mb, color);
opts.menu.menu('hide');
}
});
$(mb).menubutton({menu:opts.menu}); // attach the menu
}
function setDisabled(target, disabled){
if (disabled){
$(target).dialog('dialog').addClass('texteditor-disabled');
$(target).removeAttr('contenteditable');
$(target).next().attr('disabled', 'disabled');
} else {
$(target).dialog('dialog').removeClass('texteditor-disabled');
$(target).attr('contenteditable', true);
$(target).next().removeAttr('disabled');
}
}
function setReadonly(target, mode){
var readonly = mode == undefined ? true : mode;
if (readonly){
$(target).dialog('dialog').addClass('texteditor-readonly');
$(target).removeAttr('contenteditable');
} else {
$(target).dialog('dialog').removeClass('texteditor-readonly');
$(target).attr('contenteditable', true);
}
}
$.fn.texteditor = function(options, param){
if (typeof options == 'string'){
var method = $.fn.texteditor.methods[options];
if (method){
return method(this, param);
} else {
return this.dialog(options, param);
}
}
options = options || {};
return this.each(function(){
var state = $.data(this, 'texteditor');
if (state){
$.extend(state.options, options);
} else {
state = $.data(this, 'texteditor', {
options: $.extend({}, $.fn.texteditor.defaults, $.fn.texteditor.parseOptions(this), options)
});
}
buildEditor(this);
});
};
$.fn.texteditor.methods = {
options: function(jq){
return jq.data('texteditor').options;
},
execCommand: function(jq, cmd){
return jq.each(function(){
var a = cmd.split(' ');
var c = a.shift();
restoreRange(this);
document.execCommand(c, false, a.join(' ')||null);
updateToolbar(this);
saveRange(this);
});
},
getEditor: function(jq){
return jq.closest('.texteditor').children('.texteditor-body');
},
insertContent: function(jq, html){
return jq.each(function(){
insertContent(this, html);
$(this).dialog('dialog').children('.texteditor-value').val($(this).html());
});
},
destroy: function(jq){
return jq.each(function(){
var opts = $(this).texteditor('options');
$(opts.dlgToolbar).panel('clear');
$(this).dialog('destroy');
});
},
getValue: function(jq){
return jq.dialog('dialog').children('.texteditor-value').val();
},
setValue: function(jq, html){
return jq.each(function(){
$(this).html(html);
$(this).dialog('dialog').children('.texteditor-value').val($(this).html());
});
},
disable: function(jq){
return jq.each(function(){
setDisabled(this, true);
});
},
enable: function(jq){
return jq.each(function(){
setDisabled(this, false);
});
},
readonly: function(jq, mode){
return jq.each(function(){
setReadonly(this, mode);
});
}
};
$.fn.texteditor.parseOptions = function(target){
return $.extend({}, $.fn.dialog.parseOptions(target), {
});
};
$.fn.texteditor.defaults = $.extend({}, $.fn.dialog.defaults, {
title: null,
cls: 'texteditor',
bodyCls: 'texteditor-body',
draggable: false,
shadow: false,
closable: false,
inline: true,
border: 'thin',
name: '',
toolbar: ['bold','italic','strikethrough','underline','-','justifyleft','justifycenter','justifyright','justifyfull','-','insertorderedlist','insertunorderedlist','outdent','indent','-','forecolor','backcolor','-','formatblock','fontname','fontsize'],
commands: {
'bold': {
type: 'linkbutton',
iconCls: 'icon-bold',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','bold');
}
},
'italic': {
type: 'linkbutton',
iconCls: 'icon-italic',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','italic');
}
},
'strikethrough': {
type: 'linkbutton',
iconCls: 'icon-strikethrough',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','strikethrough');
}
},
'underline': {
type: 'linkbutton',
iconCls: 'icon-underline',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','underline');
}
},
'justifyleft': {
type: 'linkbutton',
iconCls: 'icon-justifyleft',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','justifyleft');
}
},
'justifycenter': {
type: 'linkbutton',
iconCls: 'icon-justifycenter',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','justifycenter');
}
},
'justifyright': {
type: 'linkbutton',
iconCls: 'icon-justifyright',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','justifyright');
}
},
'justifyfull': {
type: 'linkbutton',
iconCls: 'icon-justifyfull',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','justifyfull');
}
},
'insertorderedlist': {
type: 'linkbutton',
iconCls: 'icon-insertorderedlist',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','insertorderedlist');
}
},
'insertunorderedlist': {
type: 'linkbutton',
iconCls: 'icon-insertunorderedlist',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','insertunorderedlist');
}
},
'outdent': {
type: 'linkbutton',
iconCls: 'icon-outdent',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','outdent');
}
},
'indent': {
type: 'linkbutton',
iconCls: 'icon-indent',
onClick: function(){
$(this).texteditor('getEditor').texteditor('execCommand','indent');
}
},
'forecolor': {
type: 'menubutton',
iconCls: 'icon-forecolor',
width: 26,
onInit: function(){
buildColorPanel(this);
},
onClick: function(color){
$(this).texteditor('getEditor').texteditor('execCommand','forecolor '+color);
}
},
'backcolor': {
type: 'menubutton',
iconCls: 'icon-backcolor',
width: 26,
onInit: function(){
buildColorPanel(this);
},
onClick: function(color){
$(this).texteditor('getEditor').texteditor('execCommand','backcolor '+color);
}
},
'formatblock': {
type: 'combobox',
width: 100,
prompt: 'Font Format',
editable: false,
panelHeight: 'auto',
data: [
{value: 'p',text:'p'},
{value: 'pre',text:'pre'},
{value: 'h6',text:'h6'},
{value: 'h5',text:'h5'},
{value: 'h4',text:'h4'},
{value: 'h3',text:'h3'},
{value: 'h2',text:'h2'},
{value: 'h1',text:'h1'}
],
formatter: function(row){
return '<'+row.value+' style="margin:0;padding:0">'+row.text+''+row.value+'>';
},
onChange: function(value){
$(this).texteditor('getEditor').texteditor('execCommand','formatblock '+value);
}
},
'fontname': {
type: 'combobox',
width: 100,
prompt: 'Font Family',
editable: false,
panelHeight: 'auto',
data: [
{value:'arial',text:'Arial'},
{value:'comic sans ms',text:'Comic Sans'},
{value:'courier new',text:'Courier New'},
{value:'georgia',text:'Georgia'},
{value:'helvetica',text:'Helvetica'},
{value:'impact',text:'Impact'},
{value:'times new roman',text:'Times'},
{value:'trebuchet ms',text:'Trebuchet'},
{value:'verdana',text:'Verdana'}
],
formatter: function(row){
return ''+row.text+'';
},
onChange: function(value){
$(this).texteditor('getEditor').texteditor('execCommand','fontname '+value);
}
},
'fontsize': {
type: 'combobox',
width: 100,
prompt: 'Font Size',
editable: false,
panelHeight: 'auto',
data: [
{value:1,text:'Size 1'},
{value:2,text:'Size 2'},
{value:3,text:'Size 3'},
{value:4,text:'Size 4'},
{value:5,text:'Size 5'},
{value:6,text:'Size 6'}
],
formatter: function(row){
return ''+row.text+'';
},
onChange: function(value){
$(this).texteditor('getEditor').texteditor('execCommand','fontsize '+value);
}
}
}
});
$.parser.plugins.push('texteditor');
})(jQuery);