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