diff --git a/cake/libs/view/helpers/ajax.php b/cake/libs/view/helpers/ajax.php deleted file mode 100644 index f32f9df130a..00000000000 --- a/cake/libs/view/helpers/ajax.php +++ /dev/null @@ -1,1035 +0,0 @@ -options[url] - * (using the url() format) that's called in the background using - * XMLHttpRequest. The result of that request can then be inserted into a - * DOM object whose id can be specified with options[update]. - * - * Examples: - * - * link("Delete this post", - * array("update" => "posts", "url" => "delete/{$postid->id}")); - * link(imageTag("refresh"), - * array("update" => "emails", "url" => "list_emails" )); - * - * - * By default, these remote requests are processed asynchronous during - * which various callbacks can be triggered (for progress indicators and - * the likes). - * - * Example: - * - * link (word, - * array("url" => "undo", "n" => word_counter), - * array("complete" => "undoRequestCompleted(request)")); - * - * - * The callbacks that may be specified are: - * - * - loading:: Called when the remote document is being - * loaded with data by the browser. - * - loaded:: Called when the browser has finished loading - * the remote document. - * - interactive:: Called when the user can interact with the - * remote document, even though it has not - * finished loading. - * - complete:: Called when the XMLHttpRequest is complete. - * - * If you for some reason or another need synchronous processing (that'll - * block the browser while the request is happening), you can specify - * options[type] = synchronous. - * - * You can customize further browser side call logic by passing - * in Javascript code snippets via some optional parameters. In - * their order of use these are: - * - * - confirm:: Adds confirmation dialog. - * -condition:: Perform remote request conditionally - * by this expression. Use this to - * describe browser-side conditions when - * request should not be initiated. - * - before:: Called before request is initiated. - * - after:: Called immediately after request was - * initiated and before loading. - * - * @param string $title Title of link - * @param mixed $url Cake-relative URL or array of URL parameters, or external URL (starts with http://) - * @param array $options Options for JavaScript function - * @param string $confirm Confirmation message. Calls up a JavaScript confirm() message. - * - * @return string HTML code for link to remote action - * @link http://book.cakephp.org/view/1363/link - */ - function link($title, $url = null, $options = array(), $confirm = null) { - if (!isset($url)) { - $url = $title; - } - if (!isset($options['url'])) { - $options['url'] = $url; - } - - if (isset($confirm)) { - $options['confirm'] = $confirm; - unset($confirm); - } - $htmlOptions = $this->__getHtmlOptions($options, array('url')); - $options += array('safe' => true); - - unset($options['escape']); - if (empty($options['fallback']) || !isset($options['fallback'])) { - $options['fallback'] = $url; - } - $htmlDefaults = array('id' => 'link' . intval(mt_rand()), 'onclick' => ''); - $htmlOptions = array_merge($htmlDefaults, $htmlOptions); - - $htmlOptions['onclick'] .= ' event.returnValue = false; return false;'; - $return = $this->Html->link($title, $url, $htmlOptions); - $callback = $this->remoteFunction($options); - $script = $this->Javascript->event("'{$htmlOptions['id']}'", "click", $callback); - - if (is_string($script)) { - $return .= $script; - } - return $return; - } - -/** - * Creates JavaScript function for remote AJAX call - * - * This function creates the javascript needed to make a remote call - * it is primarily used as a helper for AjaxHelper::link. - * - * @param array $options options for javascript - * @return string html code for link to remote action - * @see AjaxHelper::link() for docs on options parameter. - * @link http://book.cakephp.org/view/1364/remoteFunction - */ - function remoteFunction($options) { - if (isset($options['update'])) { - if (!is_array($options['update'])) { - $func = "new Ajax.Updater('{$options['update']}',"; - } else { - $func = "new Ajax.Updater(document.createElement('div'),"; - } - if (!isset($options['requestHeaders'])) { - $options['requestHeaders'] = array(); - } - if (is_array($options['update'])) { - $options['update'] = implode(' ', $options['update']); - } - $options['requestHeaders']['X-Update'] = $options['update']; - } else { - $func = "new Ajax.Request("; - } - - $url = isset($options['url']) ? $options['url'] : ""; - if (empty($options['safe'])) { - $url = $this->url($url); - } else { - $url = Router::url($url); - } - - $func .= "'" . $url . "'"; - $func .= ", " . $this->__optionsForAjax($options) . ")"; - - if (isset($options['before'])) { - $func = "{$options['before']}; $func"; - } - if (isset($options['after'])) { - $func = "$func; {$options['after']};"; - } - if (isset($options['condition'])) { - $func = "if ({$options['condition']}) { $func; }"; - } - - if (isset($options['confirm'])) { - $func = "if (confirm('" . $this->Javascript->escapeString($options['confirm']) - . "')) { $func; } else { event.returnValue = false; return false; }"; - } - return $func; - } - -/** - * Periodically call remote url via AJAX. - * - * Periodically calls the specified url (options[url]) every options[frequency] - * seconds (default is 10). Usually used to update a specified div (options[update]) with - * the results of the remote call. The options for specifying the target with url and defining - * callbacks is the same as AjaxHelper::link(). - * - * @param array $options Callback options - * @return string Javascript code - * @see AjaxHelper::link() - * @link http://book.cakephp.org/view/1365/remoteTimer - */ - function remoteTimer($options = null) { - $frequency = (isset($options['frequency'])) ? $options['frequency'] : 10; - $callback = $this->remoteFunction($options); - $code = "new PeriodicalExecuter(function() {{$callback}}, $frequency)"; - return $this->Javascript->codeBlock($code); - } - -/** - * Returns form tag that will submit using Ajax. - * - * Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular - * reloading POST arrangement. Even though it's using Javascript to serialize the form elements, - * the form submission will work just like a regular submission as viewed by the receiving side - * (all elements available in params). The options for defining callbacks is the same - * as AjaxHelper::link(). - * - * @param mixed $params Either a string identifying the form target, or an array of method parameters, including: - * - 'params' => Acts as the form target - * - 'type' => 'post' or 'get' - * - 'options' => An array containing all HTML and script options used to - * generate the form tag and Ajax request. - * @param array $type How form data is posted: 'get' or 'post' - * @param array $options Callback/HTML options - * @return string JavaScript/HTML code - * @see AjaxHelper::link() - * @link http://book.cakephp.org/view/1366/form - */ - function form($params = null, $type = 'post', $options = array()) { - $model = false; - if (is_array($params)) { - extract($params, EXTR_OVERWRITE); - } - - if (empty($options['url'])) { - $options['url'] = array('action' => $params); - } - - $htmlDefaults = array( - 'id' => 'form' . intval(mt_rand()), - 'onsubmit' => "event.returnValue = false; return false;", - 'type' => $type - ); - $htmlOptions = $this->__getHtmlOptions($options, array('model', 'with')); - $htmlOptions = array_merge($htmlDefaults, $htmlOptions); - - $defaults = array('model' => $model, 'with' => "Form.serialize('{$htmlOptions['id']}')"); - $options = array_merge($defaults, $options); - $callback = $this->remoteFunction($options); - - $form = $this->Form->create($options['model'], $htmlOptions); - $script = $this->Javascript->event("'" . $htmlOptions['id']. "'", 'submit', $callback); - return $form . $script; - } - -/** - * Returns a button input tag that will submit using Ajax - * - * Returns a button input tag that will submit form using XMLHttpRequest in the background instead - * of regular reloading POST arrangement. options argument is the same as - * in AjaxHelper::form(). - * - * @param string $title Input button title - * @param array $options Callback options - * @return string Ajaxed input button - * @see AjaxHelper::form() - * @link http://book.cakephp.org/view/1367/submit - */ - function submit($title = 'Submit', $options = array()) { - $htmlOptions = $this->__getHtmlOptions($options); - $htmlOptions['value'] = $title; - - if (!isset($options['with'])) { - $options['with'] = 'Form.serialize(Event.element(event).form)'; - } - if (!isset($htmlOptions['id'])) { - $htmlOptions['id'] = 'submit' . intval(mt_rand()); - } - - $htmlOptions['onclick'] = "event.returnValue = false; return false;"; - $callback = $this->remoteFunction($options); - - $form = $this->Form->submit($title, $htmlOptions); - $script = $this->Javascript->event('"' . $htmlOptions['id'] . '"', 'click', $callback); - return $form . $script; - } - -/** - * Observe field and call ajax on change. - * - * Observes the field with the DOM ID specified by field and makes - * an Ajax when its contents have changed. - * - * Required +options+ are: - * - frequency:: The frequency (in seconds) at which changes to - * this field will be detected. - * - url:: @see url() -style options for the action to call - * when the field has changed. - * - * Additional options are: - * - update:: Specifies the DOM ID of the element whose - * innerHTML should be updated with the - * XMLHttpRequest response text. - * - with:: A Javascript expression specifying the - * parameters for the XMLHttpRequest. This defaults - * to Form.Element.serialize('$field'), which can be - * accessed from params['form']['field_id']. - * - * Additionally, you may specify any of the options documented in - * @see linkToRemote(). - * - * @param string $field DOM ID of field to observe - * @param array $options ajax options - * @return string ajax script - * @link http://book.cakephp.org/view/1368/observeField - */ - function observeField($field, $options = array()) { - if (!isset($options['with'])) { - $options['with'] = 'Form.Element.serialize(\'' . $field . '\')'; - } - $observer = 'Observer'; - if (!isset($options['frequency']) || intval($options['frequency']) == 0) { - $observer = 'EventObserver'; - } - return $this->Javascript->codeBlock( - $this->_buildObserver('Form.Element.' . $observer, $field, $options) - ); - } - -/** - * Observe entire form and call ajax on change. - * - * Like @see observeField(), but operates on an entire form identified by the - * DOM ID form. options are the same as observeField, except - * the default value of the with option evaluates to the - * serialized (request string) value of the form. - * - * @param string $form DOM ID of form to observe - * @param array $options ajax options - * @return string ajax script - * @link http://book.cakephp.org/view/1369/observeForm - */ - function observeForm($form, $options = array()) { - if (!isset($options['with'])) { - $options['with'] = 'Form.serialize(\'' . $form . '\')'; - } - $observer = 'Observer'; - if (!isset($options['frequency']) || intval($options['frequency']) == 0) { - $observer = 'EventObserver'; - } - return $this->Javascript->codeBlock( - $this->_buildObserver('Form.' . $observer, $form, $options) - ); - } - -/** - * Create a text field with Autocomplete. - * - * Creates an autocomplete field with the given ID and options. - * - * options['with'] defaults to "Form.Element.serialize('$field')", - * but can be any valid javascript expression defining the additional fields. - * - * @param string $field DOM ID of field to observe - * @param string $url URL for the autocomplete action - * @param array $options Ajax options - * @return string Ajax script - * @link http://book.cakephp.org/view/1370/autoComplete - */ - function autoComplete($field, $url = "", $options = array()) { - $var = ''; - if (isset($options['var'])) { - $var = 'var ' . $options['var'] . ' = '; - unset($options['var']); - } - - if (!isset($options['id'])) { - $options['id'] = Inflector::camelize(str_replace(".", "_", $field)); - } - - $divOptions = array( - 'id' => $options['id'] . "_autoComplete", - 'class' => isset($options['class']) ? $options['class'] : 'auto_complete' - ); - - if (isset($options['div_id'])) { - $divOptions['id'] = $options['div_id']; - unset($options['div_id']); - } - - $htmlOptions = $this->__getHtmlOptions($options); - $htmlOptions['autocomplete'] = "off"; - - foreach ($this->autoCompleteOptions as $opt) { - unset($htmlOptions[$opt]); - } - - if (isset($options['tokens'])) { - if (is_array($options['tokens'])) { - $options['tokens'] = $this->Javascript->object($options['tokens']); - } else { - $options['tokens'] = '"' . $options['tokens'] . '"'; - } - } - - $options = $this->_optionsToString($options, array('paramName', 'indicator')); - $options = $this->_buildOptions($options, $this->autoCompleteOptions); - - $text = $this->Form->text($field, $htmlOptions); - $div = $this->Html->div(null, '', $divOptions); - $script = "{$var}new Ajax.Autocompleter('{$htmlOptions['id']}', '{$divOptions['id']}', '"; - $script .= $this->Html->url($url) . "', {$options});"; - - return "{$text}\n{$div}\n" . $this->Javascript->codeBlock($script); - } - -/** - * Creates an Ajax-updateable DIV element - * - * @param string $id options for javascript - * @return string HTML code - */ - function div($id, $options = array()) { - if (env('HTTP_X_UPDATE') != null) { - $this->Javascript->enabled = false; - $divs = explode(' ', env('HTTP_X_UPDATE')); - - if (in_array($id, $divs)) { - @ob_end_clean(); - ob_start(); - return ''; - } - } - $attr = $this->_parseAttributes(array_merge($options, array('id' => $id))); - return sprintf($this->Html->tags['blockstart'], $attr); - } - -/** - * Closes an Ajax-updateable DIV element - * - * @param string $id The DOM ID of the element - * @return string HTML code - */ - function divEnd($id) { - if (env('HTTP_X_UPDATE') != null) { - $divs = explode(' ', env('HTTP_X_UPDATE')); - if (in_array($id, $divs)) { - $this->__ajaxBuffer[$id] = ob_get_contents(); - ob_end_clean(); - ob_start(); - return ''; - } - } - return $this->Html->tags['blockend']; - } - -/** - * Detects Ajax requests - * - * @return boolean True if the current request is a Prototype Ajax update call - * @link http://book.cakephp.org/view/1371/isAjax - */ - function isAjax() { - return (isset($this->params['isAjax']) && $this->params['isAjax'] === true); - } - -/** - * Creates a draggable element. For a reference on the options for this function, - * check out http://github.com/madrobby/scriptaculous/wikis/draggable - * - * @param unknown_type $id - * @param array $options - * @return unknown - * @link http://book.cakephp.org/view/1372/drag-drop - */ - function drag($id, $options = array()) { - $var = ''; - if (isset($options['var'])) { - $var = 'var ' . $options['var'] . ' = '; - unset($options['var']); - } - $options = $this->_buildOptions( - $this->_optionsToString($options, array('handle', 'constraint')), $this->dragOptions - ); - return $this->Javascript->codeBlock("{$var}new Draggable('$id', " .$options . ");"); - } - -/** - * For a reference on the options for this function, check out - * http://github.com/madrobby/scriptaculous/wikis/droppables - * - * @param unknown_type $id - * @param array $options - * @return string - * @link http://book.cakephp.org/view/1372/drag-drop - */ - function drop($id, $options = array()) { - $optionsString = array('overlap', 'hoverclass'); - if (!isset($options['accept']) || !is_array($options['accept'])) { - $optionsString[] = 'accept'; - } else if (isset($options['accept'])) { - $options['accept'] = $this->Javascript->object($options['accept']); - } - $options = $this->_buildOptions( - $this->_optionsToString($options, $optionsString), $this->dropOptions - ); - return $this->Javascript->codeBlock("Droppables.add('{$id}', {$options});"); - } - -/** - * Make an element with the given $id droppable, and trigger an Ajax call when a draggable is - * dropped on it. - * - * For a reference on the options for this function, check out - * http://wiki.script.aculo.us/scriptaculous/show/Droppables.add - * - * @param string $id - * @param array $options - * @param array $ajaxOptions - * @return string JavaScript block to create a droppable element - */ - function dropRemote($id, $options = array(), $ajaxOptions = array()) { - $callback = $this->remoteFunction($ajaxOptions); - $options['onDrop'] = "function(element, droppable, event) {{$callback}}"; - $optionsString = array('overlap', 'hoverclass'); - - if (!isset($options['accept']) || !is_array($options['accept'])) { - $optionsString[] = 'accept'; - } else if (isset($options['accept'])) { - $options['accept'] = $this->Javascript->object($options['accept']); - } - - $options = $this->_buildOptions( - $this->_optionsToString($options, $optionsString), - $this->dropOptions - ); - return $this->Javascript->codeBlock("Droppables.add('{$id}', {$options});"); - } - -/** - * Makes a slider control. - * - * @param string $id DOM ID of slider handle - * @param string $trackId DOM ID of slider track - * @param array $options Array of options to control the slider - * @link http://github.com/madrobby/scriptaculous/wikis/slider - * @link http://book.cakephp.org/view/1373/slider - */ - function slider($id, $trackId, $options = array()) { - if (isset($options['var'])) { - $var = 'var ' . $options['var'] . ' = '; - unset($options['var']); - } else { - $var = 'var ' . $id . ' = '; - } - - $options = $this->_optionsToString($options, array( - 'axis', 'handleImage', 'handleDisabled' - )); - $callbacks = array('change', 'slide'); - - foreach ($callbacks as $callback) { - if (isset($options[$callback])) { - $call = $options[$callback]; - $options['on' . ucfirst($callback)] = "function(value) {{$call}}"; - unset($options[$callback]); - } - } - - if (isset($options['values']) && is_array($options['values'])) { - $options['values'] = $this->Javascript->object($options['values']); - } - - $options = $this->_buildOptions($options, $this->sliderOptions); - $script = "{$var}new Control.Slider('$id', '$trackId', $options);"; - return $this->Javascript->codeBlock($script); - } - -/** - * Makes an Ajax In Place editor control. - * - * @param string $id DOM ID of input element - * @param string $url Postback URL of saved data - * @param array $options Array of options to control the editor, including ajaxOptions (see link). - * @link http://github.com/madrobby/scriptaculous/wikis/ajax-inplaceeditor - * @link http://book.cakephp.org/view/1374/editor - */ - function editor($id, $url, $options = array()) { - $url = $this->url($url); - $options['ajaxOptions'] = $this->__optionsForAjax($options); - - foreach ($this->ajaxOptions as $opt) { - if (isset($options[$opt])) { - unset($options[$opt]); - } - } - - if (isset($options['callback'])) { - $options['callback'] = 'function(form, value) {' . $options['callback'] . '}'; - } - - $type = 'InPlaceEditor'; - if (isset($options['collection']) && is_array($options['collection'])) { - $options['collection'] = $this->Javascript->object($options['collection']); - $type = 'InPlaceCollectionEditor'; - } - - $var = ''; - if (isset($options['var'])) { - $var = 'var ' . $options['var'] . ' = '; - unset($options['var']); - } - - $options = $this->_optionsToString($options, array( - 'okText', 'cancelText', 'savingText', 'formId', 'externalControl', 'highlightcolor', - 'highlightendcolor', 'savingClassName', 'formClassName', 'loadTextURL', 'loadingText', - 'clickToEditText', 'okControl', 'cancelControl' - )); - $options = $this->_buildOptions($options, $this->editorOptions); - $script = "{$var}new Ajax.{$type}('{$id}', '{$url}', {$options});"; - return $this->Javascript->codeBlock($script); - } - -/** - * Makes a list or group of floated objects sortable. - * - * @param string $id DOM ID of parent - * @param array $options Array of options to control sort. - * @link http://github.com/madrobby/scriptaculous/wikis/sortable - * @link http://book.cakephp.org/view/1375/sortable - */ - function sortable($id, $options = array()) { - if (!empty($options['url'])) { - if (empty($options['with'])) { - $options['with'] = "Sortable.serialize('$id')"; - } - $options['onUpdate'] = 'function(sortable) {' . $this->remoteFunction($options) . '}'; - } - $block = true; - - if (isset($options['block'])) { - $block = $options['block']; - unset($options['block']); - } - $strings = array( - 'tag', 'constraint', 'only', 'handle', 'hoverclass', 'tree', - 'treeTag', 'update', 'overlap' - ); - $scrollIsObject = ( - isset($options['scroll']) && - $options['scroll'] != 'window' && - strpos($options['scroll'], '$(') !== 0 - ); - - if ($scrollIsObject) { - $strings[] = 'scroll'; - } - - $options = $this->_optionsToString($options, $strings); - $options = array_merge($options, $this->_buildCallbacks($options)); - $options = $this->_buildOptions($options, $this->sortOptions); - $result = "Sortable.create('$id', $options);"; - - if (!$block) { - return $result; - } - return $this->Javascript->codeBlock($result); - } - -/** - * Private helper function for Javascript. - * - * @param array $options Set of options - * @access private - */ - function __optionsForAjax($options) { - if (isset($options['indicator'])) { - if (isset($options['loading'])) { - $loading = $options['loading']; - - if (!empty($loading) && substr(trim($loading), -1, 1) != ';') { - $options['loading'] .= '; '; - } - $options['loading'] .= "Element.show('{$options['indicator']}');"; - } else { - $options['loading'] = "Element.show('{$options['indicator']}');"; - } - if (isset($options['complete'])) { - $complete = $options['complete']; - - if (!empty($complete) && substr(trim($complete), -1, 1) != ';') { - $options['complete'] .= '; '; - } - $options['complete'] .= "Element.hide('{$options['indicator']}');"; - } else { - $options['complete'] = "Element.hide('{$options['indicator']}');"; - } - unset($options['indicator']); - } - - $jsOptions = array_merge( - array('asynchronous' => 'true', 'evalScripts' => 'true'), - $this->_buildCallbacks($options) - ); - - $options = $this->_optionsToString($options, array( - 'contentType', 'encoding', 'fallback', 'method', 'postBody', 'update', 'url' - )); - $jsOptions = array_merge($jsOptions, array_intersect_key($options, array_flip(array( - 'contentType', 'encoding', 'method', 'postBody' - )))); - - foreach ($options as $key => $value) { - switch ($key) { - case 'type': - $jsOptions['asynchronous'] = ($value == 'synchronous') ? 'false' : 'true'; - break; - case 'evalScripts': - $jsOptions['evalScripts'] = ($value) ? 'true' : 'false'; - break; - case 'position': - $pos = Inflector::camelize($options['position']); - $jsOptions['insertion'] = "Insertion.{$pos}"; - break; - case 'with': - $jsOptions['parameters'] = $options['with']; - break; - case 'form': - $jsOptions['parameters'] = 'Form.serialize(this)'; - break; - case 'requestHeaders': - $keys = array(); - foreach ($value as $key => $val) { - $keys[] = "'" . $key . "'"; - $keys[] = "'" . $val . "'"; - } - $jsOptions['requestHeaders'] = '[' . implode(', ', $keys) . ']'; - break; - } - } - return $this->_buildOptions($jsOptions, $this->ajaxOptions); - } - -/** - * Private Method to return a string of html options - * option data as a JavaScript options hash. - * - * @param array $options Options in the shape of keys and values - * @param array $extra Array of legal keys in this options context - * @return array Array of html options - * @access private - */ - function __getHtmlOptions($options, $extra = array()) { - foreach (array_merge($this->ajaxOptions, $this->callbacks, $extra) as $key) { - if (isset($options[$key])) { - unset($options[$key]); - } - } - return $options; - } - -/** - * Returns a string of JavaScript with the given option data as a JavaScript options hash. - * - * @param array $options Options in the shape of keys and values - * @param array $acceptable Array of legal keys in this options context - * @return string String of Javascript array definition - */ - function _buildOptions($options, $acceptable) { - if (is_array($options)) { - $out = array(); - - foreach ($options as $k => $v) { - if (in_array($k, $acceptable)) { - if ($v === true) { - $v = 'true'; - } elseif ($v === false) { - $v = 'false'; - } - $out[] = "$k:$v"; - } elseif ($k === 'with' && in_array('parameters', $acceptable)) { - $out[] = "parameters:${v}"; - } - } - - $out = implode(', ', $out); - $out = '{' . $out . '}'; - return $out; - } else { - return false; - } - } - -/** - * Return JavaScript text for an observer... - * - * @param string $klass Name of JavaScript class - * @param string $name - * @param array $options Ajax options - * @return string Formatted JavaScript - */ - function _buildObserver($klass, $name, $options = null) { - if (!isset($options['with']) && isset($options['update'])) { - $options['with'] = 'value'; - } - - $callback = $this->remoteFunction($options); - $hasFrequency = !(!isset($options['frequency']) || intval($options['frequency']) == 0); - $frequency = $hasFrequency ? $options['frequency'] . ', ' : ''; - - return "new $klass('$name', {$frequency}function(element, value) {{$callback}})"; - } - -/** - * Return Javascript text for callbacks. - * - * @param array $options Option array where a callback is specified - * @return array Options with their callbacks properly set - */ - protected function _buildCallbacks($options) { - $callbacks = array(); - - foreach ($this->callbacks as $callback) { - if (isset($options[$callback])) { - $name = 'on' . ucfirst($callback); - $code = $options[$callback]; - switch ($name) { - case 'onComplete': - $callbacks[$name] = "function(request, json) {" . $code . "}"; - break; - case 'onCreate': - $callbacks[$name] = "function(request, xhr) {" . $code . "}"; - break; - case 'onException': - $callbacks[$name] = "function(request, exception) {" . $code . "}"; - break; - default: - $callbacks[$name] = "function(request) {" . $code . "}"; - break; - } - if (isset($options['bind'])) { - $bind = $options['bind']; - - $hasBinding = ( - (is_array($bind) && in_array($callback, $bind)) || - (is_string($bind) && strpos($bind, $callback) !== false) - ); - - if ($hasBinding) { - $callbacks[$name] .= ".bind(this)"; - } - } - } - } - return $callbacks; - } - -/** - * Returns a string of JavaScript with a string representation of given options array. - * - * @param array $options Ajax options array - * @param array $stringOpts Options as strings in an array - * @access private - * @return array - */ - function _optionsToString($options, $stringOpts = array()) { - foreach ($stringOpts as $option) { - $hasOption = ( - isset($options[$option]) && !empty($options[$option]) && - is_string($options[$option]) && $options[$option][0] != "'" - ); - - if ($hasOption) { - if ($options[$option] === true || $options[$option] === 'true') { - $options[$option] = 'true'; - } elseif ($options[$option] === false || $options[$option] === 'false') { - $options[$option] = 'false'; - } else { - $options[$option] = "'{$options[$option]}'"; - } - } - } - return $options; - } - -/** - * Executed after a view has rendered, used to include bufferred code - * blocks. - * - */ - public function afterRender() { - if (env('HTTP_X_UPDATE') != null && !empty($this->__ajaxBuffer)) { - @ob_end_clean(); - - $data = array(); - $divs = explode(' ', env('HTTP_X_UPDATE')); - $keys = array_keys($this->__ajaxBuffer); - - if (count($divs) == 1 && in_array($divs[0], $keys)) { - echo $this->__ajaxBuffer[$divs[0]]; - } else { - foreach ($this->__ajaxBuffer as $key => $val) { - if (in_array($key, $divs)) { - $data[] = $key . ':"' . rawurlencode($val) . '"'; - } - } - $out = 'var __ajaxUpdater__ = {' . implode(", \n", $data) . '};' . "\n"; - $out .= 'for (n in __ajaxUpdater__) { if (typeof __ajaxUpdater__[n] == "string"'; - $out .= ' && $(n)) Element.update($(n), unescape(decodeURIComponent('; - $out .= '__ajaxUpdater__[n]))); }'; - echo $this->Javascript->codeBlock($out, false); - } - $scripts = $this->Javascript->getCache(); - - if (!empty($scripts)) { - echo $this->Javascript->codeBlock($scripts, false); - } - $this->_stop(); - } - } -} -?> \ No newline at end of file diff --git a/cake/libs/view/helpers/javascript.php b/cake/libs/view/helpers/javascript.php deleted file mode 100644 index ded6bffff6c..00000000000 --- a/cake/libs/view/helpers/javascript.php +++ /dev/null @@ -1,722 +0,0 @@ - blocks should be written 'safely,' i.e. wrapped in CDATA blocks - * - * @var boolean - * @access public - */ - public $safe = false; - -/** - * HTML tags used by this helper. - * - * @var array - * @access public - */ - public $tags = array( - 'javascriptstart' => '', - 'javascriptblock' => '', - 'javascriptlink' => '' - ); - -/** - * Holds options passed to codeBlock(), saved for when block is dumped to output - * - * @var array - * @access protected - * @see JavascriptHelper::codeBlock() - */ - protected $_blockOptions = array(); - -/** - * Caches events written by event() for output at the end of page execution - * - * @var array - * @access protected - * @see JavascriptHelper::event() - */ - protected $_cachedEvents = array(); - -/** - * Indicates whether generated events should be cached for later output (can be written at the - * end of the page, in the , or to an external file). - * - * @var boolean - * @access protected - * @see JavascriptHelper::event() - * @see JavascriptHelper::writeEvents() - */ - protected $_cacheEvents = false; - -/** - * Indicates whether cached events should be written to an external file - * - * @var boolean - * @access protected - * @see JavascriptHelper::event() - * @see JavascriptHelper::writeEvents() - */ - protected $_cacheToFile = false; - -/** - * Indicates whether *all* generated JavaScript should be cached for later output - * - * @var boolean - * @access protected - * @see JavascriptHelper::codeBlock() - * @see JavascriptHelper::blockEnd() - */ - protected $_cacheAll = false; - -/** - * Contains event rules attached with CSS selectors. Used with the event:Selectors JavaScript - * library. - * - * @var array - * @access protected - * @see JavascriptHelper::event() - * @link http://alternateidea.com/event-selectors/ - */ - protected $_rules = array(); - -/** - * @var string - * @access private - */ - private $__scriptBuffer = null; - -/** - * Constructor. Checks for presence of native PHP JSON extension to use for object encoding - * - */ - public function __construct($options = array()) { - if (!empty($options)) { - foreach ($options as $key => $val) { - if (is_numeric($key)) { - $key = $val; - $val = true; - } - switch ($key) { - case 'cache': - - break; - case 'safe': - $this->safe = $val; - break; - } - } - } - $this->useNative = function_exists('json_encode'); - return parent::__construct($options); - } - -/** - * Returns a JavaScript script tag. - * - * Options: - * - * - allowCache: boolean, designates whether this block is cacheable using the - * current cache settings. - * - safe: boolean, whether this block should be wrapped in CDATA tags. Defaults - * to helper's object configuration. - * - inline: whether the block should be printed inline, or written - * to cached for later output (i.e. $scripts_for_layout). - * - * @param string $script The JavaScript to be wrapped in SCRIPT tags. - * @param array $options Set of options: - * @return string The full SCRIPT element, with the JavaScript inside it, or null, - * if 'inline' is set to false. - */ - function codeBlock($script = null, $options = array()) { - if (!empty($options) && !is_array($options)) { - $options = array('allowCache' => $options); - } elseif (empty($options)) { - $options = array(); - } - $defaultOptions = array('allowCache' => true, 'safe' => true, 'inline' => true); - $options = array_merge($defaultOptions, $options); - - if (empty($script)) { - $this->__scriptBuffer = @ob_get_contents(); - $this->_blockOptions = $options; - $this->inBlock = true; - @ob_end_clean(); - ob_start(); - return null; - } - if ($this->_cacheEvents && $this->_cacheAll && $options['allowCache']) { - $this->_cachedEvents[] = $script; - return null; - } - if ($options['safe'] || $this->safe) { - $script = "\n" . '//' . "\n"; - } - if ($options['inline']) { - return sprintf($this->tags['javascriptblock'], $script); - } else { - $view =& ClassRegistry::getObject('view'); - $view->addScript(sprintf($this->tags['javascriptblock'], $script)); - } - } - -/** - * Ends a block of cached JavaScript code - * - * @return mixed - */ - function blockEnd() { - if (!isset($this->inBlock) || !$this->inBlock) { - return; - } - $script = @ob_get_contents(); - @ob_end_clean(); - ob_start(); - echo $this->__scriptBuffer; - $this->__scriptBuffer = null; - $options = $this->_blockOptions; - $this->_blockOptions = array(); - $this->inBlock = false; - - if (empty($script)) { - return null; - } - - return $this->codeBlock($script, $options); - } - -/** - * Returns a JavaScript include tag (SCRIPT element). If the filename is prefixed with "/", - * the path will be relative to the base path of your application. Otherwise, the path will - * be relative to your JavaScript path, usually webroot/js. - * - * @param mixed $url String URL to JavaScript file, or an array of URLs. - * @param boolean $inline If true, the '; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->link('script'); - $expected = ''; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->link('scriptaculous.js?load=effects'); - $expected = ''; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->link('some.json.libary'); - $expected = ''; - $this->assertEqual($result, $expected); - - $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); - - $result = $this->Javascript->link('/plugin/js/jquery-1.1.2'); - $expected = ''; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->link('/some_other_path/myfile.1.2.2.min.js'); - $expected = ''; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->link('some_other_path/myfile.1.2.2.min.js'); - $expected = ''; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->link('some_other_path/myfile.1.2.2.min'); - $expected = ''; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->link('http://example.com/jquery.js'); - $expected = ''; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->link(array('prototype.js', 'scriptaculous.js')); - $this->assertPattern('/^\s*]*><\/script>/', $result); - $this->assertPattern('/<\/script>\s*]+>/', $result); - $this->assertPattern('/]*><\/script>\s*$/', $result); - - $result = $this->Javascript->link('jquery-1.1.2', false); - $resultScripts = $this->View->scripts(); - reset($resultScripts); - $expected = ''; - $this->assertNull($result); - $this->assertEqual(count($resultScripts), 1); - $this->assertEqual(current($resultScripts), $expected); - } - -/** - * testFilteringAndTimestamping method - * - * @access public - * @return void - */ - function testFilteringAndTimestamping() { - if ($this->skipIf(!is_writable(JS), 'JavaScript directory not writable, skipping JS asset timestamp tests. %s')) { - return; - } - - cache(str_replace(WWW_ROOT, '', JS) . '__cake_js_test.js', 'alert("test")', '+999 days', 'public'); - $timestamp = substr(strtotime('now'), 0, 8); - - Configure::write('Asset.timestamp', true); - $result = $this->Javascript->link('__cake_js_test'); - $this->assertPattern('/^]+src=".*js\/__cake_js_test\.js\?' . $timestamp . '[0-9]{2}"[^<>]*>/', $result); - - $debug = Configure::read('debug'); - Configure::write('debug', 0); - $result = $this->Javascript->link('__cake_js_test'); - $expected = ''; - $this->assertEqual($result, $expected); - - Configure::write('Asset.timestamp', 'force'); - $result = $this->Javascript->link('__cake_js_test'); - $this->assertPattern('/^]+src=".*js\/__cake_js_test.js\?' . $timestamp . '[0-9]{2}"[^<>]*>/', $result); - - Configure::write('debug', $debug); - Configure::write('Asset.timestamp', false); - - $old = Configure::read('Asset.filter.js'); - - Configure::write('Asset.filter.js', 'js.php'); - $result = $this->Javascript->link('__cake_js_test'); - $this->assertPattern('/^]+src=".*cjs\/__cake_js_test\.js"[^<>]*>/', $result); - - Configure::write('Asset.filter.js', true); - $result = $this->Javascript->link('jquery-1.1.2'); - $expected = ''; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->link('folderjs/jquery-1.1.2'); - $expected = ''; - $this->assertEqual($result, $expected); - - if ($old === null) { - Configure::delete('Asset.filter.js'); - } - - $debug = Configure::read('debug'); - $webroot = $this->Javascript->webroot; - - Configure::write('debug', 0); - Configure::write('Asset.timestamp', 'force'); - - $this->Javascript->webroot = '/testing/'; - $result = $this->Javascript->link('__cake_js_test'); - $this->assertPattern('/^]+src="\/testing\/js\/__cake_js_test\.js\?\d+"[^<>]*>/', $result); - - $this->Javascript->webroot = '/testing/longer/'; - $result = $this->Javascript->link('__cake_js_test'); - $this->assertPattern('/^]+src="\/testing\/longer\/js\/__cake_js_test\.js\?\d+"[^<>]*>/', $result); - - $this->Javascript->webroot = $webroot; - Configure::write('debug', $debug); - - unlink(JS . '__cake_js_test.js'); - } - -/** - * testValue method - * - * @access public - * @return void - */ - function testValue() { - $result = $this->Javascript->value(array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8))); - $expected = '{"title":"New thing","indexes":[5,6,7,8]}'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->value(null); - $this->assertEqual($result, 'null'); - - $result = $this->Javascript->value(true); - $this->assertEqual($result, 'true'); - - $result = $this->Javascript->value(false); - $this->assertEqual($result, 'false'); - - $result = $this->Javascript->value(5); - $this->assertEqual($result, '5'); - - $result = $this->Javascript->value(floatval(5.3)); - $this->assertPattern('/^5.3[0]+$/', $result); - - $result = $this->Javascript->value(''); - $expected = '""'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->value('CakePHP' . "\n" . 'Rapid Development Framework'); - $expected = '"CakePHP\\nRapid Development Framework"'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->value('CakePHP' . "\r\n" . 'Rapid Development Framework' . "\r" . 'For PHP'); - $expected = '"CakePHP\\nRapid Development Framework\\nFor PHP"'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->value('CakePHP: "Rapid Development Framework"'); - $expected = '"CakePHP: \\"Rapid Development Framework\\""'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->value('CakePHP: \'Rapid Development Framework\''); - $expected = '"CakePHP: \\\'Rapid Development Framework\\\'"'; - $this->assertEqual($result, $expected); - } - -/** - * testObjectGeneration method - * - * @access public - * @return void - */ - function testObjectGeneration() { - $object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8)); - $result = $this->Javascript->object($object); - $expected = '{"title":"New thing","indexes":[5,6,7,8]}'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->object(array('default' => 0)); - $expected = '{"default":0}'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->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); - - if (ini_get('precision') >= 12) { - $number = 3.141592653589; - if (!$this->Javascript->useNative) { - $number = sprintf("%.11f", $number); - } - - $result = $this->Javascript->object(array('Object' => array(true, false, 1, '02101', 0, -1, 3.141592653589, "1"))); - $expected = '{"Object":[true,false,1,"02101",0,-1,' . $number . ',"1"]}'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->object(array('Object' => array(true => true, false, -3.141592653589, -10))); - $expected = '{"Object":{"1":true,"2":false,"3":' . (-1 * $number) . ',"4":-10}}'; - $this->assertEqual($result, $expected); - } - - $result = $this->Javascript->object(new TestJavascriptObject()); - $expected = '{"property1":"value1","property2":2}'; - $this->assertEqual($result, $expected); - - $object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8)); - $result = $this->Javascript->object($object, array('block' => true)); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - '{"title":"New thing","indexes":[5,6,7,8]}', - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8), 'object' => array('inner' => array('value' => 1))); - $result = $this->Javascript->object($object); - $expected = '{"title":"New thing","indexes":[5,6,7,8],"object":{"inner":{"value":1}}}'; - $this->assertEqual($result, $expected); - - foreach (array('true' => true, 'false' => false, 'null' => null) as $expected => $data) { - $result = $this->Javascript->object($data); - $this->assertEqual($result, $expected); - } - - $object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8), 'object' => array('inner' => array('value' => 1))); - $result = $this->Javascript->object($object, array('prefix' => 'PREFIX', 'postfix' => 'POSTFIX')); - $this->assertPattern('/^PREFIX/', $result); - $this->assertPattern('/POSTFIX$/', $result); - $this->assertNoPattern('/.PREFIX./', $result); - $this->assertNoPattern('/.POSTFIX./', $result); - - if ($this->Javascript->useNative) { - $this->Javascript->useNative = false; - $this->testObjectGeneration(); - $this->Javascript->useNative = true; - } - } - -/** - * testObjectNonNative method - * - * @access public - * @return void - */ - function testObjectNonNative() { - $oldNative = $this->Javascript->useNative; - $this->Javascript->useNative = false; - - $object = array( - 'Object' => array( - 'key1' => 'val1', - 'key2' => 'val2', - 'key3' => 'val3' - ) - ); - - $expected = '{"Object":{"key1":val1,"key2":"val2","key3":val3}}'; - $result = $this->Javascript->object($object, array('quoteKeys' => false, 'stringKeys' => array('key1', 'key3'))); - $this->assertEqual($result, $expected); - - $this->Javascript->useNative = $oldNative; - } - -/** - * testScriptBlock method - * - * @access public - * @return void - */ - function testScriptBlock() { - $result = $this->Javascript->codeBlock('something'); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - 'something', - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->codeBlock('something', array('allowCache' => true, 'safe' => false)); - $expected = array( - 'script' => array('type' => 'text/javascript'), - 'something', - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->codeBlock('something', array('allowCache' => false, 'safe' => false)); - $expected = array( - 'script' => array('type' => 'text/javascript'), - 'something', - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->codeBlock('something', true); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - 'something', - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->codeBlock('something', false); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - 'something', - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->codeBlock('something', array('safe' => false)); - $expected = array( - 'script' => array('type' => 'text/javascript'), - 'something', - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->codeBlock('something', array('safe' => true)); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - 'something', - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->codeBlock(null, array('safe' => true, 'allowCache' => false)); - $this->assertNull($result); - echo 'this is some javascript'; - - $result = $this->Javascript->blockEnd(); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - 'this is some javascript', - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->codeBlock(); - $this->assertNull($result); - echo "alert('hey');"; - $result = $this->Javascript->blockEnd(); - - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - "alert('hey');", - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $this->Javascript->cacheEvents(false, true); - $this->assertFalse($this->Javascript->inBlock); - - $result = $this->Javascript->codeBlock(); - $this->assertIdentical($result, null); - $this->assertTrue($this->Javascript->inBlock); - echo 'alert("this is a buffered script");'; - - $result = $this->Javascript->blockEnd(); - $this->assertIdentical($result, null); - $this->assertFalse($this->Javascript->inBlock); - - $result = $this->Javascript->getCache(); - $this->assertEqual('alert("this is a buffered script");', $result); - } - -/** - * testOutOfLineScriptWriting method - * - * @access public - * @return void - */ - function testOutOfLineScriptWriting() { - echo $this->Javascript->codeBlock('$(document).ready(function() { });', array('inline' => false)); - - $this->Javascript->codeBlock(null, array('inline' => false)); - echo '$(function(){ });'; - $this->Javascript->blockEnd(); - $script = $this->View->scripts(); - - $this->assertEqual(count($script), 2); - $this->assertPattern('/' . preg_quote('$(document).ready(function() { });', '/') . '/', $script[0]); - $this->assertPattern('/' . preg_quote('$(function(){ });', '/') . '/', $script[1]); - } - -/** - * testEvent method - * - * @access public - * @return void - */ - function testEvent() { - $result = $this->Javascript->event('myId', 'click', 'something();'); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - "Event.observe($('myId'), 'click', function(event) { something(); }, false);", - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->event('myId', 'click', 'something();', array('safe' => false)); - $expected = array( - 'script' => array('type' => 'text/javascript'), - "Event.observe($('myId'), 'click', function(event) { something(); }, false);", - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->event('myId', 'click'); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - "Event.observe($('myId'), 'click', function(event) { }, false);", - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->event('myId', 'click', 'something();', false); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - "Event.observe($('myId'), 'click', function(event) { something(); }, false);", - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->event('myId', 'click', 'something();', array('useCapture' => true)); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - "Event.observe($('myId'), 'click', function(event) { something(); }, true);", - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->event('document', 'load'); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - "Event.observe(document, 'load', function(event) { }, false);", - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->event('$(\'myId\')', 'click', 'something();', array('safe' => false)); - $expected = array( - 'script' => array('type' => 'text/javascript'), - "Event.observe($('myId'), 'click', function(event) { something(); }, false);", - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->event('\'document\'', 'load', 'something();', array('safe' => false)); - $expected = array( - 'script' => array('type' => 'text/javascript'), - "Event.observe('document', 'load', function(event) { something(); }, false);", - '/script' - ); - $this->assertTags($result, $expected); - - $this->Javascript->cacheEvents(); - $result = $this->Javascript->event('myId', 'click', 'something();'); - $this->assertNull($result); - - $result = $this->Javascript->getCache(); - $this->assertPattern('/^' . str_replace('/', '\\/', preg_quote('Event.observe($(\'myId\'), \'click\', function(event) { something(); }, false);')) . '$/s', $result); - - $result = $this->Javascript->event('#myId', 'alert(event);'); - $this->assertNull($result); - - $result = $this->Javascript->getCache(); - $this->assertPattern('/^\s*var Rules = {\s*\'#myId\': function\(element, event\)\s*{\s*alert\(event\);\s*}\s*}\s*EventSelectors\.start\(Rules\);\s*$/s', $result); - } - -/** - * testWriteEvents method - * - * @access public - * @return void - */ - function testWriteEvents() { - $this->Javascript->cacheEvents(); - $result = $this->Javascript->event('myId', 'click', 'something();'); - $this->assertNull($result); - - $result = $this->Javascript->writeEvents(); - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - "Event.observe($('myId'), 'click', function(event) { something(); }, false);", - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->getCache(); - $this->assertTrue(empty($result)); - - $this->Javascript->cacheEvents(); - $result = $this->Javascript->event('myId', 'click', 'something();'); - $this->assertNull($result); - - $result = $this->Javascript->writeEvents(false); - $resultScripts = $this->View->scripts(); - reset($resultScripts); - $this->assertNull($result); - $this->assertEqual(count($resultScripts), 1); - $result = current($resultScripts); - - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - "Event.observe($('myId'), 'click', function(event) { something(); }, false);", - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->getCache(); - $this->assertTrue(empty($result)); - } - -/** - * testEscapeScript method - * - * @access public - * @return void - */ - function testEscapeScript() { - $result = $this->Javascript->escapeScript(''); - $expected = ''; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeScript('CakePHP' . "\n" . 'Rapid Development Framework'); - $expected = 'CakePHP\\nRapid Development Framework'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeScript('CakePHP' . "\r\n" . 'Rapid Development Framework' . "\r" . 'For PHP'); - $expected = 'CakePHP\\nRapid Development Framework\\nFor PHP'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeScript('CakePHP: "Rapid Development Framework"'); - $expected = 'CakePHP: \\"Rapid Development Framework\\"'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeScript('CakePHP: \'Rapid Development Framework\''); - $expected = 'CakePHP: \\\'Rapid Development Framework\\\''; - $this->assertEqual($result, $expected); - } - -/** - * testEscapeString method - * - * @access public - * @return void - */ - function testEscapeString() { - $result = $this->Javascript->escapeString(''); - $expected = ''; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeString('CakePHP' . "\n" . 'Rapid Development Framework'); - $expected = 'CakePHP\\nRapid Development Framework'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeString('CakePHP' . "\r\n" . 'Rapid Development Framework' . "\r" . 'For PHP'); - $expected = 'CakePHP\\nRapid Development Framework\\nFor PHP'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeString('CakePHP: "Rapid Development Framework"'); - $expected = 'CakePHP: \\"Rapid Development Framework\\"'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeString('CakePHP: \'Rapid Development Framework\''); - $expected = "CakePHP: \\'Rapid Development Framework\\'"; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeString('my \\"string\\"'); - $expected = 'my \\\\\\"string\\\\\\"'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeString('my string\nanother line'); - $expected = 'my string\\\nanother line'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeString('String with \n string that looks like newline'); - $expected = 'String with \\\n string that looks like newline'; - $this->assertEqual($result, $expected); - - $result = $this->Javascript->escapeString('String with \n string that looks like newline'); - $expected = 'String with \\\n string that looks like newline'; - $this->assertEqual($result, $expected); - } - -/** - * test string escaping and compare to json_encode() - * - * @return void - */ - function testStringJsonEncodeCompliance() { - if (!function_exists('json_encode')) { - return; - } - $this->Javascript->useNative = false; - $data = array(); - $data['mystring'] = "simple string"; - $this->assertEqual(json_encode($data), $this->Javascript->object($data)); - - $data['mystring'] = "strïng with spécial chârs"; - $this->assertEqual(json_encode($data), $this->Javascript->object($data)); - - $data['mystring'] = "a two lines\nstring"; - $this->assertEqual(json_encode($data), $this->Javascript->object($data)); - - $data['mystring'] = "a \t tabbed \t string"; - $this->assertEqual(json_encode($data), $this->Javascript->object($data)); - - $data['mystring'] = "a \"double-quoted\" string"; - $this->assertEqual(json_encode($data), $this->Javascript->object($data)); - - $data['mystring'] = 'a \\"double-quoted\\" string'; - $this->assertEqual(json_encode($data), $this->Javascript->object($data)); - } - -/** - * test that text encoded with Javascript::object decodes properly - * - * @return void - */ - function testObjectDecodeCompatibility() { - if (!function_exists('json_decode')) { - return; - } - $this->Javascript->useNative = false; - - $data = array("simple string"); - $result = $this->Javascript->object($data); - $this->assertEqual(json_decode($result), $data); - - $data = array('my \"string\"'); - $result = $this->Javascript->object($data); - $this->assertEqual(json_decode($result), $data); - - $data = array('my \\"string\\"'); - $result = $this->Javascript->object($data); - $this->assertEqual(json_decode($result), $data); - } - -/** - * testAfterRender method - * - * @access public - * @return void - */ - function testAfterRender() { - $this->Javascript->cacheEvents(); - $result = $this->Javascript->event('myId', 'click', 'something();'); - $this->assertNull($result); - - ob_start(); - $this->Javascript->afterRender(); - $result = ob_get_clean(); - - $expected = array( - 'script' => array('type' => 'text/javascript'), - $this->cDataStart, - "Event.observe($('myId'), 'click', function(event) { something(); }, false);", - $this->cDataEnd, - '/script' - ); - $this->assertTags($result, $expected); - - $result = $this->Javascript->getCache(); - $this->assertTrue(empty($result)); - - $old = $this->Javascript->enabled; - $this->Javascript->enabled = false; - - $this->Javascript->cacheEvents(); - $result = $this->Javascript->event('myId', 'click', 'something();'); - $this->assertNull($result); - - ob_start(); - $this->Javascript->afterRender(); - $result = ob_get_clean(); - - $this->assertTrue(empty($result)); - - $result = $this->Javascript->getCache(); - $this->assertPattern('/^' . str_replace('/', '\\/', preg_quote('Event.observe($(\'myId\'), \'click\', function(event) { something(); }, false);')) . '$/s', $result); - - $this->Javascript->enabled = $old; - } -} -?> \ No newline at end of file