1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
16:
17: App::uses('JsBaseEngineHelper', 'View/Helper');
18:
19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31:
32: class MootoolsEngineHelper extends JsBaseEngineHelper {
33:
34: 35: 36: 37: 38:
39: protected $_optionMap = array(
40: 'request' => array(
41: 'complete' => 'onComplete',
42: 'success' => 'onSuccess',
43: 'before' => 'onRequest',
44: 'error' => 'onFailure'
45: ),
46: 'sortable' => array(
47: 'distance' => 'snap',
48: 'containment' => 'constrain',
49: 'sort' => 'onSort',
50: 'complete' => 'onComplete',
51: 'start' => 'onStart',
52: ),
53: 'drag' => array(
54: 'snapGrid' => 'snap',
55: 'start' => 'onStart',
56: 'drag' => 'onDrag',
57: 'stop' => 'onComplete',
58: ),
59: 'drop' => array(
60: 'drop' => 'onDrop',
61: 'hover' => 'onEnter',
62: 'leave' => 'onLeave',
63: ),
64: 'slider' => array(
65: 'complete' => 'onComplete',
66: 'change' => 'onChange',
67: 'direction' => 'mode',
68: 'step' => 'steps'
69: )
70: );
71:
72: 73: 74: 75: 76:
77: protected $_callbackArguments = array(
78: 'slider' => array(
79: 'onTick' => 'position',
80: 'onChange' => 'step',
81: 'onComplete' => 'event'
82: ),
83: 'request' => array(
84: 'onRequest' => '',
85: 'onComplete' => '',
86: 'onCancel' => '',
87: 'onSuccess' => 'responseText, responseXML',
88: 'onFailure' => 'xhr',
89: 'onException' => 'headerName, value',
90: ),
91: 'drag' => array(
92: 'onBeforeStart' => 'element',
93: 'onStart' => 'element',
94: 'onSnap' => 'element',
95: 'onDrag' => 'element, event',
96: 'onComplete' => 'element, event',
97: 'onCancel' => 'element',
98: ),
99: 'drop' => array(
100: 'onBeforeStart' => 'element',
101: 'onStart' => 'element',
102: 'onSnap' => 'element',
103: 'onDrag' => 'element, event',
104: 'onComplete' => 'element, event',
105: 'onCancel' => 'element',
106: 'onDrop' => 'element, droppable, event',
107: 'onLeave' => 'element, droppable',
108: 'onEnter' => 'element, droppable',
109: ),
110: 'sortable' => array(
111: 'onStart' => 'element, clone',
112: 'onSort' => 'element, clone',
113: 'onComplete' => 'element',
114: )
115: );
116:
117: 118: 119: 120: 121: 122:
123: public function get($selector) {
124: $this->_multipleSelection = false;
125: if ($selector === 'window' || $selector === 'document') {
126: $this->selection = "$(" . $selector . ")";
127: return $this;
128: }
129: if (preg_match('/^#[^\s.]+$/', $selector)) {
130: $this->selection = '$("' . substr($selector, 1) . '")';
131: return $this;
132: }
133: $this->_multipleSelection = true;
134: $this->selection = '$$("' . $selector . '")';
135: return $this;
136: }
137:
138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150:
151: public function event($type, $callback, $options = array()) {
152: $defaults = array('wrap' => true, 'stop' => true);
153: $options += $defaults;
154:
155: $function = 'function (event) {%s}';
156: if ($options['wrap'] && $options['stop']) {
157: $callback = "event.stop();\n" . $callback;
158: }
159: if ($options['wrap']) {
160: $callback = sprintf($function, $callback);
161: }
162: $out = $this->selection . ".addEvent(\"{$type}\", $callback);";
163: return $out;
164: }
165:
166: 167: 168: 169: 170: 171:
172: public function domReady($functionBody) {
173: $this->selection = 'window';
174: return $this->event('domready', $functionBody, array('stop' => false));
175: }
176:
177: 178: 179: 180: 181: 182:
183: public function each($callback) {
184: return $this->selection . '.each(function (item, index) {' . $callback . '});';
185: }
186:
187: 188: 189: 190: 191: 192: 193: 194:
195: public function effect($name, $options = array()) {
196: $speed = null;
197: if (isset($options['speed']) && in_array($options['speed'], array('fast', 'slow'))) {
198: if ($options['speed'] === 'fast') {
199: $speed = '"short"';
200: } elseif ($options['speed'] === 'slow') {
201: $speed = '"long"';
202: }
203: }
204: $effect = '';
205: switch ($name) {
206: case 'hide':
207: $effect = 'setStyle("display", "none")';
208: break;
209: case 'show':
210: $effect = 'setStyle("display", "")';
211: break;
212: case 'fadeIn':
213: case 'fadeOut':
214: case 'slideIn':
215: case 'slideOut':
216: list($effectName, $direction) = preg_split('/([A-Z][a-z]+)/', $name, -1, PREG_SPLIT_DELIM_CAPTURE);
217: $direction = strtolower($direction);
218: if ($speed) {
219: $effect .= "set(\"$effectName\", {duration:$speed}).";
220: }
221: $effect .= "$effectName(\"$direction\")";
222: break;
223: }
224: return $this->selection . '.' . $effect . ';';
225: }
226:
227: 228: 229: 230: 231: 232: 233: 234: 235: 236:
237: public function request($url, $options = array()) {
238: $url = html_entity_decode($this->url($url), ENT_COMPAT, Configure::read('App.encoding'));
239: $options = $this->_mapOptions('request', $options);
240: $type = $data = null;
241: if (isset($options['type']) || isset($options['update'])) {
242: if (isset($options['type']) && strtolower($options['type']) === 'json') {
243: $type = '.JSON';
244: }
245: if (isset($options['update'])) {
246: $options['update'] = str_replace('#', '', $options['update']);
247: $type = '.HTML';
248: }
249: unset($options['type']);
250: }
251: if (!empty($options['data'])) {
252: $data = $options['data'];
253: unset($options['data']);
254: }
255: $options['url'] = $url;
256: $options = $this->_prepareCallbacks('request', $options);
257: if (!empty($options['dataExpression'])) {
258: unset($options['dataExpression']);
259: } elseif (!empty($data)) {
260: $data = $this->object($data);
261: }
262: $options = $this->_parseOptions($options, array_keys($this->_callbackArguments['request']));
263: return "var jsRequest = new Request$type({{$options}}).send($data);";
264: }
265:
266: 267: 268: 269: 270: 271: 272: 273: 274:
275: public function sortable($options = array()) {
276: $options = $this->_processOptions('sortable', $options);
277: return 'var jsSortable = new Sortables(' . $this->selection . ', {' . $options . '});';
278: }
279:
280: 281: 282: 283: 284: 285: 286: 287: 288:
289: public function drag($options = array()) {
290: $options = $this->_processOptions('drag', $options);
291: return $this->selection . '.makeDraggable({' . $options . '});';
292: }
293:
294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304: 305: 306: 307:
308: public function drop($options = array()) {
309: if (empty($options['drag'])) {
310: trigger_error(
311: __d('cake_dev', '%s requires a "drag" option to properly function'), 'MootoolsEngine::drop()', E_USER_WARNING
312: );
313: return false;
314: }
315: $options['droppables'] = $this->selection;
316:
317: $this->get($options['drag']);
318: unset($options['drag']);
319:
320: $options = $this->_mapOptions('drag', $this->_mapOptions('drop', $options));
321: $options = $this->_prepareCallbacks('drop', $options);
322: $safe = array_merge(array_keys($this->_callbackArguments['drop']), array('droppables'));
323: $optionString = $this->_parseOptions($options, $safe);
324: $out = $this->selection . '.makeDraggable({' . $optionString . '});';
325: $this->selection = $options['droppables'];
326: return $out;
327: }
328:
329: 330: 331: 332: 333: 334: 335: 336: 337:
338: public function slider($options = array()) {
339: $slider = $this->selection;
340: $this->get($options['handle']);
341: unset($options['handle']);
342:
343: if (isset($options['min']) && isset($options['max'])) {
344: $options['range'] = array($options['min'], $options['max']);
345: unset($options['min'], $options['max']);
346: }
347: $optionString = $this->_processOptions('slider', $options);
348: if (!empty($optionString)) {
349: $optionString = ', {' . $optionString . '}';
350: }
351: $out = 'var jsSlider = new Slider(' . $slider . ', ' . $this->selection . $optionString . ');';
352: $this->selection = $slider;
353: return $out;
354: }
355:
356: 357: 358: 359: 360: 361: 362:
363: public function serializeForm($options = array()) {
364: $options += array('isForm' => false, 'inline' => false);
365: $selection = $this->selection;
366: if (!$options['isForm']) {
367: $selection = '$(' . $this->selection . '.form)';
368: }
369: $method = '.toQueryString()';
370: if (!$options['inline']) {
371: $method .= ';';
372: }
373: return $selection . $method;
374: }
375:
376: }
377: