Skip to content

Commit 5849b8f

Browse files
authored
Refactor viewer.html with UI improvements and updates
Updated the title and enhanced styles for various UI components. Added context menu and improved file handling features. Signed-off-by: Unbounded <ngde@web.de>
1 parent 25a0915 commit 5849b8f

File tree

1 file changed

+191
-78
lines changed

1 file changed

+191
-78
lines changed

viewer.html

Lines changed: 191 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>CRX/ZIP Code Inspector (Fixed Layout)</title>
6+
<title>Advanced CRX/ZIP Inspector</title>
77
<script src="https://cdn.tailwindcss.com"></script>
88

99
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css">
@@ -16,107 +16,220 @@
1616
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/xml/xml.min.js"></script>
1717
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/htmlmixed/htmlmixed.min.js"></script>
1818
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/markdown/markdown.min.js"></script>
19-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/clike/clike.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/edit/closebrackets.min.js"></script>
20-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/edit/matchbrackets.min.js"></script>
19+
20+
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/dialog/dialog.min.js"></script>
21+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/dialog/dialog.min.css">
22+
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/search/searchcursor.min.js"></script>
23+
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/search/search.min.js"></script>
24+
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/selection/active-line.min.js"></script>
25+
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldcode.min.js"></script>
26+
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldgutter.min.js"></script>
27+
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/brace-fold.min.js"></script>
28+
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/xml-fold.min.js"></script>
29+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldgutter.min.css">
2130

2231
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.0/beautify.js"></script>
32+
<script src="https://cdnjs.cloudflare.com/ajax/libs/split.js/1.6.5/split.min.js"></script>
33+
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
34+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
2335

2436
<style>
25-
/* Dark Scrollbar */
26-
#fileTree::-webkit-scrollbar, .CodeMirror-vscrollbar { width: 10px; }
27-
#fileTree::-webkit-scrollbar-track, .CodeMirror-vscrollbar { background: #1f2937; }
28-
#fileTree::-webkit-scrollbar-thumb { background-color: #55595c; border-radius: 5px; }
29-
#fileTree::-webkit-scrollbar-thumb:hover { background: #6f7478; }
30-
31-
/* Tree node styling */
32-
.tree-node-label { padding: 6px 10px; border-radius: 4px; transition: background-color 0.15s; user-select: none; }
33-
.tree-node-label:hover { background-color: #3f444c; }
34-
.file-active { background-color: #4c5258 !important; color: #a9f0d1; font-weight: 600; }
37+
/* Base Styles */
38+
body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
39+
40+
/* Scrollbars */
41+
::-webkit-scrollbar { width: 10px; height: 10px; }
42+
::-webkit-scrollbar-track { background: #111827; }
43+
::-webkit-scrollbar-thumb { background-color: #374151; border-radius: 5px; border: 2px solid #111827; }
44+
::-webkit-scrollbar-thumb:hover { background-color: #4b5563; }
45+
46+
/* Split.js Gutters */
47+
.gutter { background-color: #1f2937; background-repeat: no-repeat; background-position: 50%; transition: background 0.2s; position: relative; z-index: 10; }
48+
.gutter:hover { background-color: #3b82f6; }
49+
.gutter.gutter-horizontal { cursor: col-resize; }
50+
51+
/* Tree View */
52+
.tree-node {
53+
@apply flex items-center gap-2 px-2 py-1.5 rounded cursor-pointer select-none text-sm text-gray-400 border border-transparent transition-all;
54+
}
55+
.tree-node:hover { @apply bg-gray-800 text-gray-200; }
56+
.tree-node.active { @apply bg-blue-900/40 text-blue-300 border-blue-500/30; }
57+
/* Highlight for search matches */
58+
.tree-node.highlight-match { @apply text-yellow-300 font-medium; }
59+
60+
/* CodeMirror Overrides */
61+
.CodeMirror { height: 100%; font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 13px; line-height: 1.6; background-color: #1f2937 !important; }
62+
.cm-s-dracula.CodeMirror { background-color: #0f111a !important; }
63+
.cm-s-dracula .CodeMirror-gutters { background-color: #0f111a !important; border-right: 1px solid #1f2937; }
64+
.CodeMirror-activeline-background { background: #1e293b !important; }
65+
66+
/* Tabs Styling */
67+
#tabsContainer { scrollbar-width: none; }
68+
#tabsContainer::-webkit-scrollbar { display: none; }
3569

36-
/* CodeMirror fixes for full height and theme */
37-
/* This ensures the editor takes up the full available height and enables proper internal scrolling */
38-
.CodeMirror { height: 100%; font-size: 14px; line-height: 1.5; }
39-
.cm-s-dracula .CodeMirror-cursor { border-left: 1px solid #ff79c6 !important; }
40-
41-
/* Media Viewer Styling */
42-
#mediaViewer { overflow: auto; background-color: #1e293b; }
43-
#mediaViewer img, #mediaViewer svg { max-width: 100%; max-height: 100%; object-fit: contain; }
44-
45-
/* Toast notification style */
46-
#toast { position: fixed; top: 1rem; right: 1rem; padding: 10px 20px; border-radius: 6px; background-color: #10b981; color: white; z-index: 100; opacity: 0; transition: opacity 0.3s ease-in-out; }
47-
.toast-active { opacity: 1; }
70+
.tab-item {
71+
@apply flex items-center gap-2 px-3 py-2 text-xs border-r border-gray-700 text-gray-400 cursor-pointer bg-gray-800 transition-colors select-none min-w-[120px] max-w-[200px] h-full relative;
72+
}
73+
.tab-item:hover { @apply bg-gray-700 text-gray-200; }
74+
.tab-item.active { @apply bg-[#0f111a] text-blue-400 border-t-2 border-t-blue-500; }
75+
.tab-close { @apply opacity-0 hover:bg-red-500/20 hover:text-red-400 rounded p-0.5 transition-all; }
76+
.tab-item:hover .tab-close, .tab-item.active .tab-close { opacity: 1; }
77+
78+
/* Context Menu */
79+
#contextMenu { @apply fixed bg-gray-800 border border-gray-700 shadow-xl rounded-lg py-1 z-50 hidden min-w-[160px]; }
80+
.ctx-item { @apply px-4 py-2 text-sm text-gray-300 hover:bg-blue-600 hover:text-white cursor-pointer flex items-center gap-2; }
81+
82+
/* Markdown */
83+
.markdown-body { @apply p-8 prose prose-invert prose-sm max-w-none overflow-auto h-full bg-[#0f111a]; }
84+
85+
/* Loading Overlay */
86+
#loadingOverlay { backdrop-filter: blur(2px); }
4887
</style>
4988
</head>
50-
<body class="flex flex-col h-screen bg-gray-900 text-gray-200 overflow-hidden">
51-
52-
<header class="flex justify-between items-center bg-gray-800 text-white p-4 shadow-xl z-20 border-b border-gray-700">
53-
<h1 class="text-xl font-bold tracking-wider">
54-
<span class="text-blue-400 mr-2">{'/'}</span> CRX/ZIP Code Inspector
55-
</h1>
56-
<div class="flex gap-3 items-center">
57-
<button id="exportBtn" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg text-sm font-medium transition duration-200 shadow-md" title="Export all files as a ZIP archive">
58-
Export All
59-
</button>
60-
<button id="downloadBtn" class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded-lg text-sm font-medium transition duration-200 shadow-md" title="Download the currently viewed file">
61-
Download Current
89+
<body class="flex flex-col h-screen bg-gray-900 text-gray-200 overflow-hidden font-sans selection:bg-blue-500/30">
90+
91+
<div id="contextMenu">
92+
<div class="ctx-item" id="ctxCopyPath"><i class="fa-regular fa-copy"></i> Copy Path</div>
93+
<div class="ctx-item" id="ctxDownload"><i class="fa-solid fa-download"></i> Download</div>
94+
</div>
95+
96+
<div id="dropOverlay" class="fixed inset-0 bg-gray-900/90 z-50 hidden flex flex-col items-center justify-center border-4 border-blue-500 border-dashed m-6 rounded-2xl pointer-events-none">
97+
<i class="fa-solid fa-cloud-arrow-up text-6xl text-blue-400 mb-4 animate-bounce"></i>
98+
<h2 class="text-3xl font-bold text-white">Drop to Analyze</h2>
99+
</div>
100+
101+
<div id="loadingOverlay" class="fixed inset-0 bg-black/50 z-[60] hidden flex flex-col items-center justify-center">
102+
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500 mb-4"></div>
103+
<p class="text-white font-medium animate-pulse">Processing...</p>
104+
</div>
105+
106+
<header class="flex justify-between items-center bg-gray-800 border-b border-gray-700 px-4 h-14 flex-shrink-0 z-20">
107+
<div class="flex items-center gap-3">
108+
<div class="bg-gradient-to-br from-blue-600 to-blue-800 text-white p-1.5 rounded-lg shadow-lg">
109+
<i class="fa-solid fa-box-open text-sm"></i>
110+
</div>
111+
<h1 class="text-base font-bold tracking-wide text-gray-100">
112+
CRX<span class="text-blue-500">/</span>Inspector
113+
</h1>
114+
</div>
115+
116+
<div class="flex items-center gap-3">
117+
<button id="exportBtn" class="bg-gray-700 hover:bg-gray-600 px-3 py-1.5 rounded text-xs font-medium transition flex items-center gap-2 border border-gray-600">
118+
<i class="fa-solid fa-file-zipper"></i> Export ZIP
62119
</button>
120+
<label class="bg-blue-600 hover:bg-blue-700 px-4 py-1.5 rounded text-xs font-bold transition flex items-center gap-2 cursor-pointer shadow-lg shadow-blue-500/20">
121+
<i class="fa-solid fa-upload"></i> Open File
122+
<input type="file" id="crxInput" accept=".crx, .zip, .xpi" class="hidden">
123+
</label>
63124
</div>
64125
</header>
65126

66-
<div id="toast" role="alert" aria-live="assertive"></div>
67-
68-
<div class="flex flex-1 overflow-hidden">
69-
<div id="leftPanel" class="flex flex-col w-80 bg-gray-800 border-r border-gray-700 shadow-2xl z-10 flex-shrink-0">
70-
<div class="p-4 flex flex-col gap-3 border-b border-gray-700">
71-
<input type="file" id="crxInput" accept=".crx, .zip" class="block w-full text-sm text-gray-400 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-gray-700 file:text-blue-400 hover:file:bg-gray-600 transition duration-150" aria-label="Select CRX or ZIP File">
72-
<button id="processBtn" class="bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg font-semibold transition duration-200 shadow-md" title="Process the selected file">
73-
Analyze File
74-
</button>
75-
<input type="text" id="searchBox" placeholder="Filter file tree paths..." class="p-2 border border-gray-700 rounded-lg bg-gray-700 text-gray-100 placeholder-gray-400 focus:ring-blue-500 focus:border-blue-500" aria-label="Filter file tree">
127+
<div class="flex-1 flex overflow-hidden relative">
128+
129+
<div id="sidebar" class="bg-gray-800 flex flex-col border-r border-gray-700 min-w-[220px]">
130+
131+
<div class="p-2 border-b border-gray-700 bg-gray-800">
132+
<div class="relative">
133+
<i class="fa-solid fa-search absolute left-3 top-2.5 text-gray-500 text-xs"></i>
134+
<input type="text" id="searchBox" placeholder="Filter files (recursive)..." class="w-full bg-gray-900 border border-gray-700 text-gray-200 text-xs rounded pl-8 pr-2 py-2 focus:ring-1 focus:ring-blue-500 focus:border-blue-500 outline-none placeholder-gray-600 transition-all">
135+
</div>
76136
</div>
77-
<div id="fileTree" role="tree" class="flex-1 overflow-auto p-4">
78-
<div id="treePlaceholder" class="text-gray-500 text-center mt-8 p-2">
79-
<h3 class="text-lg font-bold text-gray-400 mb-2">Get Started</h3>
80-
<p class="text-sm">1. Select a **.crx** or **.zip** file above.</p>
81-
<p class="text-sm">2. Click **Analyze File** to view the structure.</p>
137+
138+
<div id="fileTree" role="tree" class="flex-1 overflow-auto p-2 pb-10 custom-scrollbar focus:outline-none" tabindex="0">
139+
<div id="treePlaceholder" class="flex flex-col items-center justify-center h-64 text-gray-500 opacity-60">
140+
<i class="fa-solid fa-folder-tree text-4xl mb-3 text-gray-600"></i>
141+
<p class="text-xs">No file loaded</p>
82142
</div>
83143
</div>
144+
145+
<div id="fileInfoPanel" class="p-3 bg-gray-900 border-t border-gray-700 text-[10px] text-gray-400 hidden">
146+
<div class="flex justify-between mb-1"><span class="font-bold text-gray-500">SIZE</span> <span id="infoSize" class="text-gray-300">-</span></div>
147+
<div class="flex justify-between"><span class="font-bold text-gray-500">TYPE</span> <span id="infoType" class="text-gray-300">-</span></div>
148+
</div>
84149
</div>
85150

86-
<div id="rightPanel" class="flex-1 flex flex-col overflow-hidden">
151+
<div id="mainContent" class="bg-[#0f111a] flex flex-col flex-1 overflow-hidden min-w-[300px]">
87152

88-
<div id="viewerHeader" class="p-3 border-b border-gray-700 bg-gray-800 flex justify-between items-center sticky top-0 z-10 hidden flex-shrink-0">
89-
<h2 id="currentFileNameDisplay" class="text-md font-medium text-blue-400 truncate" aria-live="polite"></h2>
90-
<div class="flex gap-3">
91-
<button id="copyFileBtn" class="bg-gray-700 hover:bg-gray-600 text-sm px-3 py-1 rounded-full transition duration-150 text-gray-300" title="Copy file content to clipboard">Copy Content</button>
92-
<button id="unminifyBtn" class="bg-yellow-600 hover:bg-yellow-700 text-white text-sm px-3 py-1 rounded-full transition duration-150 hidden" title="Toggle Prettify/Minify JavaScript code">
93-
Prettify Code
94-
</button>
153+
<div id="tabsWrapper" class="bg-gray-800 border-b border-gray-700 h-9 flex hidden">
154+
<div id="tabsContainer" class="flex-1 flex overflow-x-auto">
155+
</div>
156+
</div>
157+
158+
<div id="editorToolbar" class="h-9 border-b border-gray-700 bg-gray-800/30 flex items-center justify-between px-4 hidden backdrop-blur-sm">
159+
<div class="flex items-center gap-2 text-xs text-gray-400 overflow-hidden">
160+
<i class="fa-regular fa-folder-open text-blue-500"></i>
161+
<span id="filePathDisplay" class="font-mono text-gray-300 truncate"></span>
162+
</div>
163+
<div class="flex items-center gap-3">
164+
<button id="markdownPreviewBtn" class="hidden text-gray-400 hover:text-white text-xs gap-1 flex items-center" title="Toggle Preview">
165+
<i class="fa-solid fa-book-open"></i> Read
166+
</button>
167+
<div class="h-3 w-px bg-gray-600"></div>
168+
<button id="unminifyBtn" class="text-yellow-600 hover:text-yellow-400 text-xs font-semibold hidden flex items-center gap-1" title="Format Code">
169+
<i class="fa-solid fa-wand-magic-sparkles"></i> Prettify
170+
</button>
171+
<button id="copyFileBtn" class="text-gray-400 hover:text-white text-xs flex items-center gap-1" title="Copy Content">
172+
<i class="fa-regular fa-copy"></i> Copy
173+
</button>
174+
</div>
175+
</div>
176+
177+
<div id="viewerContainer" class="flex-1 relative overflow-hidden bg-[#0f111a]">
178+
179+
<div id="welcomeScreen" class="absolute inset-0 flex flex-col items-center justify-center text-gray-600 select-none z-10 bg-gray-900">
180+
<div class="flex flex-col items-center animate-fade-in">
181+
<div class="w-20 h-20 bg-gray-800 rounded-2xl flex items-center justify-center mb-6 shadow-xl border border-gray-700">
182+
<i class="fa-solid fa-cloud-arrow-up text-4xl text-blue-500"></i>
183+
</div>
184+
<h3 class="text-xl font-bold text-gray-200">Start Analyzing</h3>
185+
<p class="text-sm mt-2 text-gray-500 text-center max-w-xs">Open a CRX, ZIP, or XPI file to inspect its source code and assets.</p>
186+
<button id="heroUploadBtn" class="mt-6 bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-full text-sm font-medium transition shadow-lg shadow-blue-500/20">
187+
Select File
188+
</button>
189+
</div>
190+
</div>
191+
192+
<div id="noFileSelected" class="absolute inset-0 flex flex-col items-center justify-center text-gray-600 select-none z-10 bg-[#0f111a] hidden">
193+
<i class="fa-solid fa-code-branch text-5xl text-gray-700 mb-4"></i>
194+
<h3 class="text-lg font-medium text-gray-400">No File Open</h3>
195+
<p class="text-xs mt-2 text-gray-600">Select a file from the sidebar.</p>
95196
</div>
197+
198+
<div id="editorWrapper" class="h-full hidden"></div>
199+
200+
<div id="markdownViewer" class="markdown-body hidden"></div>
201+
202+
<div id="mediaViewer" class="hidden h-full flex flex-col items-center justify-center bg-[#0f111a] relative overflow-hidden">
203+
<div class="absolute bottom-6 flex gap-2 z-10 bg-gray-800/80 backdrop-blur p-1.5 rounded-full border border-gray-600 shadow-xl">
204+
<button id="zoomOut" class="w-8 h-8 rounded-full hover:bg-gray-600 text-gray-300 flex items-center justify-center"><i class="fa-solid fa-minus"></i></button>
205+
<span id="zoomLevelDisplay" class="w-12 text-center text-xs font-mono text-gray-300 flex items-center justify-center">100%</span>
206+
<button id="zoomIn" class="w-8 h-8 rounded-full hover:bg-gray-600 text-gray-300 flex items-center justify-center"><i class="fa-solid fa-plus"></i></button>
207+
<button id="resetZoom" class="w-8 h-8 rounded-full hover:bg-gray-600 text-gray-300 flex items-center justify-center" title="Reset"><i class="fa-solid fa-compress"></i></button>
208+
</div>
209+
<div id="mediaContainer" class="transform-gpu transition-transform duration-100 ease-out origin-center p-10">
210+
</div>
211+
</div>
212+
96213
</div>
97214

98-
<div id="viewerContainer" class="flex-1 flex flex-col overflow-hidden bg-gray-900">
99-
100-
<div id="editorContainer" class="flex-1 hidden">
101-
</div>
102-
103-
<div id="mediaViewer" class="p-4 h-full flex justify-center items-center hidden flex-1">
104-
</div>
105-
106-
<div id="initialMessage" class="p-8 text-center text-gray-500 h-full flex flex-col justify-center items-center flex-1">
107-
<svg class="w-16 h-16 mb-4 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>
108-
<p class="text-lg font-semibold">Select a file from the tree to inspect its source or view media.</p>
109-
<p class="text-sm mt-2 text-gray-600">The professional editor supports large files and search (Ctrl+F) for superior performance.</p>
110-
</div>
111-
112-
<div id="statusBar" class="p-1 text-xs bg-gray-700 text-gray-400 border-t border-gray-600 hidden justify-end items-center gap-4 flex-shrink-0">
113-
<span class="text-green-400 font-semibold">Ready</span>
114-
<span>Cursor: L<span id="cursorLine">1</span>, C<span id="cursorCol">1</span></span>
115-
</div>
215+
<div id="statusBar" class="h-6 bg-gray-800 border-t border-gray-700 flex justify-between items-center px-3 text-[10px] text-gray-400 select-none flex-shrink-0">
216+
<div class="flex items-center gap-2">
217+
<div class="w-2 h-2 rounded-full bg-green-500"></div>
218+
<span id="statusMsg">Ready</span>
219+
</div>
220+
<div class="flex gap-4 font-mono">
221+
<span id="langDisplay">Text</span>
222+
<span>Ln <span id="cursorLine">1</span>, Col <span id="cursorCol">1</span></span>
223+
</div>
116224
</div>
117225
</div>
118226
</div>
119227

228+
<div id="toast" class="fixed bottom-6 right-6 px-4 py-3 rounded bg-gray-800 border-l-4 border-blue-500 shadow-2xl text-white font-medium text-sm transform transition-all duration-300 translate-y-20 opacity-0 z-[100] flex items-center gap-3">
229+
<i id="toastIcon" class="fa-solid fa-info-circle text-blue-400"></i>
230+
<span id="toastMsg">Notification</span>
231+
</div>
232+
120233
<script src="https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js"></script>
121234
<script src="viewer.js"></script>
122235
</body>

0 commit comments

Comments
 (0)