diff --git a/builder.js b/builder.js index 0f5dca7..7c96707 100644 --- a/builder.js +++ b/builder.js @@ -8,6 +8,101 @@ const DEV = process.argv.includes("--dev"); const escape = (str) => str.replace(/\s+/g, " ").trim().replace(/"/g, '\\"').replace(/\$/g, "\\$"); +const minifyPhp = (code) => { + let minified = ""; + let i = 0; + let inString = false; + let stringChar = ""; + let inComment = false; + let inMultilineComment = false; + + while (i < code.length) { + const char = code[i]; + const nextChar = code[i + 1]; + const nextTwoChars = code.substring(i, i + 2); + + // Handle strings + if ((char === '"' || char === "'") && !inComment && !inMultilineComment) { + if (!inString) { + inString = true; + stringChar = char; + minified += char; + } else if (char === stringChar && code[i - 1] !== "\\") { + inString = false; + minified += char; + } else { + minified += char; + } + i++; + continue; + } + + if (inString) { + minified += char; + i++; + continue; + } + + // Handle multiline comments + if (nextTwoChars === "/*" && !inComment) { + inMultilineComment = true; + i += 2; + continue; + } + + if (nextTwoChars === "*/" && inMultilineComment) { + inMultilineComment = false; + i += 2; + continue; + } + + if (inMultilineComment) { + i++; + continue; + } + + // Handle single-line comments + if (nextTwoChars === "//" && !inComment) { + inComment = true; + i += 2; + continue; + } + + if ((char === "\n" || char === "\r") && inComment) { + inComment = false; + // Don't append the newline directly — let it fall through to the + // whitespace-collapse logic below so it becomes a single space (or + // nothing) instead of a literal newline. + } + + if (inComment) { + i++; + continue; + } + + // Remove unnecessary whitespace + if (/\s/.test(char)) { + if (minified && !/\s$/.test(minified) && !/[\{\[\(]$/.test(minified)) { + const nextNonWhitespace = code.substring(i).match(/\S/); + if ( + nextNonWhitespace && + !/[\}\]\)]/.test(nextNonWhitespace[0]) && + !/[;,:]/.test(nextNonWhitespace[0]) + ) { + minified += " "; + } + } + i++; + continue; + } + + minified += char; + i++; + } + + return minified.trim(); +}; + function build() { const data = fs.readFileSync("./script.php", "utf8"); const mountRegex = /"<.*?)\)>>"/gm; @@ -42,6 +137,35 @@ function build() { fs.writeFileSync("./output.php", result, "utf8"); console.log(`[${new Date().toLocaleTimeString()}] Built output.php`); + // Minify PHP after @BUILDER_BEGIN_MINIFY marker + try { + let phpContent = fs.readFileSync("./output.php", "utf8"); + const minifyMarker = "// @BUILDER_BEGIN_MINIFY"; + const markerIndex = phpContent.indexOf(minifyMarker); + + if (markerIndex !== -1) { + // Cut from the start of the marker's line so any indentation on that + // line doesn't leak into the untouched "before" section. + const lineStart = phpContent.lastIndexOf("\n", markerIndex) + 1; + const beforeMinify = phpContent.substring(0, lineStart); + const afterMarker = phpContent.substring( + markerIndex + minifyMarker.length, + ); + const minifiedPart = minifyPhp(afterMarker); + // The marker itself is a `//` comment — it must NOT be written back + // into the output, otherwise everything appended right after it on + // the same line gets swallowed as part of that comment. + const finalContent = beforeMinify + minifiedPart; + + fs.writeFileSync("./output.php", finalContent, "utf8"); + console.log( + `[${new Date().toLocaleTimeString()}] Minified PHP (reduced by ${(100 - (minifiedPart.length / afterMarker.length) * 100).toFixed(1)}%)`, + ); + } + } catch (err) { + console.error("Minification error:", err.message); + } + return mountedFiles; } @@ -89,4 +213,4 @@ if (DEV) { syncWatchers(watchedFiles); console.log("Watching for changes… (Ctrl+C to stop)"); -} +} \ No newline at end of file diff --git a/script.php b/script.php index 17dfefe..eb65ebf 100644 --- a/script.php +++ b/script.php @@ -15,6 +15,8 @@ const AUTH_URL = "https://login.dnevnik.ru/login/?ReturnUrl="; const OAUTH_URL = "https://login.dnevnik.ru/oauth2?response_type=token&client_id=b8006d75-70a9-4291-885c-13d8511bb2ae&scope=CommonInfo,EducationalInfo,FriendsAndRelatives&redirect_uri="; // ============ +// @BUILDER_BEGIN_MINIFY + // ===PAGES=== // NOTE: contains ai-generated styles and mine shitty while state-of-art template system // we use builder to mount these