js.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: js.php 7847 2008-11-08 02:54:07Z renan.saddam $ */
00003 /**
00004  * Javascript Generator class file.
00005  *
00006  * PHP versions 4 and 5
00007  *
00008  * CakePHP :  Rapid Development Framework (http://www.cakephp.org)
00009  * Copyright 2006-2008, Cake Software Foundation, Inc.
00010  *
00011  * Licensed under The MIT License
00012  * Redistributions of files must retain the above copyright notice.
00013  *
00014  * @filesource
00015  * @copyright     Copyright 2006-2008, Cake Software Foundation, Inc.
00016  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
00017  * @package       cake
00018  * @subpackage    cake.cake.libs.view.helpers
00019  * @since         CakePHP v 1.2
00020  * @version       $Revision: 7847 $
00021  * @modifiedby    $LastChangedBy: renan.saddam $
00022  * @lastmodified  $Date: 2008-11-07 21:54:07 -0500 (Fri, 07 Nov 2008) $
00023  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00024  */
00025 /**
00026  * Javascript Generator helper class for easy use of JavaScript.
00027  *
00028  * JsHelper provides an abstract interface for authoring JavaScript with a
00029  * given client-side library.
00030  *
00031  * @package       cake
00032  * @subpackage    cake.cake.libs.view.helpers
00033  */
00034 class JsHelper extends Overloadable2 {
00035     var $base = null;
00036     var $webroot = null;
00037     var $here = null;
00038     var $params = null;
00039     var $action = null;
00040     var $data = null;
00041     var $themeWeb = null;
00042     var $plugin = null;
00043 
00044     var $helpers = array();
00045 
00046     var $hook = null;
00047 
00048     var $__objects = array();
00049 
00050     var $effectMap = array(
00051         'Appear', 'Fade', 'Puff', 'BlindDown', 'BlindUp', 'SwitchOff', 'SlideDown', 'SlideUp',
00052         'DropOut', 'Shake', 'Pulsate', 'Squish', 'Fold', 'Grow', 'Shrink', 'Highlight', 'toggle'
00053     );
00054 
00055     var $output = false;
00056 
00057     function __construct() {
00058         $this->effectMap = array_combine(
00059             array_map('strtolower', $this->effectMap),
00060             $this->effectMap
00061         );
00062         parent::__construct();
00063     }
00064 
00065     function call__($method, $params) {
00066         if (is_object($this->hook) && method_exists($this->hook, $method)) {
00067             $this->hook->dispatchMethod($method . '_', $params);
00068         }
00069         if (method_exists($this, $method . '_')) {
00070             return $this->dispatchMethod($method . '_', $params);
00071         }
00072     }
00073 
00074     function alert_($message) {
00075         return 'alert("' . $this->escape($message) . '");';
00076     }
00077 
00078     function if_($if, $then, $else = null, $elseIf = array()) {
00079         $len = strlen($if) - 1;
00080         if ($if{$len} == ';') {
00081             $if{$len} = null;
00082         }
00083 
00084         $out = 'if (' . $if . ') { ' . $then . ' }';
00085 
00086         foreach ($elseIf as $cond => $exec) {
00087             //$out .=
00088         }
00089 
00090         if (!empty($else)) {
00091             $out .= ' else { ' . $else . ' }';
00092         }
00093 
00094         return $out;
00095     }
00096 
00097     function confirm_($message) {
00098         return 'confirm("' . $this->escape($message) . '");';
00099     }
00100 
00101     function prompt_($message, $default = '') {
00102         return 'prompt("' . $this->escape($message) . '", "' . $this->escape($default) . '");';
00103     }
00104 /*
00105  * Tries a series of expressions, and executes after first successful completion.
00106  * (See Prototype's Try.these).
00107  *
00108  * @return string
00109  */
00110     function tryThese_($expr1, $expr2, $expr3) {
00111     }
00112 /**
00113  * Loads a remote URL
00114  *
00115  * @param  string $url
00116  * @param  array  $options
00117  * @return string
00118  */
00119     function load_($url = null, $options = array()) {
00120 
00121         if (isset($options['update'])) {
00122             if (!is_array($options['update'])) {
00123                 $func = "new Ajax.Updater('{$options['update']}',";
00124             } else {
00125                 $func = "new Ajax.Updater(document.createElement('div'),";
00126             }
00127             if (!isset($options['requestHeaders'])) {
00128                 $options['requestHeaders'] = array();
00129             }
00130             if (is_array($options['update'])) {
00131                 $options['update'] = join(' ', $options['update']);
00132             }
00133             $options['requestHeaders']['X-Update'] = $options['update'];
00134         } else {
00135             $func = "new Ajax.Request(";
00136         }
00137 
00138         $func .= "'" . Router::url($url) . "'";
00139         $ajax =& new AjaxHelper();
00140         $func .= ", " . $ajax->__optionsForAjax($options) . ")";
00141 
00142         if (isset($options['before'])) {
00143             $func = "{$options['before']}; $func";
00144         }
00145         if (isset($options['after'])) {
00146             $func = "$func; {$options['after']};";
00147         }
00148         if (isset($options['condition'])) {
00149             $func = "if ({$options['condition']}) { $func; }";
00150         }
00151         if (isset($options['confirm'])) {
00152             $func = "if (confirm('" . $this->Javascript->escapeString($options['confirm'])
00153                 . "')) { $func; } else { return false; }";
00154         }
00155         return $func;
00156     }
00157 /**
00158  * Redirects to a URL
00159  *
00160  * @param  mixed $url
00161  * @param  array  $options
00162  * @return string
00163  */
00164     function redirect_($url = null) {
00165         return 'window.location = "' . Router::url($url) . '";';
00166     }
00167 /**
00168  * Escape a string to be JavaScript friendly.
00169  *
00170  * List of escaped ellements:
00171  *  + "\r\n" => '\n'
00172  *  + "\r" => '\n'
00173  *  + "\n" => '\n'
00174  *  + '"' => '\"'
00175  *  + "'" => "\\'"
00176  *
00177  * @param  string $script String that needs to get escaped.
00178  * @return string Escaped string.
00179  */
00180     function escape($string) {
00181         $escape = array("\r\n" => '\n', "\r" => '\n', "\n" => '\n', '"' => '\"', "'" => "\\'");
00182         return str_replace(array_keys($escape), array_values($escape), $string);
00183     }
00184 
00185     function get__($name) {
00186         return $this->__object($name, 'id');
00187     }
00188 
00189     function select($pattern) {
00190         return $this->__object($pattern, 'pattern');
00191     }
00192 
00193     function real($var) {
00194         return $this->__object($var, 'real');
00195     }
00196 
00197     function __object($name, $var) {
00198         if (!isset($this->__objects[$name])) {
00199             $this->__objects[$name] = new JsHelperObject($this);
00200             $this->__objects[$name]->{$var} = $name;
00201         }
00202         return $this->__objects[$name];
00203     }
00204 /**
00205  * Generates a JavaScript object in JavaScript Object Notation (JSON)
00206  * from an array
00207  *
00208  * @param array $data Data to be converted
00209  * @param boolean $block Wraps return value in a <script/> block if true
00210  * @param string $prefix Prepends the string to the returned data
00211  * @param string $postfix Appends the string to the returned data
00212  * @param array $stringKeys A list of array keys to be treated as a string
00213  * @param boolean $quoteKeys If false, treats $stringKey as a list of keys *not* to be quoted
00214  * @param string $q The type of quote to use
00215  * @return string A JSON code block
00216  */
00217     function object($data = array(), $block = false, $prefix = '', $postfix = '', $stringKeys = array(), $quoteKeys = true, $q = "\"") {
00218         if (is_object($data)) {
00219             $data = get_object_vars($data);
00220         }
00221 
00222         $out = array();
00223         $key = array();
00224 
00225         if (is_array($data)) {
00226             $keys = array_keys($data);
00227         }
00228 
00229         $numeric = true;
00230 
00231         if (!empty($keys)) {
00232             foreach ($keys as $key) {
00233                 if (!is_numeric($key)) {
00234                     $numeric = false;
00235                     break;
00236                 }
00237             }
00238         }
00239 
00240         foreach ($data as $key => $val) {
00241             if (is_array($val) || is_object($val)) {
00242                 $val = $this->object($val, false, '', '', $stringKeys, $quoteKeys, $q);
00243             } else {
00244                 if ((!count($stringKeys) && !is_numeric($val) && !is_bool($val)) || ($quoteKeys && in_array($key, $stringKeys)) || (!$quoteKeys && !in_array($key, $stringKeys)) && $val !== null) {
00245                     $val = $q . $this->escapeString($val) . $q;
00246                 }
00247                 if ($val == null) {
00248                     $val = 'null';
00249                 }
00250             }
00251 
00252             if (!$numeric) {
00253                 $val = $q . $key . $q . ':' . $val;
00254             }
00255 
00256             $out[] = $val;
00257         }
00258 
00259         if (!$numeric) {
00260             $rt = '{' . join(', ', $out) . '}';
00261         } else {
00262             $rt = '[' . join(', ', $out) . ']';
00263         }
00264         $rt = $prefix . $rt . $postfix;
00265 
00266         if ($block) {
00267             $rt = $this->codeBlock($rt);
00268         }
00269 
00270         return $rt;
00271     }
00272 }
00273 
00274 class JsHelperObject {
00275     var $__parent = null;
00276 
00277     var $id = null;
00278 
00279     var $pattern = null;
00280 
00281     var $real = null;
00282 
00283     function __construct(&$parent) {
00284         if (is_object($parent)) {
00285             $this->setParent($parent);
00286         }
00287     }
00288 
00289     function toString() {
00290         return $this->__toString();
00291     }
00292 
00293     function __toString() {
00294         return $this->literal;
00295     }
00296 
00297     function ref($ref = null) {
00298         if ($ref == null) {
00299             foreach (array('id', 'pattern', 'real') as $ref) {
00300                 if ($this->{$ref} !== null) {
00301                     return $this->{$ref};
00302                 }
00303             }
00304         } else {
00305             return ($this->{$ref} !== null);
00306         }
00307         return null;
00308     }
00309 
00310     function literal($append = null) {
00311         if (!empty($this->id)) {
00312             $data = '$("' . $this->id . '")';
00313         }
00314         if (!empty($this->pattern)) {
00315             $data = '$$("' . $this->pattern . '")';
00316         }
00317         if (!empty($this->real)) {
00318             $data = $this->real;
00319         }
00320         if (!empty($append)) {
00321             $data .= '.' . $append;
00322         }
00323         return $data;
00324     }
00325 
00326     function __call($name, $args) {
00327         $data = '';
00328 
00329         if (isset($this->__parent->effectMap[strtolower($name)])) {
00330             array_unshift($args, $this->__parent->effectMap[strtolower($name)]);
00331             $name = 'effect';
00332         }
00333 
00334         switch ($name) {
00335             case 'effect':
00336             case 'visualEffect':
00337 
00338                 if (strpos($args[0], '_') || $args[0]{0} != strtoupper($args[0]{0})) {
00339                     $args[0] = Inflector::camelize($args[0]);
00340                 }
00341 
00342                 if (strtolower($args[0]) == 'highlight') {
00343                     $data .= 'new ';
00344                 }
00345                 if ($this->pattern == null) {
00346                     $data .= 'Effect.' . $args[0] . '(' . $this->literal();
00347                 } else {
00348                     $data .= 'Effect.' . $args[0] . '(item';
00349                 }
00350 
00351                 if (isset($args[1]) && is_array($args[1])) {
00352                     $data .= ', {' . $this->__options($args[1]) . '}';
00353                 }
00354                 $data .= ');';
00355 
00356                 if ($this->pattern !== null) {
00357                     $data = $this->each($data);
00358                 }
00359             break;
00360             case 'remove':
00361             case 'toggle':
00362             case 'show':
00363             case 'hide':
00364                 if (empty($args)) {
00365                     $obj = 'Element';
00366                     $params = '';
00367                 } else {
00368                     $obj = 'Effect';
00369                     $params = ', "' . $args[0] . '"';
00370                 }
00371 
00372                 if ($this->pattern != null) {
00373                     $data = $this->each($obj . ".{$name}(item);");
00374                 } else {
00375                     $data = $obj . ".{$name}(" . $this->literal() . ');';
00376                 }
00377             break;
00378             case 'visible':
00379                 $data = $this->literal() . '.visible();';
00380             break;
00381             case 'update':
00382                 $data = $this->literal() . ".update({$args[0]});";
00383             break;
00384             case 'load':
00385                 $data = 'new Ajax.Updater("' . $this->id . '", "' . $args[0] . '"';
00386                 if (isset($args[1]) && is_array($args[1])) {
00387                     $data .= ', {' . $this->__options($args[1]) . '}';
00388                 }
00389                 $data .= ');';
00390             break;
00391             case 'each':
00392             case 'all':
00393             case 'any':
00394             case 'detect':
00395             case 'findAll':
00396                 if ($this->pattern != null) {
00397                     $data = $this->__iterate($name, $args[0]);
00398                 }
00399             break;
00400             case 'addClass':
00401             case 'removeClass':
00402             case 'hasClass':
00403             case 'toggleClass':
00404                 $data = $this->literal() . ".{$name}Name(\"{$args[0]}\");";
00405             break;
00406             case 'clone':
00407             case 'inspect':
00408             case 'keys':
00409             case 'values':
00410                 $data = "Object.{$name}(" . $this->literal() . ");";
00411             break;
00412             case 'extend':
00413                 $data = "Object.extend(" . $this->literal() . ", {$args[0]});";
00414             break;
00415             case '...':
00416                 // Handle other methods here
00417                 // including interfaces to load other files on-the-fly
00418                 // that add support for additional methods/replacing existing methods
00419             break;
00420             default:
00421                 $data = $this->literal() . '.' . $name . '();';
00422             break;
00423         }
00424 
00425         if ($this->__parent->output) {
00426             echo $data;
00427         } else {
00428             return $data;
00429         }
00430     }
00431 
00432     function __iterate($method, $data) {
00433         return '$$("' . $this->pattern . '").' . $method . '(function(item) {' . $data . '});';
00434     }
00435 
00436     function setParent(&$parent) {
00437         $this->__parent =& $parent;
00438     }
00439 
00440     function __options($opts) {
00441         $options = array();
00442         foreach ($opts as $key => $val) {
00443             if (!is_int($val)) {
00444                 $val = '"' . $val . '"';
00445             }
00446             $options[] = $key . ':' . $val;
00447         }
00448         return join(', ', $options);
00449     }
00450 }
00451 ?>

Generated on Sun Nov 22 00:30:54 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7