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: