@@ -9,8 +9,7 @@ const state = {
99 currentItem : null ,
1010 pyodide : null ,
1111 pyodideLoading : false ,
12- originalCode : '' ,
13- uploadedFiles : [ ] // Track uploaded files
12+ originalCode : ''
1413} ;
1514
1615// Pyodide Management
@@ -48,118 +47,80 @@ async function initPyodide() {
4847 }
4948}
5049
51- // Handle file upload
52- function handleFileUpload ( event ) {
53- const files = event . target . files ;
54- const fileList = document . getElementById ( 'uploaded-files-list' ) ;
55-
56- for ( let file of files ) {
57- // Check file size (1MB = 1048576 bytes)
58- if ( file . size > 1048576 ) {
59- alert ( `File ${ file . name } is too large (max 1MB)` ) ;
60- continue ;
61- }
62-
63- const reader = new FileReader ( ) ;
64- reader . onload = async ( e ) => {
65- const content = e . target . result ;
66-
67- // Store file info
68- state . uploadedFiles . push ( {
69- name : file . name ,
70- content : content ,
71- size : file . size
72- } ) ;
73-
74- // Update UI
75- const fileItem = document . createElement ( 'div' ) ;
76- fileItem . className = 'uploaded-file-item' ;
77- fileItem . innerHTML = `
78- <span>📄 ${ file . name } </span>
79- <span class="file-size">${ ( file . size / 1024 ) . toFixed ( 1 ) } KB</span>
80- <button class="remove-file-btn" onclick="window.removeUploadedFile('${ file . name } ')">✕</button>
81- ` ;
82- fileList . appendChild ( fileItem ) ;
83-
84- // Write to Pyodide filesystem if loaded
85- if ( state . pyodide ) {
86- try {
87- state . pyodide . FS . writeFile ( file . name , new Uint8Array ( content ) ) ;
88- console . log ( `File ${ file . name } written to virtual filesystem` ) ;
89- } catch ( err ) {
90- console . error ( 'Error writing file to filesystem:' , err ) ;
91- }
92- }
93- } ;
94-
95- // Read as ArrayBuffer for binary support
96- reader . readAsArrayBuffer ( file ) ;
97- }
98-
99- // Reset input
100- event . target . value = '' ;
101- }
102-
103- // Remove uploaded file
104- function removeUploadedFile ( filename ) {
105- state . uploadedFiles = state . uploadedFiles . filter ( f => f . name !== filename ) ;
106-
107- // Update UI
108- const fileList = document . getElementById ( 'uploaded-files-list' ) ;
109- const items = fileList . querySelectorAll ( '.uploaded-file-item' ) ;
110- items . forEach ( item => {
111- if ( item . textContent . includes ( filename ) ) {
112- item . remove ( ) ;
113- }
114- } ) ;
115-
116- // Remove from Pyodide filesystem
117- if ( state . pyodide ) {
118- try {
119- state . pyodide . FS . unlink ( filename ) ;
120- console . log ( `File ${ filename } removed from virtual filesystem` ) ;
121- } catch ( err ) {
122- console . error ( 'Error removing file:' , err ) ;
123- }
124- }
125- }
126-
127- // Open Interactive Editor
50+ // Open Interactive Editor - Replace code section instead of modal
12851function openEditor ( pythonCode , problemTitle ) {
12952 state . originalCode = pythonCode ;
130- const modal = document . getElementById ( 'code-editor-modal' ) ;
131- const editor = document . getElementById ( 'code-editor' ) ;
132- const title = document . getElementById ( 'modal-title' ) ;
13353
134- title . textContent = `Interactive Editor - ${ problemTitle } ` ;
135- editor . value = pythonCode ;
136- modal . style . display = 'flex' ;
54+ // Find the code box to replace
55+ const codeBox = document . querySelector ( '.code-box' ) ;
56+ if ( ! codeBox ) return ;
57+
58+ // Hide images if present
59+ const visualPanel = document . querySelector ( '.visual-panel' ) ;
60+ const imageBox = document . querySelector ( '.image-box' ) ;
61+ const multiImageGrid = document . querySelector ( '.multi-image-grid' ) ;
62+
63+ if ( visualPanel ) visualPanel . style . display = 'none' ;
64+ if ( imageBox && ! visualPanel ) imageBox . style . display = 'none' ;
65+ if ( multiImageGrid ) multiImageGrid . style . display = 'none' ;
66+
67+ // Replace code box with interactive editor
68+ codeBox . innerHTML = `
69+ <div class="code-header" style="display: flex; justify-content: space-between; align-items: center;">
70+ <span>Interactive Python Editor</span>
71+ <div style="display: flex; gap: 0.5rem;">
72+ <button id="run-code-btn-inline" class="inline-action-btn run-btn">▶️ Run</button>
73+ <button id="reset-code-btn-inline" class="inline-action-btn">↺ Reset</button>
74+ <button id="close-editor-btn-inline" class="inline-action-btn">✕ Close</button>
75+ </div>
76+ </div>
77+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; height: 500px;">
78+ <div style="display: flex; flex-direction: column; border: 1px solid #3e3e42; border-radius: 4px; overflow: hidden;">
79+ <div style="padding: 0.5rem; background: #2d2d30; border-bottom: 1px solid #3e3e42; font-size: 0.85rem; color: #fff;">Code</div>
80+ <textarea id="code-editor-inline" spellcheck="false" style="flex: 1; background: #1e1e1e; color: #d4d4d4; border: none; padding: 1rem; font-family: 'Consolas', 'Monaco', monospace; font-size: 14px; resize: none; outline: none;">${ escapeHtml ( pythonCode ) } </textarea>
81+ </div>
82+ <div style="display: flex; flex-direction: column; border: 1px solid #3e3e42; border-radius: 4px; overflow: hidden;">
83+ <div style="padding: 0.5rem; background: #2d2d30; border-bottom: 1px solid #3e3e42; font-size: 0.85rem; color: #fff; display: flex; justify-content: space-between;">
84+ <span>Output</span>
85+ <button id="clear-output-btn-inline" style="background: #3e3e42; border: none; color: #fff; padding: 0.25rem 0.5rem; border-radius: 3px; cursor: pointer; font-size: 0.75rem;">Clear</button>
86+ </div>
87+ <div id="code-output-inline" style="flex: 1; background: #1e1e1e; color: #d4d4d4; padding: 1rem; font-family: 'Consolas', 'Monaco', monospace; font-size: 14px; overflow-y: auto;"></div>
88+ </div>
89+ </div>
90+ <div style="margin-top: 1rem; border: 1px solid #3e3e42; border-radius: 4px; overflow: hidden;">
91+ <div style="padding: 0.5rem; background: #2d2d30; border-bottom: 1px solid #3e3e42; font-size: 0.85rem; color: #fff;">
92+ Test Input <span style="color: #888; font-weight: normal; margin-left: 0.5rem;">(available as input.txt or via input())</span>
93+ </div>
94+ <textarea id="test-input-inline" placeholder="Paste test data here..." style="width: 100%; height: 100px; background: #1e1e1e; color: #d4d4d4; border: none; padding: 1rem; font-family: 'Consolas', 'Monaco', monospace; font-size: 14px; resize: none; outline: none;"></textarea>
95+ </div>
96+ ` ;
13797
138- // Clear previous uploads
139- state . uploadedFiles = [ ] ;
140- document . getElementById ( 'uploaded-files-list' ) . innerHTML = '' ;
98+ // Attach event listeners
99+ document . getElementById ( 'run-code-btn-inline' ) ?. addEventListener ( 'click' , runCodeInline ) ;
100+ document . getElementById ( 'reset-code-btn-inline' ) ?. addEventListener ( 'click' , resetCodeInline ) ;
101+ document . getElementById ( 'close-editor-btn-inline' ) ?. addEventListener ( 'click' , closeEditorInline ) ;
102+ document . getElementById ( 'clear-output-btn-inline' ) ?. addEventListener ( 'click' , ( ) => {
103+ document . getElementById ( 'code-output-inline' ) . innerHTML = '' ;
104+ } ) ;
141105
142- // Load Pyodide in background if not loaded
106+ // Load Pyodide in background
143107 if ( ! state . pyodide && ! state . pyodideLoading ) {
144108 initPyodide ( ) ;
145109 }
146110}
147111
148- // Close Editor
149- function closeEditor ( ) {
150- document . getElementById ( 'code-editor-modal' ) . style . display = 'none' ;
151- document . getElementById ( 'code-output' ) . innerHTML = '' ;
152- document . getElementById ( 'test-input' ) . value = '' ;
153- state . uploadedFiles = [ ] ;
154- document . getElementById ( 'uploaded-files-list' ) . innerHTML = '' ;
112+ // Close inline editor and restore original view
113+ function closeEditorInline ( ) {
114+ // Reload the problem view to restore everything
115+ renderProblem ( ) ;
155116}
156117
157- // Run Code
158- async function runCode ( ) {
159- const code = document . getElementById ( 'code-editor' ) . value ;
160- const testInput = document . getElementById ( 'test-input' ) . value ;
161- const output = document . getElementById ( 'code-output' ) ;
162- const runBtn = document . getElementById ( 'run-code-btn' ) ;
118+ // Run Code (inline version)
119+ async function runCodeInline ( ) {
120+ const code = document . getElementById ( 'code-editor-inline ' ) . value ;
121+ const testInput = document . getElementById ( 'test-input-inline ' ) . value ;
122+ const output = document . getElementById ( 'code-output-inline ' ) ;
123+ const runBtn = document . getElementById ( 'run-code-btn-inline ' ) ;
163124
164125 console . log ( 'Run code clicked' ) ;
165126
@@ -171,20 +132,20 @@ async function runCode() {
171132 if ( ! pyodide ) {
172133 output . innerHTML = '<div style="color: red;">❌ Python environment not loaded. Please refresh the page.</div>' ;
173134 runBtn . disabled = false ;
174- runBtn . textContent = '▶️ Run Code ' ;
135+ runBtn . textContent = '▶️ Run' ;
175136 return ;
176137 }
177138
178139 console . log ( 'Pyodide ready, executing code...' ) ;
179140
180141 try {
181- // Write uploaded files to virtual filesystem
182- for ( let file of state . uploadedFiles ) {
142+ // Write test input as input.txt if provided
143+ if ( testInput ) {
183144 try {
184- pyodide . FS . writeFile ( file . name , new Uint8Array ( file . content ) ) ;
185- console . log ( `File ${ file . name } available for open()` ) ;
145+ pyodide . FS . writeFile ( 'input.txt' , testInput ) ;
146+ console . log ( 'Test input written to input.txt' ) ;
186147 } catch ( err ) {
187- console . error ( ` Error writing ${ file . name } :` , err ) ;
148+ console . error ( ' Error writing input.txt:' , err ) ;
188149 }
189150 }
190151
@@ -244,19 +205,22 @@ __builtins__.input = mock_input
244205 }
245206
246207 runBtn . disabled = false ;
247- runBtn . textContent = '▶️ Run Code ' ;
208+ runBtn . textContent = '▶️ Run' ;
248209}
249210
250- // Reset Code
251- function resetCode ( ) {
252- document . getElementById ( 'code-editor' ) . value = state . originalCode ;
253- document . getElementById ( 'code-output' ) . innerHTML = '' ;
254- document . getElementById ( 'test-input' ) . value = '' ;
211+ // Reset Code (inline version)
212+ function resetCodeInline ( ) {
213+ document . getElementById ( 'code-editor-inline ' ) . value = state . originalCode ;
214+ document . getElementById ( 'code-output-inline ' ) . innerHTML = '' ;
215+ document . getElementById ( 'test-input-inline ' ) . value = '' ;
255216}
256217
257218// Download Code
258219function downloadCode ( ) {
259- const code = document . getElementById ( 'code-editor' ) . value ;
220+ const editor = document . getElementById ( 'code-editor-inline' ) ;
221+ if ( ! editor ) return ;
222+
223+ const code = editor . value ;
260224 const blob = new Blob ( [ code ] , { type : 'text/plain' } ) ;
261225 const url = URL . createObjectURL ( blob ) ;
262226 const a = document . createElement ( 'a' ) ;
@@ -266,11 +230,6 @@ function downloadCode() {
266230 URL . revokeObjectURL ( url ) ;
267231}
268232
269- // Clear Output
270- function clearOutput ( ) {
271- document . getElementById ( 'code-output' ) . innerHTML = '' ;
272- }
273-
274233// Utility
275234function getRepoPath ( ) {
276235 const parts = window . location . pathname . split ( '/' ) ;
@@ -755,29 +714,19 @@ window.addEventListener('hashchange', () => {
755714 // Make functions globally available
756715 window . goBack = goBack ;
757716 window . openEditor = openEditor ;
758- window . runCode = runCode ;
759- window . closeEditor = closeEditor ;
760- window . resetCode = resetCode ;
717+ window . runCodeInline = runCodeInline ;
718+ window . closeEditorInline = closeEditorInline ;
719+ window . resetCodeInline = resetCodeInline ;
761720 window . downloadCode = downloadCode ;
762- window . clearOutput = clearOutput ;
763- window . handleFileUpload = handleFileUpload ;
764- window . removeUploadedFile = removeUploadedFile ;
765721
766- // Setup modal event listeners
722+ // Setup modal event listeners (legacy - not used anymore but kept for safety)
767723 const modal = document . getElementById ( 'code-editor-modal' ) ;
768724 if ( modal ) {
769725 modal . addEventListener ( 'click' , ( e ) => {
770726 if ( e . target . id === 'code-editor-modal' ) {
771- closeEditor ( ) ;
727+ modal . style . display = 'none' ;
772728 }
773729 } ) ;
774-
775- document . getElementById ( 'close-modal-btn' ) ?. addEventListener ( 'click' , closeEditor ) ;
776- document . getElementById ( 'run-code-btn' ) ?. addEventListener ( 'click' , runCode ) ;
777- document . getElementById ( 'reset-code-btn' ) ?. addEventListener ( 'click' , resetCode ) ;
778- document . getElementById ( 'download-code-btn' ) ?. addEventListener ( 'click' , downloadCode ) ;
779- document . getElementById ( 'clear-output-btn' ) ?. addEventListener ( 'click' , clearOutput ) ;
780- document . getElementById ( 'file-upload-input' ) ?. addEventListener ( 'change' , handleFileUpload ) ;
781730 }
782731
783732 await loadPlatforms ( ) ;
0 commit comments