CodeEditor.js 5.2 KB

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