Skip to content

Commit

Permalink
Making set vars with Js->set go to the top of the buffered scripts ar…
Browse files Browse the repository at this point in the history
…ray. Tests added.

Updating doc blocks for JsHelper and JsBaseEngineHelper.
Fixes #131
  • Loading branch information
markstory committed Dec 21, 2009
1 parent 42fa6ff commit 5274dce
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 16 deletions.
62 changes: 50 additions & 12 deletions cake/libs/view/helpers/js.php
Expand Up @@ -32,13 +32,15 @@ class JsHelper extends AppHelper {
* Whether or not you want scripts to be buffered or output.
*
* @var boolean
* @access public
*/
var $bufferScripts = true;

/**
* helpers
*
* @var array
* @access public
*/
var $helpers = array('Html', 'Form');

Expand All @@ -47,13 +49,15 @@ class JsHelper extends AppHelper {
*
* @var array
* @see JsHelper::set()
* @access private
*/
var $__jsVars = array();

/**
* Scripts that are queued for output
*
* @var array
* @access private
*/
var $__bufferedScripts = array();

Expand All @@ -69,15 +73,16 @@ class JsHelper extends AppHelper {
* The javascript variable created by set() variables.
*
* @var string
* @access public
*/
var $setVariable = APP_DIR;

/**
* Constructor - determines engine helper
*
* @param array $settings Settings array contains name of engine helper.
* @access public
* @return void
* @access public
*/
function __construct($settings = array()) {
$className = 'Jquery';
Expand Down Expand Up @@ -112,8 +117,8 @@ function __construct($settings = array()) {
*
* @param string $method Method to be called
* @param array $params Parameters for the method being called.
* @access public
* @return mixed Depends on the return of the dispatched method, or it could be an instance of the EngineHelper
* @access public
*/
function call__($method, $params) {
if (isset($this->{$this->__engineName}) && method_exists($this->{$this->__engineName}, $method)) {
Expand Down Expand Up @@ -157,6 +162,7 @@ function call__($method, $params) {
* @param array $options Options to use for encoding JSON. See JsBaseEngineHelper::object() for more details.
* @return string encoded JSON
* @deprecated Remove when support for PHP4 and Object::object are removed.
* @access public
*/
function object($data = array(), $options = array()) {
return $this->{$this->__engineName}->object($data, $options);
Expand Down Expand Up @@ -190,6 +196,7 @@ function value($val, $quoteString = true) {
*
* @param array $options options for the code block
* @return string completed javascript tag.
* @access public
*/
function writeBuffer($options = array()) {
$defaults = array('onDomReady' => true, 'inline' => true, 'cache' => false, 'clear' => true, 'safe' => true);
Expand Down Expand Up @@ -220,17 +227,26 @@ function writeBuffer($options = array()) {
/**
* Write a script to the cached scripts.
*
* @param string $script Script string to add to the buffer.
* @param boolean $top If true the script will be added to the top of the
* buffered scripts array. If false the bottom.
* @return void
* @access public
*/
function buffer($script) {
$this->__bufferedScripts[] = $script;
function buffer($script, $top = false) {
if ($top) {
array_unshift($this->__bufferedScripts, $script);
} else {
$this->__bufferedScripts[] = $script;
}
}

/**
* Get all the cached scripts
*
* @param boolean $clear Whether or not to clear the script caches (default true)
* @return array Array of scripts added to the request.
* @access public
*/
function getBuffer($clear = true) {
$this->_createVars();
Expand All @@ -246,11 +262,12 @@ function getBuffer($clear = true) {
* Generates the object string for variables passed to javascript.
*
* @return string
* @access public
*/
function _createVars() {
if (!empty($this->__jsVars)) {
$setVar = (strpos($this->setVariable, '.')) ? $this->setVariable : 'window.' . $this->setVariable;
$this->buffer($setVar . ' = ' . $this->object($this->__jsVars) . ';');
$this->buffer($setVar . ' = ' . $this->object($this->__jsVars) . ';', true);
}
}

Expand All @@ -271,6 +288,7 @@ function _createVars() {
* @param mixed $url Mixed either a string URL or an cake url array.
* @param array $options Options for both the HTML element and Js::request()
* @return string Completed link. If buffering is disabled a script tag will be returned as well.
* @access public
*/
function link($title, $url = null, $options = array()) {
if (!isset($options['id'])) {
Expand Down Expand Up @@ -303,9 +321,10 @@ function link($title, $url = null, $options = array()) {
* output when the buffer is fetched with `JsHelper::getBuffer()` or `JsHelper::writeBuffer()`
* The Javascript variable used to output set variables can be controlled with `JsHelper::$setVariable`
*
* @param mixed $one
* @param mixed $two
* @param mixed $one Either an array of variables to set, or the name of the variable to set.
* @param mixed $two If $one is a string, $two is the value for that key.
* @return void
* @access public
*/
function set($one, $two = null) {
$data = null;
Expand Down Expand Up @@ -335,6 +354,7 @@ function set($one, $two = null) {
* @param string $title The display text of the submit button.
* @param array $options Array of options to use.
* @return string Completed submit button.
* @access public
*/
function submit($caption = null, $options = array()) {
if (!isset($options['id'])) {
Expand Down Expand Up @@ -377,6 +397,7 @@ function submit($caption = null, $options = array()) {
* @param array $options Options to filter.
* @param array $additional Array of additional keys to extract and include in the return options array.
* @return array Array of options for non-js.
* @access public
*/
function _getHtmlOptions(&$options, $additional = array()) {
$htmlKeys = array_merge(array('class', 'id', 'escape', 'onblur', 'onfocus', 'rel', 'title'), $additional);
Expand Down Expand Up @@ -425,6 +446,7 @@ class JsBaseEngineHelper extends AppHelper {
* for end user use though.
*
* @var array
* @access protected
*/
var $_optionMap = array();

Expand All @@ -433,13 +455,15 @@ class JsBaseEngineHelper extends AppHelper {
* This allows specific 'end point' methods to be automatically buffered by the JsHelper.
*
* @var array
* @access public
*/
var $bufferedMethods = array('event', 'sortable', 'drag', 'drop', 'slider');

/**
* Contains a list of callback names -> default arguments.
*
* @var array
* @access protected
*/
var $_callbackArguments = array();

Expand All @@ -456,8 +480,8 @@ function __construct() {
* Create an alert message in Javascript
*
* @param string $message Message you want to alter.
* @access public
* @return string completed alert()
* @access public
*/
function alert($message) {
return 'alert("' . $this->escape($message) . '");';
Expand All @@ -469,6 +493,7 @@ function alert($message) {
* @param mixed $url
* @param array $options
* @return string completed redirect in javascript
* @access public
*/
function redirect($url = null) {
return 'window.location = "' . Router::url($url) . '";';
Expand All @@ -478,8 +503,8 @@ function redirect($url = null) {
* Create a confirm() message
*
* @param string $message Message you want confirmed.
* @access public
* @return string completed confirm()
* @access public
*/
function confirm($message) {
return 'confirm("' . $this->escape($message) . '");';
Expand All @@ -490,8 +515,8 @@ function confirm($message) {
* function scope.
*
* @param string $message Message to use in the confirm dialog.
* @return string completed confirm with return script
* @access public
* @return string
*/
function confirmReturn($message) {
$out = 'var _confirm = ' . $this->confirm($message);
Expand All @@ -504,8 +529,8 @@ function confirmReturn($message) {
*
* @param string $message Message you want to prompt.
* @param string $default Default message
* @access public
* @return string completed prompt()
* @access public
*/
function prompt($message, $default = '') {
return 'prompt("' . $this->escape($message) . '", "' . $this->escape($default) . '");';
Expand Down Expand Up @@ -633,7 +658,9 @@ function escape($string) {
/**
* Encode a string into JSON. Converts and escapes necessary characters.
*
* @param string $string The string that needs to be utf8->hex encoded
* @return void
* @access protected
*/
function _utf8ToHex($string) {
$length = strlen($string);
Expand Down Expand Up @@ -729,6 +756,7 @@ function _utf8ToHex($string) {
*
* @param string $selector The selector that is targeted
* @return object instance of $this. Allows chained methods.
* @access public
*/
function get($selector) {
trigger_error(sprintf(__('%s does not have get() implemented', true), get_class($this)), E_USER_WARNING);
Expand All @@ -747,6 +775,7 @@ function get($selector) {
* @param string $callback The Javascript function you wish to trigger or the function literal
* @param array $options Options for the event.
* @return string completed event handler
* @access public
*/
function event($type, $callback, $options = array()) {
trigger_error(sprintf(__('%s does not have event() implemented', true), get_class($this)), E_USER_WARNING);
Expand All @@ -757,6 +786,7 @@ function event($type, $callback, $options = array()) {
*
* @param string $functionBody The code to run on domReady
* @return string completed domReady method
* @access public
*/
function domReady($functionBody) {
trigger_error(sprintf(__('%s does not have domReady() implemented', true), get_class($this)), E_USER_WARNING);
Expand Down Expand Up @@ -794,6 +824,7 @@ function each($callback) {
* @param string $name The name of the effect to trigger.
* @param array $options Array of options for the effect.
* @return string completed string with effect.
* @access public
*/
function effect($name, $options) {
trigger_error(sprintf(__('%s does not have effect() implemented', true), get_class($this)), E_USER_WARNING);
Expand Down Expand Up @@ -823,6 +854,7 @@ function effect($name, $options) {
* @param mixed $url Array or String URL to target with the request.
* @param array $options Array of options. See above for cross library supported options
* @return string XHR request.
* @access public
*/
function request($url, $options = array()) {
trigger_error(sprintf(__('%s does not have request() implemented', true), get_class($this)), E_USER_WARNING);
Expand All @@ -846,6 +878,7 @@ function request($url, $options = array()) {
*
* @param array $options Options array see above.
* @return string Completed drag script
* @access public
*/
function drag($options = array()) {
trigger_error(sprintf(__('%s does not have drag() implemented', true), get_class($this)), E_USER_WARNING);
Expand All @@ -867,6 +900,7 @@ function drag($options = array()) {
* - `leave` - Event fired when a drag is removed from a drop zone without being dropped.
*
* @return string Completed drop script
* @access public
*/
function drop($options = array()) {
trigger_error(sprintf(__('%s does not have drop() implemented', true), get_class($this)), E_USER_WARNING);
Expand All @@ -891,6 +925,7 @@ function drop($options = array()) {
*
* @param array $options Array of options for the sortable. See above.
* @return string Completed sortable script.
* @access public
*/
function sortable() {
trigger_error(sprintf(__('%s does not have sortable() implemented', true), get_class($this)), E_USER_WARNING);
Expand All @@ -914,6 +949,7 @@ function sortable() {
* - `complete` - Fired when the user stops sliding the handle
*
* @return string Completed slider script
* @access public
*/
function slider() {
trigger_error(sprintf(__('%s does not have slider() implemented', true), get_class($this)), E_USER_WARNING);
Expand All @@ -932,6 +968,7 @@ function slider() {
*
* @param array $options options for serialization generation.
* @return string completed form serialization script
* @access public
*/
function serializeForm() {
trigger_error(
Expand Down Expand Up @@ -991,8 +1028,8 @@ function _mapOptions($method, $options) {
* @param string $method Name of the method you are preparing callbacks for.
* @param array $options Array of options being parsed
* @param string $callbacks Additional Keys that contain callbacks
* @access protected
* @return array Array of options with callbacks added.
* @access protected
*/
function _prepareCallbacks($method, $options, $callbacks = array()) {
$wrapCallbacks = true;
Expand Down Expand Up @@ -1029,6 +1066,7 @@ function _prepareCallbacks($method, $options, $callbacks = array()) {
* @param string $method Name of method processing options for.
* @param array $options Array of options to process.
* @return string Parsed options string.
* @access protected
*/
function _processOptions($method, $options) {
$options = $this->_mapOptions($method, $options);
Expand Down
21 changes: 17 additions & 4 deletions cake/tests/cases/libs/view/helpers/js.test.php
Expand Up @@ -231,9 +231,6 @@ function testWriteScriptsNoFile() {
$view->expectAt(0, 'addScript', array(new PatternExpectation('/one\s=\s1;\ntwo\=\2;/')));
$result = $this->Js->writeBuffer(array('onDomReady' => false, 'inline' => false, 'cache' => false));
}
function getTests() {
return array('start', 'startCase', 'testWriteBufferNotInline', 'endCase', 'end');
}

/**
* test that writing the buffer with inline = false includes a script tag.
Expand Down Expand Up @@ -490,8 +487,24 @@ function testSet() {
$expected = 'Application.variables = {"loggedIn":true,"height":"tall","color":"purple"};';
$this->assertEqual($result[0], $expected);
}
}

/**
* test that vars set with Js->set() go to the top of the buffered scripts list.
*
* @return void
*/
function testSetVarsAtTopOfBufferedScripts() {
$this->Js->set(array('height' => 'tall', 'color' => 'purple'));
$this->Js->alert('hey you!', array('buffer' => true));
$this->Js->confirm('Are you sure?', array('buffer' => true));
$result = $this->Js->getBuffer(false);

$expected = 'window.app = {"height":"tall","color":"purple"};';
$this->assertEqual($result[0], $expected);
$this->assertEqual($result[1], 'alert("hey you!");');
$this->assertEqual($result[2], 'confirm("Are you sure?");');
}
}

/**
* JsBaseEngine Class Test case
Expand Down

0 comments on commit 5274dce

Please sign in to comment.