|
2 | 2 | <html lang="en"> |
3 | 3 | <head> |
4 | 4 | <meta charset="UTF-8"> |
5 | | -<title>modcore CRX Viewer</title> |
| 5 | +<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 6 | +<title>CRX/ZIP Code Inspector (Fixed Layout)</title> |
| 7 | +<script src="https://cdn.tailwindcss.com"></script> |
| 8 | + |
| 9 | +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css"> |
| 10 | +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/dracula.min.css"> |
| 11 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"></script> |
| 12 | + |
| 13 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/javascript/javascript.min.js"></script> |
| 14 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/json/json.min.js"></script> |
| 15 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/css/css.min.js"></script> |
| 16 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/xml/xml.min.js"></script> |
| 17 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/htmlmixed/htmlmixed.min.js"></script> |
| 18 | +<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> |
| 21 | + |
| 22 | +<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.14.0/beautify.js"></script> |
| 23 | + |
6 | 24 | <style> |
7 | | - body { margin:0; font-family:Arial,sans-serif; } |
8 | | - header { background:#20232a; color:white; padding:12px 20px; font-size:1.5em; display:flex; justify-content:space-between; align-items:center; } |
9 | | - header button { background:#61dafb; border:none; padding:6px 12px; cursor:pointer; border-radius:4px; } |
10 | | - header button:hover { background:#21a1f1; } |
11 | | - |
12 | | - #main { display:flex; height:calc(100vh - 50px); } |
13 | | - #leftPanel { width:320px; background:#fff; border-right:1px solid #ccc; display:flex; flex-direction:column; } |
14 | | - #fileControls { padding:10px; border-bottom:1px solid #ccc; } |
15 | | - #fileTree { flex:1; overflow:auto; padding:10px; } |
16 | | - #fileTree ul { list-style:none; padding-left:15px; } |
17 | | - #fileTree li { cursor:pointer; padding:2px 4px; border-radius:3px; } |
18 | | - #fileTree li:hover { background:#e0e0e0; } |
19 | | - #fileTree li.selected { background:#61dafb; color:#fff; } |
20 | | - |
21 | | - #rightPanel { flex:1; display:flex; flex-direction:column; } |
22 | | - #searchContainer { padding:10px; border-bottom:1px solid #ccc; display:flex; gap:5px; align-items:center; } |
23 | | - #viewer { flex:1; overflow:auto; padding:10px; font-family:monospace; white-space:pre; background:#1e1e1e; color:#ddd; } |
24 | | - |
25 | | - /* Dark/light themes */ |
26 | | - body.light #viewer { background:#f5f5f5; color:#111; } |
27 | | - body.light #fileTree li.selected { background:#21a1f1; color:#fff; } |
28 | | - |
29 | | - input[type="text"] { flex:1; padding:4px 6px; border-radius:4px; border:1px solid #ccc; } |
30 | | - button.small { padding:4px 8px; font-size:0.9em; } |
| 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; } |
| 35 | + |
| 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; } |
31 | 48 | </style> |
32 | | -<link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-tomorrow.css" rel="stylesheet" /> |
33 | 49 | </head> |
34 | | -<body> |
35 | | -<header> |
36 | | - modcore CRX Viewer |
37 | | - <button id="themeToggle">Toggle Theme</button> |
| 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 |
| 62 | + </button> |
| 63 | + </div> |
38 | 64 | </header> |
39 | | -<div id="main"> |
40 | | - <div id="leftPanel"> |
41 | | - <div id="fileControls"> |
42 | | - <input type="file" id="crxInput" accept=".crx"> |
43 | | - <button id="processBtn" class="small">Process File</button> |
| 65 | + |
| 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"> |
| 76 | + </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> |
| 82 | + </div> |
44 | 83 | </div> |
45 | | - <div id="fileTree"><ul id="treeRoot"></ul></div> |
46 | 84 | </div> |
47 | | - <div id="rightPanel"> |
48 | | - <div id="searchContainer"> |
49 | | - <input type="text" id="searchBox" placeholder="Search files..."> |
50 | | - <button id="exportBtn" class="small">Export Selected</button> |
| 85 | + |
| 86 | + <div id="rightPanel" class="flex-1 flex flex-col overflow-hidden"> |
| 87 | + |
| 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> |
| 95 | + </div> |
| 96 | + </div> |
| 97 | + |
| 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> |
51 | 116 | </div> |
52 | | - <pre id="viewer" class="language-js">Upload a CRX file and press "Process File" to view source.</pre> |
53 | 117 | </div> |
54 | 118 | </div> |
55 | 119 |
|
56 | | -<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.js"></script> |
57 | | -<script src="https://cdn.jsdelivr.net/npm/jszip@3.11.0/dist/jszip.min.js"></script> |
| 120 | +<script src="https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js"></script> |
58 | 121 | <script src="viewer.js"></script> |
59 | 122 | </body> |
60 | 123 | </html> |
0 commit comments