0.1.6
- cleanup per network folder for playworks converter - loosen mraid checker file and folder scanning
This commit is contained in:
@@ -80,15 +80,21 @@ export function openMraidChecker(_context: vscode.ExtensionContext) {
|
||||
let targets: string[] = [];
|
||||
let baseDir = '';
|
||||
let skipped = 0;
|
||||
let skippedReason = '';
|
||||
let noTargetsError = 'No HTML files were found.';
|
||||
if (files && files.length) {
|
||||
const existing = files.filter(f => fs.existsSync(f));
|
||||
targets = existing.filter(isSupportedMraidBuild);
|
||||
skipped = existing.length - targets.length;
|
||||
targets = existing;
|
||||
skipped = files.length - existing.length;
|
||||
skippedReason = 'missing file(s).';
|
||||
noTargetsError = 'No selected HTML files were found.';
|
||||
baseDir = targets.length ? commonBaseDir(targets) : '';
|
||||
} else if (folder && fs.existsSync(folder)) {
|
||||
const allHtmlFiles = await collectHtmlFiles(folder);
|
||||
targets = allHtmlFiles.filter(isSupportedMraidBuild);
|
||||
targets = allHtmlFiles.filter(isInSupportedMraidFolderPath);
|
||||
skipped = allHtmlFiles.length - targets.length;
|
||||
skippedReason = 'HTML file(s) outside AppLovin/ironSource/Unity folders.';
|
||||
noTargetsError = 'No AppLovin, ironSource, or Unity folder HTML files were found.';
|
||||
baseDir = folder;
|
||||
} else {
|
||||
panel.webview.postMessage({ type: 'results', results: [], error: 'Pick a folder or files first' });
|
||||
@@ -100,7 +106,8 @@ export function openMraidChecker(_context: vscode.ExtensionContext) {
|
||||
type: 'results',
|
||||
results: [],
|
||||
skipped,
|
||||
error: 'No AppLovin, ironSource, or Unity HTML builds were found.',
|
||||
skippedReason,
|
||||
error: noTargetsError,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -116,7 +123,7 @@ export function openMraidChecker(_context: vscode.ExtensionContext) {
|
||||
// Skip unreadable files, matching the scanner pattern used elsewhere.
|
||||
}
|
||||
}
|
||||
panel.webview.postMessage({ type: 'results', results, skipped });
|
||||
panel.webview.postMessage({ type: 'results', results, skipped, skippedReason });
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -193,9 +200,24 @@ function collectMraidCallLines(html: string): Map<string, number> {
|
||||
return calls;
|
||||
}
|
||||
|
||||
function isSupportedMraidBuild(filePath: string): boolean {
|
||||
const normalized = filePath.toLowerCase().replace(/\\/g, '/');
|
||||
return /(^|[\/._ -])(al|applovin|app-lovin|is|iron.?source|un|unity|unityads|unity-ads)([\/._ -]|$)/i.test(normalized);
|
||||
function isInSupportedMraidFolderPath(filePath: string): boolean {
|
||||
const folderParts = path.dirname(filePath)
|
||||
.split(/[\\/]+/)
|
||||
.map(part => part.toLowerCase());
|
||||
return folderParts.some(part => [
|
||||
'al',
|
||||
'applovin',
|
||||
'app-lovin',
|
||||
'is',
|
||||
'ironsource',
|
||||
'iron-source',
|
||||
'iron_source',
|
||||
'un',
|
||||
'unity',
|
||||
'unityads',
|
||||
'unity-ads',
|
||||
'unity_ads',
|
||||
].includes(part));
|
||||
}
|
||||
|
||||
function hasMraidReference(ctx: ScanContext): boolean {
|
||||
@@ -387,7 +409,7 @@ function getHtml(): string {
|
||||
</head>
|
||||
<body>
|
||||
<h2>MRAID Checker</h2>
|
||||
<div class="docs">Static checks for AppLovin, ironSource, and Unity HTML builds based on MRAID 3.0 requirements and best practices from mraidDocuments/.</div>
|
||||
<div class="docs">Static checks for AppLovin, ironSource, and Unity folder HTML builds based on MRAID 3.0 requirements and best practices from mraidDocuments/.</div>
|
||||
<div class="row">
|
||||
<input id="folder" type="text" placeholder="Folder to scan recursively..." />
|
||||
<button id="pick">Browse Folder...</button>
|
||||
@@ -457,8 +479,9 @@ function getHtml(): string {
|
||||
const requirements = msg.results.reduce((n, r) => n + r.issues.filter(i => i.severity === 'requirement').length, 0);
|
||||
const bestPractices = msg.results.reduce((n, r) => n + r.issues.filter(i => i.severity === 'best-practice').length, 0);
|
||||
const skipped = Number(msg.skipped || 0);
|
||||
const skippedText = skipped ? ' Skipped ' + skipped + ' non-target HTML file(s).' : '';
|
||||
statusEl.innerHTML = '<div class="summary">Scanned ' + total + ' AppLovin/ironSource/Unity HTML file(s). ' + withIssues + ' file(s) need review. ' + requirements + ' requirement issue(s), ' + bestPractices + ' best-practice warning(s).' + skippedText + '</div>';
|
||||
const skippedReason = msg.skippedReason || 'file(s).';
|
||||
const skippedText = skipped ? ' Skipped ' + skipped + ' ' + skippedReason : '';
|
||||
statusEl.innerHTML = '<div class="summary">Scanned ' + total + ' HTML file(s). ' + withIssues + ' file(s) need review. ' + requirements + ' requirement issue(s), ' + bestPractices + ' best-practice warning(s).' + skippedText + '</div>';
|
||||
resultsEl.innerHTML = '';
|
||||
for (const r of msg.results) {
|
||||
const requirementsForFile = r.issues.filter(i => i.severity === 'requirement').length;
|
||||
|
||||
@@ -94,6 +94,17 @@ export function openPlayworksConverter(_context: vscode.ExtensionContext) {
|
||||
}
|
||||
|
||||
const ZIPPED_NETWORKS = new Set(['gg', 'vu', 'mtg']);
|
||||
const NETWORK_OUTPUT_FOLDERS: Record<string, string> = {
|
||||
al: 'Applovin',
|
||||
is: 'Ironsource',
|
||||
un: 'Unity',
|
||||
fb: 'Facebook',
|
||||
gg: 'GoogleAds',
|
||||
mo: 'Moloco',
|
||||
vu: 'Vungle',
|
||||
mtg: 'Mintegral',
|
||||
tt: 'TikTok',
|
||||
};
|
||||
|
||||
function sourceBaseName(sourcePath: string): string {
|
||||
return path.basename(sourcePath, path.extname(sourcePath))
|
||||
@@ -105,10 +116,12 @@ async function convertNetwork(html: string, opts: ConvertOptions, network: strin
|
||||
const needsZip = ZIPPED_NETWORKS.has(network);
|
||||
const baseName = sourceBaseName(opts.sourcePath);
|
||||
const htmlFileName = `${baseName}_${network}.html`;
|
||||
const outputDir = path.join(opts.outputDir, NETWORK_OUTPUT_FOLDERS[network] ?? network);
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
|
||||
if (needsZip) {
|
||||
const tmpPath = path.join(opts.outputDir, `_tmp_${Date.now()}_${network}.html`);
|
||||
const zipPath = path.join(opts.outputDir, `${baseName}_${network}.zip`);
|
||||
const tmpPath = path.join(outputDir, `_tmp_${Date.now()}_${network}.html`);
|
||||
const zipPath = path.join(outputDir, `${baseName}_${network}.zip`);
|
||||
fs.writeFileSync(tmpPath, transformed, 'utf8');
|
||||
try {
|
||||
await createZip(tmpPath, 'index.html', zipPath);
|
||||
@@ -118,7 +131,7 @@ async function convertNetwork(html: string, opts: ConvertOptions, network: strin
|
||||
return zipPath;
|
||||
}
|
||||
|
||||
const outPath = path.join(opts.outputDir, htmlFileName);
|
||||
const outPath = path.join(outputDir, htmlFileName);
|
||||
fs.writeFileSync(outPath, transformed, 'utf8');
|
||||
return outPath;
|
||||
}
|
||||
@@ -431,6 +444,11 @@ function getHtml(): string {
|
||||
if (outputDir) vscode.postMessage({ type: 'openOutput', dir: outputDir });
|
||||
});
|
||||
|
||||
function outputDisplayName(file) {
|
||||
const parts = file.split(/[\\\\/]/).filter(Boolean);
|
||||
return parts.slice(-2).join('/');
|
||||
}
|
||||
|
||||
document.getElementById('convert').addEventListener('click', () => {
|
||||
const networks = [...document.querySelectorAll('.net-cb')]
|
||||
.filter(c => c.checked).map(c => c.dataset.tag);
|
||||
@@ -484,7 +502,7 @@ function getHtml(): string {
|
||||
const detail = document.createElement('span');
|
||||
if (r.ok) {
|
||||
detail.className = 'res-file';
|
||||
detail.textContent = r.file.split(/[\\\\/]/).pop();
|
||||
detail.textContent = outputDisplayName(r.file);
|
||||
} else {
|
||||
detail.className = 'res-err';
|
||||
detail.textContent = r.error || 'Unknown error';
|
||||
|
||||
Reference in New Issue
Block a user