193 lines
3.8 KiB
PHP
193 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace Sphere\Debloat;
|
|
|
|
use Sphere\Debloat\OptimizeCss\Stylesheet;
|
|
use Sphere\Debloat\OptimizeJs\Script;
|
|
|
|
/**
|
|
* Delay load assets singleton.
|
|
*
|
|
* @author asadkn
|
|
* @since 1.0.0
|
|
*/
|
|
class DelayLoad
|
|
{
|
|
public $enabled = true;
|
|
public $use_js = false;
|
|
public $js_type;
|
|
|
|
public $preload = [];
|
|
|
|
/**
|
|
* Note: Should be used a singleton.
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->register_hooks();
|
|
}
|
|
|
|
public function register_hooks()
|
|
{
|
|
// add_action('wp_enqueue_scripts', [$this, 'register_assets']);
|
|
}
|
|
|
|
/**
|
|
* Enable injection of required scripts and preloads, as needed.
|
|
*
|
|
* @param null|true $use_js Whether to inject delay/defer JS. null keeps the current.
|
|
* @return void
|
|
*/
|
|
public function enable($use_js = null)
|
|
{
|
|
$this->enabled = true;
|
|
|
|
if ($use_js === true) {
|
|
$this->use_js = $use_js;
|
|
}
|
|
}
|
|
|
|
public function disable()
|
|
{
|
|
$this->enabled = false;
|
|
}
|
|
|
|
/**
|
|
* Enqueue a preload.
|
|
*
|
|
* @param Stylesheet|Script $asset
|
|
* @return void
|
|
*/
|
|
public function add_preload($asset)
|
|
{
|
|
$this->preload[] = $asset;
|
|
}
|
|
|
|
/**
|
|
* Add extras to the provided HTML buffer.
|
|
*
|
|
* @param string $html
|
|
* @return string
|
|
*/
|
|
public function render($html)
|
|
{
|
|
if (!$this->enabled) {
|
|
return $html;
|
|
}
|
|
|
|
$js = $this->render_js();
|
|
$preloads = $this->render_preloads();
|
|
|
|
$append = $preloads . $js;
|
|
|
|
// Add to body or at the end.
|
|
// Note: Has to be at the end to ensure all <script> tags with defer has been added.
|
|
if (strpos($html, '</body>') !== false) {
|
|
$html = str_replace('</body>', $append . "\n</body>", $html);
|
|
} else {
|
|
$html .= $append;
|
|
}
|
|
|
|
|
|
return $html;
|
|
}
|
|
|
|
protected function render_preloads()
|
|
{
|
|
$preloads = [];
|
|
foreach ($this->preload as $preload) {
|
|
$media = 'all';
|
|
$type = ($preload instanceof Stylesheet) ? 'style' : 'script';
|
|
|
|
if ($type === 'style') {
|
|
$media = $preload->media ?: $media;
|
|
}
|
|
|
|
$preloads[] = sprintf(
|
|
'<link rel="prefetch" href="%1$s" as="%2$s" media="%3$s" />',
|
|
esc_url($preload->get_content_url()),
|
|
$type,
|
|
esc_attr($media)
|
|
);
|
|
}
|
|
|
|
return implode('', $preloads);
|
|
}
|
|
|
|
/**
|
|
* Get JS enqueues and inline scripts as needed.
|
|
*
|
|
* @return string
|
|
*/
|
|
protected function render_js()
|
|
{
|
|
if (!$this->use_js) {
|
|
return '';
|
|
}
|
|
|
|
$js = '';
|
|
$min = Plugin::get_instance()->env !== 'dev' ? '.min' : '';
|
|
|
|
// Defer JS is always inline.
|
|
$js .= sprintf(
|
|
'<script data-cfasync="false">%s</script>',
|
|
Plugin::file_system()->get_contents(
|
|
Plugin::get_instance()->dir_path . 'inc/delay-load/js/defer-load'. $min .'.js'
|
|
)
|
|
);
|
|
|
|
// Delay load JS comes after, just in case, to not mess up readyState.
|
|
if ($this->js_type === 'inline') {
|
|
$js .= sprintf(
|
|
'<script data-cfasync="false">%s</script>',
|
|
Plugin::file_system()->get_contents(
|
|
Plugin::get_instance()->dir_path . 'inc/delay-load/js/delay-load'. $min .'.js'
|
|
)
|
|
);
|
|
|
|
} else {
|
|
|
|
$js .= sprintf(
|
|
'<script type="text/javascript" src="%s" data-cfasync="false"></script>',
|
|
esc_url(Plugin::get_instance()->dir_url . 'inc/delay-load/js/delay-load'. $min .'.js?ver=' . Plugin::VERSION)
|
|
);
|
|
}
|
|
|
|
if (!$js) {
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Add configs.
|
|
*/
|
|
$configs = [
|
|
'cssDelayType' => Plugin::options()->delay_css_type,
|
|
'jsDelayType' => Plugin::options()->delay_js_type,
|
|
'jsDelayMax' => Plugin::options()->delay_js_max
|
|
];
|
|
|
|
$js = sprintf(
|
|
'<script>var debloatConfig = %1$s;</script>%2$s',
|
|
json_encode($configs),
|
|
$js
|
|
);
|
|
|
|
return $js;
|
|
}
|
|
|
|
/**
|
|
* Check for conditionals for delay load.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function should_delay_css()
|
|
{
|
|
if (!Plugin::options()->delay_css_load) {
|
|
return false;
|
|
}
|
|
|
|
$valid = Plugin::process()->check_enabled(Plugin::options()->delay_css_on);
|
|
|
|
return apply_filters('debloat/should_delay_css', $valid);
|
|
}
|
|
} |