1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/dot2-com-Dot2Editor

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
dot2.editor.js 22 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
noxue Отправлено 07.12.2020 04:21 fc6c132
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
!(function ($) {
//加载必须的js
loadScript();
window.Dot2Editor = function (selector, opts) {
$(selector).append('<div class="dot2editor"><ul class="toolbar"></ul><div class="editor-container"><div class="editor-column"><div class="panel-editor"><div class="editor-content"></div></div></div><div class="preview-column"><div class="panel-preview"><div class="preview markdown-body"></div></div><div class="close-preview"><i class="fa fa-close"></i></div></div><div style="clear:both;height:0; width:100%;"></div></div></div>');
//下面是绑定到对象中的方法
this.addCommand = addCommand;
//添加一个菜单
this.addMenu = addMenu;
this.getMarkdown = getMarkdown;
this.setMarkdown = setMarkdown;
this.getHtml = getHtml;
//保存菜单
var menus = {};
//保存配置信息
var config = opts || {};
//ace编辑器实例
var editor = null;
//是否全屏预览
var isFullPrev = false;
//是否开启编辑,当预览效果的时候隐藏编辑区域。
var isFullEdit = false;
//因为ace编辑器要求指定id来创建,考虑到同一个网页可能多个编辑器,所以就用唯一标识符来表示当前的编辑器
var ace_editor_id = "ace_editor-" + uuid();
//给ace编辑器设置唯一的id属性,用于创建ace编辑器
$(selector + " .editor-content").attr("id", ace_editor_id);
//编辑器id
var editor_id = "dot2editor-" + uuid();
//给编辑器设置唯一id,用于后面获取编辑器中的其他元素
$(selector + " .dot2editor").attr("id", editor_id);
//工具栏节点
var toolbarNode = $("#" + editor_id + ">.toolbar");
//初始化编辑器
initMenus();
//初始化编辑器
initEditor();
/**
* 初始化操作
*/
function initEditor() {
//创建ace编辑器实例
editor = ace.edit(ace_editor_id);
editor.setTheme('ace/theme/xcode');
editor.getSession().setMode('ace/mode/markdown');
editor.renderer.setShowPrintMargin(false);
editor.setHighlightGutterLine(false);
editor.setFontSize(16);
editor.setOptions({
wrap: "free" //自动换行
});
//阻止控制台的警告信息
editor.$blockScrolling = Infinity;
//让选中的行不高亮
editor.setHighlightActiveLine(false);
//初始化内容改变相关的操作
initChange();
//绑定滚动鼠标和Alt + - 改变文字大小
bindChangeFontSize();
//如果配置了上传文件,就绑定拖拽和粘贴上传文件
if (config.upload) {
bindDrag();
bindPaste();
}
//绑定默认的命令,比如Alt+s保存
bindCommands();
//添加默认的菜单
addMenus();
}
//更新内容到预览窗口和textarea
function editorChange() {
//记录编辑器中是否存在textarea
var hasTextarea = $(selector + ">textarea").length > 0;
$(selector + " .preview").html(getHtml());
if (hasTextarea) {
$(selector + ">textarea").val(editor.getValue());
}
}
function initChange() {
//记录编辑器中是否存在textarea
var hasTextarea = $(selector + ">textarea").length > 0;
if (hasTextarea) {
$(selector + ">textarea").css('display', 'none');
editor.insert($(selector + ">textarea").val());
editorChange(); //插入后更新渲染
}
//编辑器内容改变
editor.on("change", editorChange);
}
function setMarkdown(markdownContent){
editor.insert($(selector + ">textarea").val());
editorChange(); //插入后更新渲染
}
function getMarkdown() {
return editor.getValue();
}
//获取处理后的html
function getHtml() {
return md2html(getMarkdown());
}
//绑定快捷命令
function addCommand(command) {
editor.commands.addCommand(command);
}
function initMenus() {
addMenu({
name: "bold",
readOnly: true,
ele: '<li><i class="fa fa-bold"></i></li>',
exec: function (editor) {
var v = editor.getSelectedText();
if (v == "") {
var p = editor.getCursorPosition();
editor.insert("****");
p.column += 2;
editor.moveCursorToPosition(p);
} else {
editor.insert("**" + v + "**");
}
}
});
for (var i = 1; i < 7; i++) {
(function (i) {
addMenu({
name: "h" + i,
readOnly: true,
ele: '<li><b>H' + i + '</b></li>',
exec: function (editor) {
//移到行首
editor.navigateLineStart();
editor.insert(repeat("#", i) + " ");
//移到行尾
editor.navigateLineEnd();
}
});
})(i);
}
addMenu({
name: "link",
readOnly: true,
ele: '<li><i class="fa fa-link"></i></li>',
exec: function (editor) {
var p = editor.getCursorPosition();
var v = editor.getSelectedText();
if (v == "") {
editor.insert("[]()");
p.column += 1;
editor.moveCursorToPosition(p);
} else {
//删除原有内容,然后添加组合的内容
editor.remove();
//获取最新的位置
p = editor.getCursorPosition();
//计算输入链接的坐标位置
p.column += (3 + v.length);
editor.insert("[" + v + "]()");
//让光标移动到填写链接的地方
editor.moveCursorToPosition(p);
}
}
});
addMenu({
name: "img",
readOnly: true,
ele: '<li><i class="fa fa-picture-o"></i></li>',
exec: function (editor) {
var p = editor.getCursorPosition();
editor.insert("![]()");
p.column += 4;
editor.moveCursorToPosition(p);
}
});
addMenu({
name: "hr",
readOnly: true,
ele: '<li><i class="fa fa-minus"></i></li>',
exec: function (editor) {
var p = editor.getCursorPosition();
editor.insert("***");
p.column += 3;
editor.moveCursorToPosition(p);
}
});
addMenu({
name: "edit",
readOnly: true,
ele: '<li><i class="fa fa-eye-slash"></i></li>',
exec: function (editor) {
if (!isFullEdit && !isFullPrev) { //如果不是全屏编辑并且不是全屏预览的时候,就全屏编辑
$("#" + editor_id + " .editor-column").css("width", "100%");
$("#" + editor_id + " .preview-column").hide();
isFullEdit = true;
} else {
$("#" + editor_id + " .editor-column").css("width", "50%");
$("#" + editor_id + " .preview-column").show(500);
isFullEdit = false;
}
editor.resize();
}
});
addMenu({
name: "preview",
readOnly: true,
ele: '<li><i class="fa fa-eye"></i></li>',
exec: function (editor) {
if (!isFullPrev) { //如果不是,就全屏预览
$("#" + editor_id + " .preview-column").css("width", "100%");
$("#" + editor_id + " .editor-column").hide();
(function () {
$("#" + editor_id + " .preview-column>.close-preview").css("display", "block").click(function () {
$(this).css("display", "none");
$("#" + editor_id + " .preview-column").css("width", "50%");
$("#" + editor_id + " .editor-column").show(200);
isFullPrev = false;
editor.focus();
});
})();
isFullPrev = true;
}
editor.resize();
}
});
addMenu({
name: "table",
readOnly: true,
ele: '<li><i class="fa fa-table"></i></li>',
exec: function (editor) {
var str = window.prompt("请输入行和列,用空格隔开,例如:3 5 就表示生成一个3行5列的表格");
if (!str) {
return;
}
var arr = str.split(/\s+/);
if (arr.length < 2) {
alert("请输入正确的行和列数据");
return;
}
var row = arr[0];
var column = arr[1];
editor.insert("|" + repeat("|", column - 2) + "\n" +
"-|-" + repeat("|-", column - 2) + "\n" +
"|" + repeat("|", column - 2) + "\n"
+ repeat("|" + repeat("|", column - 2) + "\n", row - 2));
}
});
addMenu({
name: "help",
readOnly: true,
ele: '<li><a href="https://gitee.com/dot2-com/Dot2Editor" style="color:#fff;" target="_blank"><i class="fa fa-question-circle"></i></a></li>',
exec: function (editor) {
}
});
}
//添加菜单
function addMenu(menu) {
menus[menu.name] = menu;
}
/**
* 添加所有的默认菜单
*/
function addMenus() {
for (var key in menus) {
var menu = menus[key];
(function (menu) {
var ele = $(menu.ele).attr("name", menu.name);
toolbarNode.append(ele);
toolbarNode.find("[name='" + menu.name + "']:first").click(function () {
//只读,则设置只读
if (menu.readOnly) {
editor.setReadOnly(true);
}
menu.exec(editor);
//只读,则需要解除只读
if (menu.readOnly) {
editor.setReadOnly(false);
}
//点击工具栏执行函数之后需要把焦点设置回编辑器
editor.focus();
});
})(menu);
}
}
function bindCommands() {
addCommand({
name: 'parse',
bindKey: {
win: 'Ctrl-S',
mac: 'Command-S'
},
exec: function (editor) {
console.log(editor.getValue());
},
readOnly: false // 如果不需要使用只读模式,这里设置false
});
//加粗
addCommand({
name: 'bold',
bindKey: {
win: 'Alt-B',
mac: 'Alt-B'
},
exec: function (editor) {
var v = editor.getSelectedText();
if (v == "") {
var p = editor.getCursorPosition();
editor.insert("****");
p.column += 2;
editor.moveCursorToPosition(p);
} else {
editor.insert("**" + v + "**");
}
},
readOnly: true // 如果不需要使用只读模式,这里设置false
});
//绑定h1-h6的快捷键
for (var i = 1; i < 7; i++) {
(function (i) {
addCommand({
name: 'H' + i,
bindKey: {
win: 'Alt-' + i,
mac: 'Alt-' + i
},
exec: function (editor) {
//移到行首
editor.navigateLineStart();
editor.insert(repeat("#", i) + " ");
//移到行尾
editor.navigateLineEnd();
},
readOnly: true // 如果不需要使用只读模式,这里设置false
});
})(i);
}
//a标签
addCommand({
name: 'a',
bindKey: {
win: 'Alt-A',
mac: 'Alt-A'
},
exec: function (editor) {
var p = editor.getCursorPosition();
var v = editor.getSelectedText();
if (v == "") {
editor.insert("[]()");
p.column += 1;
editor.moveCursorToPosition(p);
} else {
//删除原有内容,然后添加组合的内容
editor.remove();
//获取最新的位置
p = editor.getCursorPosition();
//计算输入链接的坐标位置
p.column += (3 + v.length);
editor.insert("[" + v + "]()");
//让光标移动到填写链接的地方
editor.moveCursorToPosition(p);
}
},
readOnly: true // 如果不需要使用只读模式,这里设置false
});
//img
addCommand({
name: 'img',
bindKey: {
win: 'Alt-I',
mac: 'Alt-I'
},
exec: function (editor) {
var p = editor.getCursorPosition();
editor.insert("![]()");
p.column += 4;
editor.moveCursorToPosition(p);
},
readOnly: true // 如果不需要使用只读模式,这里设置false
});
//hr
addCommand({
name: 'hr',
bindKey: {
win: 'Alt-H',
mac: 'Alt-H'
},
exec: function (editor) {
var p = editor.getCursorPosition();
editor.insert("***");
p.column += 3;
editor.moveCursorToPosition(p);
},
readOnly: true // 如果不需要使用只读模式,这里设置false
});
//line
addCommand({
name: 'line',
bindKey: {
win: 'Alt-L',
mac: 'Alt-L'
},
exec: function (editor) {
var p = editor.getCursorPosition();
editor.insert("---");
p.column += 3;
editor.moveCursorToPosition(p);
},
readOnly: true // 如果不需要使用只读模式,这里设置false
});
addCommand({
name: 'edit',
bindKey: {
win: 'Alt-E',
mac: 'Alt-E'
},
exec: function (editor) {
if (!isFullEdit && !isFullPrev) { //如果不是,就全屏编辑
$("#" + editor_id + " .editor-column").css("width", "100%");
$("#" + editor_id + " .preview-column").hide();
isFullEdit = true;
} else {
$("#" + editor_id + " .editor-column").css("width", "50%");
$("#" + editor_id + " .preview-column").show(500);
isFullEdit = false;
}
editor.resize();
},
readOnly: false // 如果不需要使用只读模式,这里设置false
});
addCommand({
name: 'preview',
bindKey: {
win: 'Alt-P',
mac: 'Alt-P'
},
exec: function (editor) {
if (!isFullPrev) { //如果不是,就全屏预览
$("#" + editor_id + " .preview-column").css("width", "100%");
$("#" + editor_id + " .editor-column").hide();
(function () {
$("#" + editor_id + " .preview-column>.close-preview").css("display", "block").click(function () {
$(this).css("display", "none");
$("#" + editor_id + " .preview-column").css("width", "50%");
$("#" + editor_id + " .editor-column").show(200);
isFullPrev = false;
editor.focus();
});
})();
isFullPrev = true;
}
editor.resize();
},
readOnly: false // 如果不需要使用只读模式,这里设置false
});
//table
addCommand({
name: 'table',
bindKey: {
win: 'Alt-T',
mac: 'Alt-T'
},
exec: function (editor) {
var str = window.prompt("请输入行和列,用空格隔开,例如:3 5 就表示生成一个3行5列的表格");
if (!str) {
return;
}
var arr = str.split(/\s+/);
if (arr.length < 2) {
alert("请输入正确的行和列数据");
return;
}
var row = arr[0];
var column = arr[1];
editor.insert("|" + repeat("|", column - 2) + "\n" +
"-|-" + repeat("|-", column - 2) + "\n" +
"|" + repeat("|", column - 2) + "\n"
+ repeat("|" + repeat("|", column - 2) + "\n", row - 2));
},
readOnly: true // 如果不需要使用只读模式,这里设置false
});
}
/**
* 绑定粘贴图片上传事件
*/
function bindPaste() {
//ace编辑器绑定粘贴事件,实现粘贴上传图片
window.document.getElementById(ace_editor_id).addEventListener("paste", function (e) {
var cbd = e.clipboardData;
var ua = window.navigator.userAgent;
// 如果是 Safari 直接 return
if (!(e.clipboardData && e.clipboardData.items)) {
return;
}
// Mac平台下Chrome49版本以下 复制Finder中的文件的Bug Hack掉
if (cbd.items && cbd.items.length === 2 && cbd.items[0].kind === "string" && cbd.items[1].kind === "file" &&
cbd.types && cbd.types.length === 2 && cbd.types[0] === "text/plain" && cbd.types[1] === "Files" &&
ua.match(/Macintosh/i) && Number(ua.match(/Chrome\/(\d{2})/i)[1]) < 49) {
return;
}
//如果在上传图片,不处理。
if (uploadStatus) {
return;
}
for (var i = 0; i < cbd.items.length; i++) {
var item = cbd.items[i];
if (item.kind == "file") {
var blob = item.getAsFile();
if (blob.size === 0) {
return;
}
// blob 就是从剪切板获得的文件 可以进行上传或其他操作
editor.setReadOnly(true);
uploadFile(blob);
}
}
}, false);
}
//记录图片上传状态,限制同时只能上传一个图片
var uploadStatus = false;
/**
* ajax方式上传图片
* @param file 文件的内容
*/
function uploadFile(file) {
uploadStatus = true;
var animateHtml = '<div class="dot2editor_upload_image_loader"></div>';
$("body").append($(animateHtml));
var formData = new FormData();
formData.append(config.upload.name, file);
if (config.upload.kvs) {
var kvs = config.upload.kvs;
//如果是一个函数,就调用并获取返回值,配置一个函数的区别是,每次都会调用
if (typeof kvs === "function") {
kvs = kvs();
//如果函数返回false,那就不需要上传
if (kvs == false) {
return;
}
}
//如果配置是合法的json对象
if (isJSON(kvs)) {
for (var k in kvs) {
formData.append(k, kvs[k]);
}
} else { //不合法,不上传
alert("上传文件配置中的内容必须是json对象");
return;
}
}
//上传文件
$.ajax({
url: config.upload.url,
type: 'POST',
data: formData,
// 告诉jQuery不要去处理发送的数据
processData: false,
// 告诉jQuery不要去设置Content-Type请求头
contentType: false,
success: function (res) {
res = JSON.parse(res)
if (res.code == 0) {
if (res.isImage) {
editor.insert("\n![" + res.alt + "](" + res.src + ")\n\n");
} else {
editor.insert("\n[" + res.alt + "](" + res.src + ")\n\n");
}
} else {
alert(res.errMsg);
}
editor.setReadOnly(false);
uploadStatus = false;
$(".dot2editor_upload_image_loader").remove();
},
error: function (responseStr) {
console.log(responseStr)
editor.setReadOnly(false);
uploadStatus = false;
$(".dot2editor_upload_image_loader").remove();
}
});
}
/**
* 改变文字大小
*/
function bindChangeFontSize() {
window.document.addEventListener('DOMContentLoaded', function (event) {
// chrome 浏览器直接加上下面这个样式就行了,但是ff不识别
window.document.body.style.zoom = 'reset';
window.document.addEventListener('keydown', function (event) {
if ((event.AltKey === true || event.metaKey === true)) {
var i = 0;
var stop = false; //是否阻止事件
if (event.which === 107 || event.which === 189) { //+
i++;
stop = true;
} else if (event.which === 109 || event.which === 187) { //-
i--;
stop = true;
}
editor.setFontSize(editor.getFontSize() + i);
//不是改变字体,就不阻止事件,否则复制粘贴之类的快捷键无法使用
if (stop) event.preventDefault();
}
}, false);
var EventUtil = {
addHandler: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, handler);
} else {
element['on' + type] = handler;
}
},
getEvent: function (event) {
return event ? event : window.event;
},
stopPropagation: function (event) {
event = event || window.event;
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
function handleMouseWheel(event) {
if (!(event.AltKey === true || event.metaKey === true)) return;
EventUtil.stopPropagation(event);
event = EventUtil.getEvent(event);
var value = event.wheelDelta || -event.detail;
var delta = Math.max(-1, Math.min(1, value));
var i = 0;
if (delta > 0) { //+
i++;
} else { //-
i--;
}
editor.setFontSize(editor.getFontSize() + i);
event.preventDefault();
}
EventUtil.addHandler(window.document, 'mousewheel', handleMouseWheel);
EventUtil.addHandler(window.document, 'DOMMouseScroll', handleMouseWheel);
}, false);
}
/**
* 拖拽上传
*/
function bindDrag() {
var obj = document.getElementById(editor_id);
obj.addEventListener("dragenter", handler, false);
obj.addEventListener("dragover", handler, false);
obj.addEventListener("drop", upload, false);
function upload(e) {
var e = e || window.event;
handler(e);
var files = e.dataTransfer.files;
for (var i = 0, il = files.length; i < il; i++) {
//如果是文件夹,就不处理
if (files[i].size == 0) continue;
uploadFile(files[i]);
}
}
function handler(e) {
var e = e || window.event;
e.preventDefault ? e.preventDefault() : e.returnValue = false;
e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
}
}
};
window.Dot2Editor.parse=function(selector){
var html = md2html($(selector+">textarea:first").val());
$(selector).html(html);
};
window.Dot2Editor.md2html=function(markdownContent){
return md2html(markdownContent);
};
/**
* 加载编辑器依赖的 ace 和 markd
*/
function loadScript() {
var tmp_node = 'script_dot2_' + uuid();
window.document.write('<script id="' + tmp_node + '"></script>')
var thisNode = $("#" + tmp_node).prev("script");
$('#' + tmp_node).remove();
//引入js不能写死,防止编辑器放到二级目录下
var path = $(thisNode).attr("src");
path = path.substring(0, path.lastIndexOf('/'));
$(thisNode).before($('<script src="' + path + '/libs/marked.min.js"></script>'));
$(thisNode).before($('<link rel="stylesheet" href="' + path + '/css/font-awesome.min.css">'));
$(thisNode).before($('<link rel="stylesheet" href="' + path + '/css/dot2.editor.css">'));
$(thisNode).before($('<link rel="stylesheet" href="' + path + '/css/markdown.css">'));
//语法高亮
$(thisNode).before($('<script src="' + path + '/libs/highlight/highlight.min.js"></script>'));
$(thisNode).before($('<link rel="stylesheet" href="' + path + '/libs/highlight/styles/github.css">'));
hljs.initHighlightingOnLoad();
$(thisNode).before($('<script src="' + path + '/libs/ace/ace.js"></script>'));
}
function md2html(md){
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
tables: true,
breaks: true,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: false,
highlight: function (code) {
return hljs.highlightAuto(code).value;
}
});//基本设置
return marked(md);
}
//下面放一些工具函数
function uuid() {
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
//判断是否是json对象
function isJSON(obj) {
var isjson = typeof(obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && !obj.length;
return isjson;
}
function repeat(target, n) {
return (new Array(n + 1)).join(target);
}
})($);

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/dot2-com-Dot2Editor.git
git@api.gitlife.ru:oschina-mirror/dot2-com-Dot2Editor.git
oschina-mirror
dot2-com-Dot2Editor
dot2-com-Dot2Editor
master