silverstripe-webpack/app/src/Templates/DeferredRequirements.php

230 lines
7.8 KiB
PHP
Raw Normal View History

2018-02-22 14:39:58 +01:00
<?php
2019-12-09 12:18:05 +01:00
/** @noinspection PhpUnusedPrivateFieldInspection */
2018-04-21 06:29:32 +02:00
namespace Site\Templates;
use SilverStripe\Control\Controller;
2018-03-24 11:45:31 +01:00
use SilverStripe\View\TemplateGlobalProvider;
use SilverStripe\View\Requirements;
use SilverStripe\Core\Config\Config;
use SilverStripe\Control\Director;
use SilverStripe\Core\Path;
2020-01-28 15:26:51 +01:00
use SilverStripe\FontAwesome\FontAwesomeField;
2018-03-24 11:45:31 +01:00
2019-12-09 12:18:05 +01:00
class DeferredRequirements implements TemplateGlobalProvider
2018-04-21 05:36:06 +02:00
{
2018-02-22 14:39:58 +01:00
private static $css = [];
private static $js = [];
2019-12-09 12:04:12 +01:00
private static $deferred = false;
2018-02-22 14:39:58 +01:00
private static $static_domain;
private static $version;
2018-07-25 11:03:50 +02:00
private static $nojquery = false;
private static $jquery_version = '3.4.1';
2018-07-25 11:03:50 +02:00
private static $nofontawesome = false;
2018-08-26 12:46:03 +02:00
private static $custom_requirements = [];
2018-02-22 14:39:58 +01:00
/**
* @return array
*/
2019-12-09 12:18:05 +01:00
public static function get_template_global_variables(): array
2018-02-22 14:39:58 +01:00
{
return [
'AutoRequirements' => 'Auto',
'DeferedCSS' => 'loadCSS',
'DeferedJS' => 'loadJS',
2020-01-28 15:26:51 +01:00
'WebpackActive' => 'webpackActive',
2020-09-15 22:27:17 +02:00
'EmptyImgSrc' => 'emptyImageSrc',
2018-02-22 14:39:58 +01:00
];
}
2019-12-09 12:18:05 +01:00
public static function Auto($class = false): string
2018-02-22 14:39:58 +01:00
{
2018-07-25 11:03:50 +02:00
$config = Config::inst()->get(self::class);
2019-04-11 00:38:19 +02:00
$projectName = WebpackTemplateProvider::projectName();
$mainTheme = WebpackTemplateProvider::mainTheme();
2019-12-09 12:04:12 +01:00
$mainTheme = $mainTheme ?: $projectName;
2018-07-25 11:03:50 +02:00
2019-08-27 17:25:05 +02:00
$dir = Path::join(
Director::publicFolder(),
2019-12-09 12:04:12 +01:00
RESOURCES_DIR,
2019-08-27 17:25:05 +02:00
$projectName,
'client',
'dist'
);
$cssPath = Path::join($dir, 'css');
$jsPath = Path::join($dir, 'js');
2018-02-22 14:39:58 +01:00
// Initialization
Requirements::block(THIRDPARTY_DIR.'/jquery/jquery.js');
/*if (defined('FONT_AWESOME_DIR')) {
2018-02-22 14:39:58 +01:00
Requirements::block(FONT_AWESOME_DIR.'/css/lib/font-awesome.min.css');
}*/
2018-02-22 14:39:58 +01:00
Requirements::set_force_js_to_bottom(true);
// Main libs
2018-07-25 11:03:50 +02:00
if (!$config['nojquery']) {
self::loadJS(
'//ajax.googleapis.com/ajax/libs/jquery/'
.$config['jquery_version'].'/jquery.min.js'
);
2018-07-25 11:03:50 +02:00
}
if (!$config['noreact']) {
if (!Director::isDev()) {
self::loadJS('https://unpkg.com/react@17/umd/react.production.min.js');
self::loadJS('https://unpkg.com/react-dom@17/umd/react-dom.production.min.js');
} else {
self::loadJS('https://unpkg.com/react@17/umd/react.development.js');
self::loadJS('https://unpkg.com/react-dom@17/umd/react-dom.development.js');
}
}
2018-02-22 14:39:58 +01:00
// App libs
2018-07-25 11:03:50 +02:00
if (!$config['nofontawesome']) {
2020-01-28 15:26:51 +01:00
$v = !isset($config['fontawesome_version']) || !$config['fontawesome_version']
? Config::inst()->get(FontAwesomeField::class, 'version')
: $config['fontawesome_version'];
self::loadCSS('//use.fontawesome.com/releases/v'.$v.'/css/all.css');
2018-07-25 11:03:50 +02:00
}
2019-12-09 12:04:12 +01:00
self::loadCSS($mainTheme.'.css');
// hot reloading
/*if (self::webpackActive()) {
self::loadJS('hot.js');
}*/
2019-12-09 12:04:12 +01:00
self::loadJS($mainTheme.'.js');
2018-02-22 14:39:58 +01:00
2019-04-11 00:38:19 +02:00
// Custom controller requirements
$curr_class = $class ?: get_class(Controller::curr());
2019-12-09 12:18:05 +01:00
if (isset($config['custom_requirements'][$curr_class])) {
foreach ($config['custom_requirements'][$curr_class] as $file) {
2018-09-19 07:20:43 +02:00
if (strpos($file, '.css')) {
2019-12-09 12:18:05 +01:00
self::loadCSS($file);
2018-08-26 12:46:03 +02:00
}
2018-09-19 07:20:43 +02:00
if (strpos($file, '.js')) {
2019-12-09 12:18:05 +01:00
self::loadJS($file);
2018-08-26 12:46:03 +02:00
}
}
}
2019-12-09 12:18:05 +01:00
$curr_class = str_replace('\\', '.', $curr_class);
2019-04-11 00:38:19 +02:00
// Controller requirements
2019-12-09 12:18:05 +01:00
$themePath = Path::join($cssPath, $mainTheme.'_'.$curr_class . '.css');
$projectPath = Path::join($cssPath, $projectName.'_'.$curr_class . '.css');
2019-05-23 13:02:32 +02:00
if ($mainTheme && file_exists($themePath)) {
2019-12-09 12:18:05 +01:00
self::loadCSS($mainTheme.'_'.$curr_class . '.css');
2019-05-23 13:02:32 +02:00
} elseif (file_exists($projectPath)) {
2019-12-09 12:18:05 +01:00
self::loadCSS($projectName.'_'.$curr_class . '.css');
}
2018-06-23 12:27:06 +02:00
2019-12-09 12:18:05 +01:00
$themePath = Path::join($jsPath, $mainTheme.'_'.$curr_class . '.js');
$projectPath = Path::join($jsPath, $projectName.'_'.$curr_class . '.js');
2019-05-23 13:02:32 +02:00
if ($mainTheme && file_exists($themePath)) {
2019-12-09 12:18:05 +01:00
self::loadJS($mainTheme.'_'.$curr_class . '.js');
2019-05-23 13:02:32 +02:00
} elseif (file_exists($projectPath)) {
2019-12-09 12:18:05 +01:00
self::loadJS($projectName.'_'.$curr_class . '.js');
2018-02-22 14:39:58 +01:00
}
return self::forTemplate();
}
2019-12-09 12:18:05 +01:00
public static function loadCSS($css): void
2018-02-22 14:39:58 +01:00
{
2019-12-09 12:04:12 +01:00
$external = (mb_strpos($css, '//') === 0 || mb_strpos($css, 'http') === 0);
if ($external) {
2018-02-22 14:39:58 +01:00
self::$css[] = $css;
} else {
WebpackTemplateProvider::loadCSS($css);
}
}
2019-12-09 12:18:05 +01:00
public static function loadJS($js): void
2018-02-22 14:39:58 +01:00
{
2019-04-11 00:15:29 +02:00
/*$external = (mb_substr($js, 0, 2) === '//' || mb_substr($js, 0, 4) === 'http');
2019-12-17 21:43:28 +01:00
if ($external || (self::getDeferred() && !self::_webpackActive())) {*/
2019-04-11 00:15:29 +02:00
// webpack supposed to load external JS
2020-01-28 15:26:51 +01:00
if (self::getDeferred() && !self::webpackActive()) {
2018-02-22 14:39:58 +01:00
self::$js[] = $js;
} else {
WebpackTemplateProvider::loadJS($js);
}
}
2020-01-28 15:26:51 +01:00
public static function webpackActive(): bool
2018-02-22 14:39:58 +01:00
{
2019-12-17 21:43:28 +01:00
return WebpackTemplateProvider::isActive();
2018-02-22 14:39:58 +01:00
}
2019-12-09 12:18:05 +01:00
public static function setDeferred($bool): void
2018-02-22 14:39:58 +01:00
{
2019-12-17 21:43:28 +01:00
Config::inst()->set(__CLASS__, 'deferred', $bool);
}
public static function getDeferred(): bool
{
return self::config()['deferred'];
2018-02-22 14:39:58 +01:00
}
2019-12-09 12:18:05 +01:00
public static function forTemplate(): string
2018-02-22 14:39:58 +01:00
{
$result = '';
2019-12-17 21:43:28 +01:00
self::$css = array_unique(self::$css);
2018-02-22 14:39:58 +01:00
foreach (self::$css as $css) {
$result .= '<i class="defer-cs" data-load="' . self::get_url($css) . '"></i>';
}
2019-12-17 21:43:28 +01:00
self::$js = array_unique(self::$js);
2018-02-22 14:39:58 +01:00
foreach (self::$js as $js) {
$result .= '<i class="defer-sc" data-load="' . self::get_url($js) . '"></i>';
}
$result .=
2019-12-17 21:43:28 +01:00
'<script>function lsc(a,b){var c=document.createElement("script");c.readyState'
2018-02-22 14:39:58 +01:00
.'?c.onreadystatechange=function(){"loaded"!=c.readyState&&"complete"!=c.readyState||(c.onreadystatechange=null,b())}'
.':c.onload=function(){b()},c.src=a,document.getElementsByTagName("body")[0].appendChild(c)}'
.'function lscd(a){a<s.length-1&&(a++,lsc(s.item(a).getAttribute("data-load"),function(){lscd(a)}))}'
.'for(var s=document.getElementsByClassName("defer-cs"),i=0;i<s.length;i++){var b=document.createElement("link");b.rel="stylesheet",'
.'b.type="text/css",b.href=s.item(i).getAttribute("data-load"),b.media="all";var c=document.getElementsByTagName("body")[0];'
2019-04-11 00:15:29 +02:00
.'c.appendChild(b)}var s=document.getElementsByClassName("defer-sc"),i=0;if(s.item(i)!==null)lsc(s.item(i).getAttribute("data-load"),function(){lscd(i)});'
2018-02-22 14:39:58 +01:00
.'</script>';
return $result;
}
2019-12-09 12:18:05 +01:00
private static function get_url($url): string
2018-02-22 14:39:58 +01:00
{
2019-12-09 12:18:05 +01:00
$config = self::config();
2018-07-25 11:03:50 +02:00
2018-02-22 14:39:58 +01:00
// external URL
if (strpos($url, '//') !== false) {
return $url;
}
$path = WebpackTemplateProvider::toPublicPath($url);
$absolutePath = Director::getAbsFile($path);
$hash = sha1_file($absolutePath);
2018-02-22 14:39:58 +01:00
$version = $config['version'] ? '&v='.$config['version'] : '';
2019-12-09 12:18:05 +01:00
//$static_domain = $config['static_domain'];
//$static_domain = $static_domain ?: '';
2018-02-22 14:39:58 +01:00
return Controller::join_links(WebpackTemplateProvider::toPublicPath($url), '?m='.$hash.$version);
2018-02-22 14:39:58 +01:00
}
2019-12-09 12:18:05 +01:00
2020-09-15 22:27:17 +02:00
public static function emptyImageSrc(): string
{
return 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
}
2019-12-09 12:18:05 +01:00
public static function config(): array
{
return Config::inst()->get(__CLASS__);
}
2018-02-22 14:39:58 +01:00
}