mraidChecker

This commit is contained in:
2026-05-27 18:13:51 +08:00
parent 6be55255b2
commit c7ad1e14ca
4 changed files with 623 additions and 25 deletions

View File

@@ -1,28 +1,86 @@
import * as vscode from 'vscode';
const BETA_TOOLS_ENABLED_KEY = 'hplToolbox.betaTools.enabled';
interface ToolDefinition {
command: string;
title: string;
description: string;
beta?: boolean;
}
const TOOLS: ToolDefinition[] = [
{
command: 'hplToolbox.openPlecUpload',
title: 'PLEC Upload',
description: 'Upload HTML to internal PLEC server',
},
{
command: 'hplToolbox.openApplovinUpload',
title: 'AppLovin Demo Upload',
description: 'Upload to p.applov.in (QR preview)',
},
{
command: 'hplToolbox.openBase64Scanner',
title: 'Base64 Scanner',
description: 'Find non-base64 assets in HTML',
},
{
command: 'hplToolbox.openMraidChecker',
title: 'MRAID Checker',
description: 'Check MRAID requirements and best practices',
beta: true,
},
{
command: 'hplToolbox.openDailyUpdate',
title: 'Daily Update',
description: 'Compose & copy a daily status',
},
{
command: 'hplToolbox.openSendToMobile',
title: 'Send To Mobile',
description: 'Share HTML to a phone via LAN + QR',
},
];
export class LauncherViewProvider implements vscode.WebviewViewProvider {
constructor(private readonly context: vscode.ExtensionContext) {}
resolveWebviewView(view: vscode.WebviewView) {
view.webview.options = { enableScripts: true };
const version = this.context.extension.packageJSON.version as string;
view.webview.html = getHtml(version);
view.webview.onDidReceiveMessage((msg) => {
const betaToolsEnabled = this.context.globalState.get<boolean>(BETA_TOOLS_ENABLED_KEY, false);
view.webview.html = getHtml(version, betaToolsEnabled);
view.webview.onDidReceiveMessage(async (msg) => {
if (msg?.type === 'open' && typeof msg.command === 'string') {
vscode.commands.executeCommand(msg.command);
} else if (msg?.type === 'setBetaToolsEnabled' && typeof msg.enabled === 'boolean') {
await this.context.globalState.update(BETA_TOOLS_ENABLED_KEY, msg.enabled);
view.webview.html = getHtml(version, msg.enabled);
}
});
}
}
function getHtml(version: string): string {
function getHtml(version: string, betaToolsEnabled: boolean): string {
const visibleTools = TOOLS.filter(tool => betaToolsEnabled || !tool.beta);
const hiddenBetaCount = TOOLS.filter(tool => tool.beta).length - visibleTools.filter(tool => tool.beta).length;
const toolButtons = visibleTools.map(renderToolButton).join('\n');
return `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<style>
body { font-family: var(--vscode-font-family); color: var(--vscode-foreground); padding: 12px 8px; }
body {
min-height: calc(100vh - 24px);
display: flex;
flex-direction: column;
font-family: var(--vscode-font-family);
color: var(--vscode-foreground);
padding: 12px 8px;
}
h3 { margin: 0 0 12px 0; font-size: 11px; text-transform: uppercase; letter-spacing: 0.6px; opacity: 0.7; }
.tools { flex: 1; }
.tool-btn {
display: block; width: 100%; text-align: left;
padding: 8px 10px; margin-bottom: 6px;
@@ -34,31 +92,48 @@ function getHtml(version: string): string {
.tool-btn:hover {
background: var(--vscode-button-secondaryHoverBackground);
}
.tool-title { display: flex; align-items: center; gap: 6px; }
.tool-desc { display: block; font-size: 11px; opacity: 0.7; margin-top: 2px; }
.beta-badge {
padding: 1px 5px;
border: 1px solid var(--vscode-panel-border);
border-radius: 3px;
color: var(--vscode-descriptionForeground);
font-size: 10px;
text-transform: uppercase;
}
.beta-toggle {
margin-top: 12px;
padding-top: 10px;
border-top: 1px solid var(--vscode-panel-border);
}
.beta-toggle button {
width: 100%;
padding: 7px 10px;
background: var(--vscode-button-secondaryBackground);
color: var(--vscode-button-secondaryForeground);
border: 1px solid var(--vscode-panel-border);
border-radius: 3px;
cursor: pointer;
text-align: left;
}
.beta-toggle button:hover {
background: var(--vscode-button-secondaryHoverBackground);
}
.beta-note { display: block; margin-top: 3px; color: var(--vscode-descriptionForeground); font-size: 11px; }
</style>
</head>
<body>
<h3>HPL Toolbox ${version}</h3>
<button class="tool-btn" data-cmd="hplToolbox.openPlecUpload">
PLEC Upload
<span class="tool-desc">Upload HTML to internal PLEC server</span>
</button>
<button class="tool-btn" data-cmd="hplToolbox.openApplovinUpload">
AppLovin Demo Upload
<span class="tool-desc">Upload to p.applov.in (QR preview)</span>
</button>
<button class="tool-btn" data-cmd="hplToolbox.openBase64Scanner">
Base64 Scanner
<span class="tool-desc">Find non-base64 assets in HTML</span>
</button>
<button class="tool-btn" data-cmd="hplToolbox.openDailyUpdate">
Daily Update
<span class="tool-desc">Compose &amp; copy a daily status</span>
</button>
<button class="tool-btn" data-cmd="hplToolbox.openSendToMobile">
Send To Mobile
<span class="tool-desc">Share HTML to a phone via LAN + QR</span>
</button>
<div class="tools">
${toolButtons}
</div>
<div class="beta-toggle">
<button id="betaToggle" data-enabled="${betaToolsEnabled ? 'true' : 'false'}">
${betaToolsEnabled ? 'Disable Beta Tools' : 'Enable Beta Tools'}
<span class="beta-note">${betaToolsEnabled ? 'Beta tools are visible in this launcher.' : `${hiddenBetaCount} beta tool(s) hidden until enabled.`}</span>
</button>
</div>
<script>
const vscode = acquireVsCodeApi();
document.querySelectorAll('.tool-btn').forEach((btn) => {
@@ -66,7 +141,28 @@ function getHtml(version: string): string {
vscode.postMessage({ type: 'open', command: btn.dataset.cmd });
});
});
document.getElementById('betaToggle').addEventListener('click', (event) => {
const enabled = event.currentTarget.dataset.enabled === 'true';
vscode.postMessage({ type: 'setBetaToolsEnabled', enabled: !enabled });
});
</script>
</body>
</html>`;
}
function renderToolButton(tool: ToolDefinition): string {
return ` <button class="tool-btn" data-cmd="${escapeHtml(tool.command)}">
<span class="tool-title">${escapeHtml(tool.title)}${tool.beta ? ' <span class="beta-badge">Beta</span>' : ''}</span>
<span class="tool-desc">${escapeHtml(tool.description)}</span>
</button>`;
}
function escapeHtml(value: string): string {
return value.replace(/[&<>"']/g, ch => ({
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;',
}[ch] ?? ch));
}