1
0

markdown.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. function showError($msg,$id) {
  2. if(!$id){
  3. $id = "#form-error-message"
  4. }
  5. $($id).addClass("error-message").removeClass("success-message").text($msg);
  6. return false;
  7. }
  8. function showSuccess($msg,$id) {
  9. if(!$id){
  10. $id = "#form-error-message"
  11. }
  12. $($id).addClass("success-message").removeClass("error-message").text($msg);
  13. return true;
  14. }
  15. $(function () {
  16. window.addDocumentModalFormHtml = $(this).find("form").html();
  17. window.editor = editormd("docEditor", {
  18. width : "100%",
  19. height : "100%",
  20. path : "/static/editor.md/lib/",
  21. toolbar : true,
  22. placeholder: "本编辑器支持Markdown编辑,左边编写,右边预览",
  23. imageUpload: true,
  24. imageFormats: ["jpg", "jpeg", "gif", "png", "JPG", "JPEG", "GIF", "PNG"],
  25. imageUploadURL: window.imageUploadURL ,
  26. toolbarModes : "full",
  27. fileUpload: true,
  28. fileUploadURL : window.fileUploadURL,
  29. taskList : true,
  30. flowChart : true,
  31. htmlDecode : "style,script,iframe,title,onmouseover,onmouseout,style",
  32. lineNumbers : false,
  33. tocStartLevel : 1,
  34. tocm : true,
  35. saveHTMLToTextarea : true,
  36. onload : function() {
  37. this.hideToolbar();
  38. var $select_node_id = window.treeCatalog.get_selected();
  39. if($select_node_id) {
  40. var $select_node = window.treeCatalog.get_node($select_node_id[0])
  41. if ($select_node) {
  42. $select_node.node = {
  43. id: $select_node.id
  44. };
  45. loadDocument($select_node);
  46. }
  47. }
  48. },
  49. onchange : function () {
  50. resetEditorChanged(true);
  51. }
  52. });
  53. editormd.loadPlugin("/static/editor.md/plugins/file-dialog/file-dialog");
  54. /**
  55. * 实现标题栏操作
  56. */
  57. $("#editormd-tools").on("click","a[class!='disabled']",function () {
  58. var name = $(this).find("i").attr("name");
  59. if(name === "attachment"){
  60. window.editor.fileDialog();
  61. }else if(name === "history"){
  62. }else if(name === "save"){
  63. saveDocument(false);
  64. }else if(name === "sidebar"){
  65. $("#manualCategory").toggle(0,"swing",function () {
  66. var $then = $("#manualEditorContainer");
  67. var left = parseInt($then.css("left"));
  68. if(left > 0){
  69. window.editorContainerLeft = left;
  70. $then.css("left","0");
  71. }else{
  72. $then.css("left",window.editorContainerLeft + "px");
  73. }
  74. window.editor.resize();
  75. });
  76. }else if(name === "release"){
  77. }else if(name === "tasks") {
  78. //插入GFM任务列表
  79. var cm = window.editor.cm;
  80. var selection = cm.getSelection();
  81. if (selection === "") {
  82. cm.replaceSelection("- [x] " + selection);
  83. }
  84. else {
  85. var selectionText = selection.split("\n");
  86. for (var i = 0, len = selectionText.length; i < len; i++) {
  87. selectionText[i] = (selectionText[i] === "") ? "" : "- [x] " + selectionText[i];
  88. }
  89. cm.replaceSelection(selectionText.join("\n"));
  90. }
  91. }else {
  92. var action = window.editor.toolbarHandlers[name];
  93. if (action !== "undefined") {
  94. $.proxy(action, window.editor)();
  95. window.editor.focus();
  96. }
  97. }
  98. }) ;
  99. //实现小提示
  100. $("[data-toggle='tooltip']").hover(function () {
  101. var title = $(this).attr('data-title');
  102. var direction = $(this).attr("data-direction");
  103. var tips = 3;
  104. if(direction === "top"){
  105. tips = 1;
  106. }else if(direction === "right"){
  107. tips = 2;
  108. }else if(direction === "bottom"){
  109. tips = 3;
  110. }else if(direction === "left"){
  111. tips = 4;
  112. }
  113. index = layer.tips(title, this, {
  114. tips: tips
  115. });
  116. }, function () {
  117. layer.close(index);
  118. });
  119. $("#btnAddDocument").on("click",function () {
  120. $("#addDocumentModal").modal("show");
  121. });
  122. $("#addDocumentModal").on("hidden.bs.modal",function () {
  123. $(this).find("form").html(window.addDocumentModalFormHtml);
  124. }).on("shown.bs.modal",function () {
  125. $(this).find("input[name='doc_name']").focus();
  126. });
  127. /***
  128. * 加载指定的文档到编辑器中
  129. * @param $node
  130. */
  131. function loadDocument($node) {
  132. var index = layer.load(1, {
  133. shade: [0.1,'#fff'] //0.1透明度的白色背景
  134. });
  135. $.get(window.editURL + $node.node.id ).done(function (res) {
  136. layer.close(index);
  137. resetEditor();
  138. if(res.errcode === 0){
  139. window.isLoad = true;
  140. window.editor.insertValue(res.data.markdown);
  141. window.editor.setCursor({line:0, ch:0});
  142. var node = { "id" : res.data.doc_id,'parent' : res.data.parent_id === 0 ? '#' : res.data.parent_id ,"text" : res.data.doc_name,"identify" : res.data.identify,"version" : res.data.version};
  143. pushDocumentCategory(node);
  144. }else{
  145. layer.msg("文档加载失败");
  146. }
  147. }).fail(function () {
  148. layer.close(index);
  149. layer.msg("文档加载失败");
  150. });
  151. }
  152. /**
  153. * 创建文档
  154. */
  155. function openCreateCatalogDialog($node) {
  156. var $then = $("#addDocumentModal");
  157. var doc_id = $node ? $node.id : 0;
  158. $then.find("input[name='parent_id']").val(doc_id);
  159. $then.modal("show");
  160. }
  161. /**
  162. * 将一个节点推送到现有数组中
  163. * @param $node
  164. */
  165. function pushDocumentCategory($node) {
  166. for (var index in window.documentCategory){
  167. var item = window.documentCategory[index];
  168. if(item.id === $node.id){
  169. window.documentCategory[index] = $node;
  170. console.log( window.documentCategory[index]);
  171. return;
  172. }
  173. }
  174. window.documentCategory.push($node);
  175. }
  176. /**
  177. * 打开文档编辑界面
  178. * @param $node
  179. */
  180. function openEditCatalogDialog($node) {
  181. var $then = $("#addDocumentModal");
  182. var doc_id = parseInt($node ? $node.id : 0);
  183. var text = $node ? $node.text : '';
  184. var parentId = $node && $node.parent !== '#' ? $node.parent : 0;
  185. $then.find("input[name='doc_id']").val(doc_id);
  186. $then.find("input[name='parent_id']").val(parentId);
  187. $then.find("input[name='doc_name']").val(text);
  188. for (var index in window.documentCategory){
  189. var item = window.documentCategory[index];
  190. if(item.id === doc_id){
  191. $then.find("input[name='doc_identify']").val(item.identify);
  192. break;
  193. }
  194. }
  195. $then.modal({ show : true });
  196. }
  197. /**
  198. * 删除一个文档
  199. * @param $node
  200. */
  201. function openDeleteDocumentDialog($node) {
  202. var index = layer.confirm('你确定要删除该文档吗?', {
  203. btn: ['确定','取消'] //按钮
  204. }, function(){
  205. $.post(window.deleteURL,{"identify" : window.book.identify,"doc_id" : $node.id}).done(function (res) {
  206. layer.close(index);
  207. if(res.errcode === 0){
  208. window.treeCatalog.delete_node($node);
  209. resetEditor($node);
  210. }else{
  211. layer.msg("删除失败",{icon : 2})
  212. }
  213. }).fail(function () {
  214. layer.close(index);
  215. layer.msg("删除失败",{icon : 2})
  216. });
  217. });
  218. }
  219. function saveDocument($is_cover) {
  220. var index = null;
  221. var node = window.treeCatalog.get_selected();
  222. var content = window.editor.getMarkdown();
  223. var html = window.editor.getPreviewedHTML();
  224. var version = "";
  225. if(content === ""){
  226. resetEditorChanged(false);
  227. return;
  228. }
  229. if(!node){
  230. layer.msg("获取当前文档信息失败");
  231. return;
  232. }
  233. var doc_id = parseInt(node[0]);
  234. for(var i in window.documentCategory){
  235. var item = window.documentCategory[i];
  236. if(item.id === doc_id){
  237. version = item.version;
  238. console.log(item)
  239. break;
  240. }
  241. }
  242. $.ajax({
  243. beforeSend : function () {
  244. index = layer.load(1, {shade: [0.1,'#fff'] });
  245. },
  246. url : window.editURL,
  247. data : {"identify" : window.book.identify,"doc_id" : node[0],"markdown" : content,"html" : html,"cover" : $is_cover ? "yes":"no","version": version},
  248. type :"post",
  249. dataType :"json",
  250. success : function (res) {
  251. layer.close(index);
  252. if(res.errcode === 0){
  253. resetEditorChanged(false);
  254. for(var i in window.documentCategory){
  255. var item = window.documentCategory[i];
  256. if(item.id === doc_id){
  257. window.documentCategory[i].version = res.data.version;
  258. break;
  259. }
  260. }
  261. }else if(res.errcode === 6005){
  262. var confirmIndex = layer.confirm('你确定要删除该文档吗?', {
  263. btn: ['确定','取消'] //按钮
  264. }, function(){
  265. layer.close(confirmIndex);
  266. saveDocument(true);
  267. });
  268. }else{
  269. layer.msg(res.message);
  270. }
  271. }
  272. });
  273. }
  274. function resetEditor($node) {
  275. }
  276. function resetEditorChanged($is_change) {
  277. if($is_change && !window.isLoad ){
  278. $("#markdown-save").removeClass('disabled').addClass('change');
  279. }else{
  280. $("#markdown-save").removeClass('change').addClass('disabled');
  281. }
  282. window.isLoad = false;
  283. }
  284. /**
  285. * 添加顶级文档
  286. */
  287. $("#addDocumentForm").ajaxForm({
  288. beforeSubmit : function () {
  289. var doc_name = $.trim($("#documentName").val());
  290. if (doc_name === ""){
  291. return showError("目录名称不能为空","#add-error-message")
  292. }
  293. window.addDocumentFormIndex = layer.load(1, { shade: [0.1,'#fff'] });
  294. return true;
  295. },
  296. success : function (res) {
  297. if(res.errcode === 0){
  298. var data = { "id" : res.data.doc_id,'parent' : res.data.parent_id === 0 ? '#' : res.data.parent_id ,"text" : res.data.doc_name,"identify" : res.data.identify,"version" : res.data.version};
  299. var node = window.treeCatalog.get_node(data.id);
  300. if(node){
  301. window.treeCatalog.rename_node({"id":data.id},data.text);
  302. }else {
  303. window.treeCatalog.create_node(data.parent, data);
  304. window.treeCatalog.deselect_all();
  305. window.treeCatalog.select_node(data);
  306. }
  307. pushDocumentCategory(data);
  308. $("#markdown-save").removeClass('change').addClass('disabled');
  309. $("#addDocumentModal").modal('hide');
  310. }else{
  311. showError(res.message,"#add-error-message")
  312. }
  313. layer.close(window.addDocumentFormIndex);
  314. }
  315. });
  316. /**
  317. * 文档目录树
  318. */
  319. $("#sidebar").jstree({
  320. 'plugins': ["wholerow", "types", 'dnd', 'contextmenu'],
  321. "types": {
  322. "default": {
  323. "icon": false // 删除默认图标
  324. }
  325. },
  326. 'core': {
  327. 'check_callback': true,
  328. "multiple": false,
  329. 'animation': 0,
  330. "data": window.documentCategory
  331. },
  332. "contextmenu": {
  333. show_at_node: false,
  334. select_node: false,
  335. "items": {
  336. "添加文档": {
  337. "separator_before": false,
  338. "separator_after": true,
  339. "_disabled": false,
  340. "label": "添加文档",
  341. "icon": "fa fa-plus",
  342. "action": function (data) {
  343. var inst = $.jstree.reference(data.reference),
  344. node = inst.get_node(data.reference);
  345. openCreateCatalogDialog(node);
  346. }
  347. },
  348. "编辑": {
  349. "separator_before": false,
  350. "separator_after": true,
  351. "_disabled": false,
  352. "label": "编辑",
  353. "icon": "fa fa-edit",
  354. "action": function (data) {
  355. var inst = $.jstree.reference(data.reference);
  356. var node = inst.get_node(data.reference);
  357. openEditCatalogDialog(node);
  358. }
  359. },
  360. "删除": {
  361. "separator_before": false,
  362. "separator_after": true,
  363. "_disabled": false,
  364. "label": "删除",
  365. "icon": "fa fa-trash-o",
  366. "action": function (data) {
  367. var inst = $.jstree.reference(data.reference);
  368. var node = inst.get_node(data.reference);
  369. openDeleteDocumentDialog(node);
  370. }
  371. }
  372. }
  373. }
  374. }).on('loaded.jstree', function () {
  375. window.treeCatalog = $(this).jstree();
  376. });
  377. });