MootoolsEngineHelper.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. <?php
  2. /**
  3. * MooTools Engine Helper for JsHelper
  4. *
  5. * Provides MooTools specific Javascript for JsHelper.
  6. * Assumes that you have the following MooTools packages
  7. *
  8. * - Remote, Remote.HTML, Remote.JSON
  9. * - Fx, Fx.Tween, Fx.Morph
  10. * - Selectors, DomReady,
  11. * - Drag, Drag.Move
  12. *
  13. * PHP 5
  14. *
  15. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  16. * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  17. *
  18. * Licensed under The MIT License
  19. * Redistributions of files must retain the above copyright notice.
  20. *
  21. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  22. * @link http://cakephp.org CakePHP(tm) Project
  23. * @package Cake.View.Helper
  24. * @since CakePHP(tm) v 1.3
  25. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  26. */
  27. App::uses('JsBaseEngineHelper', 'View/Helper');
  28. class MootoolsEngineHelper extends JsBaseEngineHelper {
  29. /**
  30. * Option mappings for MooTools
  31. *
  32. * @var array
  33. */
  34. protected $_optionMap = array(
  35. 'request' => array(
  36. 'complete' => 'onComplete',
  37. 'success' => 'onSuccess',
  38. 'before' => 'onRequest',
  39. 'error' => 'onFailure'
  40. ),
  41. 'sortable' => array(
  42. 'distance' => 'snap',
  43. 'containment' => 'constrain',
  44. 'sort' => 'onSort',
  45. 'complete' => 'onComplete',
  46. 'start' => 'onStart',
  47. ),
  48. 'drag' => array(
  49. 'snapGrid' => 'snap',
  50. 'start' => 'onStart',
  51. 'drag' => 'onDrag',
  52. 'stop' => 'onComplete',
  53. ),
  54. 'drop' => array(
  55. 'drop' => 'onDrop',
  56. 'hover' => 'onEnter',
  57. 'leave' => 'onLeave',
  58. ),
  59. 'slider' => array(
  60. 'complete' => 'onComplete',
  61. 'change' => 'onChange',
  62. 'direction' => 'mode',
  63. 'step' => 'steps'
  64. )
  65. );
  66. /**
  67. * Contains a list of callback names -> default arguments.
  68. *
  69. * @var array
  70. */
  71. protected $_callbackArguments = array(
  72. 'slider' => array(
  73. 'onTick' => 'position',
  74. 'onChange' => 'step',
  75. 'onComplete' => 'event'
  76. ),
  77. 'request' => array(
  78. 'onRequest' => '',
  79. 'onComplete' => '',
  80. 'onCancel' => '',
  81. 'onSuccess' => 'responseText, responseXML',
  82. 'onFailure' => 'xhr',
  83. 'onException' => 'headerName, value',
  84. ),
  85. 'drag' => array(
  86. 'onBeforeStart' => 'element',
  87. 'onStart' => 'element',
  88. 'onSnap' => 'element',
  89. 'onDrag' => 'element, event',
  90. 'onComplete' => 'element, event',
  91. 'onCancel' => 'element',
  92. ),
  93. 'drop' => array(
  94. 'onBeforeStart' => 'element',
  95. 'onStart' => 'element',
  96. 'onSnap' => 'element',
  97. 'onDrag' => 'element, event',
  98. 'onComplete' => 'element, event',
  99. 'onCancel' => 'element',
  100. 'onDrop' => 'element, droppable, event',
  101. 'onLeave' => 'element, droppable',
  102. 'onEnter' => 'element, droppable',
  103. ),
  104. 'sortable' => array(
  105. 'onStart' => 'element, clone',
  106. 'onSort' => 'element, clone',
  107. 'onComplete' => 'element',
  108. )
  109. );
  110. /**
  111. * Create javascript selector for a CSS rule
  112. *
  113. * @param string $selector The selector that is targeted
  114. * @return MootoolsEngineHelper instance of $this. Allows chained methods.
  115. */
  116. public function get($selector) {
  117. $this->_multipleSelection = false;
  118. if ($selector == 'window' || $selector == 'document') {
  119. $this->selection = "$(" . $selector .")";
  120. return $this;
  121. }
  122. if (preg_match('/^#[^\s.]+$/', $selector)) {
  123. $this->selection = '$("' . substr($selector, 1) . '")';
  124. return $this;
  125. }
  126. $this->_multipleSelection = true;
  127. $this->selection = '$$("' . $selector . '")';
  128. return $this;
  129. }
  130. /**
  131. * Add an event to the script cache. Operates on the currently selected elements.
  132. *
  133. * ### Options
  134. *
  135. * - 'wrap' - Whether you want the callback wrapped in an anonymous function. (defaults true)
  136. * - 'stop' - Whether you want the event to stopped. (defaults true)
  137. *
  138. * @param string $type Type of event to bind to the current dom id
  139. * @param string $callback The Javascript function you wish to trigger or the function literal
  140. * @param array $options Options for the event.
  141. * @return string completed event handler
  142. */
  143. public function event($type, $callback, $options = array()) {
  144. $defaults = array('wrap' => true, 'stop' => true);
  145. $options = array_merge($defaults, $options);
  146. $function = 'function (event) {%s}';
  147. if ($options['wrap'] && $options['stop']) {
  148. $callback = "event.stop();\n" . $callback;
  149. }
  150. if ($options['wrap']) {
  151. $callback = sprintf($function, $callback);
  152. }
  153. $out = $this->selection . ".addEvent(\"{$type}\", $callback);";
  154. return $out;
  155. }
  156. /**
  157. * Create a domReady event. This is a special event in many libraries
  158. *
  159. * @param string $functionBody The code to run on domReady
  160. * @return string completed domReady method
  161. */
  162. public function domReady($functionBody) {
  163. $this->selection = 'window';
  164. return $this->event('domready', $functionBody, array('stop' => false));
  165. }
  166. /**
  167. * Create an iteration over the current selection result.
  168. *
  169. * @param string $callback The function body you wish to apply during the iteration.
  170. * @return string completed iteration
  171. */
  172. public function each($callback) {
  173. return $this->selection . '.each(function (item, index) {' . $callback . '});';
  174. }
  175. /**
  176. * Trigger an Effect.
  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. $speed = null;
  185. if (isset($options['speed']) && in_array($options['speed'], array('fast', 'slow'))) {
  186. if ($options['speed'] == 'fast') {
  187. $speed = '"short"';
  188. } elseif ($options['speed'] == 'slow') {
  189. $speed = '"long"';
  190. }
  191. }
  192. $effect = '';
  193. switch ($name) {
  194. case 'hide':
  195. $effect = 'setStyle("display", "none")';
  196. break;
  197. case 'show':
  198. $effect = 'setStyle("display", "")';
  199. break;
  200. case 'fadeIn':
  201. case 'fadeOut':
  202. case 'slideIn':
  203. case 'slideOut':
  204. list($effectName, $direction) = preg_split('/([A-Z][a-z]+)/', $name, -1, PREG_SPLIT_DELIM_CAPTURE);
  205. $direction = strtolower($direction);
  206. if ($speed) {
  207. $effect .= "set(\"$effectName\", {duration:$speed}).";
  208. }
  209. $effect .= "$effectName(\"$direction\")";
  210. break;
  211. }
  212. return $this->selection . '.' . $effect . ';';
  213. }
  214. /**
  215. * Create an new Request.
  216. *
  217. * Requires `Request`. If you wish to use 'update' key you must have ```Request.HTML```
  218. * if you wish to do Json requests you will need ```JSON``` and ```Request.JSON```.
  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 = $data = null;
  228. if (isset($options['type']) || isset($options['update'])) {
  229. if (isset($options['type']) && strtolower($options['type']) == 'json') {
  230. $type = '.JSON';
  231. }
  232. if (isset($options['update'])) {
  233. $options['update'] = str_replace('#', '', $options['update']);
  234. $type = '.HTML';
  235. }
  236. unset($options['type']);
  237. }
  238. if (!empty($options['data'])) {
  239. $data = $options['data'];
  240. unset($options['data']);
  241. }
  242. $options['url'] = $url;
  243. $options = $this->_prepareCallbacks('request', $options);
  244. if (!empty($options['dataExpression'])) {
  245. $callbacks[] = 'data';
  246. unset($options['dataExpression']);
  247. } elseif (!empty($data)) {
  248. $data = $this->object($data);
  249. }
  250. $options = $this->_parseOptions($options, array_keys($this->_callbackArguments['request']));
  251. return "var jsRequest = new Request$type({{$options}}).send($data);";
  252. }
  253. /**
  254. * Create a sortable element.
  255. *
  256. * Requires the `Sortables` plugin from MootoolsMore
  257. *
  258. * @param array $options Array of options for the sortable.
  259. * @return string Completed sortable script.
  260. * @see JsBaseEngineHelper::sortable() for options list.
  261. */
  262. public function sortable($options = array()) {
  263. $options = $this->_processOptions('sortable', $options);
  264. return 'var jsSortable = new Sortables(' . $this->selection . ', {' . $options . '});';
  265. }
  266. /**
  267. * Create a Draggable element.
  268. *
  269. * Requires the `Drag` plugin from MootoolsMore
  270. *
  271. * @param array $options Array of options for the draggable.
  272. * @return string Completed draggable script.
  273. * @see JsHelper::drag() for options list.
  274. */
  275. public function drag($options = array()) {
  276. $options = $this->_processOptions('drag', $options);
  277. return $this->selection . '.makeDraggable({' . $options . '});';
  278. }
  279. /**
  280. * Create a Droppable element.
  281. *
  282. * Requires the `Drag` and `Drag.Move` plugins from MootoolsMore
  283. *
  284. * Droppables in Mootools function differently from other libraries. Droppables
  285. * are implemented as an extension of Drag. So in addtion to making a get() selection for
  286. * the droppable element. You must also provide a selector rule to the draggable element. Furthermore,
  287. * Mootools droppables inherit all options from Drag.
  288. *
  289. * @param array $options Array of options for the droppable.
  290. * @return string Completed droppable script.
  291. * @see JsBaseEngineHelper::drop() for options list.
  292. */
  293. public function drop($options = array()) {
  294. if (empty($options['drag'])) {
  295. trigger_error(
  296. __d('cake_dev', 'MootoolsEngine::drop() requires a "drag" option to properly function'), E_USER_WARNING
  297. );
  298. return false;
  299. }
  300. $options['droppables'] = $this->selection;
  301. $this->get($options['drag']);
  302. unset($options['drag']);
  303. $options = $this->_mapOptions('drag', $this->_mapOptions('drop', $options));
  304. $options = $this->_prepareCallbacks('drop', $options);
  305. $safe = array_merge(array_keys($this->_callbackArguments['drop']), array('droppables'));
  306. $optionString = $this->_parseOptions($options, $safe);
  307. $out = $this->selection . '.makeDraggable({' . $optionString . '});';
  308. $this->selection = $options['droppables'];
  309. return $out;
  310. }
  311. /**
  312. * Create a slider control
  313. *
  314. * Requires `Slider` from MootoolsMore
  315. *
  316. * @param array $options Array of options for the slider.
  317. * @return string Completed slider script.
  318. * @see JsBaseEngineHelper::slider() for options list.
  319. */
  320. public function slider($options = array()) {
  321. $slider = $this->selection;
  322. $this->get($options['handle']);
  323. unset($options['handle']);
  324. if (isset($options['min']) && isset($options['max'])) {
  325. $options['range'] = array($options['min'], $options['max']);
  326. unset($options['min'], $options['max']);
  327. }
  328. $optionString = $this->_processOptions('slider', $options);
  329. if (!empty($optionString)) {
  330. $optionString = ', {' . $optionString . '}';
  331. }
  332. $out = 'var jsSlider = new Slider(' . $slider . ', ' . $this->selection . $optionString . ');';
  333. $this->selection = $slider;
  334. return $out;
  335. }
  336. /**
  337. * Serialize the form attached to $selector.
  338. *
  339. * @param array $options Array of options.
  340. * @return string Completed serializeForm() snippet
  341. * @see JsBaseEngineHelper::serializeForm()
  342. */
  343. public function serializeForm($options = array()) {
  344. $options = array_merge(array('isForm' => false, 'inline' => false), $options);
  345. $selection = $this->selection;
  346. if (!$options['isForm']) {
  347. $selection = '$(' . $this->selection . '.form)';
  348. }
  349. $method = '.toQueryString()';
  350. if (!$options['inline']) {
  351. $method .= ';';
  352. }
  353. return $selection . $method;
  354. }
  355. }