@@ -41,6 +41,9 @@ import { history, indentWithTab } from "@codemirror/commands";
4141import { defaultKeymap , historyKeymap } from " @codemirror/commands" ;
4242import { simpleMode } from " @codemirror/legacy-modes/mode/simple-mode" ;
4343
44+ const TRY_PAGE_DRAFT_KEY = " yuescript.try.code" ;
45+ const TRY_PAGE_DRAFT_SAVE_DELAY = 1000 ;
46+
4447function createEditorTheme ({ bg, fg, gutterColor, selectionBg, cursorColor, matchingBracketBg, dark }) {
4548 return EditorView .theme (
4649 {
@@ -161,6 +164,7 @@ export default {
161164 highlightCompartment: null ,
162165 themeObserver: null ,
163166 _onYueReady: null ,
167+ draftSaveTimer: null ,
164168 };
165169 },
166170 computed: {
@@ -170,13 +174,17 @@ export default {
170174 highlightedLua () {
171175 return highlight (this .compiled || " " , languages .lua );
172176 },
177+ shouldPersistDraft () {
178+ return ! this .compileronly && ! this .displayonly && this .text === " " ;
179+ },
173180 },
174181 mounted () {
175182 this .windowWidth = window .innerWidth ;
176183 window .addEventListener (" resize" , this .handleResize );
184+ window .addEventListener (" beforeunload" , this .saveDraftNow );
177185 this .observeTheme ();
178186
179- const initialCode = this .text ;
187+ const initialCode = this .loadDraftCode () ;
180188 this .code = initialCode;
181189 this .codeChanged (initialCode);
182190 this .initEditor (initialCode);
@@ -199,11 +207,17 @@ export default {
199207 }
200208 },
201209 beforeUnmount () {
210+ this .saveDraftNow ();
202211 window .removeEventListener (" resize" , this .handleResize );
212+ window .removeEventListener (" beforeunload" , this .saveDraftNow );
203213 if (this ._onYueReady ) {
204214 window .removeEventListener (" yue:ready" , this ._onYueReady );
205215 this ._onYueReady = null ;
206216 }
217+ if (this .draftSaveTimer ) {
218+ clearTimeout (this .draftSaveTimer );
219+ this .draftSaveTimer = null ;
220+ }
207221 if (this .editorView ) {
208222 this .editorView .destroy ();
209223 this .editorView = null ;
@@ -214,6 +228,46 @@ export default {
214228 }
215229 },
216230 methods: {
231+ loadDraftCode () {
232+ if (! this .shouldPersistDraft ) {
233+ return this .text ;
234+ }
235+ try {
236+ const draft = window .localStorage .getItem (TRY_PAGE_DRAFT_KEY );
237+ return draft === null ? this .text : draft;
238+ } catch (error) {
239+ return this .text ;
240+ }
241+ },
242+ scheduleDraftSave (text ) {
243+ if (! this .shouldPersistDraft ) {
244+ return ;
245+ }
246+ if (this .draftSaveTimer ) {
247+ clearTimeout (this .draftSaveTimer );
248+ }
249+ this .draftSaveTimer = window .setTimeout (() => {
250+ this .draftSaveTimer = null ;
251+ this .saveDraft (text);
252+ }, TRY_PAGE_DRAFT_SAVE_DELAY );
253+ },
254+ saveDraftNow () {
255+ if (! this .shouldPersistDraft ) {
256+ return ;
257+ }
258+ if (this .draftSaveTimer ) {
259+ clearTimeout (this .draftSaveTimer );
260+ this .draftSaveTimer = null ;
261+ }
262+ this .saveDraft (this .code );
263+ },
264+ saveDraft (text ) {
265+ try {
266+ window .localStorage .setItem (TRY_PAGE_DRAFT_KEY , text);
267+ } catch (error) {
268+ // Ignore unavailable or full localStorage; compiling should still work.
269+ }
270+ },
217271 focusEditorToEnd () {
218272 if (! this .editorView ) {
219273 return ;
@@ -506,6 +560,7 @@ export default {
506560 }
507561 const nextCode = update .state .doc .toString ();
508562 this .code = nextCode;
563+ this .scheduleDraftSave (nextCode);
509564 this .codeChanged (nextCode);
510565 });
511566
0 commit comments