CodeEditor.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. class CodeEditor {
  2. constructor() { }
  3. dataID = "";
  4. set dataType(value) {
  5. this._dataType = value;
  6. if (value == 0) {
  7. this.language = "html";
  8. } else if (value == 1 || value == 2) {
  9. this.language = "css";
  10. } else if (value == 3) {
  11. this.language = "javascript";
  12. } else if (value == 4) {
  13. this.language = "json";
  14. }
  15. if (this.editor) {
  16. let model = this.editor.getModel();
  17. monaco.editor.setModelLanguage(model, this.language);
  18. }
  19. }
  20. /**
  21. * 初始化编辑器
  22. * @param {*} container 创建编辑器的主容器,通常为DIV
  23. * @param {*} language 编辑器支持的语言,html,css,javascript三选一
  24. * @param {*} contextmenu 是否开启鼠标右键菜单,默认false
  25. * @param {*} minimap 是否开启缩略图,默认false
  26. * @param {*} btnItems 自定义按钮,格式为[{name: "自定义按钮", callback: function(){}}]
  27. * @param {*} showSupplementCodeList 是否显示补充代码列表,默认false
  28. */
  29. InitEditor(
  30. container,
  31. contextmenu = true,
  32. minimap = false,
  33. btnItems = [],
  34. showSupplementCodeList = false
  35. ) {
  36. let _this = this;
  37. this.container = container;
  38. this.showSupplementCodeList = showSupplementCodeList;
  39. if (!container) {
  40. throw new Error("codeEditor.InitEditor()必须传入container参数");
  41. }
  42. //初始化容器
  43. let html = ``;
  44. if (this.showSupplementCodeList) {
  45. html = `<div id="supplementCodeList" style="overflow: auto;height:calc(50% - 50px);"></div>
  46. <div style="width:100%;height:50%;">
  47. <div id="html_editor" style="height:100%;border: 1px solid #d4d4d4;"></div>
  48. </div>`;
  49. } else {
  50. html = `<div style="width:100%;height:100%;">
  51. <div id="html_editor" style="height:100%;border: 1px solid #d4d4d4;"></div>
  52. </div>`;
  53. }
  54. this.container.innerHTML = html;
  55. btnItems.forEach((btnItem) => {
  56. let btn = document.createElement("button");
  57. btn.classList.add("code-btn");
  58. container.appendChild(btn);
  59. btn.innerText = btnItem.name;
  60. btn.onclick = function (e) {
  61. btnItem.callback(
  62. e,
  63. _this._dataType,
  64. _this.dataID,
  65. _this.editor.getValue(),
  66. _this.oldData
  67. );
  68. };
  69. });
  70. //#region 初始化编辑器
  71. this.waitShowCode = "";
  72. let editorContainer = this.container.querySelector(`#html_editor`);
  73. require.config({ "vs/nls": { availableLanguages: { "*": "zh-cn" } } });
  74. require.config({
  75. paths: { vs: "../../lib/zlExpressEditor/monaco-editor/min/vs" },
  76. });
  77. require(["vs/editor/editor.main"], function () {
  78. _this.editor = monaco.editor.create(editorContainer, {
  79. language: _this.language ?? "html",
  80. value: "",
  81. // automaticLayout: true,
  82. minimap: {
  83. enabled: minimap,
  84. },
  85. contextmenu: contextmenu,
  86. });
  87. let editorModel = _this.editor.getModel();
  88. editorModel.setValue(_this.waitShowCode);
  89. _this.editor.getAction("editor.action.formatDocument").run();
  90. });
  91. }
  92. /**
  93. * 设置编辑器代码
  94. * @param {*} code 代码
  95. */
  96. SetCode(code) {
  97. if (this.editor) {
  98. let editorModel = this.editor.getModel();
  99. editorModel.setValue(code ?? "");
  100. // this.editor.getAction("editor.action.formatDocument").run();
  101. } else {
  102. this.waitShowCode = code ?? "";
  103. }
  104. }
  105. /**获取代码 */
  106. GetCode() {
  107. return this.editor.getValue();
  108. }
  109. #decorationsIds = [];
  110. CreateHighlight({ startLine, startColumn, endLine, endColumn }) {
  111. // 创建装饰
  112. const decorations = [
  113. {
  114. range: new monaco.Range(startLine, startColumn, endLine, endColumn),
  115. options: {
  116. isWholeLine: false,
  117. className: "monaco-highlight",
  118. },
  119. },
  120. ];
  121. // 添加装饰并保存 ID
  122. let decorationsIds = this.editor.deltaDecorations([], decorations);
  123. this.#decorationsIds.push(...decorationsIds);
  124. // 确保装饰的范围滚动到视图中
  125. const rangeToReveal = new monaco.Range(startLine, startColumn, endLine, endColumn);
  126. this.editor.revealRangeInCenterIfOutsideViewport(rangeToReveal);
  127. // 返回取消装饰的回调函数
  128. return () => {
  129. this.#decorationsIds = this.#decorationsIds.filter(id => !decorationsIds.includes(id));
  130. this.editor.deltaDecorations(decorationsIds, []); // 取消装饰
  131. };
  132. }
  133. RemoveAllHighlight() {
  134. this.editor.deltaDecorations(this.#decorationsIds, []);
  135. }
  136. }
  137. window.CodeEditor = CodeEditor;