+function($){
/**
* 定义基础内部全局变量
*/
var
/**
* 当前window对象
* @type {jQuery Object}
*/
$win = $(window),
/**
* 当前document对象
* @type {jQuery Object}
*/
$doc = $(document),
/**
* ThinkEditor 对象
* @type {Object}
*/
ThinkEditor,
/**
* 封装过的textarea Range对象
* @type {Object}
*/
Range,
/**
* 编辑器弹出层对象
* 主要提供给一些需要复杂功能的插件使用
* 在插件中使用 this.dialog()方法调用
* @type {Object}
*/
Dialog,
/**
* ThinkEditor插件对象,所有的操作都是通过该对象实现
* @type {Object}
*/
Plugin = {},
/**
* ThinkEditor语言包对象
*/
Language = {},
/**
* 键盘按键对应数值表
* @type {Object}
*/
KeyCode = {
"BACKSPACE" : 8,
"TAB" : 9,
"ENTER" : 13,
"ESC" : 27,
"SPACE" : 32,
"F1" : 112,
"F2" : 113,
"F3" : 114,
"F4" : 115,
"F5" : 116,
"F6" : 117,
"F7" : 118,
"F8" : 119,
"F9" : 120,
"F10" : 121,
"F11" : 122,
"F12" : 123
},
/**
* 默认配置项,创建Tree时传入的配置项会和该配置合并
* @type {Object}
*/
Defaults = {
/**
* 显示风格
* 目前仅支持默认风格,可自己扩展
*/
"style" : "default",
/**
* 编辑器插件按钮配置
* 没配置到这里的插件不能显示在工具栏
* 如果设置了快捷键依然生效
*/
"items" : "h1,h2,h3,h4,h5,h6,-,link,image,-,bold,italic,code,-," +
"ul,ol,blockquote,hr,-,fullscreen,save",
/**
* 编辑器默认宽度
* 默认自适应父容器
*/
"width" : "100%",
/**
* 编辑器高度,默认自适应父容器
* 设置为100%时一定要给父元素设置高度
*/
"height" : "100%",
/**
* 编辑器显示语言
* 目前仅支持简体中文和英文
* 可以在调用编辑器之前调用$.thinkeditor.language方法扩展
*/
"lang" : "zh-cn",
/**
* 按TAB键插入的字符
* 默认为四个空格,一般情况下为空格或制表符
* 插入制表符请写 \t
*/
"tab" : " ",
/**
* 图片上传插件上传到的URL
* 该URL必须返回JSON数据
* 数据格式:
* {
* "status" : 1,
* "info" : "message",
* "files" : [] //文件信息
* }
*/
"uploader" : "",
/**
* 图片上传表单名称
* 即name属性默认设置的值
*/
"dataName" : "images",
/**
* 保存按钮点击后调用的回调函数
*/
"onSave" : $.noop //保存按钮回调接口
},
DialogWraper = [
'
'
].join("");
/**
* Range构造器,用于创建一个新的Range对象
* @param {Object} textarea 一个textarea对象,用于创建Range
*/
Range = function(textarea){
/* 绑定Range对象的textarea */
this.textarea = textarea;
}
/**
* 扩展Range原型,主要添加了get,set,insert三个方法
* @type {Object}
*/
Range.prototype = {
/**
* 获取当前range
* @return {Object} 当前range对象
*/
"get" : function(){
var textarea = this.textarea,
data = {"start" : 0, "end" : 0, "text" : ""},
range, dupRange, rangeNl, dupRangeNl;
textarea.focus();
if (textarea.setSelectionRange) { // W3C
data.start = textarea.selectionStart;
data.end = textarea.selectionEnd;
data.text = (data.start != data.end) ?
textarea.value.substring(data.start, data.end) : "";
} else if (document.selection) { // For IE
range = document.selection.createRange(),
dupRange = range.duplicate();
dupRange.moveToElementText(textarea);
dupRange.setEndPoint("EndToEnd", range );
data.text = range.text; //选中的文本内容
rangeNl = range.text.split("\n").length - 1; //选中文本换行数
dupRangeNl = dupRange.text.split("\n").length - 1; //选中之前换行数
data.start = dupRange.text.length - range.text.length -
dupRangeNl + rangeNl;
data.end = data.text.length + data.start - rangeNl;
}
return data;
},
/**
* 设置当前range的位置
* @param {Integer} start 起始位置
* @param {Integer} end 结束位置
* @return {Object} 当前Range对象
*/
"set" : function (start, end) {
var range, textarea = this.textarea;
textarea.focus();
if (textarea.setSelectionRange) { // W3C
textarea.setSelectionRange(start, end);
} else if (textarea.createTextRange) { // For IE
range = textarea.createTextRange();
range.collapse(true);
range.moveStart("character", start);
range.moveEnd("character", end - start);
range.select();
}
return this;
},
/**
* 在当前Range处插入文本
* @param {String} text 文本内容
* @return {Object} 当前Range对象
*/
"insert" : function (text) {
var textarea = this.textarea, data = this.get(),
oValue, nValue, range, scroll;
if (textarea.setSelectionRange) { // W3C
oValue = textarea.value;
nValue = oValue.substring(0, data.start) + text +
oValue.substring(data.end);
scroll = textarea.scrollTop;
data.end = data.start + text.length;
textarea.value = nValue;
/**
* Fixbug:
* After textarea.values = nValue, scrollTop value to 0
*/
if(textarea.scrollTop != scroll) {
textarea.scrollTop = scroll;
}
textarea.setSelectionRange(data.start, data.end);
} else if (textarea.createTextRange) { //For IE
range = document.selection.createRange();
range.text = text;
range.setEndPoint("StartToEnd", range);
range.select();
}
return this;
}
};
/**
* 简单的弹出层对象,供需要弹出显示的插件调用
* @param {Object} editor 编辑器对象
* @param {Object} options 编辑器配置对象
*/
Dialog = function(editor, options){
var self = this, $dialog, $modal, defaults,
$editor = $(editor.range.textarea).closest(".thinkeditor");
/* 弹出层默认配置 */
defaults = {
"title" : "title",
"content" : "",
"onOkClick" : $.noop,
"onCancelClick" : $.noop
}
//合并配置并创建弹出层
options = $.extend({}, defaults, options || {});
/* 创建弹出层内容区 */
this.dialog = $dialog = $(DialogWraper).appendTo($editor);
//创建遮罩层
this.modal = $modal = $("").addClass("thinkeditor-dialog-modal")
.appendTo($editor);
/* 弹出层相关容器 */
this.title = $dialog.find(".thinkeditor-dialog-title"); //标题
this.content = $dialog.find(".thinkeditor-dialog-body"); //内容
this.status = $dialog.find(".thinkeditor-dialog-status"); //状态信息
/* 弹出层按钮 */
this.btn = {
"close" : $dialog.find(".thinkeditor-dialog-close"),
"ok" : $dialog.find(".thinkeditor-dialog-btn-ok"),
"cancel" : $dialog.find(".thinkeditor-dialog-btn-cancel")
}
/* 绑定关闭事件 */
this.btn.close.click(function(){
self.remove();
});
/* 绑定确定按钮事件 */
this.btn.ok.click(function(){
options.onOkClick.call(self, this);
});
/* 绑定取消按钮事件 */
this.btn.cancel.click(function(){
options.onCancelClick.call(self, this);
self.remove();
});
//添加弹出层内容并
this.setTitle(options.title);
this.setContent(options.content);
this.btn.ok.text(editor.lang("ok"));
this.btn.cancel.text(editor.lang("cancel"));
//显示弹出层
$dialog.add($modal).fadeIn("fast");
}
/**
* 弹出层标准接口
* @type {Object}
*/
Dialog.prototype = {
/**
* 查找弹出层内容里的元素
* @param {String} expr jQuery支持的所有选择器
* @return {Object} jQuery对象
*/
"find" : function(expr){
return this.content.find(expr);
},
/**
* 移动弹出层到屏幕中央
* @return {Object} 弹出层对象
*/
"moveToCenter" : function(){
this.dialog.css({
"top" : ($win.height() - this.dialog.outerHeight()) / 2,
"left" : ($win.width() - this.dialog.outerWidth()) / 2
});
return this;
},
/**
* 重置弹出层内容
* @param {Object} content 弹出层内容对象,可以是html代码
* @return {Object} 弹出层对象
*/
"setContent" : function(content){
this.content.empty().append(content);
this.moveToCenter();
return this;
},
/**
* 改变弹出层标题
* @param {String} title 弹出层标题文字,可以是html代码
* @return {Object} 弹出层对象
*/
"setTitle" : function(title){
return this.title.html(title);
},
/**
* 设置弹出层状态信息
* @param {String} info 状态信息
* @param {String} status 状态标识,success,error
* @param {Boolean} dealy 是否自动关闭
* @return {Object} 当前弹出层对象
*/
"setStatus" : function(info, status, dealy){
var $status = $("").text(info), timeout;
/* 清楚原来计时器 */
timeout = this.status.children("span").data("timeout");
timeout && clearTimeout(timeout);
/* 显示状态信息 */
status && $status.addClass("thinkeditor-dialog-" + status);
this.status.empty().append($status);
/* 延时关闭 */
if(dealy){
$status.data("timeout", setTimeout(function(){
$status.fadeOut("fast");
}, 5000));
}
return this;
},
/**
* 卸载当前弹出层
*/
"remove" : function(){
this.dialog.add(this.modal).fadeOut("fast", function(){
this.remove();
});
}
};
/**
* 创建编辑器工具栏
* @param {Object} $editor 编辑器对象
* @param {Object} options 配置项
*/
function create_editor_tools($editor, options){
var self = this, items, groups = options.items.split(",-,"), $group,
$tools = $("");
/* 创建按钮组 */
for(i in groups){
items = groups[i].split(",");
$group = $("").addClass("thinkeditor-tools-group")
.appendTo($tools);
for(j in items){
$("").addClass("thinkeditor-tools-" + items[j])
.attr({"title" : this.lang(items[j]), "href" : "javascript:;"})
.data("name", items[j])
.appendTo($group);
}
}
/* 工具栏放入editor */
$tools.addClass("thinkeditor-tools clearfix").prependTo($editor);
/* 绑定操作事件 */
$tools.on("click", ".thinkeditor-tools-group a", function(event){
event.stopPropagation();
self.plugin($(this).data("name"), options);
});
}
/**
* 执行快捷键
* @param {event} event 事件对象
*/
function keyboard(event){
var keyboard = Array(4),
self = event.data.self,
options = event.data.options;
/* 当前按键 */
keyboard[0] = event.ctrlKey ? "ctrl" : "";
keyboard[1] = event.shiftKey ? "shift" : "";
keyboard[2] = event.altKey ? "alt" : "";
keyboard[3] = event.which;
keyboard = keyboard.join("");
/* 执行快捷键 */
if(self.keyboards[keyboard]){
if($.isFunction(self.keyboards[keyboard])){
self.keyboards[keyboard].call(self);
} else {
self.plugin(self.keyboards[keyboard], options);
}
return false;
}
}
/**
* 编辑器构造器,用于创建一个新的编辑器对象
* @param {Object} textarea 被创建编辑器的textarea对象
* @param {Object} options 编辑器初始化选项
*/
ThinkEditor = function(textarea, options){
var options, self = this, $textarea = $(textarea), $editor;
/* 合并配置项 */
options = $.extend({}, Defaults, options || {});
options.width = options.width ? options.width : $textarea.width();
options.height = options.height ? options.height : $textarea.height();
/* 创建Range对象 */
this.range = new Range(textarea);
this.language = Language[options.lang] ? options.lang : "en-us";
/* 创建编辑器 */
$textarea.wrap("").parent().wrap("");
$editor = $textarea.parent().parent();
$editor.addClass("thinkeditor thinkeditor-" + options.style);
$editor.children("div").addClass("thinkeditor-textarea");
//如果是预览创建预览div
if(options.preview){
options.width = '50%';
$textarea.parent().after('');
$textarea.css({resize: 'none'});
$preview = $editor.find('.thinkeditor-textarea').next('div');
}
/* 设置editor尺寸 */
$editor.css({"width" : options.width, "height" : options.height});
/* 创建工具栏 */
create_editor_tools.call(this, $editor, options);
/* 绑定快捷键事件 */
$textarea.keydown({"self" : this, "options" : options}, keyboard);
/* 绑定插件的快捷键 */
for(name in Plugin){
Plugin[name].keyboard && this.keyboard(Plugin[name].keyboard, name);
}
if(options.preview){
$preview.css({
"width" : '100%',
"height" : $textarea.outerHeight(true)+'px',
left: '100%'
});
$preview.addClass('thinkeditor-preview');
$preview.html(this.preview(this.range.textarea.value));
_this = this;
$textarea.keyup(function(){
$preview.html(_this.preview(this.value));
});
$textarea.scroll(function(){
fix_img_scroll();
});
var fix_img_scroll = function(){
imgs = $preview.find("img") //获取预览下所有图片
if (imgs.length > 0){
imgs_height = 0
for (var i in imgs){
tm = new Image()
tm.src = this.src
tow = tm.width
toh = tm.height
var limit_width = $preview.width()*0.5 //父容器50%的宽度
if (tow > limit_width){ //如果原始图片宽度大于限制宽度,真实rh高度也要缩放比例
r = tow / limit_width
rh = toh / r
}else{
rh = toh
}
imgs_height += rh //这个就是得到所有图片的高度
}
}
caculate_and_scroll($textarea, $preview, imgs_height);
}
var caculate_and_scroll = function(editor, preview, imgs_height){ //这里只要再按比例计算一下滚动高度就行
real_height = preview[0].scrollHeight + imgs_height;
setTimeout(function(){
if (real_height > editor[0].scrollHeight){
r = real_height / editor[0].scrollHeight;
preview.prop('scrollTop', editor.scrollTop() * r);
}else{
r = editor[0].scrollHeight / real_height;
preview.prop('scrollTop', editor.scrollTop() / r);
}
}, 500);
}
}
}
/**
* 编辑器原型,用于扩展编辑器的外部调用接口
* @type {Object}
*/
ThinkEditor.prototype = {
/**
* 获取语言变量
* @param {String} name 变量名
* @param {String} language 语言,默认去当前options.lang
* @return {String} 指定语言的值
*/
"lang" : function(name, language){
return Language[language || this.language][name] || name;
},
/**
* 执行某个插件插件
* @param {String} name 插件名称
* @param {Object} options 编辑器配置项
*/
"plugin" : function(name, options){
var plugin = Plugin[name]
plugin.markdown.call(this, options, plugin);
return this;
},
/**
* 插入数据到编辑器光标处
* @param {String} text 要插入的数据
* @return {Object} ThinkEditor对象
*/
"insert" : function(text){
var range = this.range.get(), start, _start, end, length, line = 0;
if(arguments.length > 1){ //首尾添加文本
start = arguments[0];
end = arguments[1];
if(arguments[2]){ //按行添加
text = range.text.split("\n");
length = range.text.length;
/* 逐行添加 */
for(i in text){
if(!length || $.trim(text[i])){
_start = start.replace("{$line}", ++line)
.replace("{$i}", i);
text[i] = _start + text[i] + end;
}
}
/* 插入数据 */
this.range.insert(text.join("\n"));
/* 没有选中文本时设置光标位置 */
if(!length){
start = range.start + _start.length;
this.range.set(start, start);
}
} else {
this.range.insert(start + range.text + end);
}
} else { //插入文本
this.range.insert(text);
}
return this;
},
/**
* 设置或获取编辑器的值
* @param {String} text 要设置的值,不传递此参数则获取编辑器的值
* @return {String} 设置值 - 返回ThinkEditor对象, 获取值 - 返回当前值
*/
"value" : function(text){
if(text === undefined){
return this.range.textarea.value;
} else {
this.range.textarea.value = text;
return this;
}
},
/**
* 给编辑器绑定快捷键
* @param {String} keys 快捷键名称
* @param {Function} callback 触发快捷键时执行额函数或插件名称
* @return {Object} 当前编辑器对象
*/
"keyboard" : function(keys, callback){
var keyboard = Array(4); //[ctrl, shift, alt, code]
//初始化快捷键
if(!this.keyboards) {
this.keyboards = {};
}
keys = keys.toUpperCase().split("+");
for(i in keys){
switch(keys[i]){
case "CTRL" :
keyboard[0] = "ctrl";
break;
case "SHIFT" :
keyboard[1] = "shift";
break;
case "ALT" :
keyboard[2] = "alt";
break;
default:
keyboard[3] = KeyCode[keys[i]] || keys[i].charCodeAt();
break;
}
}
this.keyboards[keyboard.join("")] = callback;
return this;
},
"dialog" : function(options){
return new Dialog(this, options);
},
"preview": function(text){
var opt = {
renderer: new marked.Renderer(),
gfm: true,
tables: true,
breaks: false,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: false
}
return marked(text, opt);
}
}
/**
* 通过textarea获取通过当前textarea创建的ThinkEditor对象
* @param {elements} textarea textarea对象或jquery textarea选择器
* @return {Object} ThinkEditor对象
*/
$.thinkeditor = function(textarea){
return $(textarea).data("ThinkEditor");
};
/**
* 添加ThinkEditor全局扩展
* 提供对编辑器的语言包,插件,全局设置等功能
*/
$.extend($.thinkeditor, {
/**
* 扩展语言包
* @param {Object} language 语言包
*/
"language" : function(language){
$.extend(Language, $.isPlainObject(language) ? language : {});
},
/**
* 扩展插件
* @param {Object} plugin 一个或多个插件
*/
"plugin" : function(plugin){
$.extend(Plugin, $.isPlainObject(plugin) ? plugin : {});
},
/**
* 全局设置ThinkEditor
* @param {Object} options 要改变的编辑器默认设置项
*/
"defaults" : function(options){
$.extend(Defaults, $.isPlainObject(options) ? options : {});
}
});
/**
* jQuery.fn对象,用于创建ThinkEditor插件
* @param {Object} options ThinkEditor初始化参数
*/
$.fn.thinkeditor = function(options){
return this.each(function(){
$(this).data("ThinkEditor", new ThinkEditor(this, options));
});
}
/**
* ThinkEditor编辑器插件,工具按显示的每一个按钮代表一个插件
* 一个合法的插件必须包含markdown方法,用于内部调用
* 如果需要给插件设置快捷键,则可以通过 keyboard 属性来设置
* 插件的this指针指向当前ThinkEditor对象
*/
$.thinkeditor.plugin({
/* 标题一插件 */
"h1" : {
/* 标题一快捷键 */
"keyboard" : "ctrl+1",
/* 执行标题一 */
"markdown" : function(options){
this.insert("# ", "", true);
}
},
/* 标题二插件 */
"h2" : {
/* 标题二快捷键 */
"keyboard" : "ctrl+2",
/* 执行标题二 */
"markdown" : function(options){
this.insert("## ", "", true);
}
},
/* 标题三插件 */
"h3" : {
/* 标题三快捷键 */
"keyboard" : "ctrl+3",
/* 执行标题三 */
"markdown" : function(options){
this.insert("### ", "", true);
}
},
/* 标题四插件 */
"h4" : {
/* 标题四快捷键 */
"keyboard" : "ctrl+4",
/* 执行标题四 */
"markdown" : function(options){
this.insert("#### ", "", true);
}
},
/* 标题五插件 */
"h5" : {
/* 标题五快捷键 */
"keyboard" : "ctrl+5",
/* 执行标题五 */
"markdown" : function(options){
this.insert("##### ", "", true);
}
},
/* 标题六插件 */
"h6" : {
/* 标题六快捷键 */
"keyboard" : "ctrl+6",
/* 执行标题六 */
"markdown" : function(options){
this.insert("###### ", "", true);
}
},
/* 添加链接 */
"link" : {
/* 连接快捷键 */
"keyboard" : "ctrl+l",
/* 插入连接 */
"markdown" : function(options){
var range = this.range.get(), start;
if(range.text.length){
if(range.text.match(/^http:\/\/.*/i)){
this.insert("[" + range.text + "](" + range.text + ")");
} else {
this.insert("[" + range.text + "]()");
start = range.start + range.text.length + 3;
this.range.set(start, start);
}
} else {
this.insert("[]()");
start = range.start + 1;
this.range.set(start, start);
}
}
},
/* 添加图片 */
"image" : {
/* 图片快捷键 */
"keyboard" : "ctrl+p",
/* 插入图片 */
"markdown" : function(options, self){
var $text, drop, dialog, start,
editor = this,
range = this.range.get();
/* 当选中文本是远程图片URL时不弹出上传层 */
if(range.text.length && range.text.match(/^http:\/\/.*/i)){
this.insert("![ALT](" + range.text + ")");
start = range.start + 2;
this.range.set(start, start + 3);
return;
}
//拖动上传容器
$text = $("").text(this.lang("image-text"));
self.drop = drop = $("").addClass("thinkeditor-plugin-image")
.append($text);
//弹出图片上传层
self.dialog = dialog = this.dialog({
"title" : this.lang("image-title"),
"content" : drop,
"onOkClick" : function(){ self.upload(editor, options) }
});
/* 初始化数据对象 */
self.data = new FormData();
//初始化文件数
self.data.length = 0;
/* 绑定drag事件,主要是用来设置文件放置框的样式 */
drop.on("dragenter dragleave", function(event){
drop.toggleClass("thinkeditor-image-draghover");
event.stopPropagation();
return false;
});
/* 文件拖动事件,不绑定该事件 drop 事件不生效 */
drop.on("dragover", function(){ return false });
/**
* 文件拖动结束事件
* 该事件必须用原生方式绑定,拖动结束后浏览器会自动跳转到图片预览页面
* ?暂不明白是什么原因
*/
drop[0].addEventListener("drop", function(event) {
var files = event.target.files || event.dataTransfer.files;
if(!files) return; //不支持文件拖动
/* 取消拖动样式,阻止事件冒泡及默认事件 */
drop.removeClass("thinkeditor-image-draghover");
event.stopPropagation();
event.preventDefault();
//上传文件
self.show(files, options);
}, false);
},
/**
* 将上传好的图片插入到编辑器
* @param {Array} imgs 上传的图片数组
* @param {Object} editor 图片对象
*/
"insert" : function(imgs, editor){
var range = editor.range.get(), img, alt, src, text = [];
for(name in imgs){
img = imgs[name];
alt = range.text.length ? range.text : img.name.split(".")[0];
src = img.rootpath + img.savepath + img.savename;
text.push("![" + alt + "](" + src + ")");
}
editor.insert(text.join("\n"));
text = text[0];
editor.range.set(range.start + 2, range.start + text.indexOf("]"));
},
/**
* 预览选择的图片
* @param {Object} files 选择的图片对象
* @param {Object} options 编辑器配置对象
*/
"show" : function(files, options){
var data = this.data, msg;
for(var i = 0, file; file = files[i]; i++){
//禁止上传非图片文件
if(!file.type.match(/^image\/(?:png|jpeg|jpg|gif)$/)){
msg = "忽略非图片文件:" + file.name;
this.dialog.setStatus(msg, "error", true);
} else if(file.size > 1024 * 1024 * 10) {
msg = "忽略超过大小限制的图片:" + file.name;
this.dialog.setStatus(msg, "error", true);
} else {
if(data.length < 3){
data.append(options.dataName + i, file);
data.length ++;
this.reader(file);
} else {
msg = "最多同时上传3张图片,";
msg += "已忽略" + (files.length - i) + "张";
this.dialog.setStatus(msg, "error", true);
break;
}
}
}
},
/**
* 读取图片数据以提供预览
* @param {Object} file 图片对象
*/
"reader" : function(file){
var self = this, reader = new FileReader(); //初始化文件对象
/* 展示选择的图片 */
reader.onload = function(){
var html = [
"", //用于浮动
"
", //再添加一层标签主要是为了解决图片垂直居中
"",
"",
"
"
].join("");
self.drop.append(html);
}
reader.readAsDataURL(file);
},
/**
* AJAX上传图片,只有支持HTML的浏览器才能支持该方法
* @param {Object} editor 编辑器对象
* @param {Object} options 编辑器配置对象
*/
"upload" : function(editor, options){
var self = this, xhr = new XMLHttpRequest(), msg;
if (!xhr.upload) {
msg = "您的浏览器不支持ajax上传文件!";
this.dialog.setStatus(msg, "error", true);
return;
}
// 上传中
xhr.upload.addEventListener("progress", function(event) {
var progress = Math.round(event.loaded / event.total);
msg = "正在上传图片..." + progress + "%";
self.dialog.setStatus(msg, "success");
}, false);
// 文件上传成功或是失败
xhr.onreadystatechange = function() {
var data, images = [];
if (xhr.readyState == 4) {
if (xhr.status == 200) {
data = $.parseJSON(xhr.responseText);
if(data.status){
self.insert(data.files, editor);
self.dialog.remove();
} else {
self.dialog.setStatus(data.info, "error", true);
}
} else {
self.dialog.setStatus("图片上传失败!", "error", true);
}
}
};
// 开始上传
this.dialog.setStatus("正在上传图片...0%", "success");
xhr.open("POST", options.uploader, true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.send(this.data);
}
},
/* 文本加粗插件 */
"bold" : {
/* 文本加粗快捷键 */
"keyboard" : "ctrl+b",
/* 执行文本加粗 */
"markdown" : function(options){
this.insert("**", "**", true);
}
},
/* 文字倾斜插件 */
"italic" : {
/* 文字倾斜快捷键 */
"keyboard" : "ctrl+i",
/* 执行文字倾斜 */
"markdown" : function(options){
this.insert("_", "_", true);
}
},
/* 插入代码 */
"code" : {
/* 代码快捷键 */
"keyboard" : "ctrl+d",
/* 插入代码 */
"markdown" : function(options){
var range = this.range.get(), start;
if(range.text.length){
if(range.text.split("\n").length > 1){
this.insert("~~~\n"+ range.text +"\n~~~");
start = range.start + 3;
this.range.set(start, start);
} else {
this.insert("`"+ range.text +"`");
}
} else {
this.insert("``");
start = range.start + 1;
this.range.set(start, start);
}
}
},
/* 无序列表插件 */
"ul" : {
/* 代码快捷键 */
"keyboard" : "ctrl+u",
/* 插入代码 */
"markdown" : function(options){
this.insert("* ", "", true);
}
},
/* 插入有序列表 */
"ol" : {
/* 有序列表捷键 */
"keyboard" : "ctrl+o",
/* 插入有序列表 */
"markdown" : function(options){
this.insert("{$line}. ", "", true);
}
},
/* 引用文本 */
"blockquote" : {
/* 引用快捷键 */
"keyboard" : "ctrl+q",
/* 插入代码 */
"markdown" : function(options){
this.insert("> ", "", true);
}
},
/* 插入水平分割线 */
"hr" : {
/* 分割线快捷键 */
"keyboard" : "ctrl+h",
/* 插入分割线 */
"markdown" : function(options){
var range = this.range.get(),
start = range.start + range.text.length + 11;
this.insert(range.text + "\n* * * * *\n");
this.range.set(start, start);
}
},
/* 全屏编辑 */
"fullscreen" : {
/* 全屏编辑快捷键 */
"keyboard" : "ctrl+f",
/* 执行全屏编辑 */
"markdown" : function(options){
var $body = $("body"),
$editor = $(this.range.textarea).closest(".thinkeditor");
if($editor.hasClass("thinkeditor-fullscreen")){
$body.css("overflow", "");
$editor.removeClass("thinkeditor-fullscreen");
} else {
$body.css("overflow", "hidden");
$editor.addClass("thinkeditor-fullscreen");
}
}
},
/* 保存数据 */
"save" : {
/* 保存数据快捷键 */
"keyboard" : "ctrl+s",
/* 执行全屏编辑 */
"markdown" : function(options){
if($.isFunction(options.onSave)){
options.onSave.call(this.range.textarea);
}
}
},
/* 文本缩进 */
"indent" : {
/* 缩进快捷键 */
"keyboard" : "tab",
/* 插入缩进 */
"markdown" : function(options){
var range = this.range.get(), text, start;
if(range.start){
text = this.range.textarea.value.substring(0, range.start);
start = text.lastIndexOf("\n") + 1;
if(range.text.length && start != text.length){
this.range.set(start, range.end);
}
}
this.insert(options.tab, "", true);
}
},
/* 减少缩进 */
"outdent" : {
/* 减少缩进快捷键 */
"keyboard" : "shift+tab",
/* 插入代码 */
"markdown" : function(options){
var range = this.range.get(), text, start;
if(range.start){
text = this.range.textarea.value.substring(0, range.start);
start = text.lastIndexOf("\n") + 1;
if(start != text.length){
range = this.range.set(start, range.end).get();
}
}
if(range.text.length){
text = range.text.split("\n");
for(i in text){
text[i] = text[i].replace(/^((\t)|( {1,4}))/, "");
}
this.insert(text.join("\n"));
}
}
}
});
/**
* ThinkEditor编辑器默认语言包
* 默认仅支持英文和简体中文语言包
* 其他语言包可以通过 $.thinkeditor.laguage() 方法扩展
*/
$.thinkeditor.language({
/* 英文语言包 */
"en-us" : {
/* 工具栏语言 */
"h1" : "H1 (Ctrl+1)",
"h2" : "H2 (Ctrl+2)",
"h3" : "H3 (Ctrl+3)",
"h4" : "H4 (Ctrl+4)",
"h5" : "H5 (Ctrl+5)",
"h6" : "H6 (Ctrl+6)",
"link" : "Link (Ctrl+L)",
"image" : "Image (Ctrl+P)",
"bold" : "Blod (Ctrl+B)",
"italic" : "Italic (Ctrl+I)",
"code" : "Code (Ctrl+D)",
"ul" : "Unordered List (Ctrl+U)",
"ol" : "Ordered List (Ctrl+O)",
"blockquote" : "Blockquote (Ctrl+Q)",
"hr" : "Horizontal Rule (Ctrl+H)",
"fullscreen" : "Full Screen (Ctrl+F)",
"save" : "Save (Ctrl+S)",
/* 弹出层语言 */
"ok" : "OK",
"cancel" : "Cancel",
/* 图片插件语言 */
"image-title" : "Insert Image",
"image-text" : "Drag the image to here"
},
/* 简体中文语言包 */
"zh-cn" : {
/* 工具栏语言 */
"h1" : "标题一 (Ctrl+1)",
"h2" : "标题二 (Ctrl+2)",
"h3" : "标题三 (Ctrl+3)",
"h4" : "标题四 (Ctrl+4)",
"h5" : "标题五 (Ctrl+5)",
"h6" : "标题六 (Ctrl+6)",
"link" : "链接 (Ctrl+L)",
"image" : "图片 (Ctrl+P)",
"bold" : "加粗 (Ctrl+B)",
"italic" : "斜体 (Ctrl+I)",
"code" : "代码 (Ctrl+D)",
"ul" : "无序列表 (Ctrl+U)",
"ol" : "有序列表 (Ctrl+O)",
"blockquote" : "引用 (Ctrl+Q)",
"hr" : "分割线 (Ctrl+H)",
"fullscreen" : "全屏编辑 (Ctrl+F)",
"save" : "保存 (Ctrl+S)",
/* 弹出层语言 */
"ok" : "确定",
"cancel" : "取消",
/* 图片插件语言 */
"image-title" : "插入图片",
"image-text" : "拖动图片到这里上传"
}
});
}(jQuery);