Skip to content
This repository was archived by the owner on Sep 20, 2024. It is now read-only.

Fixed issues #30, #36, #36 #37

Merged
merged 1 commit into from
Apr 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions defer.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@
} elseif (file_exists($vendorDir . $autoload)) {
require_once $vendorDir . $autoload;
} else {
require_once $baseDir . '/src/Helpers/JsMin.php';
require_once $baseDir . '/src/DeferException.php';
require_once $baseDir . '/src/DeferCache.php';
require_once $baseDir . '/src/Helpers/JsMin.php';
require_once $baseDir . '/src/DeferHttpRequest.php';
require_once $baseDir . '/src/DeferInterface.php';
require_once $baseDir . '/src/DeferOptimizer.php';
require_once $baseDir . '/src/DeferOptions.php';
require_once $baseDir . '/src/DeferParser.php';
require_once $baseDir . '/src/DeferOptimizer.php';
require_once $baseDir . '/src/DeferCache.php';
require_once $baseDir . '/src/Defer.php';
}
}
5 changes: 2 additions & 3 deletions src/Defer.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public function __construct($html = null, $options = [], $charset = null)
{
$this->native_libxml = class_exists('DOMDocument');
$this->cache_manager = new DeferCache(static::DEFERJS_CACHE, 1);
$this->http = new DeferHttpRequest();

// Set library options
if (!empty($options)) {
Expand All @@ -49,8 +50,6 @@ public function __construct($html = null, $options = [], $charset = null)
$this->fromHtml($html, $charset);
}

$this->http = new DeferHttpRequest();

return $this;
}

Expand Down Expand Up @@ -141,7 +140,7 @@ public function toHtml()
$output = $this->dom->saveHtml();
}

$output = $this->entity2charset($output, $this->charset);
$output = $this->script_decode($this->entity2charset($output, $this->charset));

if (!empty($this->bug72288_body)) {
$output = preg_replace('/(<body[^>]*>)/mi', $this->bug72288_body, $output, 1);
Expand Down
37 changes: 25 additions & 12 deletions src/DeferOptimizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,25 +129,38 @@ protected function addDeferJs()
return;
}

$the_anchor = $this->head->childNodes->item(0);
$extra_scripts = [];
$the_anchor = $this->head->childNodes->item(0);

// Append the defer.js library and polyfill
if (!$this->manually_add_deferjs) {
if (!$this->append_defer_js || empty(static::$deferjs_script)) {
$script_tag = $this->createNode(static::SCRIPT_TAG, [
static::ATTR_SRC => static::DEFERJS_URL,
static::ATTR_ID => 'defer-js',
]);

// Append defer.js library loaded script is empty
if (!$this->append_defer_js || empty(static::$deferjs_script)) {
$script_tag = $this->createNode(static::SCRIPT_TAG, [
static::ATTR_SRC => static::DEFERJS_URL,
static::ATTR_ID => 'defer-js',
]);
$this->head->insertBefore($script_tag, $the_anchor);
$script_tag = null;
}

$this->head->insertBefore($script_tag, $the_anchor);
$script_tag = null;
$extra_scripts[] = static::$deferjs_script;
$extra_scripts[] = '"IntersectionObserver"in window||deferscript("' . static::POLYFILL_URL . '","polyfill-js",1)';
} else {
$message = implode('\n', [
'You should manually add the defer.js.\n\nFor example:',
'<script id="defer-js" src="' . static::DEFERJS_URL . '"><\/script>',
'<script id="polyfill-js" src="' . static::POLYFILL_URL . '"><\/script>',
]);
$extra_scripts[] = "window.defer=setTimeout;defer(function(){console.info('${message}')});";
}

// Append helpers
$extra_scripts = (array) $this->loader_scripts;
$extra_scripts[] = '"IntersectionObserver"in window||deferscript("' . static::POLYFILL_URL . '","polyfill-js",1)';
$extra_scripts[] = static::$helpers;
$extra_scripts = array_merge($extra_scripts, $this->loader_scripts);

$script = static::$deferjs_script . implode(';', array_filter($extra_scripts));
// Combine all extra scripts
$script = implode(';', array_filter($extra_scripts));

if (!empty($script)) {
$script_tag = $this->createNode(static::SCRIPT_TAG, trim($script), [static::ATTR_ID => 'defer-script']);
Expand Down
3 changes: 3 additions & 0 deletions src/DeferOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ trait DeferOptions
// Disable libxml errors and warnings
'hide_warnings' => true,

// manually add deferjs
'manually_add_deferjs' => false,

// Library injection
'append_defer_js' => false,
'default_defer_time' => 10,
Expand Down
48 changes: 47 additions & 1 deletion src/DeferParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ trait DeferParser
// https://bugs.php.net/bug.php?id=72288
protected $bug72288_body;

// Bugs with script tags which contains HTML
protected $bug_script_templates;

/**
* Cleanup internal variables
*
Expand Down Expand Up @@ -85,6 +88,10 @@ public function cleanup()
$this->preload_map[static::DEFERJS_URL] = static::PRELOAD_SCRIPT;
}

// Bug fixes
$this->bug72288_body = null;
$this->bug_script_templates = [];

@gc_collect_cycles();

return $this;
Expand Down Expand Up @@ -123,10 +130,12 @@ protected function parseHtml($html)
// Force HTML5 doctype
$html = preg_replace('/<!DOCTYPE html[^>]*>/i', '<!DOCTYPE html>', $html, 1);
$html = preg_replace('/<\?xml[^>]*>/i', '', $html, 1);
$html = $this->script_encode($html);

// Create DOM document
$this->dom->preserveWhiteSpace = false;
$this->dom->preserveWhiteSpace = true;
$this->dom->loadHTML($html);
$this->dom->formatOutput = false;

// Create xpath object for searching tags
$this->xpath = new \DOMXPath($this->dom);
Expand Down Expand Up @@ -625,4 +634,41 @@ protected function setOrRemoveAttribute($node, $attr, $value)

return $this;
}

/**
* This is used to fix script tags which contain html templates
*
* @since 1.0.10
* @param $html
* @return string
*/
protected function script_encode($html)
{
return preg_replace_callback('/(<script[^>]*>)(.*?)(<\/script>)/si', function ($matches) {
if (!preg_match('/type=/i', $matches[1]) || strpos($matches[1], 'text/javascript') !== false) {
return $matches[0];
}

$next = '@@@SCRIPT@@@' . count($this->bug_script_templates) . '@@@SCRIPT@@@';
$this->bug_script_templates[$next] = trim($matches[2]);

return "{$matches[1]}{$next}{$matches[3]}";
}, $html);
}

/**
* This is used revert script tags to its original content
*
* @since 1.0.10
* @param array $matches
* @param mixed $html
* @return string
*/
protected function script_decode($html)
{
$result = str_replace(array_keys($this->bug_script_templates), array_values($this->bug_script_templates), $html);
$this->bug_script_templates = [];

return $result;
}
}
2 changes: 2 additions & 0 deletions test/test.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
$defer->use_css_fadein_effects = true;
$defer->use_color_placeholder = false;

$defer->manually_add_deferjs = true;

// $defer->clearCache();

// Scan test files
Expand Down