MAPG-180 ability to inline CSS and JS assets

This commit is contained in:
Bence Pőcze 2020-06-27 12:51:00 +02:00
parent 825e0744ec
commit efdd5c54be
Signed by: bence
GPG Key ID: AA52B11A3269D1C1
2 changed files with 57 additions and 43 deletions

View File

@ -2,6 +2,8 @@
class Linker class Linker
{ {
const INLINE_ASSET_LIMIT = 2000;
private string $view; private string $view;
public function __construct(string $view) public function __construct(string $view)
@ -14,9 +16,7 @@ class Linker
$input = ROOT . '/views/' . $this->view . '.php'; $input = ROOT . '/views/' . $this->view . '.php';
$temporaryFiles = []; $temporaryFiles = [];
$css = []; $sections = ['externalCss' => '', 'inlineCss' => '', 'externalJs' => '', 'inlineJs' => ''];
$js = [];
$sections = [];
$extra = ['', '']; $extra = ['', ''];
do { do {
@ -25,14 +25,14 @@ class Linker
$extends = $fragment->getExtends(); $extends = $fragment->getExtends();
$css = array_merge($css, $fragment->getCss()); $this->generateAssets($fragment, $sections);
$js = array_merge($js, $fragment->getJs());
$sections = array_merge($sections, $fragment->getSections()); //TODO: detect if section defined multiple times $sections = array_merge($sections, $fragment->getSections()); //TODO: detect if section defined multiple times
$extra[0] = $fragment->getExtra()[0] . $extra[0]; $extra[0] = $fragment->getExtra()[0] . $extra[0];
$extra[1] = $extra[1] . $fragment->getExtra()[1]; $extra[1] = $extra[1] . $fragment->getExtra()[1];
if ($extends === null) { if ($extends === null) {
$this->writeFinal($css, $js, $extra, $input, ROOT . '/cache/views/' . $this->view . '.php'); $this->writeFinal($extra, $input, ROOT . '/cache/views/' . $this->view . '.php');
break; break;
} }
@ -78,7 +78,7 @@ class Linker
fclose($outputFileHandle); fclose($outputFileHandle);
} }
private function writeFinal(array $css, array $js, array $extra, string $file, string $output): void private function writeFinal(array $extra, string $file, string $output): void
{ {
$dirname = pathinfo($output, PATHINFO_DIRNAME); $dirname = pathinfo($output, PATHINFO_DIRNAME);
if (!is_dir($dirname)) { if (!is_dir($dirname)) {
@ -95,22 +95,6 @@ class Linker
throw new \Exception('Cannot open file ' . $output . 'for writing.'); throw new \Exception('Cannot open file ' . $output . 'for writing.');
} }
if (count($css) > 0) {
fwrite($outputFileHandle, '<?php' . PHP_EOL . '$cssFiles = [];' . PHP_EOL);
foreach ($css as $cssFile) {
fwrite($outputFileHandle, '$cssFiles[] = ' . $cssFile . ';' . PHP_EOL);
}
fwrite($outputFileHandle, '?>' . PHP_EOL);
}
if (count($js) > 0) {
fwrite($outputFileHandle, '<?php' . PHP_EOL . '$jsFiles = [];' . PHP_EOL);
foreach ($js as $jsFile) {
fwrite($outputFileHandle, '$jsFiles[] = ' . $jsFile . ';' . PHP_EOL);
}
fwrite($outputFileHandle, '?>' . PHP_EOL);
}
fwrite($outputFileHandle, $extra[0]); fwrite($outputFileHandle, $extra[0]);
while (($line = fgets($inputFileHandle)) !== false) { while (($line = fgets($inputFileHandle)) !== false) {
fwrite($outputFileHandle, $line); fwrite($outputFileHandle, $line);
@ -120,4 +104,52 @@ class Linker
fclose($inputFileHandle); fclose($inputFileHandle);
fclose($outputFileHandle); fclose($outputFileHandle);
} }
private function generateAssets(ParsedFragment $fragment, array &$sections)
{
foreach ($fragment->getCss() as $cssFile) {
$asset = $this->parseAsset($cssFile, 'css');
if (isset($asset['code'])) {
$sections['inlineCss'] .= '<style>' . PHP_EOL;
$sections['inlineCss'] .= $asset['code'];
$sections['inlineCss'] .= '</style>' . PHP_EOL;
} elseif (isset($asset['file'])) {
$sections['externalCss'] .= '<link href="' . $asset['file'] . '" rel="stylesheet">' . PHP_EOL;
}
}
foreach ($fragment->getJs() as $jsFile) {
$asset = $this->parseAsset($jsFile, 'js');
if (isset($asset['code'])) {
$sections['inlineJs'] .= '<script>' . PHP_EOL;
$sections['inlineJs'] .= $asset['code'];
$sections['inlineJs'] .= '</script>' . PHP_EOL;
} elseif (isset($asset['file'])) {
$sections['externalJs'] .= '<script src="' . $asset['file'] . '"></script>' . PHP_EOL;
}
}
}
private function parseAsset(string $asset, string $type): array
{
$output = [];
eval('$asset = ' . $asset . ';');
if (
empty($_ENV['DEV']) &&
preg_match('/^' . $type . '\/.*/', $asset) &&
filesize(ROOT . '/public/static/' . $asset) < self::INLINE_ASSET_LIMIT
) {
$output['code'] = file_get_contents(ROOT . '/public/static/' . $asset);
} else {
if (!preg_match('/^http(s)?/', $asset)) {
$output['file'] = $_ENV['STATIC_ROOT'] . '/' . $asset . '?rev=' . REVISION;
} else {
$output['file'] = $asset;
}
}
return $output;
}
} }

View File

@ -5,16 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= $_ENV['APP_NAME'] ?></title> <title><?= $_ENV['APP_NAME'] ?></title>
<link href="<?= $_ENV['STATIC_ROOT'] ?>/css/mapguesser.css?rev=<?= REVISION ?>" rel="stylesheet"> <link href="<?= $_ENV['STATIC_ROOT'] ?>/css/mapguesser.css?rev=<?= REVISION ?>" rel="stylesheet">
<?php if (isset($cssFiles)) : ?> @yields('externalCss')
<?php foreach ($cssFiles as $cssFile) : ?>
<?php
if (!preg_match('/^http(s)?/', $cssFile)) {
$cssFile = $_ENV['STATIC_ROOT'] . '/' . $cssFile . '?rev=' . REVISION;
}
?>
<link href="<?= $cssFile ?>" rel="stylesheet">
<?php endforeach; ?>
<?php endif; ?>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;500&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;500&display=swap" rel="stylesheet">
@yields('inlineCss') @yields('inlineCss')
<link rel="icon" type="image/png" sizes="192x192" href="<?= $_ENV['STATIC_ROOT'] ?>/img/favicon/192x192.png?rev=<?= REVISION ?>"> <link rel="icon" type="image/png" sizes="192x192" href="<?= $_ENV['STATIC_ROOT'] ?>/img/favicon/192x192.png?rev=<?= REVISION ?>">
@ -53,16 +44,7 @@
</script> </script>
@yields('pageScript') @yields('pageScript')
<script src="<?= $_ENV['STATIC_ROOT'] ?>/js/mapguesser.js?rev=<?= REVISION ?>"></script> <script src="<?= $_ENV['STATIC_ROOT'] ?>/js/mapguesser.js?rev=<?= REVISION ?>"></script>
<?php if (isset($jsFiles)) : ?> @yields('externalJs')
<?php foreach ($jsFiles as $jsFile) : ?>
<?php
if (!preg_match('/^http(s)?/', $jsFile)) {
$jsFile = $_ENV['STATIC_ROOT'] . '/' . $jsFile . '?rev=' . REVISION;
}
?>
<script src="<?= $jsFile ?>"></script>
<?php endforeach; ?>
<?php endif; ?>
@yields('inlineJs') @yields('inlineJs')
<?php if (!isset($_COOKIE['COOKIES_CONSENT'])): ?> <?php if (!isset($_COOKIE['COOKIES_CONSENT'])): ?>
<script> <script>