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