mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #2684 from Firesphere/feature/force_write_js_to_bottom
NEW Forcefully write javascripts to the end of the HTML if wished
This commit is contained in:
commit
78a530524b
@ -350,6 +350,55 @@ class RequirementsTest extends SapphireTest {
|
||||
$this->assertContains('</script></body>', $html);
|
||||
}
|
||||
|
||||
public function testForceJsToBottom() {
|
||||
$backend = new Requirements_Backend();
|
||||
$backend->javascript('http://www.mydomain.com/test.js');
|
||||
|
||||
// Test matching with HTML5 <header> tags as well
|
||||
$template = '<html><head></head><body><header>My header</header><p>Body<script></script></p></body></html>';
|
||||
|
||||
// The expected outputs
|
||||
$JsInHead = "<html><head><script type=\"text/javascript\" src=\"http://www.mydomain.com/test.js\"></script>\n</head><body><header>My header</header><p>Body<script></script></p></body></html>";
|
||||
$JsInBody = "<html><head></head><body><header>My header</header><p>Body<script type=\"text/javascript\" src=\"http://www.mydomain.com/test.js\"></script><script></script></p></body></html>";
|
||||
$JsAtEnd = "<html><head></head><body><header>My header</header><p>Body<script></script></p><script type=\"text/javascript\" src=\"http://www.mydomain.com/test.js\"></script></body></html>";
|
||||
|
||||
|
||||
// Test if the script is before the head tag, not before the body.
|
||||
// Expected: $JsInHead
|
||||
$backend->set_write_js_to_body(false);
|
||||
$backend->set_force_js_to_bottom(false);
|
||||
$html = $backend->includeInHTML(false, $template);
|
||||
$this->assertNotEquals($JsInBody, $html);
|
||||
$this->assertNotEquals($JsAtEnd, $html);
|
||||
$this->assertEquals($JsInHead, $html);
|
||||
|
||||
// Test if the script is before the first <script> tag, not before the body.
|
||||
// Expected: $JsInBody
|
||||
$backend->set_write_js_to_body(true);
|
||||
$backend->set_force_js_to_bottom(false);
|
||||
$html = $backend->includeInHTML(false, $template);
|
||||
$this->assertNotEquals($JsAtEnd, $html);
|
||||
$this->assertEquals($JsInBody, $html);
|
||||
|
||||
// Test if the script is placed just before the closing bodytag, with write-to-body false.
|
||||
// Expected: $JsAtEnd
|
||||
$backend->set_write_js_to_body(false);
|
||||
$backend->set_force_js_to_bottom(true);
|
||||
$html = $backend->includeInHTML(false, $template);
|
||||
$this->assertNotEquals($JsInHead, $html);
|
||||
$this->assertNotEquals($JsInBody, $html);
|
||||
$this->assertEquals($JsAtEnd, $html);
|
||||
|
||||
// Test if the script is placed just before the closing bodytag, with write-to-body true.
|
||||
// Expected: $JsAtEnd
|
||||
$backend->set_write_js_to_body(true);
|
||||
$backend->set_force_js_to_bottom(true);
|
||||
$html = $backend->includeInHTML(false, $template);
|
||||
$this->assertNotEquals($JsInHead, $html);
|
||||
$this->assertNotEquals($JsInBody, $html);
|
||||
$this->assertEquals($JsAtEnd, $html);
|
||||
}
|
||||
|
||||
public function testSuffix() {
|
||||
$template = '<html><head></head><body><header>My header</header><p>Body</p></body></html>';
|
||||
$basePath = $this->getCurrentRelativePath();
|
||||
|
@ -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 <script> tags, that don't need the javascripts
|
||||
* included via Requirements::require();
|
||||
*
|
||||
* @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()->set_force_js_to_bottom($var);
|
||||
}
|
||||
|
||||
public static function debug() {
|
||||
return self::backend()->debug();
|
||||
}
|
||||
@ -436,7 +447,15 @@ class Requirements_Backend {
|
||||
* @var boolean
|
||||
*/
|
||||
public $write_js_to_body = true;
|
||||
|
||||
|
||||
/**
|
||||
* Force the javascripts to the bottom of the page, even if there's a
|
||||
* <script> tag in the body already
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $force_js_to_bottom = false;
|
||||
|
||||
public function set_combined_files_enabled($enable) {
|
||||
$this->combined_files_enabled = (bool) $enable;
|
||||
}
|
||||
@ -487,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'
|
||||
@ -701,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.
|
||||
// We forcefully put it at the bottom instead of before
|
||||
// the first script-tag occurence
|
||||
$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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user