From 191c59c1a30b6be42601d11213d6ea3a053eda0b Mon Sep 17 00:00:00 2001 From: Firesphere Date: Mon, 25 Nov 2013 20:49:35 +0100 Subject: [PATCH 1/3] IMPROVEMENT/FEATURE Forcefully write javascripts to the end of the HTML if wanted. It's defaulted to false. But when set to true, the JS is written to the end of the HTML, even though there are earlier scripts. This results in faster page-loading if the JS isn't needed earlier-on. --- view/Requirements.php | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/view/Requirements.php b/view/Requirements.php index 34f7fc066..7c528903e 100644 --- a/view/Requirements.php +++ b/view/Requirements.php @@ -308,6 +308,17 @@ class Requirements { self::backend()->set_write_js_to_body($var); } + /** + * Set the javascript to be forced to end of the HTML, or use the default. + * Useful if you use inline ', $html); } + public function testForceJsToBottom() { + $backend = new Requirements_Backend(); + $backend->javascript('http://www.mydomain.com/test.js'); + + // Test matching with HTML5
tags as well + $template = '
My header

Body

'; + + // Test if the script is before the first ', $html); + $this->assertNotContains('assertContains(' tag, not before the body. + $backend->set_write_js_to_body(true); + $backend->set_force_js_to_bottom(false); + $html = $backend->includeInHTML(false, $template); + $this->assertNotContains('', $html); + $this->assertContains('set_write_js_to_body(false); + $backend->set_force_js_to_bottom(true); + $html = $backend->includeInHTML(false, $template); + $this->assertNotContains('assertNotContains('assertContains('', $html); + + // Test if the script is placed just before the closing bodytag, with write-to-body true. + $backend->set_write_js_to_body(true); + $backend->set_force_js_to_bottom(true); + $html = $backend->includeInHTML(false, $template); + $this->assertNotContains('assertNotContains('assertContains('', $html); + } + public function testSuffix() { $template = '
My header

Body

'; $basePath = $this->getCurrentRelativePath(); diff --git a/view/Requirements.php b/view/Requirements.php index 7c528903e..a495bbfbf 100644 --- a/view/Requirements.php +++ b/view/Requirements.php @@ -316,7 +316,7 @@ class Requirements { * @param boolean $var If true, force the javascripts to be included at the bottom. */ public static function set_force_js_to_bottom($var) { - self::backend()->force_js_to_bottom = $var; + self::backend()->set_force_js_to_bottom($var); } public static function debug() { @@ -454,7 +454,7 @@ class Requirements_Backend { * * @var boolean */ - public $force_js_to_bottom = false; + protected $force_js_to_bottom = false; public function set_combined_files_enabled($enable) { $this->combined_files_enabled = (bool) $enable; @@ -506,6 +506,14 @@ class Requirements_Backend { public function set_write_js_to_body($var) { $this->write_js_to_body = $var; } + /** + * Forces the javascript to the end of the body, just before the closing body-tag. + * + * @param boolean + */ + public function set_force_js_to_bottom($var) { + $this->force_js_to_bottom = $var; + } /** * Register the given javascript file as required. * Filenames should be relative to the base, eg, 'framework/javascript/loader.js' @@ -720,7 +728,18 @@ class Requirements_Backend { $requirements .= "$customHeadTag\n"; } - if($this->write_js_to_body) { + if ($this->force_js_to_bottom) { + // Remove all newlines from code to preserve layout + $jsRequirements = preg_replace('/>\n*/', '>', $jsRequirements); + + // We put script tags into the body, for performance. + // If your template already has script tags in the body, then we put our script + // tags just before those. Otherwise, we put it at the bottom. + $content = preg_replace("/(<\/body[^>]*>)/i", $jsRequirements . "\\1", $content); + + // Put CSS at the bottom of the head + $content = preg_replace("/(<\/head>)/i", $requirements . "\\1", $content); + } elseif($this->write_js_to_body) { // Remove all newlines from code to preserve layout $jsRequirements = preg_replace('/>\n*/', '>', $jsRequirements); @@ -730,7 +749,7 @@ class Requirements_Backend { $p2 = stripos($content, 'force_js_to_bottom) { + if($p1 !== false) { $content = substr($content,0,$p1) . $jsRequirements . substr($content,$p1); } else { $content = preg_replace("/(<\/body[^>]*>)/i", $jsRequirements . "\\1", $content);