1+ <?php
2+ if (!isset ($ _GET ["filename " ]) || !is_file ($ _GET ["filename " ])) {
3+ die ("Invalid file specified. " );
4+ }
5+ $ filename = $ _GET ["filename " ];
6+ if ($ _SERVER ["REQUEST_METHOD " ] == "POST " ) {
7+ $ content = $ _POST ["content " ];
8+ file_put_contents ($ filename , $ content );
9+ echo "File saved successfully! " ;
10+ exit ();
11+ }
12+ $ fileContents = htmlspecialchars (
13+ file_get_contents ($ filename ),
14+ ENT_QUOTES ,
15+ "UTF-8 "
16+ );
17+ $ fileExtension = strtolower (pathinfo ($ filename , PATHINFO_EXTENSION ));
18+ $ languageModes = [
19+ "html " => "html " ,
20+ "php " => "php " ,
21+ "js " => "javascript " ,
22+ "css " => "css " ,
23+ "json " => "json " ,
24+ "sh " => "sh " ,
25+ "py " => "python " ,
26+ ];
27+ $ editorMode = isset ($ languageModes [$ fileExtension ])
28+ ? $ languageModes [$ fileExtension ]
29+ : "sh " ;
30+ ?>
31+ <!DOCTYPE html>
32+ <html lang="en">
33+ <head>
34+ <meta charset="UTF-8">
35+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
36+ <title><?php echo basename ($ filename ); ?> </title>
37+
38+ <!-- Include Ace Editor -->
39+ <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js"></script>
40+ <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ext-language_tools.js"></script>
41+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
42+
43+ <!-- Include Prettier -->
44+ <script src="https://unpkg.com/prettier@2.7.1/standalone.js"></script>
45+ <script src="https://unpkg.com/prettier@2.7.1/parser-html.js"></script>
46+ <script src="https://unpkg.com/prettier@2.7.1/parser-babel.js"></script> <!-- For JavaScript -->
47+ <script src="https://unpkg.com/prettier@2.7.1/parser-postcss.js"></script> <!-- For CSS -->
48+ <script src="https://unpkg.com/@prettier/plugin-php@0.19.0/standalone.js"></script> <!-- PHP plugin -->
49+ <script src="https://unpkg.com/@prettier/plugin-php@0.19.0/parser-php.js"></script>
50+ <script src="https://unpkg.com/prettier@2.7.1/parser-markdown.js"></script>
51+ <link rel="icon" href="icon.png" type="image/png">
52+ <style>
53+ body, html {
54+ margin: 0;
55+ padding: 0;
56+ height: 100%;
57+ font-family: Arial, sans-serif;
58+ }
59+
60+ #editor {
61+ position: absolute;
62+ top: 50px;
63+ bottom: 10px;
64+ left: 0;
65+ right: 0;
66+ }
67+
68+ #controls {
69+ position: absolute;
70+ top: 0;
71+ left: 0;
72+ right: 0;
73+ height: 50px;
74+ background-color: #333;
75+ color: white;
76+ padding: 5px;
77+ display: flex;
78+ justify-content: space-between;
79+ align-items: center;
80+ cursor: pointer;
81+ }
82+
83+ #controls button, #controls select {
84+ padding: 5px;
85+ font-size: 14px;
86+ margin-left: 5px;
87+ cursor: pointer;
88+ }
89+
90+ #save-status {
91+ padding: 10px;
92+ background-color: #4CAF50;
93+ color: white;
94+ position: absolute;
95+ top: 0;
96+ left: 0;
97+ right: 0;
98+ text-align: center;
99+ display: none;
100+ z-index: 9999;
101+ }
102+
103+ #saveBtn {
104+ background-color: #4CAF50;
105+ border: 1px solid #4CAF50;
106+ color: white;
107+ width: 100px;
108+ }
109+
110+ #formatBtn {
111+ background-color: #4493f8;
112+ border: 1px solid #4493f8;
113+ color: white;
114+ }
115+
116+ #spinner-container {
117+ display: flex;
118+ justify-content: center;
119+ align-items: center;
120+ position: absolute;
121+ top: 0;
122+ left: 0;
123+ right: 0;
124+ bottom: 0;
125+ background-color: #fff; /* or any background */
126+ z-index: 9999;
127+ }
128+ .spinner {
129+ border: 4px solid rgba(0, 0, 0, 0.1);
130+ border-left-color: #000;
131+ border-radius: 50%;
132+ width: 40px;
133+ height: 40px;
134+ animation: spin 1s linear infinite;
135+ }
136+ @keyframes spin {
137+ 0% {
138+ transform: rotate(0deg);
139+ }
140+ 100% {
141+ transform: rotate(360deg);
142+ }
143+ }
144+
145+ </style>
146+ </head>
147+ <body>
148+
149+
150+ <div id="controls">
151+ <div>
152+ <label for="theme">Theme:</label>
153+ <select id="theme" onchange="changeTheme(this.value)">
154+ <option value="cobalt">Cobalt</option>
155+ <option value="monokai">Monokai</option>
156+ <option value="github">GitHub</option>
157+ <option value="tomorrow">Tomorrow</option>
158+ <option value="kuroir">Kuroir</option>
159+ </select>
160+
161+
162+ <select id="mode" onchange="changeMode(this.value)">
163+ <option value="html" <?php if ($ fileExtension == "html " ) {
164+ echo "selected " ;
165+ } ?> >HTML</option>
166+ <option value="php" <?php if ($ fileExtension == "php " ) {
167+ echo "selected " ;
168+ } ?> >PHP</option>
169+ <option value="javascript" <?php if ($ fileExtension == "js " ) {
170+ echo "selected " ;
171+ } ?> >JavaScript</option>
172+ <option value="css" <?php if ($ fileExtension == "css " ) {
173+ echo "selected " ;
174+ } ?> >CSS</option>
175+ <option value="json" <?php if ($ fileExtension == "json " ) {
176+ echo "selected " ;
177+ } ?> >JSON</option>
178+ <option value="sh" <?php if ($ fileExtension == "sh " ) {
179+ echo "selected " ;
180+ } ?> >Bash</option>
181+ <option value="python" <?php if ($ fileExtension == "py " ) {
182+ echo "selected " ;
183+ } ?> >Python</option>
184+ </select>
185+
186+
187+ <select id="fontSize" onchange="changeFontSize(this.value)">
188+ <option value="12px">Font: 12px</option>
189+ <option value="14px" selected>Font: 14px</option>
190+ <option value="16px">Font: 16px</option>
191+ <option value="18px">Font: 18px</option>
192+ <option value="20px">Font: 20px</option>
193+ </select>
194+
195+
196+ <span style="font-size:12px"><strong>FILE PATH: </strong><span style="color:#4493f8"><?= $ filename ?> </span></span>
197+ </div>
198+
199+
200+ <div>
201+ <button onclick="formatCode()" id="formatBtn"><i class="fa fa-code"></i> Format Code</button>
202+ <button onclick="editor.undo()"><i class="fa fa-undo" aria-hidden="true"></i> Undo</button>
203+ <button onclick="editor.redo()"><i class="fa fa-repeat" aria-hidden="true"></i> Redo</button>
204+ <button onclick="editor.execCommand('replace')"><i class="fa fa-search-plus" aria-hidden="true"></i> Search/Replace</button>
205+ <button onclick="saveFile()" id="saveBtn"><i class="fa fa-floppy-o" aria-hidden="true"></i> Save</button>
206+ </div>
207+ </div>
208+ <div id="spinner-container">
209+ <div class="spinner"></div>
210+ </div>
211+ <div id="editor" style="display:none;"><?php echo $ fileContents ; ?> </div>
212+
213+ <div id="save-status">File Saved!</div>
214+
215+ <script>
216+
217+ document.addEventListener('DOMContentLoaded', function () {
218+ document.getElementById('spinner-container').style.display = 'none';
219+ document.getElementById('editor').style.display = 'block';
220+ });
221+
222+ // Initialize Ace Editor
223+ var editor = ace.edit("editor");
224+ editor.setTheme("ace/theme/cobalt");
225+ editor.session.setMode("ace/mode/<?php echo $ editorMode ; ?> ");
226+ editor.setOptions({
227+ enableBasicAutocompletion: true,
228+ enableSnippets: true,
229+ enableLiveAutocompletion: true,
230+ fontSize: "14px",
231+ wrap: true,
232+ highlightActiveLine: true,
233+ highlightSelectedWord: true,
234+ enableAutoIndent: true,
235+ enableKeyboardAccessibility: true
236+ });
237+
238+
239+ function changeTheme(theme) {
240+ editor.setTheme("ace/theme/" + theme);
241+ }
242+
243+ function changeMode(mode) {
244+ editor.session.setMode("ace/mode/" + mode);
245+ }
246+
247+ function changeFontSize(fontSize) {
248+ editor.setOptions({
249+ fontSize: fontSize
250+ });
251+ }
252+
253+ function saveFile() {
254+ var btn = document.getElementById('saveBtn');
255+ btn.disabled = true;
256+ btn.textContent = 'Saving...';
257+ var content = editor.getValue();
258+ var xhr = new XMLHttpRequest();
259+ xhr.open("POST", "codeEditor.php?filename=<?php echo $ filename ; ?> ", true);
260+ xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
261+ xhr.onreadystatechange = function() {
262+ if (xhr.readyState === 4 && xhr.status === 200) {
263+ document.getElementById('save-status').style.display = 'block';
264+ setTimeout(function() {
265+ document.getElementById('save-status').style.display = 'none';
266+ btn.disabled = false;
267+ btn.textContent = 'Save';
268+ }, 1000);
269+ }
270+ };
271+ xhr.send("content=" + encodeURIComponent(content));
272+ }
273+
274+
275+ function formatCode() {
276+ const code = editor.getValue();
277+ let formattedCode;
278+
279+ const mode = "<?= $ fileExtension ?> ";
280+ try {
281+ switch (mode) {
282+ case 'html':
283+ formattedCode = prettier.format(code, { parser: "html", plugins: prettierPlugins });
284+ break;
285+ case 'js':
286+ formattedCode = prettier.format(code, { parser: "babel", plugins: prettierPlugins });
287+ break;
288+ case 'css':
289+ formattedCode = prettier.format(code, { parser: "css", plugins: prettierPlugins });
290+ break;
291+ case 'php':
292+ formattedCode = prettier.format(code, { parser: "php", plugins: prettierPlugins });
293+ break;
294+ default:
295+ formattedCode = prettier.format(code, { parser: "html", plugins: prettierPlugins });
296+ break;
297+ }
298+
299+ editor.setValue(formattedCode, -1);
300+ } catch (error) {
301+ console.error("Formatting error:", error);
302+ alert("Error while formatting the code.");
303+ }
304+ }
305+
306+ </script>
307+ </body>
308+ </html>
0 commit comments