Skip to content
Permalink
Browse files

Moving JS generating methods to BaseEngine class

Adding duplicate script detection.
  • Loading branch information...
markstory committed Mar 8, 2009
1 parent 2362f28 commit 3e0d6459574210977a735ed82cfa28c7f67233a9
Showing with 161 additions and 107 deletions.
  1. +54 −44 cake/libs/view/helpers/js.php
  2. +107 −63 cake/tests/cases/libs/view/helpers/js.test.php
@@ -111,7 +111,7 @@ class JsHelper extends AppHelper {
* @var array
* @access private
**/
var $__includedScriptNames = array();
var $__includedScripts = array();
/**
* __objects
*
@@ -169,16 +169,6 @@ function call__($method, $params) {
}
trigger_error(sprintf(__('JsHelper:: Missing Method %s is undefined', true), $method), E_USER_WARNING);
}
/**
* Create an alert message in Javascript
*
* @param string $message Message you want to alter.
* @access public
* @return void
*/
function alert_($message) {
return 'alert("' . $this->escape($message) . '");';
}
/**
* Returns one or many <script> tags depending on the number of scripts given.
*
@@ -190,9 +180,11 @@ function alert_($message) {
*
* @param mixed $url String or array of javascript files to include
* @param boolean $inline Whether script should be output inline or into scripts_for_layout.
* @param boolean $once Whether or not the script should be checked for uniqueness. If true scripts will only be
* included once, use false to allow the same script to be included more than once per request.
* @return mixed
**/
function uses($url, $inline = true) {
function uses($url, $inline = true, $once = true) {
if (is_array($url)) {
$out = '';
foreach ($url as $i) {
@@ -204,6 +196,11 @@ function uses($url, $inline = true) {
return;
}
if ($once && isset($this->__includedScripts[$url])) {
return null;
}
$this->__includedScripts[$url] = true;
if (strpos($url, '://') === false) {
if ($url[0] !== '/') {
$url = JS_URL . $url;
@@ -266,27 +263,7 @@ function if_($if, $then, $else = null, $elseIf = array()) {
return $out;
}
/**
* Create a confirm() message
*
* @param string $message Message you want confirmed.
* @access public
* @return void
*/
function confirm_($message) {
return 'confirm("' . $this->escape($message) . '");';
}
/**
* Create a prompt() Javascript function
*
* @param string $message Message you want to prompt.
* @param string $default Default message
* @access public
* @return void
*/
function prompt_($message, $default = '') {
return 'prompt("' . $this->escape($message) . '", "' . $this->escape($default) . '");';
}
/*
* Tries a series of expressions, and executes after first successful completion.
* (See Prototype's Try.these).
@@ -340,16 +317,7 @@ function load_($url = null, $options = array()) {
}
return $func;
}
/**
* Redirects to a URL
*
* @param mixed $url
* @param array $options
* @return string
*/
function redirect_($url = null) {
return 'window.location = "' . Router::url($url) . '";';
}
/* function get__($name) {
return $this->__object($name, 'id');
@@ -397,11 +365,53 @@ class JsBaseEngineHelper extends AppHelper {
function __construct() {
$this->useNative = function_exists('json_encode');
}
/**
* Create an alert message in Javascript
*
* @param string $message Message you want to alter.
* @access public
* @return void
*/
function alert($message) {
return 'alert("' . $this->escape($message) . '");';
}
/**
* Redirects to a URL
*
* @param mixed $url
* @param array $options
* @return string
*/
function redirect($url = null) {
return 'window.location = "' . Router::url($url) . '";';
}
/**
* Create a confirm() message
*
* @param string $message Message you want confirmed.
* @access public
* @return void
*/
function confirm($message) {
return 'confirm("' . $this->escape($message) . '");';
}
/**
* Create a prompt() Javascript function
*
* @param string $message Message you want to prompt.
* @param string $default Default message
* @access public
* @return void
*/
function prompt($message, $default = '') {
return 'prompt("' . $this->escape($message) . '", "' . $this->escape($default) . '");';
}
/**
* Generates a JavaScript object in JavaScript Object Notation (JSON)
* from an array
* from an array. Will use native JSON encode method if available, and $useNative == true
*
* Options:
*
* - prefix - String prepended to the returned data.
* - postfix - String appended to the returned data.
* - stringKeys - A list of array keys to be treated as a string
@@ -91,34 +91,6 @@ function testMethodDispatching() {
$this->expectError();
$js->someMethodThatSurelyDoesntExist();
}
/**
* test prompt() creation
*
* @return void
**/
function testPrompt() {
$result = $this->Js->prompt('Hey, hey you', 'hi!');
$expected = 'prompt("Hey, hey you", "hi!");';
$this->assertEqual($result, $expected);
$result = $this->Js->prompt('"Hey"', '"hi"');
$expected = 'prompt("\"Hey\"", "\"hi\"");';
$this->assertEqual($result, $expected);
}
/**
* test alert generation
*
* @return void
**/
function testAlert() {
$result = $this->Js->alert('Hey there');
$expected = 'alert("Hey there");';
$this->assertEqual($result, $expected);
$result = $this->Js->alert('"Hey"');
$expected = 'alert("\"Hey\"");';
$this->assertEqual($result, $expected);
}
/**
* test script tag generation
*
@@ -130,16 +102,25 @@ function testUses() {
'script' => array('type' => 'text/javascript', 'src' => 'js/foo.js')
);
$this->assertTags($result, $expected);
$result = $this->Js->uses(array('foobar', 'bar'));
$expected = array(
array('script' => array('type' => 'text/javascript', 'src' => 'js/foobar.js')),
'/script',
array('script' => array('type' => 'text/javascript', 'src' => 'js/bar.js')),
'/script',
);
$this->assertTags($result, $expected);
$result = $this->Js->uses('jquery-1.3');
$expected = array(
'script' => array('type' => 'text/javascript', 'src' => 'js/jquery-1.3.js')
);
$this->assertTags($result, $expected);
$result = $this->Js->uses('/plugin/js/jquery-1.3');
$result = $this->Js->uses('/plugin/js/jquery-1.3.2');
$expected = array(
'script' => array('type' => 'text/javascript', 'src' => '/plugin/js/jquery-1.3.js')
'script' => array('type' => 'text/javascript', 'src' => '/plugin/js/jquery-1.3.2.js')
);
$this->assertTags($result, $expected);
@@ -148,15 +129,6 @@ function testUses() {
'script' => array('type' => 'text/javascript', 'src' => 'js/scriptaculous.js?load=effects')
);
$this->assertTags($result, $expected);
$result = $this->Js->uses(array('foo', 'bar'));
$expected = array(
array('script' => array('type' => 'text/javascript', 'src' => 'js/foo.js')),
'/script',
array('script' => array('type' => 'text/javascript', 'src' => 'js/bar.js')),
'/script',
);
$this->assertTags($result, $expected);
$view = new JsHelperView();
ClassRegistry::addObject('view', $view);
@@ -205,45 +177,36 @@ function testAssetTimestamping() {
touch(WWW_ROOT . 'js' . DS. '__cake_js_test.js');
$timestamp = substr(strtotime('now'), 0, 8);
$result = $this->Js->uses('__cake_js_test');
$this->assertPattern('/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result);
$result = $this->Js->uses('__cake_js_test', true, false);
$this->assertPattern('/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result, 'Timestamp value not found %s');
Configure::write('debug', 0);
$result = $this->Js->uses('__cake_js_test');
$result = $this->Js->uses('__cake_js_test', true, false);
$this->assertPattern('/__cake_js_test.js"/', $result);
Configure::write('Asset.timestamp', 'force');
$result = $this->Js->uses('__cake_js_test');
$this->assertPattern('/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"/', $result);
$result = $this->Js->uses('__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);
}
/**
* test confirm generation
*
* @return void
**/
function testConfirm() {
$result = $this->Js->confirm('Are you sure?');
$expected = 'confirm("Are you sure?");';
$this->assertEqual($result, $expected);
$result = $this->Js->confirm('"Are you sure?"');
$expected = 'confirm("\"Are you sure?\"");';
$this->assertEqual($result, $expected);
}
/**
* test Redirect
* test that scripts added with uses() are only ever included once.
*
* @return void
**/
function testRedirect() {
$result = $this->Js->redirect(array('controller' => 'posts', 'action' => 'view', 1));
$expected = 'window.location = "/posts/view/1";';
$this->assertEqual($result, $expected);
function testUniqueScriptInsertion() {
$result = $this->Js->uses('foo');
$this->assertNotNull($result);
$result = $this->Js->uses('foo');
$this->assertNull($result, 'Script returned upon duplicate inclusion %s');
}
}
/**
* JsBaseEngine Class Test case
*
@@ -299,6 +262,87 @@ function testEscaping() {
$expected = 'my \\\"string\\\"';
$this->assertEqual($result, $expected);
}
/**
* test prompt() creation
*
* @return void
**/
function testPrompt() {
$result = $this->JsEngine->prompt('Hey, hey you', 'hi!');
$expected = 'prompt("Hey, hey you", "hi!");';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->prompt('"Hey"', '"hi"');
$expected = 'prompt("\"Hey\"", "\"hi\"");';
$this->assertEqual($result, $expected);
}
/**
* test alert generation
*
* @return void
**/
function testAlert() {
$result = $this->JsEngine->alert('Hey there');
$expected = 'alert("Hey there");';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->alert('"Hey"');
$expected = 'alert("\"Hey\"");';
$this->assertEqual($result, $expected);
}
/**
* test confirm generation
*
* @return void
**/
function testConfirm() {
$result = $this->JsEngine->confirm('Are you sure?');
$expected = 'confirm("Are you sure?");';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->confirm('"Are you sure?"');
$expected = 'confirm("\"Are you sure?\"");';
$this->assertEqual($result, $expected);
}
/**
* test Redirect
*
* @return void
**/
function testRedirect() {
$result = $this->JsEngine->redirect(array('controller' => 'posts', 'action' => 'view', 1));
$expected = 'window.location = "/posts/view/1";';
$this->assertEqual($result, $expected);
}
/**
* testObject encoding with non-native methods.
*
* @return void
**/
function testObject() {
$this->JsEngine->useNative = false;
$object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8));
$result = $this->JsEngine->object($object);
$expected = '{"title":"New thing","indexes":[5,6,7,8]}';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->object(array('default' => 0));
$expected = '{"default":0}';
$this->assertEqual($result, $expected);
$result = $this->JsEngine->object(array(
'2007' => array(
'Spring' => array('1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')),
'Fall' => array('1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky'))
), '2006' => array(
'Spring' => array('1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')),
'Fall' => array('1' => array('id' => 1, 'name' => 'Josh'), '2' => array('id' => 2, 'name' => 'Becky')
))
));
$expected = '{"2007":{"Spring":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}},"Fall":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}}},"2006":{"Spring":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}},"Fall":{"1":{"id":1,"name":"Josh"},"2":{"id":2,"name":"Becky"}}}}';
$this->assertEqual($result, $expected);
}
}
?>

0 comments on commit 3e0d645

Please sign in to comment.
You can’t perform that action at this time.