From 2414a43c9163466fc271c718c80cdda0f73e30e3 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 25 Jul 2009 15:43:26 -0400 Subject: [PATCH] Adding HtmlHelper::scriptStart and HtmlHelper::scriptEnd. Further deprecates JavascriptHelper. Fixing issues in test case. --- cake/libs/view/helpers/html.php | 56 ++++++++++++++-- .../cases/libs/view/helpers/html.test.php | 64 ++++++++++++++++--- 2 files changed, 104 insertions(+), 16 deletions(-) diff --git a/cake/libs/view/helpers/html.php b/cake/libs/view/helpers/html.php index 5347bd73c..d99156197 100644 --- a/cake/libs/view/helpers/html.php +++ b/cake/libs/view/helpers/html.php @@ -134,16 +134,23 @@ class HtmlHelper extends AppHelper { * Breadcrumbs. * * @var array - * @access private + * @access protected */ var $_crumbs = array(); /** * Names of script files that have been included once * * @var array - * @access public + * @access private **/ var $__includedScripts = array(); +/** + * Options for the currently opened script block buffer if any. + * + * @var array + * @access protected + **/ + var $_scriptBlockOptions = array(); /** * Document type definitions * @@ -362,7 +369,11 @@ class HtmlHelper extends AppHelper { $path = $this->webroot($path); $url = $path; - if (strpos($path, '?') === false && ((Configure::read('Asset.timestamp') === true && Configure::read() > 0) || Configure::read('Asset.timestamp') === 'force')) { + $timestampEnabled = ( + (Configure::read('Asset.timestamp') === true && Configure::read() > 0) || + Configure::read('Asset.timestamp') === 'force' + ); + if (strpos($path, '?') === false && $timestampEnabled) { $url .= '?' . @filemtime(WWW_ROOT . str_replace('/', DS, $path)); } @@ -416,7 +427,7 @@ class HtmlHelper extends AppHelper { } if ($once && isset($this->__includedScripts[$url])) { - return null; + return null; } $this->__includedScripts[$url] = true; @@ -425,7 +436,6 @@ class HtmlHelper extends AppHelper { $url = JS_URL . $url; } $url = $this->webroot($url); - if (strpos($url, '?') === false) { if (strpos($url, '.js') === false) { $url .= '.js'; @@ -433,7 +443,7 @@ class HtmlHelper extends AppHelper { } $timestampEnabled = ( - (Configure::read('Asset.timestamp') === true && Configure::read() > 0) || + (Configure::read('Asset.timestamp') === true && Configure::read('debug') > 0) || Configure::read('Asset.timestamp') === 'force' ); @@ -475,6 +485,39 @@ class HtmlHelper extends AppHelper { return null; } } +/** + * Begin a script block that captures output until HtmlHelper::scriptEnd() + * is called. This capturing block will capture all output between the methods + * and create a scriptBlock from it. + * + * ### Options + * + * - `safe` Whether the code block should contain a CDATA + * - `inline` Should the generated script tag be output inline or in `$scripts_for_layout` + * + * @param array $options Options for the code block. + * @return void + **/ + function scriptStart($options = array()) { + $defaultOptions = array('safe' => true, 'inline' => true); + $options = array_merge($defaultOptions, $options); + $this->_scriptBlockOptions = $options; + ob_start(); + return null; + } +/** + * End a Buffered section of Javascript capturing. + * Generates a script tag inline or in `$scripts_for_layout` depending on the settings + * used when the scriptblock was started + * + * @return mixed depending on the settings of scriptStart() either a script tag or null + **/ + function scriptEnd() { + $buffer = ob_get_clean(); + $options = $this->_scriptBlockOptions; + $this->_scriptBlockOptions = array(); + return $this->scriptBlock($buffer, $options); + } /** * Builds CSS style data from an array of CSS properties * @@ -538,7 +581,6 @@ class HtmlHelper extends AppHelper { $path = $this->webroot($path); } elseif (strpos($path, '://') === false) { $path = $this->webroot(IMAGES_URL . $path); - if ((Configure::read('Asset.timestamp') == true && Configure::read() > 0) || Configure::read('Asset.timestamp') === 'force') { $path .= '?' . @filemtime(str_replace('/', DS, WWW_ROOT . $path)); } diff --git a/cake/tests/cases/libs/view/helpers/html.test.php b/cake/tests/cases/libs/view/helpers/html.test.php index 92cef1f4e..ac43bb45c 100644 --- a/cake/tests/cases/libs/view/helpers/html.test.php +++ b/cake/tests/cases/libs/view/helpers/html.test.php @@ -250,7 +250,7 @@ class HtmlHelperTest extends CakeTestCase { ); $this->assertTags($result, $expected); - Configure::write('Asset.timestamp', true); + Configure::write('Asset.timestamp', 'force'); $result = $this->Html->link($this->Html->image('test.gif'), '#', array(), false, false, false); $expected = array( @@ -289,7 +289,7 @@ class HtmlHelperTest extends CakeTestCase { $result = $this->Html->image('/test/view/1.gif'); $this->assertTags($result, array('img' => array('src' => '/test/view/1.gif', 'alt' => ''))); - Configure::write('Asset.timestamp', true); + Configure::write('Asset.timestamp', 'force'); $result = $this->Html->image('cake.icon.gif'); $this->assertTags($result, array('img' => array('src' => 'preg:/img\/cake\.icon\.gif\?\d+/', 'alt' => ''))); @@ -370,6 +370,7 @@ class HtmlHelperTest extends CakeTestCase { $result = $this->Html->css('cake.generic'); $expected['link']['href'] = 'preg:/.*ccss\/cake\.generic\.css/'; $this->assertTags($result, $expected); + Configure::write('Asset.filter.css', false); $result = explode("\n", trim($this->Html->css(array('cake.generic', 'vendor.generic')))); @@ -378,7 +379,8 @@ class HtmlHelperTest extends CakeTestCase { $expected['link']['href'] = 'preg:/.*css\/vendor\.generic\.css/'; $this->assertTags($result[1], $expected); $this->assertEqual(count($result), 2); - + + Configure::write('debug', 2); Configure::write('Asset.timestamp', true); Configure::write('Asset.filter.css', 'css.php'); @@ -423,10 +425,13 @@ class HtmlHelperTest extends CakeTestCase { * @return void **/ function testScriptTimestamping() { - if ($this->skipIf(!is_writable(JS), 'webroot/js is not Writable, timestamp testing has been skipped')) { + $skip = $this->skipIf(!is_writable(JS), 'webroot/js is not Writable, timestamp testing has been skipped'); + if ($skip) { return; } + Configure::write('debug', 2); Configure::write('Asset.timestamp', true); + touch(WWW_ROOT . 'js' . DS. '__cake_js_test.js'); $timestamp = substr(strtotime('now'), 0, 8); @@ -434,15 +439,10 @@ class HtmlHelperTest extends CakeTestCase { $this->assertPattern('/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result, 'Timestamp value not found %s'); Configure::write('debug', 0); - $result = $this->Html->script('__cake_js_test', true, false); - $this->assertPattern('/__cake_js_test.js"/', $result); - Configure::write('Asset.timestamp', 'force'); $result = $this->Html->script('__cake_js_test', true, false); $this->assertPattern('/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result, 'Timestamp value not found %s'); - unlink(WWW_ROOT . 'js' . DS. '__cake_js_test.js'); - Configure::write('debug', 2); Configure::write('Asset.timestamp', false); } /** @@ -529,6 +529,52 @@ class HtmlHelperTest extends CakeTestCase { $result = $this->Html->scriptBlock('window.foo = 2;', array('inline' => false)); $this->assertNull($result); } +/** + * test script tag output buffering when using scriptStart() and scriptEnd(); + * + * @return void + **/ + function testScriptStartAndScriptEnd() { + $result = $this->Html->scriptStart(array('safe' => true)); + $this->assertNull($result); + echo 'this is some javascript'; + + $result = $this->Html->scriptEnd(); + $expected = array( + 'script' => array('type' => 'text/javascript'), + $this->cDataStart, + 'this is some javascript', + $this->cDataEnd, + '/script' + ); + $this->assertTags($result, $expected); + + + $result = $this->Html->scriptStart(array('safe' => false)); + $this->assertNull($result); + echo 'this is some javascript'; + + $result = $this->Html->scriptEnd(); + $expected = array( + 'script' => array('type' => 'text/javascript'), + 'this is some javascript', + '/script' + ); + $this->assertTags($result, $expected); + + ClassRegistry::removeObject('view'); + $View =& new HtmlHelperMockView(); + + $View->expectOnce('addScript'); + ClassRegistry::addObject('view', $View); + + $result = $this->Html->scriptStart(array('safe' => false, 'inline' => false)); + $this->assertNull($result); + echo 'this is some javascript'; + + $result = $this->Html->scriptEnd(); + $this->assertNull($result); + } /** * testCharsetTag method *