From 18110fe97a58a6cb26d558947186e02963704718 Mon Sep 17 00:00:00 2001 From: nate Date: Mon, 31 Dec 2007 04:24:14 +0000 Subject: [PATCH] Adding asset timestamps for JS, CSS, and images. Set 'Asset.timestamp' to true in Configure (only in dev mode), fixes #921 git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6286 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/view/helpers/html.php | 16 ++++-- cake/libs/view/helpers/javascript.php | 49 ++++++++++++------- .../cases/libs/view/helpers/html.test.php | 10 ++++ .../libs/view/helpers/javascript.test.php | 30 +++++++++++- 4 files changed, 82 insertions(+), 23 deletions(-) diff --git a/cake/libs/view/helpers/html.php b/cake/libs/view/helpers/html.php index 0d3132635..47477e1b1 100644 --- a/cake/libs/view/helpers/html.php +++ b/cake/libs/view/helpers/html.php @@ -342,14 +342,19 @@ class HtmlHelper extends AppHelper { if (strpos($path, '://') !== false) { $url = $path; } else { - if (strpos($path, '.css') === false && strpos($path, '?') === false) { - $path .= '.css'; - } - if ($path{0} !== '/') { $path = CSS_URL . $path; } + if (strpos($path, '?') === false) { + if (strpos($path, '.css') === false) { + $path .= '.css'; + } + if (Configure::read('Asset.timestamp') == true && Configure::read() > 0) { + $path .= '?' . @filemtime(WWW_ROOT . str_replace('/', DS, $path)); + } + } + if (COMPRESS_CSS) { $path = str_replace('css/', 'ccss/', $path); } @@ -434,6 +439,9 @@ class HtmlHelper extends AppHelper { } elseif (strpos($path, '://') !== false) { $path = $path; } else { + if (Configure::read('Asset.timestamp') == true && Configure::read() > 0) { + $path .= '?' . @filemtime(str_replace('/', DS, WWW_ROOT . IMAGES_URL . $path)); + } $path = $this->webroot(IMAGES_URL . $path); } diff --git a/cake/libs/view/helpers/javascript.php b/cake/libs/view/helpers/javascript.php index 9301ea6fc..ccff81ef1 100644 --- a/cake/libs/view/helpers/javascript.php +++ b/cake/libs/view/helpers/javascript.php @@ -36,7 +36,9 @@ */ class JavascriptHelper extends AppHelper { + var $__scriptBuffer = null; + var $_blockOptions = array(); var $_cachedEvents = array(); var $_cacheEvents = false; var $_cacheToFile = false; @@ -64,21 +66,15 @@ class JavascriptHelper extends AppHelper { * @param boolean $safe DEPRECATED. Use $options['safe'] instead * @return string The full SCRIPT element, with the JavaScript inside it. */ - function codeBlock($script = null, $options = array(), $safe = null) { + function codeBlock($script = null, $options = array(), $safe = true) { if (!empty($options) && !is_array($options)) { $options = array('allowCache' => $options); } else if (empty($options)) { $options = array(); } - $defaultOptions = array('allowCache' => true, 'safe' => true); - $options = array_merge($defaultOptions, $options); - - foreach($defaultOptions as $option => $value) { - if (isset($$option) && $$option !== null) { - $options[$option] = $$option; - } - } + $defaultOptions = array('allowCache' => true, 'safe' => true, 'inline' => true); + $options = array_merge($defaultOptions, compact('safe'), $options); if ($this->_cacheEvents && $this->_cacheAll && $options['allowCache'] && $script !== null) { $this->_cachedEvents[] = $script; @@ -91,17 +87,23 @@ class JavascriptHelper extends AppHelper { } } - if ($script === null && $this->_cacheAll && $options['allowCache']) { + if ($script === null) { $this->__scriptBuffer = @ob_get_contents(); + $this->_blockOptions = $options; @ob_end_clean(); ob_start(); return null; } - if ($block) { - return sprintf($this->tags['javascriptblock'], $script); - } else { - return sprintf($this->tags['javascriptstart'], $script); + if ($options['inline']) { + if ($block) { + return sprintf($this->tags['javascriptblock'], $script); + } else { + return sprintf($this->tags['javascriptstart']); + } + } elseif ($block) { + $view =& ClassRegistry::getObject('view'); + $view->addScript(sprintf($this->tags['javascriptblock'], $script)); } } } @@ -116,8 +118,15 @@ class JavascriptHelper extends AppHelper { ob_start(); echo $this->__scriptBuffer; $this->__scriptBuffer = null; + $options = $this->_blockOptions; + $this->_blockOptions = array(); - if (!empty($script)) { + if (isset($options['inline']) && !$options['inline']) { + $view =& ClassRegistry::getObject('view'); + $view->addScript(sprintf($this->tags['javascriptblock'], $script)); + } + + if (!empty($script) && $this->_cacheAll && $options['allowCache']) { $this->_cachedEvents[] = $script; return null; } @@ -143,9 +152,15 @@ class JavascriptHelper extends AppHelper { return; } - if (strpos($url, '.js') === false && strpos($url, '?') === false) { - $url .= '.js'; + if (strpos($url, '?') === false) { + if (strpos($url, '.js') === false) { + $url .= '.js'; + } + if (Configure::read('Asset.timestamp') == true && Configure::read() > 0) { + $url .= '?' . @filemtime(WWW_ROOT . str_replace('/', DS, $url)); + } } + if (strpos($url, '://') === false) { $url = $this->webroot(JS_URL . $url); } diff --git a/cake/tests/cases/libs/view/helpers/html.test.php b/cake/tests/cases/libs/view/helpers/html.test.php index 6121b4bbb..0f9e82f75 100644 --- a/cake/tests/cases/libs/view/helpers/html.test.php +++ b/cake/tests/cases/libs/view/helpers/html.test.php @@ -73,6 +73,11 @@ class HtmlHelperTest extends UnitTestCase { $result = $this->Html->image('/test/view/1.gif'); $this->assertPattern('/src="\/test\/view\/1.gif"/', $result); + + Configure::write('Asset.timestamp', true); + $result = $this->Html->image('logo.gif'); + $this->assertPattern('/^]+\/>$/', $result); + Configure::write('Asset.timestamp', false); } function testStyle() { @@ -113,6 +118,11 @@ class HtmlHelperTest extends UnitTestCase { $this->assertPattern('/^]+type="text\/css"[^<>]+\/>$/', $result); $this->assertPattern('/^]+href="http:\/\/.*\/screen\.css\?1234"[^<>]+\/>$/', $result); $this->assertNoPattern('/^]+[^rel|type|href]=[^<>]*>/', $result); + + Configure::write('Asset.timestamp', true); + $result = $this->Html->css('cake.generic'); + $this->assertPattern('/^]+href=".*css\/cake\.generic\.css\?[0-9]+"[^<>]+\/>$/', $result); + Configure::write('Asset.timestamp', false); } function testBreadcrumb() { diff --git a/cake/tests/cases/libs/view/helpers/javascript.test.php b/cake/tests/cases/libs/view/helpers/javascript.test.php index 92cfaeb09..3e3138d8b 100644 --- a/cake/tests/cases/libs/view/helpers/javascript.test.php +++ b/cake/tests/cases/libs/view/helpers/javascript.test.php @@ -26,8 +26,13 @@ * @lastmodified $Date$ * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License */ -uses('view'.DS.'helpers'.DS.'app_helper', 'view'.DS.'helper', 'view'.DS.'helpers'.DS.'javascript', - 'view'.DS.'helpers'.DS.'html', 'view'.DS.'helpers'.DS.'form'); +uses('view'.DS.'helpers'.DS.'app_helper', 'view'.DS.'helper', 'view'.DS.'helpers'.DS.'javascript','view'.DS.'view', + 'view'.DS.'helpers'.DS.'html', 'view'.DS.'helpers'.DS.'form', 'class_registry', 'controller'.DS.'controller'); + +class TheJsTestController extends Controller { + var $name = 'TheTest'; + var $uses = null; +} /** * Short description for class. * @@ -41,6 +46,8 @@ class JavascriptTest extends UnitTestCase { $this->Javascript = new JavascriptHelper(); $this->Javascript->Html = new HtmlHelper(); $this->Javascript->Form = new FormHelper(); + $view =& new View(new TheJsTestController()); + ClassRegistry::addObject('view', $view); } function testLink() { @@ -59,6 +66,15 @@ class JavascriptTest extends UnitTestCase { $result = $this->Javascript->link('jquery-1.1.2'); $expected = ''; $this->assertEqual($result, $expected); + + $result = $this->Javascript->link('jquery-1.1.2'); + $expected = ''; + $this->assertEqual($result, $expected); + + Configure::write('Asset.timestamp', true); + $result = $this->Javascript->link('jquery-1.1.2'); + $this->assertPattern('/^]+src=".*js\/jquery-1\.1\.2\.js\?"[^<>]*>/', $result); + Configure::write('Asset.timestamp', false); } function testObjectGeneration() { @@ -123,6 +139,16 @@ class JavascriptTest extends UnitTestCase { $this->assertEqual('alert("this is a buffered script");', $result); } + function testOutOfLineScriptWriting() { + echo $this->Javascript->codeBlock('$(document).ready(function() { /* ... */ });', array('inline' => false)); + + $this->Javascript->codeBlock(null, array('inline' => false)); + echo '$(function(){ /* ... */ });'; + $this->Javascript->blockEnd(); + + $view =& ClassRegistry::getObject('view'); + } + function testEvent() { $result = $this->Javascript->event('myId', 'click', 'something();'); $this->assertPattern('/^]+>\s*' . str_replace('/', '\\/', preg_quote('//')) . '\s*<\/script>$/', $result);