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