統計
| ブランチ: | リビジョン:

pictcode / lib / Cake / View / Helper / MootoolsEngineHelper.php @ 635eef61

履歴 | 表示 | アノテート | ダウンロード (10.944 KB)

1
<?php
2
/**
3
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice.
9
 *
10
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11
 * @link          http://cakephp.org CakePHP(tm) Project
12
 * @package       Cake.View.Helper
13
 * @since         CakePHP(tm) v 1.3
14
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
15
 */
16

    
17
App::uses('JsBaseEngineHelper', 'View/Helper');
18

    
19
/**
20
 * MooTools Engine Helper for JsHelper
21
 *
22
 * Provides MooTools specific JavaScript for JsHelper.
23
 * Assumes that you have the following MooTools packages
24
 *
25
 * - Remote, Remote.HTML, Remote.JSON
26
 * - Fx, Fx.Tween, Fx.Morph
27
 * - Selectors, DomReady,
28
 * - Drag, Drag.Move
29
 *
30
 * @package       Cake.View.Helper
31
 */
32
class MootoolsEngineHelper extends JsBaseEngineHelper {
33

    
34
/**
35
 * Option mappings for MooTools
36
 *
37
 * @var array
38
 */
39
        protected $_optionMap = array(
40
                'request' => array(
41
                        'complete' => 'onComplete',
42
                        'success' => 'onSuccess',
43
                        'before' => 'onRequest',
44
                        'error' => 'onFailure'
45
                ),
46
                'sortable' => array(
47
                        'distance' => 'snap',
48
                        'containment' => 'constrain',
49
                        'sort' => 'onSort',
50
                        'complete' => 'onComplete',
51
                        'start' => 'onStart',
52
                ),
53
                'drag' => array(
54
                        'snapGrid' => 'snap',
55
                        'start' => 'onStart',
56
                        'drag' => 'onDrag',
57
                        'stop' => 'onComplete',
58
                ),
59
                'drop' => array(
60
                        'drop' => 'onDrop',
61
                        'hover' => 'onEnter',
62
                        'leave' => 'onLeave',
63
                ),
64
                'slider' => array(
65
                        'complete' => 'onComplete',
66
                        'change' => 'onChange',
67
                        'direction' => 'mode',
68
                        'step' => 'steps'
69
                )
70
        );
71

    
72
/**
73
 * Contains a list of callback names -> default arguments.
74
 *
75
 * @var array
76
 */
77
        protected $_callbackArguments = array(
78
                'slider' => array(
79
                        'onTick' => 'position',
80
                        'onChange' => 'step',
81
                        'onComplete' => 'event'
82
                ),
83
                'request' => array(
84
                        'onRequest' => '',
85
                        'onComplete' => '',
86
                        'onCancel' => '',
87
                        'onSuccess' => 'responseText, responseXML',
88
                        'onFailure' => 'xhr',
89
                        'onException' => 'headerName, value',
90
                ),
91
                'drag' => array(
92
                        'onBeforeStart' => 'element',
93
                        'onStart' => 'element',
94
                        'onSnap' => 'element',
95
                        'onDrag' => 'element, event',
96
                        'onComplete' => 'element, event',
97
                        'onCancel' => 'element',
98
                ),
99
                'drop' => array(
100
                        'onBeforeStart' => 'element',
101
                        'onStart' => 'element',
102
                        'onSnap' => 'element',
103
                        'onDrag' => 'element, event',
104
                        'onComplete' => 'element, event',
105
                        'onCancel' => 'element',
106
                        'onDrop' => 'element, droppable, event',
107
                        'onLeave' => 'element, droppable',
108
                        'onEnter' => 'element, droppable',
109
                ),
110
                'sortable' => array(
111
                        'onStart' => 'element, clone',
112
                        'onSort' => 'element, clone',
113
                        'onComplete' => 'element',
114
                )
115
        );
116

    
117
/**
118
 * Create javascript selector for a CSS rule
119
 *
120
 * @param string $selector The selector that is targeted
121
 * @return $this
122
 */
123
        public function get($selector) {
124
                $this->_multipleSelection = false;
125
                if ($selector === 'window' || $selector === 'document') {
126
                        $this->selection = "$(" . $selector . ")";
127
                        return $this;
128
                }
129
                if (preg_match('/^#[^\s.]+$/', $selector)) {
130
                        $this->selection = '$("' . substr($selector, 1) . '")';
131
                        return $this;
132
                }
133
                $this->_multipleSelection = true;
134
                $this->selection = '$$("' . $selector . '")';
135
                return $this;
136
        }
137

    
138
/**
139
 * Add an event to the script cache. Operates on the currently selected elements.
140
 *
141
 * ### Options
142
 *
143
 * - 'wrap' - Whether you want the callback wrapped in an anonymous function. (defaults true)
144
 * - 'stop' - Whether you want the event to stopped. (defaults true)
145
 *
146
 * @param string $type Type of event to bind to the current dom id
147
 * @param string $callback The JavaScript function you wish to trigger or the function literal
148
 * @param array $options Options for the event.
149
 * @return string completed event handler
150
 */
151
        public function event($type, $callback, $options = array()) {
152
                $defaults = array('wrap' => true, 'stop' => true);
153
                $options += $defaults;
154

    
155
                $function = 'function (event) {%s}';
156
                if ($options['wrap'] && $options['stop']) {
157
                        $callback = "event.stop();\n" . $callback;
158
                }
159
                if ($options['wrap']) {
160
                        $callback = sprintf($function, $callback);
161
                }
162
                $out = $this->selection . ".addEvent(\"{$type}\", $callback);";
163
                return $out;
164
        }
165

    
166
/**
167
 * Create a domReady event. This is a special event in many libraries
168
 *
169
 * @param string $functionBody The code to run on domReady
170
 * @return string completed domReady method
171
 */
172
        public function domReady($functionBody) {
173
                $this->selection = 'window';
174
                return $this->event('domready', $functionBody, array('stop' => false));
175
        }
176

    
177
/**
178
 * Create an iteration over the current selection result.
179
 *
180
 * @param string $callback The function body you wish to apply during the iteration.
181
 * @return string completed iteration
182
 */
183
        public function each($callback) {
184
                return $this->selection . '.each(function (item, index) {' . $callback . '});';
185
        }
186

    
187
/**
188
 * Trigger an Effect.
189
 *
190
 * @param string $name The name of the effect to trigger.
191
 * @param array $options Array of options for the effect.
192
 * @return string completed string with effect.
193
 * @see JsBaseEngineHelper::effect()
194
 */
195
        public function effect($name, $options = array()) {
196
                $speed = null;
197
                if (isset($options['speed']) && in_array($options['speed'], array('fast', 'slow'))) {
198
                        if ($options['speed'] === 'fast') {
199
                                $speed = '"short"';
200
                        } elseif ($options['speed'] === 'slow') {
201
                                $speed = '"long"';
202
                        }
203
                }
204
                $effect = '';
205
                switch ($name) {
206
                        case 'hide':
207
                                $effect = 'setStyle("display", "none")';
208
                                break;
209
                        case 'show':
210
                                $effect = 'setStyle("display", "")';
211
                                break;
212
                        case 'fadeIn':
213
                        case 'fadeOut':
214
                        case 'slideIn':
215
                        case 'slideOut':
216
                                list($effectName, $direction) = preg_split('/([A-Z][a-z]+)/', $name, -1, PREG_SPLIT_DELIM_CAPTURE);
217
                                $direction = strtolower($direction);
218
                                if ($speed) {
219
                                        $effect .= "set(\"$effectName\", {duration:$speed}).";
220
                                }
221
                                $effect .= "$effectName(\"$direction\")";
222
                                break;
223
                }
224
                return $this->selection . '.' . $effect . ';';
225
        }
226

    
227
/**
228
 * Create a new Request.
229
 *
230
 * Requires `Request`. If you wish to use 'update' key you must have ```Request.HTML```
231
 * if you wish to do Json requests you will need ```JSON``` and ```Request.JSON```.
232
 *
233
 * @param string|array $url URL
234
 * @param array $options Options list.
235
 * @return string The completed ajax call.
236
 */
237
        public function request($url, $options = array()) {
238
                $url = html_entity_decode($this->url($url), ENT_COMPAT, Configure::read('App.encoding'));
239
                $options = $this->_mapOptions('request', $options);
240
                $type = $data = null;
241
                if (isset($options['type']) || isset($options['update'])) {
242
                        if (isset($options['type']) && strtolower($options['type']) === 'json') {
243
                                $type = '.JSON';
244
                        }
245
                        if (isset($options['update'])) {
246
                                $options['update'] = str_replace('#', '', $options['update']);
247
                                $type = '.HTML';
248
                        }
249
                        unset($options['type']);
250
                }
251
                if (!empty($options['data'])) {
252
                        $data = $options['data'];
253
                        unset($options['data']);
254
                }
255
                $options['url'] = $url;
256
                $options = $this->_prepareCallbacks('request', $options);
257
                if (!empty($options['dataExpression'])) {
258
                        unset($options['dataExpression']);
259
                } elseif (!empty($data)) {
260
                        $data = $this->object($data);
261
                }
262
                $options = $this->_parseOptions($options, array_keys($this->_callbackArguments['request']));
263
                return "var jsRequest = new Request$type({{$options}}).send($data);";
264
        }
265

    
266
/**
267
 * Create a sortable element.
268
 *
269
 * Requires the `Sortables` plugin from MootoolsMore
270
 *
271
 * @param array $options Array of options for the sortable.
272
 * @return string Completed sortable script.
273
 * @see JsBaseEngineHelper::sortable() for options list.
274
 */
275
        public function sortable($options = array()) {
276
                $options = $this->_processOptions('sortable', $options);
277
                return 'var jsSortable = new Sortables(' . $this->selection . ', {' . $options . '});';
278
        }
279

    
280
/**
281
 * Create a Draggable element.
282
 *
283
 * Requires the `Drag` plugin from MootoolsMore
284
 *
285
 * @param array $options Array of options for the draggable.
286
 * @return string Completed draggable script.
287
 * @see JsHelper::drag() for options list.
288
 */
289
        public function drag($options = array()) {
290
                $options = $this->_processOptions('drag', $options);
291
                return $this->selection . '.makeDraggable({' . $options . '});';
292
        }
293

    
294
/**
295
 * Create a Droppable element.
296
 *
297
 * Requires the `Drag` and `Drag.Move` plugins from MootoolsMore
298
 *
299
 * Droppables in Mootools function differently from other libraries. Droppables
300
 * are implemented as an extension of Drag. So in addition to making a get() selection for
301
 * the droppable element. You must also provide a selector rule to the draggable element. Furthermore,
302
 * Mootools droppables inherit all options from Drag.
303
 *
304
 * @param array $options Array of options for the droppable.
305
 * @return string Completed droppable script.
306
 * @see JsBaseEngineHelper::drop() for options list.
307
 */
308
        public function drop($options = array()) {
309
                if (empty($options['drag'])) {
310
                        trigger_error(
311
                                __d('cake_dev', '%s requires a "drag" option to properly function'), 'MootoolsEngine::drop()', E_USER_WARNING
312
                        );
313
                        return false;
314
                }
315
                $options['droppables'] = $this->selection;
316

    
317
                $this->get($options['drag']);
318
                unset($options['drag']);
319

    
320
                $options = $this->_mapOptions('drag', $this->_mapOptions('drop', $options));
321
                $options = $this->_prepareCallbacks('drop', $options);
322
                $safe = array_merge(array_keys($this->_callbackArguments['drop']), array('droppables'));
323
                $optionString = $this->_parseOptions($options, $safe);
324
                $out = $this->selection . '.makeDraggable({' . $optionString . '});';
325
                $this->selection = $options['droppables'];
326
                return $out;
327
        }
328

    
329
/**
330
 * Create a slider control
331
 *
332
 * Requires `Slider` from MootoolsMore
333
 *
334
 * @param array $options Array of options for the slider.
335
 * @return string Completed slider script.
336
 * @see JsBaseEngineHelper::slider() for options list.
337
 */
338
        public function slider($options = array()) {
339
                $slider = $this->selection;
340
                $this->get($options['handle']);
341
                unset($options['handle']);
342

    
343
                if (isset($options['min']) && isset($options['max'])) {
344
                        $options['range'] = array($options['min'], $options['max']);
345
                        unset($options['min'], $options['max']);
346
                }
347
                $optionString = $this->_processOptions('slider', $options);
348
                if (!empty($optionString)) {
349
                        $optionString = ', {' . $optionString . '}';
350
                }
351
                $out = 'var jsSlider = new Slider(' . $slider . ', ' . $this->selection . $optionString . ');';
352
                $this->selection = $slider;
353
                return $out;
354
        }
355

    
356
/**
357
 * Serialize the form attached to $selector.
358
 *
359
 * @param array $options Array of options.
360
 * @return string Completed serializeForm() snippet
361
 * @see JsBaseEngineHelper::serializeForm()
362
 */
363
        public function serializeForm($options = array()) {
364
                $options += array('isForm' => false, 'inline' => false);
365
                $selection = $this->selection;
366
                if (!$options['isForm']) {
367
                        $selection = '$(' . $this->selection . '.form)';
368
                }
369
                $method = '.toQueryString()';
370
                if (!$options['inline']) {
371
                        $method .= ';';
372
                }
373
                return $selection . $method;
374
        }
375

    
376
}