diff --git a/editor/index.html b/editor/index.html index ede19d9..bee0ace 100644 --- a/editor/index.html +++ b/editor/index.html @@ -3,12 +3,11 @@ + + - - - @@ -30,14 +29,19 @@

Editor

+
+ + + +
-
+
-
+
diff --git a/editor/index.js b/editor/index.js index 08c4f40..eec3396 100644 --- a/editor/index.js +++ b/editor/index.js @@ -11,8 +11,125 @@ var editor = null, diffEditor = null; "use strict"; var editor = null, diffEditor = null; +var currentMode = null; +var autoSaveTimer = null; +const STORAGE_KEY = 'monaco-editor-state'; -$(document).ready(function() { +function saveEditorState() { + if (!editor || !currentMode) return; + var $ = window.jQuery; + + const state = { + mode: currentMode, + theme: $('.theme-picker').val(), + code: editor.getValue() + }; + + localStorage.setItem(STORAGE_KEY, JSON.stringify(state)); +} + +function loadEditorState() { + const savedState = localStorage.getItem(STORAGE_KEY); + if (!savedState) return null; + + try { + return JSON.parse(savedState); + } catch (e) { + console.error('Failed to parse saved state:', e); + return null; + } +} + +function setupAutoSave() { + if (!editor) return; + + editor.onDidChangeModelContent(function() { + if (autoSaveTimer) { + clearTimeout(autoSaveTimer); + } + + autoSaveTimer = setTimeout(function() { + saveEditorState(); + }, 1000); // 1秒后自动保存 + }); +} + +function generateShareURL() { + if (!editor || !currentMode) return ''; + var $ = window.jQuery; + + const state = { + mode: currentMode, + theme: $('.theme-picker').val(), + code: editor.getValue() + }; + + const encodedState = btoa(unescape(encodeURIComponent(JSON.stringify(state)))); + const baseURL = window.location.origin + window.location.pathname; + + return `${baseURL}?state=${encodedState}`; +} + +function getSharedStateFromURL() { + const urlParams = new URLSearchParams(window.location.search); + const encodedState = urlParams.get('state'); + + if (!encodedState) return null; + + try { + const decodedState = decodeURIComponent(escape(atob(encodedState))); + return JSON.parse(decodedState); + } catch (e) { + console.error('Failed to parse shared state:', e); + return null; + } +} + +function applyState(state, MODES) { + if (!state) return; + var $ = window.jQuery; + + // 找到对应的语言模式 + let modeIndex = 0; + for (let i = 0; i < MODES.length; i++) { + if (MODES[i].modeId === state.mode) { + modeIndex = i; + break; + } + } + + // 设置语言选择器 + $(".language-picker")[0].selectedIndex = modeIndex; + + // 设置主题 + if (state.theme) { + const themeOptions = $(".theme-picker option"); + for (let i = 0; i < themeOptions.length; i++) { + if (themeOptions[i].text === state.theme) { + $(".theme-picker")[0].selectedIndex = i; + changeTheme(i); + break; + } + } + } + + // 加载代码 + if (state.code !== undefined) { + loadSample(MODES[modeIndex], state.code); + } else { + loadSample(MODES[modeIndex]); + } +} + +function initializeEditor() { + // 确保 jQuery 可用 + if (typeof window.jQuery === 'undefined') { + setTimeout(initializeEditor, 100); + return; + } + + var $ = window.jQuery; + require(['vs/editor/editor.main'], function () { var MODES = (function() { var modesIds = monaco.languages.getLanguages().map(function(lang) { return lang.id; }); @@ -35,8 +152,23 @@ $(document).ready(function() { } $(".language-picker").append(o); } - $(".language-picker")[0].selectedIndex = startModeIndex; - loadSample(MODES[startModeIndex]); + + // 检查 URL 中是否有分享的代码 + var sharedState = getSharedStateFromURL(); + var savedState = loadEditorState(); + + if (sharedState) { + // 如果有分享的代码,优先使用分享的代码 + applyState(sharedState, MODES); + } else if (savedState) { + // 如果没有分享的代码,但有保存的状态,恢复保存的状态 + applyState(savedState, MODES); + } else { + // 否则,使用默认值 + $(".language-picker")[0].selectedIndex = startModeIndex; + loadSample(MODES[startModeIndex]); + } + $(".language-picker").change(function() { loadSample(MODES[this.selectedIndex]); }); @@ -45,6 +177,31 @@ $(document).ready(function() { changeTheme(this.selectedIndex); }); + $("#format-btn").click(function() { + if (editor) { + editor.getAction('editor.action.formatDocument').run(); + } + }); + + $("#share-btn").click(function() { + if (!editor || !currentMode) { + alert('编辑器尚未准备好'); + return; + } + + var shareURL = generateShareURL(); + + // 创建一个临时输入框来复制 URL + var tempInput = document.createElement('input'); + tempInput.value = shareURL; + document.body.appendChild(tempInput); + tempInput.select(); + document.execCommand('copy'); + document.body.removeChild(tempInput); + + alert('分享链接已复制到剪贴板:\n' + shareURL); + }); + loadDiffSample(); $('#inline-diff-checkbox').change(function () { @@ -62,7 +219,14 @@ $(document).ready(function() { diffEditor.layout(); } }; -}); +} + +// 等待 DOM 加载完成后再初始化 +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initializeEditor); +} else { + initializeEditor(); +} var preloaded = {}; (function() { @@ -79,6 +243,7 @@ function xhr(url, cb) { if (preloaded[url]) { return cb(null, preloaded[url]); } + var $ = window.jQuery; $.ajax({ type: 'GET', url: url, @@ -91,9 +256,18 @@ function xhr(url, cb) { }); } -function loadSample(mode) { +function loadSample(mode, customCode) { + currentMode = mode.modeId; + var $ = window.jQuery; + + if (customCode !== undefined) { + loadCodeWithMode(mode.modeId, customCode); + return; + } + $('.loading.editor').show(); xhr(mode.sampleURL, function(err, data) { + var $ = window.jQuery; if (err) { if (editor) { if (editor.getModel()) { @@ -108,23 +282,32 @@ function loadSample(mode) { return; } - if (!editor) { - $('#editor').empty(); - editor = monaco.editor.create(document.getElementById('editor'), { - model: null, - }); - } - - var oldModel = editor.getModel(); - var newModel = monaco.editor.createModel(data, mode.modeId); - editor.setModel(newModel); - if (oldModel) { - oldModel.dispose(); - } - $('.loading.editor').fadeOut({ duration: 300 }); + loadCodeWithMode(mode.modeId, data); }) } +function loadCodeWithMode(modeId, code) { + var $ = window.jQuery; + if (!editor) { + $('#editor').empty(); + editor = monaco.editor.create(document.getElementById('editor'), { + model: null, + automaticLayout: true, + scrollBeyondLastLine: false, + }); + setupAutoSave(); + } + + currentMode = modeId; + var oldModel = editor.getModel(); + var newModel = monaco.editor.createModel(code, modeId); + editor.setModel(newModel); + if (oldModel) { + oldModel.dispose(); + } + $('.loading.editor').fadeOut({ duration: 300 }); +} + function loadDiffSample() { var onError = function() { @@ -173,4 +356,5 @@ function loadDiffSample() { function changeTheme(theme) { var newTheme = (theme === 1 ? 'vs-dark' : ( theme === 0 ? 'vs' : 'hc-black' )); monaco.editor.setTheme(newTheme); + saveEditorState(); } \ No newline at end of file