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