/lib/Cake/View/Helper/PrototypeEngineHelper.php

https://bitbucket.org/udeshika/fake_twitter · PHP · 368 lines · 214 code · 17 blank · 137 comment · 32 complexity · 5dbf881ea2b4c7b8fbfbcc87dc721408 MD5 · raw file

  1. <?php
  2. /**
  3. * Prototype Engine Helper for JsHelper
  4. *
  5. * Provides Prototype specific Javascript for JsHelper. Requires at least
  6. * Prototype 1.6
  7. *
  8. * PHP 5
  9. *
  10. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  11. * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  12. *
  13. * Licensed under The MIT License
  14. * Redistributions of files must retain the above copyright notice.
  15. *
  16. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  17. * @link http://cakephp.org CakePHP(tm) Project
  18. * @package Cake.View.Helper
  19. * @since CakePHP(tm) v 1.3
  20. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  21. */
  22. App::uses('JsBaseEngineHelper', 'View/Helper');
  23. /**
  24. * Prototype Engine Helper for JsHelper
  25. *
  26. * Provides Prototype specific Javascript for JsHelper. Requires at least
  27. * Prototype 1.6
  28. *
  29. * @package Cake.View.Helper
  30. */
  31. class PrototypeEngineHelper extends JsBaseEngineHelper {
  32. /**
  33. * Is the current selection a multiple selection? or is it just a single element.
  34. *
  35. * @var boolean
  36. */
  37. protected $_multiple = false;
  38. /**
  39. * Option mappings for Prototype
  40. *
  41. * @var array
  42. */
  43. protected $_optionMap = array(
  44. 'request' => array(
  45. 'async' => 'asynchronous',
  46. 'data' => 'parameters',
  47. 'before' => 'onCreate',
  48. 'success' => 'onSuccess',
  49. 'complete' => 'onComplete',
  50. 'error' => 'onFailure'
  51. ),
  52. 'sortable' => array(
  53. 'sort' => 'onChange',
  54. 'complete' => 'onUpdate',
  55. ),
  56. 'drag' => array(
  57. 'snapGrid' => 'snap',
  58. 'container' => 'constraint',
  59. 'stop' => 'onEnd',
  60. 'start' => 'onStart',
  61. 'drag' => 'onDrag',
  62. ),
  63. 'drop' => array(
  64. 'hover' => 'onHover',
  65. 'drop' => 'onDrop',
  66. 'hoverClass' => 'hoverclass',
  67. ),
  68. 'slider' => array(
  69. 'direction' => 'axis',
  70. 'change' => 'onSlide',
  71. 'complete' => 'onChange',
  72. 'value' => 'sliderValue',
  73. )
  74. );
  75. /**
  76. * Contains a list of callback names -> default arguments.
  77. *
  78. * @var array
  79. */
  80. protected $_callbackArguments = array(
  81. 'slider' => array(
  82. 'onSlide' => 'value',
  83. 'onChange' => 'value',
  84. ),
  85. 'drag' => array(
  86. 'onStart' => 'event',
  87. 'onDrag' => 'event',
  88. 'change' => 'draggable',
  89. 'onEnd' => 'event',
  90. ),
  91. 'drop' => array(
  92. 'onHover' => 'draggable, droppable, event',
  93. 'onDrop' => 'draggable, droppable, event',
  94. ),
  95. 'request' => array(
  96. 'onCreate' => 'transport',
  97. 'onComplete' => 'transport',
  98. 'onFailure' => 'response, jsonHeader',
  99. 'onRequest' => 'transport',
  100. 'onSuccess' => 'response, jsonHeader'
  101. ),
  102. 'sortable' => array(
  103. 'onStart' => 'element',
  104. 'onChange' => 'element',
  105. 'onUpdate' => 'element',
  106. ),
  107. );
  108. /**
  109. * Create javascript selector for a CSS rule
  110. *
  111. * @param string $selector The selector that is targeted
  112. * @return PrototypeEngineHelper instance of $this. Allows chained methods.
  113. */
  114. public function get($selector) {
  115. $this->_multiple = false;
  116. if ($selector == 'window' || $selector == 'document') {
  117. $this->selection = "$(" . $selector .")";
  118. return $this;
  119. }
  120. if (preg_match('/^#[^\s.]+$/', $selector)) {
  121. $this->selection = '$("' . substr($selector, 1) . '")';
  122. return $this;
  123. }
  124. $this->_multiple = true;
  125. $this->selection = '$$("' . $selector . '")';
  126. return $this;
  127. }
  128. /**
  129. * Add an event to the script cache. Operates on the currently selected elements.
  130. *
  131. * ### Options
  132. *
  133. * - `wrap` - Whether you want the callback wrapped in an anonymous function. (defaults true)
  134. * - `stop` - Whether you want the event to stopped. (defaults true)
  135. *
  136. * @param string $type Type of event to bind to the current 946 id
  137. * @param string $callback The Javascript function you wish to trigger or the function literal
  138. * @param array $options Options for the event.
  139. * @return string completed event handler
  140. */
  141. public function event($type, $callback, $options = array()) {
  142. $defaults = array('wrap' => true, 'stop' => true);
  143. $options = array_merge($defaults, $options);
  144. $function = 'function (event) {%s}';
  145. if ($options['wrap'] && $options['stop']) {
  146. $callback = "event.stop();\n" . $callback;
  147. }
  148. if ($options['wrap']) {
  149. $callback = sprintf($function, $callback);
  150. }
  151. $out = $this->selection . ".observe(\"{$type}\", $callback);";
  152. return $out;
  153. }
  154. /**
  155. * Create a domReady event. This is a special event in many libraries
  156. *
  157. * @param string $functionBody The code to run on domReady
  158. * @return string completed domReady method
  159. */
  160. public function domReady($functionBody) {
  161. $this->selection = 'document';
  162. return $this->event('dom:loaded', $functionBody, array('stop' => false));
  163. }
  164. /**
  165. * Create an iteration over the current selection result.
  166. *
  167. * @param string $callback The function body you wish to apply during the iteration.
  168. * @return string completed iteration
  169. */
  170. public function each($callback) {
  171. return $this->selection . '.each(function (item, index) {' . $callback . '});';
  172. }
  173. /**
  174. * Trigger an Effect.
  175. *
  176. * ### Note: Effects require Scriptaculous to be loaded.
  177. *
  178. * @param string $name The name of the effect to trigger.
  179. * @param array $options Array of options for the effect.
  180. * @return string completed string with effect.
  181. * @see JsBaseEngineHelper::effect()
  182. */
  183. public function effect($name, $options = array()) {
  184. $effect = '';
  185. $optionString = null;
  186. if (isset($options['speed'])) {
  187. if ($options['speed'] == 'fast') {
  188. $options['duration'] = 0.5;
  189. } elseif ($options['speed'] == 'slow') {
  190. $options['duration'] = 2;
  191. } else {
  192. $options['duration'] = 1;
  193. }
  194. unset($options['speed']);
  195. }
  196. if (!empty($options)) {
  197. $optionString = ', {' . $this->_parseOptions($options) . '}';
  198. }
  199. switch ($name) {
  200. case 'hide':
  201. case 'show':
  202. $effect = $this->selection . '.' . $name . '();';
  203. break;
  204. case 'slideIn':
  205. case 'slideOut':
  206. $name = ($name == 'slideIn') ? 'slideDown' : 'slideUp';
  207. $effect = 'Effect.' . $name . '(' . $this->selection . $optionString . ');';
  208. break;
  209. case 'fadeIn':
  210. case 'fadeOut':
  211. $name = ($name == 'fadeIn') ? 'appear' : 'fade';
  212. $effect = $this->selection . '.' . $name .'(' . substr($optionString, 2) . ');';
  213. break;
  214. }
  215. return $effect;
  216. }
  217. /**
  218. * Create an Ajax or Ajax.Updater call.
  219. *
  220. * @param mixed $url
  221. * @param array $options
  222. * @return string The completed ajax call.
  223. */
  224. public function request($url, $options = array()) {
  225. $url = '"'. $this->url($url) . '"';
  226. $options = $this->_mapOptions('request', $options);
  227. $type = '.Request';
  228. $data = null;
  229. if (isset($options['type']) && strtolower($options['type']) == 'json') {
  230. unset($options['type']);
  231. }
  232. if (isset($options['update'])) {
  233. $url = '"' . str_replace('#', '', $options['update']) . '", ' . $url;
  234. $type = '.Updater';
  235. unset($options['update'], $options['type']);
  236. }
  237. $safe = array_keys($this->_callbackArguments['request']);
  238. $options = $this->_prepareCallbacks('request', $options, $safe);
  239. if (!empty($options['dataExpression'])) {
  240. $safe[] = 'parameters';
  241. unset($options['dataExpression']);
  242. }
  243. $options = $this->_parseOptions($options, $safe);
  244. if (!empty($options)) {
  245. $options = ', {' . $options . '}';
  246. }
  247. return "var jsRequest = new Ajax$type($url$options);";
  248. }
  249. /**
  250. * Create a sortable element.
  251. *
  252. * #### Note: Requires scriptaculous to be loaded.
  253. *
  254. * The scriptaculous implementation of sortables does not support the 'start'
  255. * and 'distance' options.
  256. *
  257. * @param array $options Array of options for the sortable.
  258. * @return string Completed sortable script.
  259. * @see JsBaseEngineHelper::sortable() for options list.
  260. */
  261. public function sortable($options = array()) {
  262. $options = $this->_processOptions('sortable', $options);
  263. if (!empty($options)) {
  264. $options = ', {' . $options . '}';
  265. }
  266. return 'var jsSortable = Sortable.create(' . $this->selection . $options . ');';
  267. }
  268. /**
  269. * Create a Draggable element.
  270. *
  271. * #### Note: Requires scriptaculous to be loaded.
  272. *
  273. * @param array $options Array of options for the draggable.
  274. * @return string Completed draggable script.
  275. * @see JsBaseEngineHelper::draggable() for options list.
  276. */
  277. public function drag($options = array()) {
  278. $options = $this->_processOptions('drag', $options);
  279. if (!empty($options)) {
  280. $options = ', {' . $options . '}';
  281. }
  282. if ($this->_multiple) {
  283. return $this->each('new Draggable(item' . $options . ');');
  284. }
  285. return 'var jsDrag = new Draggable(' . $this->selection . $options . ');';
  286. }
  287. /**
  288. * Create a Droppable element.
  289. *
  290. * #### Note: Requires scriptaculous to be loaded.
  291. *
  292. * @param array $options Array of options for the droppable.
  293. * @return string Completed droppable script.
  294. * @see JsBaseEngineHelper::droppable() for options list.
  295. */
  296. public function drop($options = array()) {
  297. $options = $this->_processOptions('drop', $options);
  298. if (!empty($options)) {
  299. $options = ', {' . $options . '}';
  300. }
  301. return 'Droppables.add(' . $this->selection . $options . ');';
  302. }
  303. /**
  304. * Creates a slider control widget.
  305. *
  306. * ### Note: Requires scriptaculous to be loaded.
  307. *
  308. * @param array $options Array of options for the slider.
  309. * @return string Completed slider script.
  310. * @see JsBaseEngineHelper::slider() for options list.
  311. */
  312. public function slider($options = array()) {
  313. $slider = $this->selection;
  314. $this->get($options['handle']);
  315. unset($options['handle']);
  316. if (isset($options['min']) && isset($options['max'])) {
  317. $options['range'] = sprintf('$R(%s,%s)', $options['min'], $options['max']);
  318. unset($options['min'], $options['max']);
  319. }
  320. $options = $this->_mapOptions('slider', $options);
  321. $options = $this->_prepareCallbacks('slider', $options);
  322. $optionString = $this->_parseOptions(
  323. $options, array_merge(array_keys($this->_callbackArguments['slider']), array('range'))
  324. );
  325. if (!empty($optionString)) {
  326. $optionString = ', {' . $optionString . '}';
  327. }
  328. $out = 'var jsSlider = new Control.Slider(' . $this->selection . ', ' . $slider . $optionString . ');';
  329. $this->selection = $slider;
  330. return $out;
  331. }
  332. /**
  333. * Serialize the form attached to $selector.
  334. *
  335. * @param array $options Array of options.
  336. * @return string Completed serializeForm() snippet
  337. * @see JsBaseEngineHelper::serializeForm()
  338. */
  339. public function serializeForm($options = array()) {
  340. $options = array_merge(array('isForm' => false, 'inline' => false), $options);
  341. $selection = $this->selection;
  342. if (!$options['isForm']) {
  343. $selection = '$(' . $this->selection . '.form)';
  344. }
  345. $method = '.serialize()';
  346. if (!$options['inline']) {
  347. $method .= ';';
  348. }
  349. return $selection . $method;
  350. }
  351. }