UNPKG

@gramercytech/gx-toolkit

Version:
525 lines (455 loc) 11.5 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> :root { --main-bg: #f8f9fa; --header-bg: #2563eb; --card-bg: #ffffff; --border-color: #e5e7eb; --text-primary: #1f2937; --text-secondary: #6b7280; --success-color: #10b981; --error-color: #ef4444; --warning-color: #f59e0b; --shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); } * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-size: 14px; line-height: 1.5; color: var(--text-primary); background: var(--main-bg); width: 420px; min-height: 500px; } .header { background: linear-gradient(135deg, var(--header-bg) 0%, #1d4ed8 100%); color: white; padding: 20px; text-align: center; box-shadow: var(--shadow); } .header h1 { font-size: 18px; font-weight: 600; margin: 0 0 8px 0; } .header .subtitle { font-size: 12px; opacity: 0.9; font-weight: 400; } .main-container { padding: 20px; } /* Main Toggle Section */ .main-toggle { background: var(--card-bg); border-radius: 12px; box-shadow: var(--shadow); overflow: hidden; margin-bottom: 20px; } .toggle-header { padding: 16px 20px; border-bottom: 1px solid var(--border-color); display: flex; align-items: center; justify-content: space-between; } .toggle-title { font-weight: 600; font-size: 15px; } .master-toggle { position: relative; width: 52px; height: 28px; } .master-toggle input { opacity: 0; width: 0; height: 0; } .master-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #cbd5e1; border-radius: 28px; transition: all 0.3s ease; } .master-slider:before { position: absolute; content: ""; height: 22px; width: 22px; left: 3px; bottom: 3px; background-color: white; border-radius: 50%; transition: all 0.3s ease; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .master-toggle input:checked + .master-slider { background-color: var(--success-color); } .master-toggle input:checked + .master-slider:before { transform: translateX(24px); } .status-info { padding: 12px 20px; background: #f1f5f9; font-size: 13px; color: var(--text-secondary); } /* Rule Cards */ .rule-container { background: var(--card-bg); border-radius: 12px; box-shadow: var(--shadow); overflow: hidden; margin-bottom: 16px; } .rule-header { padding: 16px 20px; border-bottom: 1px solid var(--border-color); display: flex; align-items: center; justify-content: space-between; background: #fafbfc; } .rule-title { font-weight: 600; font-size: 14px; color: var(--text-primary); } .rule-subtitle { font-size: 12px; color: var(--text-secondary); margin-top: 2px; } .rule-toggle { position: relative; width: 44px; height: 24px; } .rule-toggle input { opacity: 0; width: 0; height: 0; } .rule-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #cbd5e1; border-radius: 24px; transition: all 0.3s ease; } .rule-slider:before { position: absolute; content: ""; height: 18px; width: 18px; left: 3px; bottom: 3px; background-color: white; border-radius: 50%; transition: all 0.3s ease; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); } .rule-toggle input:checked + .rule-slider { background-color: var(--success-color); } .rule-toggle input:checked + .rule-slider:before { transform: translateX(20px); } .rule-content { padding: 20px; } /* Form Fields */ .form-group { margin-bottom: 16px; } .form-group:last-child { margin-bottom: 0; } .form-group label { display: block; font-weight: 500; margin-bottom: 6px; font-size: 13px; color: var(--text-primary); } .form-group input, .form-group textarea { width: 100%; padding: 10px 12px; border: 1px solid var(--border-color); border-radius: 8px; font-size: 13px; transition: all 0.2s ease; background: white; } .form-group input:focus, .form-group textarea:focus { outline: none; border-color: var(--header-bg); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); } .form-group textarea { resize: vertical; min-height: 65px; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; } /* Checkbox */ .checkbox-group { display: flex; align-items: center; margin-bottom: 16px; } .checkbox-group input[type="checkbox"] { width: auto; margin-right: 8px; cursor: pointer; } .checkbox-group label { margin-bottom: 0; cursor: pointer; font-size: 13px; } /* Action Buttons */ .action-buttons { display: flex; gap: 8px; margin-top: 20px; } .btn { flex: 1; padding: 10px 16px; border: none; border-radius: 8px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; text-align: center; } .btn-primary { background: var(--header-bg); color: white; } .btn-primary:hover { background: #1d4ed8; transform: translateY(-1px); box-shadow: var(--shadow-lg); } .btn-secondary { background: #f3f4f6; color: var(--text-primary); border: 1px solid var(--border-color); } .btn-secondary:hover { background: #e5e7eb; transform: translateY(-1px); } .btn:disabled { opacity: 0.6; cursor: not-allowed; transform: none !important; } /* Status Messages */ .status-message { padding: 12px 16px; border-radius: 8px; margin-bottom: 16px; font-size: 13px; font-weight: 500; } .status-success { background: #ecfdf5; color: #065f46; border: 1px solid #a7f3d0; } .status-error { background: #fef2f2; color: #991b1b; border: 1px solid #fca5a5; } /* Hidden class */ .hidden { display: none !important; } /* Disabled state for rule containers */ .rule-container.disabled { opacity: 0.6; } .rule-container.disabled .rule-content { pointer-events: none; } /* Pattern info */ .pattern-info { font-size: 11px; color: var(--text-secondary); margin-top: 4px; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; } /* Advanced Settings */ .advanced-settings { background: var(--card-bg); border-radius: 12px; box-shadow: var(--shadow); overflow: hidden; margin-top: 20px; } .advanced-header { padding: 16px 20px; background: #fafbfc; border-bottom: 1px solid var(--border-color); cursor: pointer; display: flex; align-items: center; justify-content: space-between; } .advanced-header:hover { background: #f1f5f9; } .advanced-title { font-weight: 600; font-size: 14px; } .advanced-toggle { font-size: 12px; color: var(--text-secondary); } .advanced-content { padding: 20px; } </style> </head> <body> <div class="header"> <h1>JavaScript Proxy</h1> <div class="subtitle">Intercept & redirect web requests</div> </div> <div class="main-container"> <!-- Status Messages --> <div id="statusMessage" class="status-message hidden"></div> <!-- Main Toggle --> <div class="main-toggle"> <div class="toggle-header"> <div class="toggle-title">Proxy Extension</div> <label class="master-toggle"> <input type="checkbox" id="masterToggle"> <span class="master-slider"></span> </label> </div> <div class="status-info" id="statusInfo"> Extension is currently disabled </div> </div> <!-- JavaScript Rule --> <div class="rule-container" id="jsRuleContainer"> <div class="rule-header"> <div> <div class="rule-title">JavaScript Files (.js)</div> <div class="rule-subtitle">Redirect JavaScript files to development server</div> </div> <label class="rule-toggle"> <input type="checkbox" id="jsRuleToggle"> <span class="rule-slider"></span> </label> </div> <div class="rule-content"> <div class="form-group"> <label for="jsRedirectUrl">Redirect URL:</label> <input type="url" id="jsRedirectUrl" placeholder="https://localhost:3060/src/Plugin.vue"> </div> <div class="checkbox-group"> <input type="checkbox" id="jsUseCustomPattern"> <label for="jsUseCustomPattern">Use custom URL pattern</label> </div> <div class="form-group" id="jsPatternGroup"> <label for="jsPattern">URL Pattern (RegEx):</label> <textarea id="jsPattern" placeholder="uploads\/plugin-version\/\d+\/file_name\/.*\.js(\?.*)?"></textarea> <div class="pattern-info">Matches JavaScript files in plugin uploads</div> </div> </div> </div> <!-- CSS Rule --> <div class="rule-container" id="cssRuleContainer"> <div class="rule-header"> <div> <div class="rule-title">CSS Files (.css)</div> <div class="rule-subtitle">Handle CSS files with redirect or blank return</div> </div> <label class="rule-toggle"> <input type="checkbox" id="cssRuleToggle"> <span class="rule-slider"></span> </label> </div> <div class="rule-content"> <div class="checkbox-group"> <input type="checkbox" id="cssReturnBlank"> <label for="cssReturnBlank">Return blank CSS document instead of redirecting</label> </div> <div class="form-group" id="cssRedirectGroup"> <label for="cssRedirectUrl">Redirect URL:</label> <input type="url" id="cssRedirectUrl" placeholder="https://localhost:3060/src/styles.css"> </div> <div class="checkbox-group"> <input type="checkbox" id="cssUseCustomPattern"> <label for="cssUseCustomPattern">Use custom URL pattern</label> </div> <div class="form-group" id="cssPatternGroup"> <label for="cssPattern">URL Pattern (RegEx):</label> <textarea id="cssPattern" placeholder="uploads\/plugin-version\/\d+\/style_file_name\/.*\.css(\?.*)?"></textarea> <div class="pattern-info">Matches CSS files in plugin uploads</div> </div> </div> </div> <!-- Advanced Settings --> <div class="advanced-settings"> <div class="advanced-header" id="advancedHeader"> <div class="advanced-title">Advanced Settings</div> <div class="advanced-toggle" id="advancedToggle">Show ▼</div> </div> <div class="advanced-content hidden" id="advancedContent"> <div class="checkbox-group"> <input type="checkbox" id="maskingMode"> <label for="maskingMode">URL Masking Mode (experimental)</label> </div> <div class="checkbox-group"> <input type="checkbox" id="clearCacheOnEnable"> <label for="clearCacheOnEnable">Clear cache when enabling proxy</label> </div> <div class="checkbox-group"> <input type="checkbox" id="disableCacheForRedirects"> <label for="disableCacheForRedirects">Disable cache for redirected requests</label> </div> </div> </div> <!-- Action Buttons --> <div class="action-buttons"> <button class="btn btn-secondary" id="clearCacheBtn">Clear Cache</button> <button class="btn btn-primary" id="saveBtn">Save Changes</button> </div> </div> <script src="popup.js"></script> </body> </html>