Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('resize-base', function (Y, NAME) {
2
 
3
/**
4
 * The Resize Utility allows you to make an HTML element resizable.
5
 * @module resize
6
 * @main resize
7
 */
8
 
9
var Lang = Y.Lang,
10
    isArray = Lang.isArray,
11
    isBoolean = Lang.isBoolean,
12
    isNumber = Lang.isNumber,
13
    isString = Lang.isString,
14
 
15
    yArray  = Y.Array,
16
    trim = Lang.trim,
17
    indexOf = yArray.indexOf,
18
 
19
    COMMA = ',',
20
    DOT = '.',
21
    EMPTY_STR = '',
22
    HANDLE_SUB = '{handle}',
23
    SPACE = ' ',
24
 
25
    ACTIVE = 'active',
26
    ACTIVE_HANDLE = 'activeHandle',
27
    ACTIVE_HANDLE_NODE = 'activeHandleNode',
28
    ALL = 'all',
29
    AUTO_HIDE = 'autoHide',
30
    BORDER = 'border',
31
    BOTTOM = 'bottom',
32
    CLASS_NAME = 'className',
33
    COLOR = 'color',
34
    DEF_MIN_HEIGHT = 'defMinHeight',
35
    DEF_MIN_WIDTH = 'defMinWidth',
36
    HANDLE = 'handle',
37
    HANDLES = 'handles',
38
    HANDLES_WRAPPER = 'handlesWrapper',
39
    HIDDEN = 'hidden',
40
    INNER = 'inner',
41
    LEFT = 'left',
42
    MARGIN = 'margin',
43
    NODE = 'node',
44
    NODE_NAME = 'nodeName',
45
    NONE = 'none',
46
    OFFSET_HEIGHT = 'offsetHeight',
47
    OFFSET_WIDTH = 'offsetWidth',
48
    PADDING = 'padding',
49
    PARENT_NODE = 'parentNode',
50
    POSITION = 'position',
51
    RELATIVE = 'relative',
52
    RESIZE = 'resize',
53
    RESIZING = 'resizing',
54
    RIGHT = 'right',
55
    STATIC = 'static',
56
    STYLE = 'style',
57
    TOP = 'top',
58
    WIDTH = 'width',
59
    WRAP = 'wrap',
60
    WRAPPER = 'wrapper',
61
    WRAP_TYPES = 'wrapTypes',
62
 
63
    EV_MOUSE_UP = 'resize:mouseUp',
64
    EV_RESIZE = 'resize:resize',
65
    EV_RESIZE_ALIGN = 'resize:align',
66
    EV_RESIZE_END = 'resize:end',
67
    EV_RESIZE_START = 'resize:start',
68
 
69
    T = 't',
70
    TR = 'tr',
71
    R = 'r',
72
    BR = 'br',
73
    B = 'b',
74
    BL = 'bl',
75
    L = 'l',
76
    TL = 'tl',
77
 
78
    concat = function() {
79
        return Array.prototype.slice.call(arguments).join(SPACE);
80
    },
81
 
82
    // round the passed number to get rid of pixel-flickering
83
    toRoundNumber = function(num) {
84
        return Math.round(parseFloat(num)) || 0;
85
    },
86
 
87
    getCompStyle = function(node, val) {
88
        return node.getComputedStyle(val);
89
    },
90
 
91
    handleAttrName = function(handle) {
92
        return HANDLE + handle.toUpperCase();
93
    },
94
 
95
    isNode = function(v) {
96
        return (v instanceof Y.Node);
97
    },
98
 
99
    toInitialCap = Y.cached(
100
        function(str) {
101
            return str.substring(0, 1).toUpperCase() + str.substring(1);
102
        }
103
    ),
104
 
105
    capitalize = Y.cached(function() {
106
        var out = [],
107
            args = yArray(arguments, 0, true);
108
 
109
        yArray.each(args, function(part, i) {
110
            if (i > 0) {
111
                part = toInitialCap(part);
112
            }
113
            out.push(part);
114
        });
115
 
116
        return out.join(EMPTY_STR);
117
    }),
118
 
119
    getCN = Y.ClassNameManager.getClassName,
120
 
121
    CSS_RESIZE = getCN(RESIZE),
122
    CSS_RESIZE_HANDLE = getCN(RESIZE, HANDLE),
123
    CSS_RESIZE_HANDLE_ACTIVE = getCN(RESIZE, HANDLE, ACTIVE),
124
    CSS_RESIZE_HANDLE_INNER = getCN(RESIZE, HANDLE, INNER),
125
    CSS_RESIZE_HANDLE_INNER_PLACEHOLDER = getCN(RESIZE, HANDLE, INNER, HANDLE_SUB),
126
    CSS_RESIZE_HANDLE_PLACEHOLDER = getCN(RESIZE, HANDLE, HANDLE_SUB),
127
    CSS_RESIZE_HIDDEN_HANDLES = getCN(RESIZE, HIDDEN, HANDLES),
128
    CSS_RESIZE_HANDLES_WRAPPER = getCN(RESIZE, HANDLES, WRAPPER),
129
    CSS_RESIZE_WRAPPER = getCN(RESIZE, WRAPPER);
130
 
131
/**
132
A base class for Resize, providing:
133
 
134
   * Basic Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)
135
   * Applies drag handles to an element to make it resizable
136
   * Here is the list of valid resize handles:
137
       `[ 't', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl' ]`. You can
138
       read this list as top, top-right, right, bottom-right, bottom,
139
       bottom-left, left, top-left.
140
   * The drag handles are inserted into the element and positioned
141
       absolute. Some elements, such as a textarea or image, don't support
142
       children. To overcome that, set wrap:true in your config and the
143
       element willbe wrapped for you automatically.
144
 
145
Quick Example:
146
 
147
    var instance = new Y.Resize({
148
        node: '#resize1',
149
        preserveRatio: true,
150
        wrap: true,
151
        maxHeight: 170,
152
        maxWidth: 400,
153
        handles: 't, tr, r, br, b, bl, l, tl'
154
    });
155
 
156
Check the list of <a href="Resize.html#attrs">Configuration Attributes</a> available for
157
Resize.
158
 
159
@class Resize
160
@param config {Object} Object literal specifying widget configuration properties.
161
@constructor
162
@extends Base
163
*/
164
 
165
function Resize() {
166
    Resize.superclass.constructor.apply(this, arguments);
167
}
168
 
169
Y.mix(Resize, {
170
    /**
171
     * Static property provides a string to identify the class.
172
     *
173
     * @property NAME
174
     * @type String
175
     * @static
176
     */
177
    NAME: RESIZE,
178
 
179
    /**
180
     * Static property used to define the default attribute
181
     * configuration for the Resize.
182
     *
183
     * @property ATTRS
184
     * @type Object
185
     * @static
186
     */
187
    ATTRS: {
188
        /**
189
         * Stores the active handle during the resize.
190
         *
191
         * @attribute activeHandle
192
         * @default null
193
         * @private
194
         * @type String
195
         */
196
        activeHandle: {
197
            value: null,
198
            validator: function(v) {
199
                return Y.Lang.isString(v) || Y.Lang.isNull(v);
200
            }
201
        },
202
 
203
        /**
204
         * Stores the active handle element during the resize.
205
         *
206
         * @attribute activeHandleNode
207
         * @default null
208
         * @private
209
         * @type Node
210
         */
211
        activeHandleNode: {
212
            value: null,
213
            validator: isNode
214
        },
215
 
216
        /**
217
         * False to ensure that the resize handles are always visible, true to
218
         * display them only when the user mouses over the resizable borders.
219
         *
220
         * @attribute autoHide
221
         * @default false
222
         * @type boolean
223
         */
224
        autoHide: {
225
            value: false,
226
            validator: isBoolean
227
        },
228
 
229
        /**
230
         * The default minimum height of the element. Only used when
231
         * ResizeConstrained is not plugged.
232
         *
233
         * @attribute defMinHeight
234
         * @default 15
235
         * @type Number
236
         */
237
        defMinHeight: {
238
            value: 15,
239
            validator: isNumber
240
        },
241
 
242
        /**
243
         * The default minimum width of the element. Only used when
244
         * ResizeConstrained is not plugged.
245
         *
246
         * @attribute defMinWidth
247
         * @default 15
248
         * @type Number
249
         */
250
        defMinWidth: {
251
            value: 15,
252
            validator: isNumber
253
        },
254
 
255
        /**
256
         * The handles to use (any combination of): 't', 'b', 'r', 'l', 'bl',
257
         * 'br', 'tl', 'tr'. Can use a shortcut of All.
258
         *
259
         * @attribute handles
260
         * @default all
261
         * @type Array | String
262
         */
263
        handles: {
264
            setter: '_setHandles',
265
            value: ALL
266
        },
267
 
268
        /**
269
         * Node to wrap the resize handles.
270
         *
271
         * @attribute handlesWrapper
272
         * @type Node
273
         */
274
        handlesWrapper: {
275
            readOnly: true,
276
            setter: Y.one,
277
            valueFn: '_valueHandlesWrapper'
278
        },
279
 
280
        /**
281
         * The selector or element to resize. Required.
282
         *
283
         * @attribute node
284
         * @type Node
285
         */
286
        node: {
287
            setter: Y.one
288
        },
289
 
290
        /**
291
         * True when the element is being Resized.
292
         *
293
         * @attribute resizing
294
         * @default false
295
         * @type boolean
296
         */
297
        resizing: {
298
            value: false,
299
            validator: isBoolean
300
        },
301
 
302
        /**
303
         * True to wrap an element with a div if needed (required for textareas
304
         * and images, defaults to false) in favor of the handles config option.
305
         * The wrapper element type (default div) could be over-riden passing the
306
         * <code>wrapper</code> attribute.
307
         *
308
         * @attribute wrap
309
         * @default false
310
         * @type boolean
311
         */
312
        wrap: {
313
            setter: '_setWrap',
314
            value: false,
315
            validator: isBoolean
316
        },
317
 
318
        /**
319
         * Elements that requires a wrapper by default. Normally are elements
320
         * which cannot have children elements.
321
         *
322
         * @attribute wrapTypes
323
         * @default /canvas|textarea|input|select|button|img/i
324
         * @readOnly
325
         * @type Regex
326
         */
327
        wrapTypes: {
328
            readOnly: true,
329
            value: /^canvas|textarea|input|select|button|img|iframe|table|embed$/i
330
        },
331
 
332
        /**
333
         * Element to wrap the <code>wrapTypes</code>. This element will house
334
         * the handles elements.
335
         *
336
         * @attribute wrapper
337
         * @default div
338
         * @type String | Node
339
         * @writeOnce
340
         */
341
        wrapper: {
342
            readOnly: true,
343
            valueFn: '_valueWrapper',
344
            writeOnce: true
345
        }
346
    },
347
 
348
    RULES: {
349
        b: function(instance, dx, dy) {
350
            var info = instance.info,
351
                originalInfo = instance.originalInfo;
352
 
353
            info.offsetHeight = originalInfo.offsetHeight + dy;
354
        },
355
 
356
        l: function(instance, dx) {
357
            var info = instance.info,
358
                originalInfo = instance.originalInfo;
359
 
360
            info.left = originalInfo.left + dx;
361
            info.offsetWidth = originalInfo.offsetWidth - dx;
362
        },
363
 
364
        r: function(instance, dx) {
365
            var info = instance.info,
366
                originalInfo = instance.originalInfo;
367
 
368
            info.offsetWidth = originalInfo.offsetWidth + dx;
369
        },
370
 
371
        t: function(instance, dx, dy) {
372
            var info = instance.info,
373
                originalInfo = instance.originalInfo;
374
 
375
            info.top = originalInfo.top + dy;
376
            info.offsetHeight = originalInfo.offsetHeight - dy;
377
        },
378
 
379
        tr: function() {
380
            this.t.apply(this, arguments);
381
            this.r.apply(this, arguments);
382
        },
383
 
384
        bl: function() {
385
            this.b.apply(this, arguments);
386
            this.l.apply(this, arguments);
387
        },
388
 
389
        br: function() {
390
            this.b.apply(this, arguments);
391
            this.r.apply(this, arguments);
392
        },
393
 
394
        tl: function() {
395
            this.t.apply(this, arguments);
396
            this.l.apply(this, arguments);
397
        }
398
    },
399
 
400
    capitalize: capitalize
401
});
402
 
403
Y.Resize = Y.extend(
404
    Resize,
405
    Y.Base,
406
    {
407
        /**
408
         * Array containing all possible resizable handles.
409
         *
410
         * @property ALL_HANDLES
411
         * @type {String}
412
         */
413
        ALL_HANDLES: [ T, TR, R, BR, B, BL, L, TL ],
414
 
415
        /**
416
         * Regex which matches with the handles that could change the height of
417
         * the resizable element.
418
         *
419
         * @property REGEX_CHANGE_HEIGHT
420
         * @type {String}
421
         */
422
        REGEX_CHANGE_HEIGHT: /^(t|tr|b|bl|br|tl)$/i,
423
 
424
        /**
425
         * Regex which matches with the handles that could change the left of
426
         * the resizable element.
427
         *
428
         * @property REGEX_CHANGE_LEFT
429
         * @type {String}
430
         */
431
        REGEX_CHANGE_LEFT: /^(tl|l|bl)$/i,
432
 
433
        /**
434
         * Regex which matches with the handles that could change the top of
435
         * the resizable element.
436
         *
437
         * @property REGEX_CHANGE_TOP
438
         * @type {String}
439
         */
440
        REGEX_CHANGE_TOP: /^(tl|t|tr)$/i,
441
 
442
        /**
443
         * Regex which matches with the handles that could change the width of
444
         * the resizable element.
445
         *
446
         * @property REGEX_CHANGE_WIDTH
447
         * @type {String}
448
         */
449
        REGEX_CHANGE_WIDTH: /^(bl|br|l|r|tl|tr)$/i,
450
 
451
        /**
452
         * Template used to create the resize wrapper for the handles.
453
         *
454
         * @property HANDLES_WRAP_TEMPLATE
455
         * @type {String}
456
         */
457
        HANDLES_WRAP_TEMPLATE: '<div class="'+CSS_RESIZE_HANDLES_WRAPPER+'"></div>',
458
 
459
        /**
460
         * Template used to create the resize wrapper node when needed.
461
         *
462
         * @property WRAP_TEMPLATE
463
         * @type {String}
464
         */
465
        WRAP_TEMPLATE: '<div class="'+CSS_RESIZE_WRAPPER+'"></div>',
466
 
467
        /**
468
         * Template used to create each resize handle.
469
         *
470
         * @property HANDLE_TEMPLATE
471
         * @type {String}
472
         */
473
        HANDLE_TEMPLATE: '<div class="'+concat(CSS_RESIZE_HANDLE, CSS_RESIZE_HANDLE_PLACEHOLDER)+'">' +
474
                            '<div class="'+concat(CSS_RESIZE_HANDLE_INNER, CSS_RESIZE_HANDLE_INNER_PLACEHOLDER)+'">&nbsp;</div>' +
475
                        '</div>',
476
 
477
 
478
        /**
479
         * Each box has a content area and optional surrounding padding and
480
         * border areas. This property stores the sum of all horizontal
481
         * surrounding * information needed to adjust the node height.
482
         *
483
         * @property totalHSurrounding
484
         * @default 0
485
         * @type number
486
         */
487
        totalHSurrounding: 0,
488
 
489
        /**
490
         * Each box has a content area and optional surrounding padding and
491
         * border areas. This property stores the sum of all vertical
492
         * surrounding * information needed to adjust the node height.
493
         *
494
         * @property totalVSurrounding
495
         * @default 0
496
         * @type number
497
         */
498
        totalVSurrounding: 0,
499
 
500
        /**
501
         * Stores the <a href="Resize.html#attr_node">node</a>
502
         * surrounding information retrieved from
503
         * <a href="Resize.html#method__getBoxSurroundingInfo">_getBoxSurroundingInfo</a>.
504
         *
505
         * @property nodeSurrounding
506
         * @type Object
507
         * @default null
508
         */
509
        nodeSurrounding: null,
510
 
511
        /**
512
         * Stores the <a href="Resize.html#attr_wrapper">wrapper</a>
513
         * surrounding information retrieved from
514
         * <a href="Resize.html#method__getBoxSurroundingInfo">_getBoxSurroundingInfo</a>.
515
         *
516
         * @property wrapperSurrounding
517
         * @type Object
518
         * @default null
519
         */
520
        wrapperSurrounding: null,
521
 
522
        /**
523
         * Whether the handle being dragged can change the height.
524
         *
525
         * @property changeHeightHandles
526
         * @default false
527
         * @type boolean
528
         */
529
        changeHeightHandles: false,
530
 
531
        /**
532
         * Whether the handle being dragged can change the left.
533
         *
534
         * @property changeLeftHandles
535
         * @default false
536
         * @type boolean
537
         */
538
        changeLeftHandles: false,
539
 
540
        /**
541
         * Whether the handle being dragged can change the top.
542
         *
543
         * @property changeTopHandles
544
         * @default false
545
         * @type boolean
546
         */
547
        changeTopHandles: false,
548
 
549
        /**
550
         * Whether the handle being dragged can change the width.
551
         *
552
         * @property changeWidthHandles
553
         * @default false
554
         * @type boolean
555
         */
556
        changeWidthHandles: false,
557
 
558
        /**
559
         * Store DD.Delegate reference for the respective Resize instance.
560
         *
561
         * @property delegate
562
         * @default null
563
         * @type Object
564
         */
565
        delegate: null,
566
 
567
        /**
568
         * Stores the current values for the height, width, top and left. You are
569
         * able to manipulate these values on resize in order to change the resize
570
         * behavior.
571
         *
572
         * @property info
573
         * @type Object
574
         * @protected
575
         */
576
        info: null,
577
 
578
        /**
579
         * Stores the last values for the height, width, top and left.
580
         *
581
         * @property lastInfo
582
         * @type Object
583
         * @protected
584
         */
585
        lastInfo: null,
586
 
587
        /**
588
         * Stores the original values for the height, width, top and left, stored
589
         * on resize start.
590
         *
591
         * @property originalInfo
592
         * @type Object
593
         * @protected
594
         */
595
        originalInfo: null,
596
 
597
        /**
598
         * Construction logic executed during Resize instantiation. Lifecycle.
599
         *
600
         * @method initializer
601
         * @protected
602
         */
603
        initializer: function() {
604
            this._eventHandles = [];
605
 
606
            this.renderer();
607
        },
608
 
609
        /**
610
         * Create the DOM structure for the Resize. Lifecycle.
611
         *
612
         * @method renderUI
613
         * @protected
614
         */
615
        renderUI: function() {
616
            var instance = this;
617
 
618
            instance._renderHandles();
619
        },
620
 
621
        /**
622
         * Bind the events on the Resize UI. Lifecycle.
623
         *
624
         * @method bindUI
625
         * @protected
626
         */
627
        bindUI: function() {
628
            var instance = this;
629
 
630
            instance._createEvents();
631
            instance._bindDD();
632
            instance._bindHandle();
633
        },
634
 
635
        /**
636
         * Sync the Resize UI.
637
         *
638
         * @method syncUI
639
         * @protected
640
         */
641
        syncUI: function() {
642
            var instance = this;
643
 
644
            this.get(NODE).addClass(CSS_RESIZE);
645
 
646
            // hide handles if AUTO_HIDE is true
647
            instance._setHideHandlesUI(
648
                instance.get(AUTO_HIDE)
649
            );
650
        },
651
 
652
        /**
653
         * Destructor lifecycle implementation for the Resize class.
654
         * Detaches all previously attached listeners and removes the Resize handles.
655
         *
656
         * @method destructor
657
         * @protected
658
         */
659
        destructor: function() {
660
            var instance = this,
661
                node = instance.get(NODE),
662
                wrapper = instance.get(WRAPPER),
663
                pNode = wrapper.get(PARENT_NODE);
664
 
665
            Y.each(
666
                instance._eventHandles,
667
                function(handle) {
668
                    handle.detach();
669
                }
670
            );
671
 
672
            instance._eventHandles.length = 0;
673
 
674
            // destroy handles dd and remove them from the dom
675
            instance.eachHandle(function(handleEl) {
676
                instance.delegate.dd.destroy();
677
 
678
                // remove handle
679
                handleEl.remove(true);
680
            });
681
 
682
            instance.delegate.destroy();
683
 
684
            // unwrap node
685
            if (instance.get(WRAP)) {
686
                instance._copyStyles(wrapper, node);
687
 
688
                if (pNode) {
689
                    pNode.insertBefore(node, wrapper);
690
                }
691
 
692
                wrapper.remove(true);
693
            }
694
 
695
            node.removeClass(CSS_RESIZE);
696
            node.removeClass(CSS_RESIZE_HIDDEN_HANDLES);
697
        },
698
 
699
        /**
700
         * Creates DOM (or manipulates DOM for progressive enhancement)
701
         * This method is invoked by initializer(). It's chained automatically for
702
         * subclasses if required.
703
         *
704
         * @method renderer
705
         * @protected
706
         */
707
        renderer: function() {
708
            this.renderUI();
709
            this.bindUI();
710
            this.syncUI();
711
        },
712
 
713
        /**
714
         * <p>Loop through each handle which is being used and executes a callback.</p>
715
         * <p>Example:</p>
716
         * <pre><code>instance.eachHandle(
717
         *      function(handleName, index) { ... }
718
         *  );</code></pre>
719
         *
720
         * @method eachHandle
721
         * @param {function} fn Callback function to be executed for each handle.
722
         */
723
        eachHandle: function(fn) {
724
            var instance = this;
725
 
726
            Y.each(
727
                instance.get(HANDLES),
728
                function(handle, i) {
729
                    var handleEl = instance.get(
730
                        handleAttrName(handle)
731
                    );
732
 
733
                    fn.apply(instance, [handleEl, handle, i]);
734
                }
735
            );
736
        },
737
 
738
        /**
739
         * Bind the handles DragDrop events to the Resize instance.
740
         *
741
         * @method _bindDD
742
         * @private
743
         */
744
        _bindDD: function() {
745
            var instance = this;
746
 
747
            instance.delegate = new Y.DD.Delegate(
748
                {
749
                    bubbleTargets: instance,
750
                    container: instance.get(HANDLES_WRAPPER),
751
                    dragConfig: {
752
                        clickPixelThresh: 0,
753
                        clickTimeThresh: 0,
754
                        useShim: true,
755
                        move: false
756
                    },
757
                    nodes: DOT+CSS_RESIZE_HANDLE,
758
                    target: false
759
                }
760
            );
761
 
762
            instance._eventHandles.push(
763
                instance.on('drag:drag', instance._handleResizeEvent),
764
                instance.on('drag:dropmiss', instance._handleMouseUpEvent),
765
                instance.on('drag:end', instance._handleResizeEndEvent),
766
                instance.on('drag:start', instance._handleResizeStartEvent)
767
            );
768
        },
769
 
770
        /**
771
         * Bind the events related to the handles (_onHandleMouseEnter, _onHandleMouseLeave).
772
         *
773
         * @method _bindHandle
774
         * @private
775
         */
776
        _bindHandle: function() {
777
            var instance = this,
778
                wrapper = instance.get(WRAPPER);
779
 
780
            instance._eventHandles.push(
781
                wrapper.on('mouseenter', Y.bind(instance._onWrapperMouseEnter, instance)),
782
                wrapper.on('mouseleave', Y.bind(instance._onWrapperMouseLeave, instance)),
783
                wrapper.delegate('mouseenter', Y.bind(instance._onHandleMouseEnter, instance), DOT+CSS_RESIZE_HANDLE),
784
                wrapper.delegate('mouseleave', Y.bind(instance._onHandleMouseLeave, instance), DOT+CSS_RESIZE_HANDLE)
785
            );
786
        },
787
 
788
        /**
789
         * Create the custom events used on the Resize.
790
         *
791
         * @method _createEvents
792
         * @private
793
         */
794
        _createEvents: function() {
795
            var instance = this,
796
                // create publish function for kweight optimization
797
                publish = function(name, fn) {
798
                    instance.publish(name, {
799
                        defaultFn: fn,
800
                        queuable: false,
801
                        emitFacade: true,
802
                        bubbles: true,
803
                        prefix: RESIZE
804
                    });
805
                };
806
 
807
            /**
808
             * Handles the resize start event. Fired when a handle starts to be
809
             * dragged.
810
             *
811
             * @event resize:start
812
             * @preventable _defResizeStartFn
813
             * @param {EventFacade} event The resize start event.
814
             * @bubbles Resize
815
             */
816
            publish(EV_RESIZE_START, this._defResizeStartFn);
817
 
818
            /**
819
             * Handles the resize event. Fired on each pixel when the handle is
820
             * being dragged.
821
             *
822
             * @event resize:resize
823
             * @preventable _defResizeFn
824
             * @param {EventFacade} event The resize event.
825
             * @bubbles Resize
826
             */
827
            publish(EV_RESIZE, this._defResizeFn);
828
 
829
            /**
830
             * Handles the resize align event.
831
             *
832
             * @event resize:align
833
             * @preventable _defResizeAlignFn
834
             * @param {EventFacade} event The resize align event.
835
             * @bubbles Resize
836
             */
837
            publish(EV_RESIZE_ALIGN, this._defResizeAlignFn);
838
 
839
            /**
840
             * Handles the resize end event. Fired when a handle stop to be
841
             * dragged.
842
             *
843
             * @event resize:end
844
             * @preventable _defResizeEndFn
845
             * @param {EventFacade} event The resize end event.
846
             * @bubbles Resize
847
             */
848
            publish(EV_RESIZE_END, this._defResizeEndFn);
849
 
850
            /**
851
             * Handles the resize mouseUp event. Fired when a mouseUp event happens on a
852
             * handle.
853
             *
854
             * @event resize:mouseUp
855
             * @preventable _defMouseUpFn
856
             * @param {EventFacade} event The resize mouseUp event.
857
             * @bubbles Resize
858
             */
859
            publish(EV_MOUSE_UP, this._defMouseUpFn);
860
        },
861
 
862
        /**
863
          * Responsible for loop each handle element and append to the wrapper.
864
          *
865
          * @method _renderHandles
866
          * @protected
867
          */
868
        _renderHandles: function() {
869
            var instance = this,
870
                wrapper = instance.get(WRAPPER),
871
                handlesWrapper = instance.get(HANDLES_WRAPPER);
872
 
873
            instance.eachHandle(function(handleEl) {
874
                handlesWrapper.append(handleEl);
875
            });
876
 
877
            wrapper.append(handlesWrapper);
878
        },
879
 
880
        /**
881
         * Creates the handle element based on the handle name and initialize the
882
         * DragDrop on it.
883
         *
884
         * @method _buildHandle
885
         * @param {String} handle Handle name ('t', 'tr', 'b', ...).
886
         * @protected
887
         */
888
        _buildHandle: function(handle) {
889
            var instance = this;
890
 
891
            return Y.Node.create(
892
                Y.Lang.sub(instance.HANDLE_TEMPLATE, {
893
                    handle: handle
894
                })
895
            );
896
        },
897
 
898
        /**
899
         * Basic resize calculations.
900
         *
901
         * @method _calcResize
902
         * @protected
903
         */
904
        _calcResize: function() {
905
            var instance = this,
906
                handle = instance.handle,
907
                info = instance.info,
908
                originalInfo = instance.originalInfo,
909
 
910
                dx = info.actXY[0] - originalInfo.actXY[0],
911
                dy = info.actXY[1] - originalInfo.actXY[1];
912
 
913
            if (handle && Y.Resize.RULES[handle]) {
914
                Y.Resize.RULES[handle](instance, dx, dy);
915
            }
916
            else {
917
                Y.log('Handle rule not found: ' + handle, 'warn', 'resize');
918
            }
919
        },
920
 
921
        /**
922
         * Helper method to update the current size value on
923
         * <a href="Resize.html#property_info">info</a> to respect the
924
         * min/max values and fix the top/left calculations.
925
         *
926
         * @method _checkSize
927
         * @param {String} offset 'offsetHeight' or 'offsetWidth'
928
         * @param {number} size Size to restrict the offset
929
         * @protected
930
         */
931
        _checkSize: function(offset, size) {
932
            var instance = this,
933
                info = instance.info,
934
                originalInfo = instance.originalInfo,
935
                axis = (offset === OFFSET_HEIGHT) ? TOP : LEFT;
936
 
937
            // forcing the offsetHeight/offsetWidth to be the passed size
938
            info[offset] = size;
939
 
940
            // predicting, based on the original information, the last left valid in case of reach the min/max dimension
941
            // this calculation avoid browser event leaks when user interact very fast
942
            if (((axis === LEFT) && instance.changeLeftHandles) ||
943
                ((axis === TOP) && instance.changeTopHandles)) {
944
 
945
                info[axis] = originalInfo[axis] + originalInfo[offset] - size;
946
            }
947
        },
948
 
949
        /**
950
         * Copy relevant styles of the <a href="Resize.html#attr_node">node</a>
951
         * to the <a href="Resize.html#attr_wrapper">wrapper</a>.
952
         *
953
         * @method _copyStyles
954
         * @param {Node} node Node from.
955
         * @param {Node} wrapper Node to.
956
         * @protected
957
         */
958
        _copyStyles: function(node, wrapper) {
959
            var position = node.getStyle(POSITION).toLowerCase(),
960
                surrounding = this._getBoxSurroundingInfo(node),
961
                wrapperStyle;
962
 
963
            // resizable wrapper should be positioned
964
            if (position === STATIC) {
965
                position = RELATIVE;
966
            }
967
 
968
            wrapperStyle = {
969
                position: position,
970
                left: getCompStyle(node, LEFT),
971
                top: getCompStyle(node, TOP)
972
            };
973
 
974
            Y.mix(wrapperStyle, surrounding.margin);
975
            Y.mix(wrapperStyle, surrounding.border);
976
 
977
            wrapper.setStyles(wrapperStyle);
978
 
979
            // remove margin and border from the internal node
980
            node.setStyles({ border: 0, margin: 0 });
981
 
982
            wrapper.sizeTo(
983
                node.get(OFFSET_WIDTH) + surrounding.totalHBorder,
984
                node.get(OFFSET_HEIGHT) + surrounding.totalVBorder
985
            );
986
        },
987
 
988
        // extract handle name from a string
989
        // using Y.cached to memoize the function for performance
990
        _extractHandleName: Y.cached(
991
            function(node) {
992
                var className = node.get(CLASS_NAME),
993
 
994
                    match = className.match(
995
                        new RegExp(
996
                            getCN(RESIZE, HANDLE, '(\\w{1,2})\\b')
997
                        )
998
                    );
999
 
1000
                return match ? match[1] : null;
1001
            }
1002
        ),
1003
 
1004
        /**
1005
         * <p>Generates metadata to the <a href="Resize.html#property_info">info</a>
1006
         * and <a href="Resize.html#property_originalInfo">originalInfo</a></p>
1007
         * <pre><code>bottom, actXY, left, top, offsetHeight, offsetWidth, right</code></pre>
1008
         *
1009
         * @method _getInfo
1010
         * @param {Node} node
1011
         * @param {EventFacade} event
1012
         * @private
1013
         */
1014
        _getInfo: function(node, event) {
1015
            var actXY = [0,0],
1016
                drag = event.dragEvent.target,
1017
                nodeXY = node.getXY(),
1018
                nodeX = nodeXY[0],
1019
                nodeY = nodeXY[1],
1020
                offsetHeight = node.get(OFFSET_HEIGHT),
1021
                offsetWidth = node.get(OFFSET_WIDTH);
1022
 
1023
            if (event) {
1024
                // the xy that the node will be set to. Changing this will alter the position as it's dragged.
1025
                actXY = (drag.actXY.length ? drag.actXY : drag.lastXY);
1026
            }
1027
 
1028
            return {
1029
                actXY: actXY,
1030
                bottom: (nodeY + offsetHeight),
1031
                left: nodeX,
1032
                offsetHeight: offsetHeight,
1033
                offsetWidth: offsetWidth,
1034
                right: (nodeX + offsetWidth),
1035
                top: nodeY
1036
            };
1037
        },
1038
 
1039
        /**
1040
         * Each box has a content area and optional surrounding margin,
1041
         * padding and * border areas. This method get all this information from
1042
         * the passed node. For more reference see
1043
         * <a href="http://www.w3.org/TR/CSS21/box.html#box-dimensions">
1044
         * http://www.w3.org/TR/CSS21/box.html#box-dimensions</a>.
1045
         *
1046
         * @method _getBoxSurroundingInfo
1047
         * @param {Node} node
1048
         * @private
1049
         * @return {Object}
1050
         */
1051
        _getBoxSurroundingInfo: function(node) {
1052
            var info = {
1053
                padding: {},
1054
                margin: {},
1055
                border: {}
1056
            };
1057
 
1058
            if (isNode(node)) {
1059
                Y.each([ TOP, RIGHT, BOTTOM, LEFT ], function(dir) {
1060
                    var paddingProperty = capitalize(PADDING, dir),
1061
                        marginProperty = capitalize(MARGIN, dir),
1062
                        borderWidthProperty = capitalize(BORDER, dir, WIDTH),
1063
                        borderColorProperty = capitalize(BORDER, dir, COLOR),
1064
                        borderStyleProperty = capitalize(BORDER, dir, STYLE);
1065
 
1066
                    info.border[borderColorProperty] = getCompStyle(node, borderColorProperty);
1067
                    info.border[borderStyleProperty] = getCompStyle(node, borderStyleProperty);
1068
                    info.border[borderWidthProperty] = getCompStyle(node, borderWidthProperty);
1069
                    info.margin[marginProperty] = getCompStyle(node, marginProperty);
1070
                    info.padding[paddingProperty] = getCompStyle(node, paddingProperty);
1071
                });
1072
            }
1073
 
1074
            info.totalHBorder = (toRoundNumber(info.border.borderLeftWidth) + toRoundNumber(info.border.borderRightWidth));
1075
            info.totalHPadding = (toRoundNumber(info.padding.paddingLeft) + toRoundNumber(info.padding.paddingRight));
1076
            info.totalVBorder = (toRoundNumber(info.border.borderBottomWidth) + toRoundNumber(info.border.borderTopWidth));
1077
            info.totalVPadding = (toRoundNumber(info.padding.paddingBottom) + toRoundNumber(info.padding.paddingTop));
1078
 
1079
            return info;
1080
        },
1081
 
1082
        /**
1083
         * Sync the Resize UI with internal values from
1084
         * <a href="Resize.html#property_info">info</a>.
1085
         *
1086
         * @method _syncUI
1087
         * @protected
1088
         */
1089
        _syncUI: function() {
1090
            var instance = this,
1091
                info = instance.info,
1092
                wrapperSurrounding = instance.wrapperSurrounding,
1093
                wrapper = instance.get(WRAPPER),
1094
                node = instance.get(NODE);
1095
 
1096
            wrapper.sizeTo(info.offsetWidth, info.offsetHeight);
1097
 
1098
            if (instance.changeLeftHandles || instance.changeTopHandles) {
1099
                wrapper.setXY([info.left, info.top]);
1100
            }
1101
 
1102
            // if a wrap node is being used
1103
            if (!wrapper.compareTo(node)) {
1104
                // the original internal node borders were copied to the wrapper on
1105
                // _copyStyles, to compensate that subtract the borders from the internal node
1106
                node.sizeTo(
1107
                    info.offsetWidth - wrapperSurrounding.totalHBorder,
1108
                    info.offsetHeight - wrapperSurrounding.totalVBorder
1109
                );
1110
            }
1111
 
1112
            // prevent webkit textarea resize
1113
            if (Y.UA.webkit) {
1114
                node.setStyle(RESIZE, NONE);
1115
            }
1116
        },
1117
 
1118
        /**
1119
         * Update <code>instance.changeHeightHandles,
1120
         * instance.changeLeftHandles, instance.changeTopHandles,
1121
         * instance.changeWidthHandles</code> information.
1122
         *
1123
         * @method _updateChangeHandleInfo
1124
         * @private
1125
         */
1126
        _updateChangeHandleInfo: function(handle) {
1127
            var instance = this;
1128
 
1129
            instance.changeHeightHandles = instance.REGEX_CHANGE_HEIGHT.test(handle);
1130
            instance.changeLeftHandles = instance.REGEX_CHANGE_LEFT.test(handle);
1131
            instance.changeTopHandles = instance.REGEX_CHANGE_TOP.test(handle);
1132
            instance.changeWidthHandles = instance.REGEX_CHANGE_WIDTH.test(handle);
1133
        },
1134
 
1135
        /**
1136
         * Update <a href="Resize.html#property_info">info</a> values (bottom, actXY, left, top, offsetHeight, offsetWidth, right).
1137
         *
1138
         * @method _updateInfo
1139
         * @private
1140
         */
1141
        _updateInfo: function(event) {
1142
            var instance = this;
1143
 
1144
            instance.info = instance._getInfo(instance.get(WRAPPER), event);
1145
        },
1146
 
1147
        /**
1148
         * Update properties
1149
         * <a href="Resize.html#property_nodeSurrounding">nodeSurrounding</a>,
1150
         * <a href="Resize.html#property_nodeSurrounding">wrapperSurrounding</a>,
1151
         * <a href="Resize.html#property_nodeSurrounding">totalVSurrounding</a>,
1152
         * <a href="Resize.html#property_nodeSurrounding">totalHSurrounding</a>.
1153
         *
1154
         * @method _updateSurroundingInfo
1155
         * @private
1156
         */
1157
        _updateSurroundingInfo: function() {
1158
            var instance = this,
1159
                node = instance.get(NODE),
1160
                wrapper = instance.get(WRAPPER),
1161
                nodeSurrounding = instance._getBoxSurroundingInfo(node),
1162
                wrapperSurrounding = instance._getBoxSurroundingInfo(wrapper);
1163
 
1164
            instance.nodeSurrounding = nodeSurrounding;
1165
            instance.wrapperSurrounding = wrapperSurrounding;
1166
 
1167
            instance.totalVSurrounding = (nodeSurrounding.totalVPadding + wrapperSurrounding.totalVBorder);
1168
            instance.totalHSurrounding = (nodeSurrounding.totalHPadding + wrapperSurrounding.totalHBorder);
1169
        },
1170
 
1171
        /**
1172
         * Set the active state of the handles.
1173
         *
1174
         * @method _setActiveHandlesUI
1175
         * @param {boolean} val True to activate the handles, false to deactivate.
1176
         * @protected
1177
         */
1178
        _setActiveHandlesUI: function(val) {
1179
            var instance = this,
1180
                activeHandleNode = instance.get(ACTIVE_HANDLE_NODE);
1181
 
1182
            if (activeHandleNode) {
1183
                if (val) {
1184
                    // remove CSS_RESIZE_HANDLE_ACTIVE from all handles before addClass on the active
1185
                    instance.eachHandle(
1186
                        function(handleEl) {
1187
                            handleEl.removeClass(CSS_RESIZE_HANDLE_ACTIVE);
1188
                        }
1189
                    );
1190
 
1191
                    activeHandleNode.addClass(CSS_RESIZE_HANDLE_ACTIVE);
1192
                }
1193
                else {
1194
                    activeHandleNode.removeClass(CSS_RESIZE_HANDLE_ACTIVE);
1195
                }
1196
            }
1197
        },
1198
 
1199
        /**
1200
         * Setter for the handles attribute
1201
         *
1202
         * @method _setHandles
1203
         * @protected
1204
         * @param {String} val
1205
         */
1206
        _setHandles: function(val) {
1207
            var instance = this,
1208
                handles = [];
1209
 
1210
            // handles attr accepts both array or string
1211
            if (isArray(val)) {
1212
                handles = val;
1213
            }
1214
            else if (isString(val)) {
1215
                // if the handles attr passed in is an ALL string...
1216
                if (val.toLowerCase() === ALL) {
1217
                    handles = instance.ALL_HANDLES;
1218
                }
1219
                // otherwise, split the string to extract the handles
1220
                else {
1221
                    Y.each(
1222
                        val.split(COMMA),
1223
                        function(node) {
1224
                            var handle = trim(node);
1225
 
1226
                            // if its a valid handle, add it to the handles output
1227
                            if (indexOf(instance.ALL_HANDLES, handle) > -1) {
1228
                                handles.push(handle);
1229
                            }
1230
                        }
1231
                    );
1232
                }
1233
            }
1234
 
1235
            return handles;
1236
        },
1237
 
1238
        /**
1239
         * Set the visibility of the handles.
1240
         *
1241
         * @method _setHideHandlesUI
1242
         * @param {boolean} val True to hide the handles, false to show.
1243
         * @protected
1244
         */
1245
        _setHideHandlesUI: function(val) {
1246
            var instance = this,
1247
                wrapper = instance.get(WRAPPER);
1248
 
1249
            if (!instance.get(RESIZING)) {
1250
                if (val) {
1251
                    wrapper.addClass(CSS_RESIZE_HIDDEN_HANDLES);
1252
                }
1253
                else {
1254
                    wrapper.removeClass(CSS_RESIZE_HIDDEN_HANDLES);
1255
                }
1256
            }
1257
        },
1258
 
1259
        /**
1260
         * Setter for the wrap attribute
1261
         *
1262
         * @method _setWrap
1263
         * @protected
1264
         * @param {boolean} val
1265
         */
1266
        _setWrap: function(val) {
1267
            var instance = this,
1268
                node = instance.get(NODE),
1269
                nodeName = node.get(NODE_NAME),
1270
                typeRegex = instance.get(WRAP_TYPES);
1271
 
1272
            // if nodeName is listed on WRAP_TYPES force use the wrapper
1273
            if (typeRegex.test(nodeName)) {
1274
                val = true;
1275
            }
1276
 
1277
            return val;
1278
        },
1279
 
1280
        /**
1281
         * Default resize:mouseUp handler
1282
         *
1283
         * @method _defMouseUpFn
1284
         * @param {EventFacade} event The Event object
1285
         * @protected
1286
         */
1287
        _defMouseUpFn: function() {
1288
            var instance = this;
1289
 
1290
            instance.set(RESIZING, false);
1291
        },
1292
 
1293
        /**
1294
         * Default resize:resize handler
1295
         *
1296
         * @method _defResizeFn
1297
         * @param {EventFacade} event The Event object
1298
         * @protected
1299
         */
1300
        _defResizeFn: function(event) {
1301
            var instance = this;
1302
 
1303
            instance._resize(event);
1304
        },
1305
 
1306
        /**
1307
         * Logic method for _defResizeFn. Allow AOP.
1308
         *
1309
         * @method _resize
1310
         * @param {EventFacade} event The Event object
1311
         * @protected
1312
         */
1313
        _resize: function(event) {
1314
            var instance = this;
1315
 
1316
            instance._handleResizeAlignEvent(event.dragEvent);
1317
 
1318
            // _syncUI of the wrapper, not using proxy
1319
            instance._syncUI();
1320
        },
1321
 
1322
        /**
1323
         * Default resize:align handler
1324
         *
1325
         * @method _defResizeAlignFn
1326
         * @param {EventFacade} event The Event object
1327
         * @protected
1328
         */
1329
        _defResizeAlignFn: function(event) {
1330
            var instance = this;
1331
 
1332
            instance._resizeAlign(event);
1333
        },
1334
 
1335
        /**
1336
         * Logic method for _defResizeAlignFn. Allow AOP.
1337
         *
1338
         * @method _resizeAlign
1339
         * @param {EventFacade} event The Event object
1340
         * @protected
1341
         */
1342
        _resizeAlign: function(event) {
1343
            var instance = this,
1344
                info,
1345
                defMinHeight,
1346
                defMinWidth;
1347
 
1348
            instance.lastInfo = instance.info;
1349
 
1350
            // update the instance.info values
1351
            instance._updateInfo(event);
1352
 
1353
            info = instance.info;
1354
 
1355
            // basic resize calculations
1356
            instance._calcResize();
1357
 
1358
            // if Y.Plugin.ResizeConstrained is not plugged, check for min dimension
1359
            if (!instance.con) {
1360
                defMinHeight = (instance.get(DEF_MIN_HEIGHT) + instance.totalVSurrounding);
1361
                defMinWidth = (instance.get(DEF_MIN_WIDTH) + instance.totalHSurrounding);
1362
 
1363
                if (info.offsetHeight <= defMinHeight) {
1364
                    instance._checkSize(OFFSET_HEIGHT, defMinHeight);
1365
                }
1366
 
1367
                if (info.offsetWidth <= defMinWidth) {
1368
                    instance._checkSize(OFFSET_WIDTH, defMinWidth);
1369
                }
1370
            }
1371
        },
1372
 
1373
        /**
1374
         * Default resize:end handler
1375
         *
1376
         * @method _defResizeEndFn
1377
         * @param {EventFacade} event The Event object
1378
         * @protected
1379
         */
1380
        _defResizeEndFn: function(event) {
1381
            var instance = this;
1382
 
1383
            instance._resizeEnd(event);
1384
        },
1385
 
1386
        /**
1387
         * Logic method for _defResizeEndFn. Allow AOP.
1388
         *
1389
         * @method _resizeEnd
1390
         * @param {EventFacade} event The Event object
1391
         * @protected
1392
         */
1393
        _resizeEnd: function(event) {
1394
            var instance = this,
1395
                drag = event.dragEvent.target;
1396
 
1397
            // reseting actXY from drag when drag end
1398
            drag.actXY = [];
1399
 
1400
            // syncUI when resize end
1401
            instance._syncUI();
1402
 
1403
            instance._setActiveHandlesUI(false);
1404
 
1405
            instance.set(ACTIVE_HANDLE, null);
1406
            instance.set(ACTIVE_HANDLE_NODE, null);
1407
 
1408
            instance.handle = null;
1409
        },
1410
 
1411
        /**
1412
         * Default resize:start handler
1413
         *
1414
         * @method _defResizeStartFn
1415
         * @param {EventFacade} event The Event object
1416
         * @protected
1417
         */
1418
        _defResizeStartFn: function(event) {
1419
            var instance = this;
1420
 
1421
            instance._resizeStart(event);
1422
        },
1423
 
1424
        /**
1425
         * Logic method for _defResizeStartFn. Allow AOP.
1426
         *
1427
         * @method _resizeStart
1428
         * @param {EventFacade} event The Event object
1429
         * @protected
1430
         */
1431
        _resizeStart: function(event) {
1432
            var instance = this,
1433
                wrapper = instance.get(WRAPPER);
1434
 
1435
            instance.handle = instance.get(ACTIVE_HANDLE);
1436
 
1437
            instance.set(RESIZING, true);
1438
 
1439
            instance._updateSurroundingInfo();
1440
 
1441
            // create an originalInfo information for reference
1442
            instance.originalInfo = instance._getInfo(wrapper, event);
1443
 
1444
            instance._updateInfo(event);
1445
        },
1446
 
1447
        /**
1448
         * Fires the resize:mouseUp event.
1449
         *
1450
         * @method _handleMouseUpEvent
1451
         * @param {EventFacade} event resize:mouseUp event facade
1452
         * @protected
1453
         */
1454
        _handleMouseUpEvent: function(event) {
1455
            this.fire(EV_MOUSE_UP, { dragEvent: event, info: this.info });
1456
        },
1457
 
1458
        /**
1459
         * Fires the resize:resize event.
1460
         *
1461
         * @method _handleResizeEvent
1462
         * @param {EventFacade} event resize:resize event facade
1463
         * @protected
1464
         */
1465
        _handleResizeEvent: function(event) {
1466
            this.fire(EV_RESIZE, { dragEvent: event, info: this.info });
1467
        },
1468
 
1469
        /**
1470
         * Fires the resize:align event.
1471
         *
1472
         * @method _handleResizeAlignEvent
1473
         * @param {EventFacade} event resize:resize event facade
1474
         * @protected
1475
         */
1476
        _handleResizeAlignEvent: function(event) {
1477
            this.fire(EV_RESIZE_ALIGN, { dragEvent: event, info: this.info });
1478
        },
1479
 
1480
        /**
1481
         * Fires the resize:end event.
1482
         *
1483
         * @method _handleResizeEndEvent
1484
         * @param {EventFacade} event resize:end event facade
1485
         * @protected
1486
         */
1487
        _handleResizeEndEvent: function(event) {
1488
            this.fire(EV_RESIZE_END, { dragEvent: event, info: this.info });
1489
        },
1490
 
1491
        /**
1492
         * Fires the resize:start event.
1493
         *
1494
         * @method _handleResizeStartEvent
1495
         * @param {EventFacade} event resize:start event facade
1496
         * @protected
1497
         */
1498
        _handleResizeStartEvent: function(event) {
1499
            if (!this.get(ACTIVE_HANDLE)) {
1500
                //This handles the "touch" case
1501
                this._setHandleFromNode(event.target.get('node'));
1502
            }
1503
            this.fire(EV_RESIZE_START, { dragEvent: event, info: this.info });
1504
        },
1505
 
1506
        /**
1507
         * Mouseenter event handler for the <a href="Resize.html#attr_wrapper">wrapper</a>.
1508
         *
1509
         * @method _onWrapperMouseEnter
1510
         * @param {EventFacade} event
1511
         * @protected
1512
         */
1513
        _onWrapperMouseEnter: function() {
1514
            var instance = this;
1515
 
1516
            if (instance.get(AUTO_HIDE)) {
1517
                instance._setHideHandlesUI(false);
1518
            }
1519
        },
1520
 
1521
        /**
1522
         * Mouseleave event handler for the <a href="Resize.html#attr_wrapper">wrapper</a>.
1523
         *
1524
         * @method _onWrapperMouseLeave
1525
         * @param {EventFacade} event
1526
         * @protected
1527
         */
1528
        _onWrapperMouseLeave: function() {
1529
            var instance = this;
1530
 
1531
            if (instance.get(AUTO_HIDE)) {
1532
                instance._setHideHandlesUI(true);
1533
            }
1534
        },
1535
 
1536
        /**
1537
         * Handles setting the activeHandle from a node, used from startDrag (for touch) and mouseenter (for mouse).
1538
         *
1539
         * @method _setHandleFromNode
1540
         * @param {Node} node
1541
         * @protected
1542
         */
1543
        _setHandleFromNode: function(node) {
1544
            var instance = this,
1545
                handle = instance._extractHandleName(node);
1546
 
1547
            if (!instance.get(RESIZING)) {
1548
                instance.set(ACTIVE_HANDLE, handle);
1549
                instance.set(ACTIVE_HANDLE_NODE, node);
1550
 
1551
                instance._setActiveHandlesUI(true);
1552
                instance._updateChangeHandleInfo(handle);
1553
            }
1554
        },
1555
 
1556
        /**
1557
         * Mouseenter event handler for the handles.
1558
         *
1559
         * @method _onHandleMouseEnter
1560
         * @param {EventFacade} event
1561
         * @protected
1562
         */
1563
        _onHandleMouseEnter: function(event) {
1564
            this._setHandleFromNode(event.currentTarget);
1565
        },
1566
 
1567
        /**
1568
         * Mouseout event handler for the handles.
1569
         *
1570
         * @method _onHandleMouseLeave
1571
         * @param {EventFacade} event
1572
         * @protected
1573
         */
1574
        _onHandleMouseLeave: function() {
1575
            var instance = this;
1576
 
1577
            if (!instance.get(RESIZING)) {
1578
                instance._setActiveHandlesUI(false);
1579
            }
1580
        },
1581
 
1582
        /**
1583
         * Default value for the wrapper handles node attribute
1584
         *
1585
         * @method _valueHandlesWrapper
1586
         * @protected
1587
         * @readOnly
1588
         */
1589
        _valueHandlesWrapper: function() {
1590
            return Y.Node.create(this.HANDLES_WRAP_TEMPLATE);
1591
        },
1592
 
1593
        /**
1594
         * Default value for the wrapper attribute
1595
         *
1596
         * @method _valueWrapper
1597
         * @protected
1598
         * @readOnly
1599
         */
1600
        _valueWrapper: function() {
1601
            var instance = this,
1602
                node = instance.get(NODE),
1603
                pNode = node.get(PARENT_NODE),
1604
                // by deafult the wrapper is always the node
1605
                wrapper = node;
1606
 
1607
            // if the node is listed on the wrapTypes or wrap is set to true, create another wrapper
1608
            if (instance.get(WRAP)) {
1609
                wrapper = Y.Node.create(instance.WRAP_TEMPLATE);
1610
 
1611
                if (pNode) {
1612
                    pNode.insertBefore(wrapper, node);
1613
                }
1614
 
1615
                wrapper.append(node);
1616
 
1617
                instance._copyStyles(node, wrapper);
1618
 
1619
                // remove positioning of wrapped node, the WRAPPER take care about positioning
1620
                node.setStyles({
1621
                    position: STATIC,
1622
                    left: 0,
1623
                    top: 0
1624
                });
1625
            }
1626
 
1627
            return wrapper;
1628
        }
1629
    }
1630
);
1631
 
1632
Y.each(Y.Resize.prototype.ALL_HANDLES, function(handle) {
1633
    // creating ATTRS with the handles elements
1634
    Y.Resize.ATTRS[handleAttrName(handle)] = {
1635
        setter: function() {
1636
            return this._buildHandle(handle);
1637
        },
1638
        value: null,
1639
        writeOnce: true
1640
    };
1641
});
1642
 
1643
 
1644
}, '3.18.1', {"requires": ["base", "widget", "event", "oop", "dd-drag", "dd-delegate", "dd-drop"], "skinnable": true});