PageRenderTime 57ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/cake/libs/view/helpers/js.php

https://github.com/MrRio/wildflower
PHP | 451 lines | 367 code | 18 blank | 66 comment | 17 complexity | 2363f19c825d35fe83a5952bfc55df9d MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /* SVN FILE: $Id: js.php 7945 2008-12-19 02:16:01Z gwoo $ */
  3. /**
  4. * Javascript Generator class file.
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * CakePHP : Rapid Development Framework (http://www.cakephp.org)
  9. * Copyright 2006-2008, Cake Software Foundation, Inc.
  10. *
  11. * Licensed under The MIT License
  12. * Redistributions of files must retain the above copyright notice.
  13. *
  14. * @filesource
  15. * @copyright Copyright 2006-2008, Cake Software Foundation, Inc.
  16. * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
  17. * @package cake
  18. * @subpackage cake.cake.libs.view.helpers
  19. * @since CakePHP v 1.2
  20. * @version $Revision: 7945 $
  21. * @modifiedby $LastChangedBy: gwoo $
  22. * @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
  23. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  24. */
  25. /**
  26. * Javascript Generator helper class for easy use of JavaScript.
  27. *
  28. * JsHelper provides an abstract interface for authoring JavaScript with a
  29. * given client-side library.
  30. *
  31. * @package cake
  32. * @subpackage cake.cake.libs.view.helpers
  33. */
  34. class JsHelper extends Overloadable2 {
  35. var $base = null;
  36. var $webroot = null;
  37. var $here = null;
  38. var $params = null;
  39. var $action = null;
  40. var $data = null;
  41. var $themeWeb = null;
  42. var $plugin = null;
  43. var $helpers = array();
  44. var $hook = null;
  45. var $__objects = array();
  46. var $effectMap = array(
  47. 'Appear', 'Fade', 'Puff', 'BlindDown', 'BlindUp', 'SwitchOff', 'SlideDown', 'SlideUp',
  48. 'DropOut', 'Shake', 'Pulsate', 'Squish', 'Fold', 'Grow', 'Shrink', 'Highlight', 'toggle'
  49. );
  50. var $output = false;
  51. function __construct() {
  52. $this->effectMap = array_combine(
  53. array_map('strtolower', $this->effectMap),
  54. $this->effectMap
  55. );
  56. parent::__construct();
  57. }
  58. function call__($method, $params) {
  59. if (is_object($this->hook) && method_exists($this->hook, $method)) {
  60. $this->hook->dispatchMethod($method . '_', $params);
  61. }
  62. if (method_exists($this, $method . '_')) {
  63. return $this->dispatchMethod($method . '_', $params);
  64. }
  65. }
  66. function alert_($message) {
  67. return 'alert("' . $this->escape($message) . '");';
  68. }
  69. function if_($if, $then, $else = null, $elseIf = array()) {
  70. $len = strlen($if) - 1;
  71. if ($if{$len} == ';') {
  72. $if{$len} = null;
  73. }
  74. $out = 'if (' . $if . ') { ' . $then . ' }';
  75. foreach ($elseIf as $cond => $exec) {
  76. //$out .=
  77. }
  78. if (!empty($else)) {
  79. $out .= ' else { ' . $else . ' }';
  80. }
  81. return $out;
  82. }
  83. function confirm_($message) {
  84. return 'confirm("' . $this->escape($message) . '");';
  85. }
  86. function prompt_($message, $default = '') {
  87. return 'prompt("' . $this->escape($message) . '", "' . $this->escape($default) . '");';
  88. }
  89. /*
  90. * Tries a series of expressions, and executes after first successful completion.
  91. * (See Prototype's Try.these).
  92. *
  93. * @return string
  94. */
  95. function tryThese_($expr1, $expr2, $expr3) {
  96. }
  97. /**
  98. * Loads a remote URL
  99. *
  100. * @param string $url
  101. * @param array $options
  102. * @return string
  103. */
  104. function load_($url = null, $options = array()) {
  105. if (isset($options['update'])) {
  106. if (!is_array($options['update'])) {
  107. $func = "new Ajax.Updater('{$options['update']}',";
  108. } else {
  109. $func = "new Ajax.Updater(document.createElement('div'),";
  110. }
  111. if (!isset($options['requestHeaders'])) {
  112. $options['requestHeaders'] = array();
  113. }
  114. if (is_array($options['update'])) {
  115. $options['update'] = join(' ', $options['update']);
  116. }
  117. $options['requestHeaders']['X-Update'] = $options['update'];
  118. } else {
  119. $func = "new Ajax.Request(";
  120. }
  121. $func .= "'" . Router::url($url) . "'";
  122. $ajax =& new AjaxHelper();
  123. $func .= ", " . $ajax->__optionsForAjax($options) . ")";
  124. if (isset($options['before'])) {
  125. $func = "{$options['before']}; $func";
  126. }
  127. if (isset($options['after'])) {
  128. $func = "$func; {$options['after']};";
  129. }
  130. if (isset($options['condition'])) {
  131. $func = "if ({$options['condition']}) { $func; }";
  132. }
  133. if (isset($options['confirm'])) {
  134. $func = "if (confirm('" . $this->Javascript->escapeString($options['confirm'])
  135. . "')) { $func; } else { return false; }";
  136. }
  137. return $func;
  138. }
  139. /**
  140. * Redirects to a URL
  141. *
  142. * @param mixed $url
  143. * @param array $options
  144. * @return string
  145. */
  146. function redirect_($url = null) {
  147. return 'window.location = "' . Router::url($url) . '";';
  148. }
  149. /**
  150. * Escape a string to be JavaScript friendly.
  151. *
  152. * List of escaped ellements:
  153. * + "\r\n" => '\n'
  154. * + "\r" => '\n'
  155. * + "\n" => '\n'
  156. * + '"' => '\"'
  157. * + "'" => "\\'"
  158. *
  159. * @param string $script String that needs to get escaped.
  160. * @return string Escaped string.
  161. */
  162. function escape($string) {
  163. $escape = array("\r\n" => '\n', "\r" => '\n', "\n" => '\n', '"' => '\"', "'" => "\\'");
  164. return str_replace(array_keys($escape), array_values($escape), $string);
  165. }
  166. function get__($name) {
  167. return $this->__object($name, 'id');
  168. }
  169. function select($pattern) {
  170. return $this->__object($pattern, 'pattern');
  171. }
  172. function real($var) {
  173. return $this->__object($var, 'real');
  174. }
  175. function __object($name, $var) {
  176. if (!isset($this->__objects[$name])) {
  177. $this->__objects[$name] = new JsHelperObject($this);
  178. $this->__objects[$name]->{$var} = $name;
  179. }
  180. return $this->__objects[$name];
  181. }
  182. /**
  183. * Generates a JavaScript object in JavaScript Object Notation (JSON)
  184. * from an array
  185. *
  186. * @param array $data Data to be converted
  187. * @param boolean $block Wraps return value in a <script/> block if true
  188. * @param string $prefix Prepends the string to the returned data
  189. * @param string $postfix Appends the string to the returned data
  190. * @param array $stringKeys A list of array keys to be treated as a string
  191. * @param boolean $quoteKeys If false, treats $stringKey as a list of keys *not* to be quoted
  192. * @param string $q The type of quote to use
  193. * @return string A JSON code block
  194. */
  195. function object($data = array(), $block = false, $prefix = '', $postfix = '', $stringKeys = array(), $quoteKeys = true, $q = "\"") {
  196. if (is_object($data)) {
  197. $data = get_object_vars($data);
  198. }
  199. $out = array();
  200. $key = array();
  201. if (is_array($data)) {
  202. $keys = array_keys($data);
  203. }
  204. $numeric = true;
  205. if (!empty($keys)) {
  206. foreach ($keys as $key) {
  207. if (!is_numeric($key)) {
  208. $numeric = false;
  209. break;
  210. }
  211. }
  212. }
  213. foreach ($data as $key => $val) {
  214. if (is_array($val) || is_object($val)) {
  215. $val = $this->object($val, false, '', '', $stringKeys, $quoteKeys, $q);
  216. } else {
  217. if ((!count($stringKeys) && !is_numeric($val) && !is_bool($val)) || ($quoteKeys && in_array($key, $stringKeys)) || (!$quoteKeys && !in_array($key, $stringKeys)) && $val !== null) {
  218. $val = $q . $this->escapeString($val) . $q;
  219. }
  220. if ($val == null) {
  221. $val = 'null';
  222. }
  223. }
  224. if (!$numeric) {
  225. $val = $q . $key . $q . ':' . $val;
  226. }
  227. $out[] = $val;
  228. }
  229. if (!$numeric) {
  230. $rt = '{' . join(', ', $out) . '}';
  231. } else {
  232. $rt = '[' . join(', ', $out) . ']';
  233. }
  234. $rt = $prefix . $rt . $postfix;
  235. if ($block) {
  236. $rt = $this->codeBlock($rt);
  237. }
  238. return $rt;
  239. }
  240. }
  241. class JsHelperObject {
  242. var $__parent = null;
  243. var $id = null;
  244. var $pattern = null;
  245. var $real = null;
  246. function __construct(&$parent) {
  247. if (is_object($parent)) {
  248. $this->setParent($parent);
  249. }
  250. }
  251. function toString() {
  252. return $this->__toString();
  253. }
  254. function __toString() {
  255. return $this->literal;
  256. }
  257. function ref($ref = null) {
  258. if ($ref == null) {
  259. foreach (array('id', 'pattern', 'real') as $ref) {
  260. if ($this->{$ref} !== null) {
  261. return $this->{$ref};
  262. }
  263. }
  264. } else {
  265. return ($this->{$ref} !== null);
  266. }
  267. return null;
  268. }
  269. function literal($append = null) {
  270. if (!empty($this->id)) {
  271. $data = '$("' . $this->id . '")';
  272. }
  273. if (!empty($this->pattern)) {
  274. $data = '$$("' . $this->pattern . '")';
  275. }
  276. if (!empty($this->real)) {
  277. $data = $this->real;
  278. }
  279. if (!empty($append)) {
  280. $data .= '.' . $append;
  281. }
  282. return $data;
  283. }
  284. function __call($name, $args) {
  285. $data = '';
  286. if (isset($this->__parent->effectMap[strtolower($name)])) {
  287. array_unshift($args, $this->__parent->effectMap[strtolower($name)]);
  288. $name = 'effect';
  289. }
  290. switch ($name) {
  291. case 'effect':
  292. case 'visualEffect':
  293. if (strpos($args[0], '_') || $args[0]{0} != strtoupper($args[0]{0})) {
  294. $args[0] = Inflector::camelize($args[0]);
  295. }
  296. if (strtolower($args[0]) == 'highlight') {
  297. $data .= 'new ';
  298. }
  299. if ($this->pattern == null) {
  300. $data .= 'Effect.' . $args[0] . '(' . $this->literal();
  301. } else {
  302. $data .= 'Effect.' . $args[0] . '(item';
  303. }
  304. if (isset($args[1]) && is_array($args[1])) {
  305. $data .= ', {' . $this->__options($args[1]) . '}';
  306. }
  307. $data .= ');';
  308. if ($this->pattern !== null) {
  309. $data = $this->each($data);
  310. }
  311. break;
  312. case 'remove':
  313. case 'toggle':
  314. case 'show':
  315. case 'hide':
  316. if (empty($args)) {
  317. $obj = 'Element';
  318. $params = '';
  319. } else {
  320. $obj = 'Effect';
  321. $params = ', "' . $args[0] . '"';
  322. }
  323. if ($this->pattern != null) {
  324. $data = $this->each($obj . ".{$name}(item);");
  325. } else {
  326. $data = $obj . ".{$name}(" . $this->literal() . ');';
  327. }
  328. break;
  329. case 'visible':
  330. $data = $this->literal() . '.visible();';
  331. break;
  332. case 'update':
  333. $data = $this->literal() . ".update({$args[0]});";
  334. break;
  335. case 'load':
  336. $data = 'new Ajax.Updater("' . $this->id . '", "' . $args[0] . '"';
  337. if (isset($args[1]) && is_array($args[1])) {
  338. $data .= ', {' . $this->__options($args[1]) . '}';
  339. }
  340. $data .= ');';
  341. break;
  342. case 'each':
  343. case 'all':
  344. case 'any':
  345. case 'detect':
  346. case 'findAll':
  347. if ($this->pattern != null) {
  348. $data = $this->__iterate($name, $args[0]);
  349. }
  350. break;
  351. case 'addClass':
  352. case 'removeClass':
  353. case 'hasClass':
  354. case 'toggleClass':
  355. $data = $this->literal() . ".{$name}Name(\"{$args[0]}\");";
  356. break;
  357. case 'clone':
  358. case 'inspect':
  359. case 'keys':
  360. case 'values':
  361. $data = "Object.{$name}(" . $this->literal() . ");";
  362. break;
  363. case 'extend':
  364. $data = "Object.extend(" . $this->literal() . ", {$args[0]});";
  365. break;
  366. case '...':
  367. // Handle other methods here
  368. // including interfaces to load other files on-the-fly
  369. // that add support for additional methods/replacing existing methods
  370. break;
  371. default:
  372. $data = $this->literal() . '.' . $name . '();';
  373. break;
  374. }
  375. if ($this->__parent->output) {
  376. echo $data;
  377. } else {
  378. return $data;
  379. }
  380. }
  381. function __iterate($method, $data) {
  382. return '$$("' . $this->pattern . '").' . $method . '(function(item) {' . $data . '});';
  383. }
  384. function setParent(&$parent) {
  385. $this->__parent =& $parent;
  386. }
  387. function __options($opts) {
  388. $options = array();
  389. foreach ($opts as $key => $val) {
  390. if (!is_int($val)) {
  391. $val = '"' . $val . '"';
  392. }
  393. $options[] = $key . ':' . $val;
  394. }
  395. return join(', ', $options);
  396. }
  397. }
  398. ?>