Beautifier Differentjs
Beautifier Differentjs
/usr/bin/env python3
2 import tkinter as tk
3 from tkinter import filedialog, scrolledtext, ttk, messagebox
4 import jsbeautifier
5 import os
6 import threading
7
8 class JSBeautifierApp:
9 def __init__(self, root):
10 self.root = root
11 self.root.title("JavaScript Beautifier")
12 self.root.geometry("900x700")
13 self.root.minsize(800, 600)
14
15 # Set theme colors
16 self.bg_color = "#f5f5f5"
17 self.accent_color = "#4a86e8"
18 self.root.configure(bg=self.bg_color)
19
20 self.create_widgets()
21 self.create_menu()
22
23 def create_widgets(self):
24 # Main frame
25 main_frame = tk.Frame(self.root, bg=self.bg_color)
26 main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
27
28 # Top frame for file selection
29 top_frame = tk.Frame(main_frame, bg=self.bg_color)
30 top_frame.pack(fill=tk.X, pady=5)
31
32 # File selection
33 tk.Label(top_frame, text="Input File:", bg=self.bg_color).pack(side=tk.LEFT, padx
=5)
34 self.file_path = tk.StringVar()
35 file_entry = tk.Entry(top_frame, textvariable=self.file_path, width=50)
36 file_entry.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
37
38 browse_btn = tk.Button(top_frame, text="Browse", command=self.browse_file,
39 bg=self.accent_color, fg="white", padx=10)
40 browse_btn.pack(side=tk.LEFT, padx=5)
41
42 # Options frame
43 options_frame = tk.Frame(main_frame, bg=self.bg_color)
44 options_frame.pack(fill=tk.X, pady=5)
45
46 # Indent size
47 tk.Label(options_frame, text="Indent Size:", bg=self.bg_color).pack(side=tk.LEFT,
padx=5)
48 self.indent_size = tk.IntVar(value=2)
49 indent_spinbox = tk.Spinbox(options_frame, from_=1, to=8, width=5, textvariable=
self.indent_size)
50 indent_spinbox.pack(side=tk.LEFT, padx=5)
51
52 # Brace style
53 tk.Label(options_frame, text="Brace Style:", bg=self.bg_color).pack(side=tk.LEFT,
padx=5)
54 self.brace_style = tk.StringVar(value="collapse")
55 brace_combo = ttk.Combobox(options_frame, textvariable=self.brace_style, width=15
)
56 brace_combo['values'] = ('collapse', 'expand', 'end-expand', 'none')
57 brace_combo.pack(side=tk.LEFT, padx=5)
58
59 # Preserve newlines
60 self.preserve_newlines = tk.BooleanVar(value=True)
61 preserve_check = tk.Checkbutton(options_frame, text="Preserve Newlines",
62 variable=self.preserve_newlines, bg=self.bg_color)
63 preserve_check.pack(side=tk.LEFT, padx=10)
64
65 # Action buttons
66 button_frame = tk.Frame(main_frame, bg=self.bg_color)
67 button_frame.pack(fill=tk.X, pady=5)
68
69 beautify_btn = tk.Button(button_frame, text="Beautify", command=self.beautify_js,
70 bg=self.accent_color, fg="white", padx=15, pady=5)
71 beautify_btn.pack(side=tk.LEFT, padx=5)
72
73 save_btn = tk.Button(button_frame, text="Save As", command=self.save_file,
74 bg=self.accent_color, fg="white", padx=15, pady=5)
75 save_btn.pack(side=tk.LEFT, padx=5)
76
77 clear_btn = tk.Button(button_frame, text="Clear", command=self.clear_text,
78 bg="#e74c3c", fg="white", padx=15, pady=5)
79 clear_btn.pack(side=tk.LEFT, padx=5)
80
81 # Text areas
82 text_frame = tk.Frame(main_frame)
83 text_frame.pack(fill=tk.BOTH, expand=True, pady=5)
84
85 # Split the frame into two columns
86 left_frame = tk.Frame(text_frame)
87 left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
88
89 right_frame = tk.Frame(text_frame)
90 right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
91
92 # Minified JS (left)
93 tk.Label(left_frame, text="Minified JavaScript:").pack(anchor=tk.W)
94 self.minified_text = scrolledtext.ScrolledText(left_frame, wrap=tk.WORD, height=
20, width=40)
95 self.minified_text.pack(fill=tk.BOTH, expand=True, padx=5)
96
97 # Beautified JS (right)
98 tk.Label(right_frame, text="Beautified JavaScript:").pack(anchor=tk.W)
99 self.beautified_text = scrolledtext.ScrolledText(right_frame, wrap=tk.WORD,
height=20, width=40)
100 self.beautified_text.pack(fill=tk.BOTH, expand=True, padx=5)
101
102 # Status bar
103 self.status_var = tk.StringVar()
104 self.status_var.set("Ready")
105 status_bar = tk.Label(self.root, textvariable=self.status_var, bd=1, relief=tk.
SUNKEN, anchor=tk.W)
106 status_bar.pack(side=tk.BOTTOM, fill=tk.X)
107
108 def create_menu(self):
109 menubar = tk.Menu(self.root)
110
111 # File menu
112 file_menu = tk.Menu(menubar, tearoff=0)
113 file_menu.add_command(label="Open", command=self.browse_file)
114 file_menu.add_command(label="Save As", command=self.save_file)
115 file_menu.add_separator()
116 file_menu.add_command(label="Exit", command=self.root.quit)
117 menubar.add_cascade(label="File", menu=file_menu)
118
119 # Edit menu
120 edit_menu = tk.Menu(menubar, tearoff=0)
121 edit_menu.add_command(label="Clear", command=self.clear_text)
122 edit_menu.add_command(label="Beautify", command=self.beautify_js)
123 menubar.add_cascade(label="Edit", menu=edit_menu)
124
125 # Help menu
126 help_menu = tk.Menu(menubar, tearoff=0)
127 help_menu.add_command(label="About", command=self.show_about)
128 menubar.add_cascade(label="Help", menu=help_menu)
129
130 self.root.config(menu=menubar)
131
132 def browse_file(self):
133 file_path = filedialog.askopenfilename(
134 filetypes=[("JavaScript Files", "*.js"), ("All Files", "*.*")]
135 )
136 if file_path:
137 self.file_path.set(file_path)
138 self.load_file(file_path)
139
140 def load_file(self, file_path):
141 try:
142 with open(file_path, 'r', encoding='utf-8') as f:
143 content = f.read()
144 self.minified_text.delete(1.0, tk.END)
145 self.minified_text.insert(tk.END, content)
146 self.status_var.set(f"Loaded: {file_path}")
147 except Exception as e:
148 messagebox.showerror("Error", f"Failed to load file: {str(e)}")
149 self.status_var.set("Error loading file")
150
151 def beautify_js(self):
152 js_code = self.minified_text.get(1.0, tk.END)
153 if not js_code.strip():
154 if self.file_path.get():
155 self.load_file(self.file_path.get())
156 js_code = self.minified_text.get(1.0, tk.END)
157 else:
158 messagebox.showinfo("Info", "Please enter JavaScript code or load a file
first.")
159 return
160
161 # Show processing status
162 self.status_var.set("Processing...")
163 self.root.update_idletasks()
164
165 # Run beautification in a separate thread to avoid UI freezing
166 threading.Thread(target=self._beautify_thread, args=(js_code,)).start()
167
168 def _beautify_thread(self, js_code):
169 try:
170 # Configure the beautifier options
171 opts = jsbeautifier.default_options()
172 opts.indent_size = self.indent_size.get()
173 opts.indent_char = ' '
174 opts.max_preserve_newlines = 2 if self.preserve_newlines.get() else 0
175 opts.preserve_newlines = self.preserve_newlines.get()
176 opts.keep_array_indentation = False
177 opts.break_chained_methods = False
178 opts.indent_scripts = "normal"
179 opts.brace_style = self.brace_style.get()
180 opts.space_before_conditional = True
181 opts.unescape_strings = True
182 opts.jslint_happy = False
183 opts.end_with_newline = True
184 opts.wrap_line_length = 0
185
186 # Beautify the JS
187 beautified_js = jsbeautifier.beautify(js_code, opts)
188
189 # Update UI in the main thread
190 self.root.after(0, self._update_beautified_text, beautified_js)
191 except Exception as e:
192 self.root.after(0, self._show_error, str(e))
193
194 def _update_beautified_text(self, beautified_js):
195 self.beautified_text.delete(1.0, tk.END)
196 self.beautified_text.insert(tk.END, beautified_js)
197 self.status_var.set("Beautification completed")
198
199 def _show_error(self, error_msg):
200 messagebox.showerror("Error", f"Failed to beautify JavaScript: {error_msg}")
201 self.status_var.set("Error during beautification")
202
203 def save_file(self):
204 if not self.beautified_text.get(1.0, tk.END).strip():
205 messagebox.showinfo("Info", "No beautified code to save.")
206 return
207
208 file_path = filedialog.asksaveasfilename(
209 defaultextension=".js",
210 filetypes=[("JavaScript Files", "*.js"), ("All Files", "*.*")]
211 )
212
213 if file_path:
214 try:
215 with open(file_path, 'w', encoding='utf-8') as f:
216 f.write(self.beautified_text.get(1.0, tk.END))
217 self.status_var.set(f"Saved to: {file_path}")
218 messagebox.showinfo("Success", f"File saved successfully to:\n{file_path
}")
219 except Exception as e:
220 messagebox.showerror("Error", f"Failed to save file: {str(e)}")
221 self.status_var.set("Error saving file")
222
223 def clear_text(self):
224 self.minified_text.delete(1.0, tk.END)
225 self.beautified_text.delete(1.0, tk.END)
226 self.file_path.set("")
227 self.status_var.set("Ready")
228
229 def show_about(self):
230 about_text = """JavaScript Beautifier
231
232 A simple tool to convert minified JavaScript to readable format.
233
234 Features:
235 - Load minified JavaScript files
236 - Customize beautification options
237 - Save beautified code to a new file
238
239 Created with Python, Tkinter, and jsbeautifier."""
240
241 messagebox.showinfo("About JavaScript Beautifier", about_text)
242
243 def main():
244 root = tk.Tk()
245 app = JSBeautifierApp(root)
246 root.mainloop()
247
248 if __name__ == "__main__":
249 main()
250