@xcanwin/manyoyo 5.8.10 → 5.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -352,6 +352,20 @@ textarea:focus-visible {
352
352
  white-space: pre-wrap;
353
353
  }
354
354
 
355
+ .link-confirm-url {
356
+ margin-top: 2px;
357
+ padding: 12px 14px;
358
+ border: 1px solid rgba(146, 100, 42, 0.18);
359
+ border-radius: 10px;
360
+ background: #fff8ef;
361
+ color: var(--text);
362
+ font-family: var(--font-mono);
363
+ font-size: 12px;
364
+ line-height: 1.6;
365
+ word-break: break-all;
366
+ user-select: text;
367
+ }
368
+
355
369
  .config-editor {
356
370
  width: 100%;
357
371
  min-height: 340px;
@@ -1126,6 +1140,177 @@ body.mobile-actions-open .header-actions {
1126
1140
  background: #131923;
1127
1141
  }
1128
1142
 
1143
+ .files-pane {
1144
+ min-height: 0;
1145
+ border: 1px solid var(--line);
1146
+ border-radius: 14px;
1147
+ overflow: hidden;
1148
+ background:
1149
+ linear-gradient(180deg, rgba(255, 255, 255, 0.88) 0%, rgba(252, 246, 236, 0.88) 100%);
1150
+ }
1151
+
1152
+ .files-browser {
1153
+ height: 100%;
1154
+ min-height: 0;
1155
+ display: grid;
1156
+ grid-template-rows: auto minmax(0, 1fr);
1157
+ }
1158
+
1159
+ .files-toolbar {
1160
+ display: flex;
1161
+ align-items: center;
1162
+ gap: 8px;
1163
+ padding: 12px 14px;
1164
+ border-bottom: 1px solid var(--line);
1165
+ background: rgba(255, 251, 244, 0.96);
1166
+ }
1167
+
1168
+ .files-toolbar-path {
1169
+ flex: 1;
1170
+ min-width: 0;
1171
+ padding: 8px 10px;
1172
+ border: 1px solid rgba(181, 146, 99, 0.35);
1173
+ border-radius: 10px;
1174
+ background: #fffdf9;
1175
+ color: var(--text);
1176
+ font-family: var(--font-mono);
1177
+ font-size: 12px;
1178
+ line-height: 1.5;
1179
+ word-break: break-all;
1180
+ }
1181
+
1182
+ .files-toolbar-status {
1183
+ color: var(--muted);
1184
+ font-size: 12px;
1185
+ }
1186
+
1187
+ .files-layout {
1188
+ min-height: 0;
1189
+ display: grid;
1190
+ grid-template-columns: minmax(240px, 320px) minmax(0, 1fr);
1191
+ }
1192
+
1193
+ .files-sidebar {
1194
+ min-height: 0;
1195
+ border-right: 1px solid var(--line);
1196
+ background: rgba(255, 251, 244, 0.84);
1197
+ overflow: auto;
1198
+ }
1199
+
1200
+ .files-list {
1201
+ display: flex;
1202
+ flex-direction: column;
1203
+ gap: 6px;
1204
+ padding: 12px;
1205
+ }
1206
+
1207
+ .files-entry {
1208
+ width: 100%;
1209
+ display: flex;
1210
+ align-items: center;
1211
+ justify-content: space-between;
1212
+ gap: 10px;
1213
+ padding: 10px 12px;
1214
+ border: 1px solid rgba(181, 146, 99, 0.28);
1215
+ border-radius: 12px;
1216
+ background: rgba(255, 255, 255, 0.92);
1217
+ color: var(--text);
1218
+ text-align: left;
1219
+ cursor: pointer;
1220
+ }
1221
+
1222
+ .files-entry.is-active {
1223
+ border-color: rgba(120, 78, 27, 0.45);
1224
+ background: rgba(255, 244, 224, 0.9);
1225
+ }
1226
+
1227
+ .files-entry-name {
1228
+ min-width: 0;
1229
+ display: flex;
1230
+ flex-direction: column;
1231
+ gap: 0;
1232
+ }
1233
+
1234
+ .files-entry-title {
1235
+ font-size: 13px;
1236
+ font-weight: 600;
1237
+ word-break: break-word;
1238
+ }
1239
+
1240
+ .files-entry-meta {
1241
+ color: var(--muted);
1242
+ font-size: 11px;
1243
+ white-space: nowrap;
1244
+ }
1245
+
1246
+ .files-preview {
1247
+ min-height: 0;
1248
+ display: grid;
1249
+ grid-template-rows: auto minmax(0, 1fr);
1250
+ }
1251
+
1252
+ .files-preview-head {
1253
+ display: flex;
1254
+ flex-direction: column;
1255
+ gap: 6px;
1256
+ padding: 12px 14px;
1257
+ border-bottom: 1px solid var(--line);
1258
+ background: rgba(255, 251, 244, 0.96);
1259
+ }
1260
+
1261
+ .files-preview-title {
1262
+ font-family: var(--font-display);
1263
+ font-size: 15px;
1264
+ font-weight: 700;
1265
+ }
1266
+
1267
+ .files-preview-meta {
1268
+ color: var(--muted);
1269
+ font-size: 12px;
1270
+ word-break: break-all;
1271
+ }
1272
+
1273
+ .files-preview-body {
1274
+ min-height: 0;
1275
+ overflow: auto;
1276
+ padding: 14px;
1277
+ }
1278
+
1279
+ .files-empty,
1280
+ .files-note {
1281
+ padding: 18px;
1282
+ border: 1px dashed rgba(181, 146, 99, 0.45);
1283
+ border-radius: 12px;
1284
+ background: rgba(255, 255, 255, 0.7);
1285
+ color: var(--muted);
1286
+ line-height: 1.6;
1287
+ }
1288
+
1289
+ .files-pre {
1290
+ margin: 0;
1291
+ white-space: pre-wrap;
1292
+ word-break: break-word;
1293
+ font-family: var(--font-mono);
1294
+ font-size: 12px;
1295
+ line-height: 1.6;
1296
+ }
1297
+
1298
+ .files-editor-host {
1299
+ min-height: 100%;
1300
+ }
1301
+
1302
+ .files-editor-host .cm-editor {
1303
+ height: 100%;
1304
+ border: 1px solid rgba(181, 146, 99, 0.32);
1305
+ border-radius: 12px;
1306
+ overflow: hidden;
1307
+ background: rgba(255, 255, 255, 0.94);
1308
+ }
1309
+
1310
+ .files-editor-host .cm-scroller {
1311
+ font-family: var(--font-mono);
1312
+ }
1313
+
1129
1314
  .inspector-pane {
1130
1315
  overflow-y: auto;
1131
1316
  padding: 0;
@@ -1925,7 +2110,7 @@ details.trace-card > .trace-card-summary {
1925
2110
 
1926
2111
  .workbench-tabs {
1927
2112
  display: grid;
1928
- grid-template-columns: repeat(5, minmax(0, 1fr));
2113
+ grid-template-columns: repeat(6, minmax(0, 1fr));
1929
2114
  gap: 6px;
1930
2115
  }
1931
2116
 
@@ -1939,6 +2124,16 @@ details.trace-card > .trace-card-summary {
1939
2124
  align-items: flex-start;
1940
2125
  }
1941
2126
 
2127
+ .files-layout {
2128
+ grid-template-columns: minmax(0, 1fr);
2129
+ grid-template-rows: minmax(180px, 38%) minmax(0, 1fr);
2130
+ }
2131
+
2132
+ .files-sidebar {
2133
+ border-right: 0;
2134
+ border-bottom: 1px solid var(--line);
2135
+ }
2136
+
1942
2137
  .composer-toolbar-meta {
1943
2138
  width: 100%;
1944
2139
  justify-content: space-between;
@@ -68,6 +68,7 @@
68
68
  <div class="workbench-tabs" id="workbenchTabs" aria-label="工作台视图">
69
69
  <button type="button" id="viewActivityBtn" class="secondary is-active">活动</button>
70
70
  <button type="button" id="viewTerminalBtn" class="secondary">终端</button>
71
+ <button type="button" id="viewFilesBtn" class="secondary">文件</button>
71
72
  <button type="button" id="viewDetailBtn" class="secondary">详情</button>
72
73
  <button type="button" id="viewConfigBtn" class="secondary">配置</button>
73
74
  <button type="button" id="viewCheckBtn" class="secondary">检查</button>
@@ -90,6 +91,7 @@
90
91
  </div>
91
92
  <div id="terminalScreen" aria-label="终端输出区域"></div>
92
93
  </section>
94
+ <section id="filesPanel" class="workspace-pane files-pane" hidden></section>
93
95
  <section id="detailPanel" class="workspace-pane inspector-pane" hidden>
94
96
  <div id="detailSummary" class="inspector-stack"></div>
95
97
  </section>
@@ -275,12 +277,30 @@
275
277
  </footer>
276
278
  </section>
277
279
  </div>
280
+
281
+ <div id="externalLinkModal" class="modal-backdrop" hidden>
282
+ <section class="modal" role="dialog" aria-modal="true" aria-labelledby="externalLinkTitle">
283
+ <header class="modal-header">
284
+ <h2 id="externalLinkTitle">打开外部链接</h2>
285
+ <button type="button" id="externalLinkCancelBtn" class="secondary">取消</button>
286
+ </header>
287
+ <div class="modal-body">
288
+ <div class="modal-tip">即将新标签页打开外部页面。请确认完整链接可信后再继续。</div>
289
+ <div id="externalLinkUrl" class="link-confirm-url"></div>
290
+ </div>
291
+ <footer class="modal-footer">
292
+ <button type="button" id="externalLinkOpenBtn">确认并新标签打开</button>
293
+ </footer>
294
+ </section>
295
+ </div>
278
296
  </div>
279
297
 
280
298
  <script src="/app/vendor/xterm.js"></script>
281
299
  <script src="/app/vendor/xterm-addon-fit.js"></script>
282
300
  <script src="/app/vendor/marked.min.js"></script>
283
301
  <script src="/app/frontend/markdown-renderer.js"></script>
302
+ <script src="/app/frontend/codemirror.bundle.js"></script>
303
+ <script src="/app/frontend/file-browser.js"></script>
284
304
  <script src="/app/frontend/app.js"></script>
285
305
  </body>
286
306
  </html>
@@ -51,6 +51,7 @@
51
51
  configModalOpen: false,
52
52
  createModalOpen: false,
53
53
  agentTemplateModalOpen: false,
54
+ externalLinkModalOpen: false,
54
55
  configLoading: false,
55
56
  configSaving: false,
56
57
  configSaveMessage: '',
@@ -105,7 +106,8 @@
105
106
  lastSentRows: 0,
106
107
  ctrlMode: false,
107
108
  altMode: false
108
- }
109
+ },
110
+ externalLinkUrl: ''
109
111
  };
110
112
 
111
113
  const sidebarNode = document.querySelector('.sidebar');
@@ -116,6 +118,7 @@
116
118
  const headerActions = document.getElementById('headerActions');
117
119
  const viewActivityBtn = document.getElementById('viewActivityBtn');
118
120
  const viewTerminalBtn = document.getElementById('viewTerminalBtn');
121
+ const viewFilesBtn = document.getElementById('viewFilesBtn');
119
122
  const viewDetailBtn = document.getElementById('viewDetailBtn');
120
123
  const viewConfigBtn = document.getElementById('viewConfigBtn');
121
124
  const viewCheckBtn = document.getElementById('viewCheckBtn');
@@ -172,6 +175,7 @@
172
175
  const activityModelChip = document.getElementById('activityModelChip');
173
176
  const messagesNode = document.getElementById('messages');
174
177
  const terminalPanel = document.getElementById('terminalPanel');
178
+ const filesPanel = document.getElementById('filesPanel');
175
179
  const detailPanel = document.getElementById('detailPanel');
176
180
  const configPanel = document.getElementById('configPanel');
177
181
  const checkPanel = document.getElementById('checkPanel');
@@ -196,6 +200,10 @@
196
200
  const agentTemplateCancelBtn = document.getElementById('agentTemplateCancelBtn');
197
201
  const agentTemplateResetBtn = document.getElementById('agentTemplateResetBtn');
198
202
  const agentTemplateSaveBtn = document.getElementById('agentTemplateSaveBtn');
203
+ const externalLinkModal = document.getElementById('externalLinkModal');
204
+ const externalLinkUrl = document.getElementById('externalLinkUrl');
205
+ const externalLinkCancelBtn = document.getElementById('externalLinkCancelBtn');
206
+ const externalLinkOpenBtn = document.getElementById('externalLinkOpenBtn');
199
207
  const refreshBtn = document.getElementById('refreshBtn');
200
208
  const removeBtn = document.getElementById('removeBtn');
201
209
  const removeAllBtn = document.getElementById('removeAllBtn');
@@ -242,6 +250,7 @@
242
250
  && typeof window.ManyoyoMarkdown.render === 'function'
243
251
  ? window.ManyoyoMarkdown
244
252
  : null;
253
+ let fileBrowser = null;
245
254
  function normalizeBooleanMap(source) {
246
255
  const result = {};
247
256
  if (!source || typeof source !== 'object' || Array.isArray(source)) {
@@ -740,6 +749,45 @@
740
749
  configStatus.textContent = text;
741
750
  }
742
751
 
752
+ function openExternalLinkModalView(url) {
753
+ const text = String(url || '').trim();
754
+ if (!text) {
755
+ return;
756
+ }
757
+ state.externalLinkUrl = text;
758
+ state.externalLinkModalOpen = true;
759
+ if (externalLinkUrl) {
760
+ externalLinkUrl.textContent = text;
761
+ }
762
+ setModalVisible(externalLinkModal, true);
763
+ }
764
+
765
+ function closeExternalLinkModalView() {
766
+ state.externalLinkModalOpen = false;
767
+ state.externalLinkUrl = '';
768
+ if (externalLinkUrl) {
769
+ externalLinkUrl.textContent = '';
770
+ }
771
+ setModalVisible(externalLinkModal, false);
772
+ }
773
+
774
+ function confirmExternalLinkOpen() {
775
+ const targetUrl = String(state.externalLinkUrl || '').trim();
776
+ if (!targetUrl) {
777
+ closeExternalLinkModalView();
778
+ return;
779
+ }
780
+ if (markdownRenderer && typeof markdownRenderer.openExternalLink === 'function') {
781
+ markdownRenderer.openExternalLink(targetUrl);
782
+ } else {
783
+ const popup = window.open(targetUrl, '_blank', 'noopener,noreferrer');
784
+ if (popup) {
785
+ popup.opener = null;
786
+ }
787
+ }
788
+ closeExternalLinkModalView();
789
+ }
790
+
743
791
  function showDirectoryPickerError(message) {
744
792
  if (!directoryPickerError) return;
745
793
  const text = String(message || '').trim();
@@ -1678,6 +1726,7 @@
1678
1726
  const VIEW_LABELS = {
1679
1727
  activity: '活动',
1680
1728
  terminal: '终端',
1729
+ files: '文件',
1681
1730
  detail: '详情',
1682
1731
  config: '配置',
1683
1732
  check: '检查'
@@ -1956,6 +2005,7 @@
1956
2005
 
1957
2006
  const activityTab = state.activeTab === 'activity';
1958
2007
  const terminalTab = state.activeTab === 'terminal';
2008
+ const filesTab = state.activeTab === 'files';
1959
2009
  const detailTab = state.activeTab === 'detail';
1960
2010
  const configTab = state.activeTab === 'config';
1961
2011
  const checkTab = state.activeTab === 'check';
@@ -1966,6 +2016,7 @@
1966
2016
  document.body.classList.toggle('command-mode', commandMode);
1967
2017
  document.body.classList.toggle('agent-mode', agentMode);
1968
2018
  document.body.classList.toggle('terminal-mode', terminalTab);
2019
+ document.body.classList.toggle('files-tab', filesTab);
1969
2020
  document.body.classList.toggle('detail-tab', detailTab);
1970
2021
  document.body.classList.toggle('config-tab', configTab);
1971
2022
  document.body.classList.toggle('check-tab', checkTab);
@@ -1991,6 +2042,7 @@
1991
2042
  }
1992
2043
  if (viewActivityBtn) viewActivityBtn.classList.toggle('is-active', activityTab);
1993
2044
  if (viewTerminalBtn) viewTerminalBtn.classList.toggle('is-active', terminalTab);
2045
+ if (viewFilesBtn) viewFilesBtn.classList.toggle('is-active', filesTab);
1994
2046
  if (viewDetailBtn) viewDetailBtn.classList.toggle('is-active', detailTab);
1995
2047
  if (viewConfigBtn) viewConfigBtn.classList.toggle('is-active', configTab);
1996
2048
  if (viewCheckBtn) viewCheckBtn.classList.toggle('is-active', checkTab);
@@ -2000,6 +2052,9 @@
2000
2052
  if (terminalPanel) {
2001
2053
  terminalPanel.hidden = !terminalTab;
2002
2054
  }
2055
+ if (filesPanel) {
2056
+ filesPanel.hidden = !filesTab;
2057
+ }
2003
2058
  if (detailPanel) {
2004
2059
  detailPanel.hidden = !detailTab;
2005
2060
  }
@@ -2012,6 +2067,14 @@
2012
2067
  if (terminalTab && state.terminal.terminalReady) {
2013
2068
  scheduleTerminalFit(false);
2014
2069
  }
2070
+ if (fileBrowser) {
2071
+ fileBrowser.sync({
2072
+ visible: filesTab,
2073
+ session: getActiveSession(),
2074
+ detail: state.sessionDetail,
2075
+ historyOnly: isActiveSessionHistoryOnly()
2076
+ });
2077
+ }
2015
2078
 
2016
2079
  const activeAgentRunning = isAgentRunActiveForSession(state.active);
2017
2080
  const busy = state.loadingSessions || state.loadingMessages || state.sending;
@@ -2095,6 +2158,9 @@
2095
2158
  if (agentTemplateModal) {
2096
2159
  agentTemplateModal.hidden = !state.agentTemplateModalOpen;
2097
2160
  }
2161
+ if (externalLinkModal) {
2162
+ externalLinkModal.hidden = !state.externalLinkModalOpen;
2163
+ }
2098
2164
  if (agentTemplateSaveBtn) {
2099
2165
  agentTemplateSaveBtn.disabled = state.agentTemplateSaving || !state.active;
2100
2166
  }
@@ -2118,7 +2184,7 @@
2118
2184
  }
2119
2185
  document.body.classList.toggle(
2120
2186
  'modal-open',
2121
- state.configModalOpen || state.createModalOpen || state.directoryPicker.open || state.agentTemplateModalOpen
2187
+ state.configModalOpen || state.createModalOpen || state.directoryPicker.open || state.agentTemplateModalOpen || state.externalLinkModalOpen
2122
2188
  );
2123
2189
  if (!state.active) {
2124
2190
  sendState.textContent = '未选择会话';
@@ -3901,6 +3967,12 @@
3901
3967
  });
3902
3968
  }
3903
3969
 
3970
+ if (viewFilesBtn) {
3971
+ viewFilesBtn.addEventListener('click', function () {
3972
+ setActiveTab('files');
3973
+ });
3974
+ }
3975
+
3904
3976
  if (viewDetailBtn) {
3905
3977
  viewDetailBtn.addEventListener('click', function () {
3906
3978
  setActiveTab('detail');
@@ -4030,6 +4102,15 @@
4030
4102
  });
4031
4103
  }
4032
4104
 
4105
+ if (externalLinkModal) {
4106
+ externalLinkModal.addEventListener('click', function (event) {
4107
+ if (event.target === externalLinkModal) {
4108
+ closeExternalLinkModalView();
4109
+ syncUi();
4110
+ }
4111
+ });
4112
+ }
4113
+
4033
4114
  window.addEventListener('keydown', function (event) {
4034
4115
  if (event.key === 'Escape' && state.configModalOpen) {
4035
4116
  closeConfigModal();
@@ -4046,6 +4127,10 @@
4046
4127
  closeAgentTemplateModal();
4047
4128
  syncUi();
4048
4129
  }
4130
+ if (event.key === 'Escape' && state.externalLinkModalOpen) {
4131
+ closeExternalLinkModalView();
4132
+ syncUi();
4133
+ }
4049
4134
  if (event.key === 'Escape' && state.mobileSidebarOpen) {
4050
4135
  closeMobileSessionPanel();
4051
4136
  }
@@ -4128,6 +4213,37 @@
4128
4213
  }
4129
4214
  });
4130
4215
 
4216
+ if (externalLinkCancelBtn) {
4217
+ externalLinkCancelBtn.addEventListener('click', function () {
4218
+ closeExternalLinkModalView();
4219
+ syncUi();
4220
+ });
4221
+ }
4222
+
4223
+ if (externalLinkOpenBtn) {
4224
+ externalLinkOpenBtn.addEventListener('click', function () {
4225
+ confirmExternalLinkOpen();
4226
+ syncUi();
4227
+ });
4228
+ }
4229
+
4230
+ if (markdownRenderer && typeof markdownRenderer.setLinkOpenHandler === 'function') {
4231
+ markdownRenderer.setLinkOpenHandler(function (url) {
4232
+ openExternalLinkModalView(url);
4233
+ syncUi();
4234
+ });
4235
+ }
4236
+
4237
+ if (window.ManyoyoFileBrowser && typeof window.ManyoyoFileBrowser.create === 'function') {
4238
+ fileBrowser = window.ManyoyoFileBrowser.create({
4239
+ root: filesPanel,
4240
+ api,
4241
+ onError: function (message) {
4242
+ alert(message);
4243
+ }
4244
+ });
4245
+ }
4246
+
4131
4247
  window.addEventListener('beforeunload', function () {
4132
4248
  disconnectTerminal('', true);
4133
4249
  });
@@ -0,0 +1,98 @@
1
+ import { basicSetup } from 'codemirror';
2
+ import { Compartment, EditorState } from '@codemirror/state';
3
+ import { EditorView } from '@codemirror/view';
4
+ import { css } from '@codemirror/lang-css';
5
+ import { html } from '@codemirror/lang-html';
6
+ import { javascript } from '@codemirror/lang-javascript';
7
+ import { json } from '@codemirror/lang-json';
8
+ import { markdown } from '@codemirror/lang-markdown';
9
+ import { python } from '@codemirror/lang-python';
10
+ import { yaml } from '@codemirror/lang-yaml';
11
+
12
+ function resolveLanguageExtension(language) {
13
+ switch (String(language || '').trim()) {
14
+ case 'css':
15
+ return css();
16
+ case 'html':
17
+ return html();
18
+ case 'javascript':
19
+ return javascript({ jsx: true, typescript: true });
20
+ case 'json':
21
+ return json();
22
+ case 'markdown':
23
+ return markdown();
24
+ case 'python':
25
+ return python();
26
+ case 'yaml':
27
+ return yaml();
28
+ default:
29
+ return [];
30
+ }
31
+ }
32
+
33
+ function createEditor(parent, options = {}) {
34
+ const target = parent;
35
+ const initialDoc = String(options.doc || '');
36
+ const initialLanguage = String(options.language || 'text').trim();
37
+ const initialReadOnly = options.readOnly !== false;
38
+ const languageCompartment = new Compartment();
39
+ const readOnlyCompartment = new Compartment();
40
+ const view = new EditorView({
41
+ parent: target,
42
+ state: EditorState.create({
43
+ doc: initialDoc,
44
+ extensions: [
45
+ basicSetup,
46
+ EditorView.lineWrapping,
47
+ readOnlyCompartment.of([
48
+ EditorState.readOnly.of(initialReadOnly),
49
+ EditorView.editable.of(!initialReadOnly)
50
+ ]),
51
+ languageCompartment.of(resolveLanguageExtension(initialLanguage)),
52
+ EditorView.theme({
53
+ '&': {
54
+ height: '100%',
55
+ fontSize: '12px'
56
+ },
57
+ '.cm-scroller': {
58
+ overflow: 'auto'
59
+ }
60
+ })
61
+ ]
62
+ })
63
+ });
64
+
65
+ return {
66
+ setValue(nextValue) {
67
+ const text = String(nextValue == null ? '' : nextValue);
68
+ view.dispatch({
69
+ changes: {
70
+ from: 0,
71
+ to: view.state.doc.length,
72
+ insert: text
73
+ }
74
+ });
75
+ },
76
+ setLanguage(nextLanguage) {
77
+ view.dispatch({
78
+ effects: languageCompartment.reconfigure(resolveLanguageExtension(nextLanguage))
79
+ });
80
+ },
81
+ setReadOnly(readOnly) {
82
+ const value = readOnly !== false;
83
+ view.dispatch({
84
+ effects: readOnlyCompartment.reconfigure([
85
+ EditorState.readOnly.of(value),
86
+ EditorView.editable.of(!value)
87
+ ])
88
+ });
89
+ },
90
+ destroy() {
91
+ view.destroy();
92
+ }
93
+ };
94
+ }
95
+
96
+ window.ManyoyoCodeEditor = {
97
+ create: createEditor
98
+ };