Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('yui2-imagecropper', function(Y) {
2
    var YAHOO    = Y.YUI2;
3
    /*
4
Copyright (c) 2011, Yahoo! Inc. All rights reserved.
5
Code licensed under the BSD License:
6
http://developer.yahoo.com/yui/license.html
7
version: 2.9.0
8
*/
9
/**
10
 * @description <p>Creates a Image Cropper control.</p>
11
 * @namespace YAHOO.widget
12
 * @requires yahoo, dom, dragdrop, element, event, resize
13
 * @module imagecropper
14
 */
15
(function() {
16
var Dom = YAHOO.util.Dom,
17
    Event = YAHOO.util.Event,
18
    Lang = YAHOO.lang;
19
 
20
    /**
21
     * @constructor
22
     * @class ImageCropper
23
     * @description <p>Creates a Image Cropper control.</p>
24
     * @extends YAHOO.util.Element
25
     * @param {String/HTMLElement} el The image element to make croppable.
26
     * @param {Object} attrs Object liternal containing configuration parameters.
27
    */
28
    var Crop = function(el, config) {
29
        YAHOO.log('Initializing', 'log', 'ImageCropper');
30
        var oConfig = {
31
            element: el,
32
            attributes: config || {}
33
        };
34
 
35
        Crop.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
36
    };
37
 
38
    /**
39
    * @private
40
    * @static
41
    * @property _instances
42
    * @description Internal hash table for all ImageCropper instances
43
    * @type Object
44
    */
45
    Crop._instances = {};
46
    /**
47
    * @static
48
    * @method getCropperById
49
    * @description Get's an ImageCropper object by the HTML id of the image associated with the ImageCropper object.
50
    * @return {Object} The ImageCropper Object
51
    */
52
    Crop.getCropperById = function(id) {
53
        if (Crop._instances[id]) {
54
            return Crop._instances[id];
55
        }
56
        return false;
57
    };
58
 
59
    YAHOO.extend(Crop, YAHOO.util.Element, {
60
        /**
61
        * @private
62
        * @property CSS_MAIN
63
        * @description The CSS class used to wrap the element
64
        * @type String
65
        */
66
        CSS_MAIN: 'yui-crop',
67
        /**
68
        * @private
69
        * @property CSS_MASK
70
        * @description The CSS class for the mask element
71
        * @type String
72
        */
73
        CSS_MASK: 'yui-crop-mask',
74
        /**
75
        * @private
76
        * @property CSS_RESIZE_MASK
77
        * @description The CSS class for the mask inside the resize element
78
        * @type {HTML}
79
        */
80
        CSS_RESIZE_MASK: 'yui-crop-resize-mask',
81
 
82
        /**
83
        * @private
84
        * @property _image
85
        * @description The url of the image we are cropping
86
        * @type String
87
        */
88
        _image: null,
89
        /**
90
        * @private
91
        * @property _active
92
        * @description Flag to determine if the crop region is active
93
        * @type Boolean
94
        */
95
        _active: null,
96
        /**
97
        * @private
98
        * @property _resize
99
        * @description A reference to the Resize Utility used in this Cropper Instance
100
        * @type Object
101
        */
102
        _resize: null,
103
        /**
104
        * @private
105
        * @property _resizeEl
106
        * @description The HTML Element used to create the Resize Oject
107
        * @type HTMLElement
108
        */
109
        _resizeEl: null,
110
        /**
111
        * @private
112
        * @property _resizeMaskEl
113
        * @description The HTML Element used to create the Resize mask
114
        * @type HTMLElement
115
        */
116
        _resizeMaskEl: null,
117
        /**
118
        * @private
119
        * @property _wrap
120
        * @description The HTML Element created to wrap the image
121
        * @type HTMLElement
122
        */
123
        _wrap: null,
124
        /**
125
        * @private
126
        * @property _mask
127
        * @description The HTML Element created to "mask" the image being cropped
128
        * @type HTMLElement
129
        */
130
        _mask: null,
131
        /**
132
        * @private
133
        * @method _createWrap
134
        * @description Creates the wrapper element used to wrap the image
135
        */
136
        _createWrap: function() {
137
            YAHOO.log('Creating the wrap element', 'log', 'ImageCropper');
138
            this._wrap = document.createElement('div');
139
            this._wrap.id = this.get('element').id + '_wrap';
140
            this._wrap.className = this.CSS_MAIN;
141
            var el = this.get('element');
142
            this._wrap.style.width = el.width ? el.width + 'px' : Dom.getStyle(el, 'width');
143
            this._wrap.style.height = el.height ? el.height + 'px' : Dom.getStyle(el, 'height');
144
 
145
            var par = this.get('element').parentNode;
146
            par.replaceChild(this._wrap, this.get('element'));
147
            this._wrap.appendChild(this.get('element'));
148
 
149
            Event.on(this._wrap, 'mouseover', this._handleMouseOver, this, true);
150
            Event.on(this._wrap, 'mouseout', this._handleMouseOut, this, true);
151
 
152
            Event.on(this._wrap, 'click', function(ev) { Event.stopEvent(ev); }, this, true);
153
        },
154
 
155
        /**
156
        * @private
157
        * @method _createMask
158
        * @description Creates the mask element used to mask the image
159
        */
160
        _createMask: function() {
161
            YAHOO.log('Creating the Mask', 'log', 'ImageCropper');
162
            this._mask = document.createElement('div');
163
            this._mask.className = this.CSS_MASK;
164
            this._wrap.appendChild(this._mask);
165
        },
166
 
167
        /**
168
        * @private
169
        * @method _createResize
170
        * @description Creates the resize element and the instance of the Resize Utility
171
        */
172
        _createResize: function() {
173
            YAHOO.log('Creating the Resize element', 'log', 'ImageCropper');
174
            this._resizeEl = document.createElement('div');
175
            this._resizeEl.className = YAHOO.util.Resize.prototype.CSS_RESIZE;
176
            this._resizeEl.style.position = 'absolute';
177
 
178
            this._resizeEl.innerHTML = '<div class="' + this.CSS_RESIZE_MASK + '"></div>';
179
            this._resizeMaskEl = this._resizeEl.firstChild;
180
            this._wrap.appendChild(this._resizeEl);
181
            this._resizeEl.style.top = this.get('initialXY')[1] + 'px';
182
            this._resizeEl.style.left = this.get('initialXY')[0] + 'px';
183
            this._resizeMaskEl.style.height = Math.floor(this.get('initHeight')) + 'px';
184
            this._resizeMaskEl.style.width = Math.floor(this.get('initWidth')) + 'px';
185
 
186
            this._resize = new YAHOO.util.Resize(this._resizeEl, {
187
                knobHandles: true,
188
                handles: 'all',
189
                draggable: true,
190
                status: this.get('status'),
191
                minWidth: this.get('minWidth'),
192
                minHeight: this.get('minHeight'),
193
                ratio: this.get('ratio'),
194
                autoRatio: this.get('autoRatio'),
195
                height: this.get('initHeight'),
196
                width: this.get('initWidth')
197
            });
198
 
199
            this._setBackgroundImage(this.get('element').getAttribute('src', 2));
200
            this._setBackgroundPosition(-(this.get('initialXY')[0]),  -(this.get('initialXY')[1]));
201
 
202
            this._resize.on('startResize', this._handleStartResizeEvent, this, true);
203
            this._resize.on('endResize', this._handleEndResizeEvent, this, true);
204
            this._resize.on('dragEvent', this._handleDragEvent, this, true);
205
            this._resize.on('beforeResize', this._handleBeforeResizeEvent, this, true);
206
            this._resize.on('resize', this._handleResizeEvent, this, true);
207
            this._resize.dd.on('b4StartDragEvent', this._handleB4DragEvent, this, true);
208
        },
209
 
210
        /**
211
        * @private
212
        * @method _handleMouseOver
213
        * @description Handles the mouseover event
214
        */
215
        _handleMouseOver: function(ev) {
216
            var evType = 'keydown';
217
            if (YAHOO.env.ua.gecko || YAHOO.env.ua.opera) {
218
                evType = 'keypress';
219
            }
220
            if (!this._active) {
221
                this._active = true;
222
                if (this.get('useKeys')) {
223
                    Event.on(document, evType, this._handleKeyPress, this, true);
224
                }
225
            }
226
        },
227
        /**
228
        * @private
229
        * @method _handleMouseOut
230
        * @description Handles the mouseout event
231
        */
232
        _handleMouseOut: function(ev) {
233
            var evType = 'keydown';
234
            if (YAHOO.env.ua.gecko || YAHOO.env.ua.opera) {
235
                evType = 'keypress';
236
            }
237
            this._active = false;
238
            if (this.get('useKeys')) {
239
                Event.removeListener(document, evType, this._handleKeyPress);
240
            }
241
        },
242
 
243
        /**
244
        * @private
245
        * @method _moveEl
246
        * @description Moves the resize element based on the arrow keys
247
        */
248
        _moveEl: function(dir, inc) {
249
            YAHOO.log('Moving the element', 'log', 'ImageCropper');
250
            var t = 0, l = 0,
251
                region = this._setConstraints(),
252
                resize = true;
253
 
254
            switch (dir) {
255
                case 'down':
256
                    t = -(inc);
257
                    if ((region.bottom - inc) < 0) {
258
                        resize = false;
259
                        this._resizeEl.style.top = (region.top + region.bottom) + 'px';
260
                    }
261
                    break;
262
                case 'up':
263
                    t = (inc);
264
                    if ((region.top - inc) < 0) {
265
                        resize = false;
266
                        this._resizeEl.style.top = '0px';
267
                    }
268
                    break;
269
                case 'right':
270
                    l = -(inc);
271
                    if ((region.right - inc) < 0) {
272
                        resize = false;
273
                        this._resizeEl.style.left = (region.left + region.right) + 'px';
274
                    }
275
                    break;
276
                case 'left':
277
                    l = inc;
278
                    if ((region.left - inc) < 0) {
279
                        resize = false;
280
                        this._resizeEl.style.left = '0px';
281
                    }
282
                    break;
283
            }
284
 
285
            if (resize) {
286
                YAHOO.log('Moving via Key Listener: ' + dir, 'log', 'ImageCropper');
287
                this._resizeEl.style.left = (parseInt(this._resizeEl.style.left, 10) - l) + 'px';
288
                this._resizeEl.style.top = (parseInt(this._resizeEl.style.top, 10) - t) + 'px';
289
                this.fireEvent('moveEvent', { target: 'keypress' });
290
            } else {
291
                this._setConstraints();
292
            }
293
            this._syncBackgroundPosition();
294
        },
295
 
296
        /**
297
        * @private
298
        * @method _handleKeyPress
299
        * @description Handles the keypress event
300
        */
301
        _handleKeyPress: function(ev) {
302
            var kc = Event.getCharCode(ev),
303
                stopEvent = false,
304
                inc = ((ev.shiftKey) ? this.get('shiftKeyTick') : this.get('keyTick'));
305
 
306
            switch (kc) {
307
                case 0x25: // left
308
                    this._moveEl('left', inc);
309
                    stopEvent = true;
310
                    break;
311
                case 0x26: // up
312
                    this._moveEl('up', inc);
313
                    stopEvent = true;
314
                    break;
315
                case 0x27: // right
316
                    this._moveEl('right', inc);
317
                    stopEvent = true;
318
                    break;
319
                case 0x28: // down
320
                    this._moveEl('down', inc);
321
                    stopEvent = true;
322
                    break;
323
                default:
324
            }
325
            if (stopEvent) {
326
                Event.preventDefault(ev);
327
            }
328
        },
329
 
330
        /**
331
        * @private
332
        * @method _handleB4DragEvent
333
        * @description Handles the DragDrop b4DragEvent event
334
        */
335
        _handleB4DragEvent: function() {
336
            this._setConstraints();
337
        },
338
 
339
        /**
340
        * @private
341
        * @method _handleDragEvent
342
        * @description Handles the DragDrop DragEvent event
343
        */
344
        _handleDragEvent: function() {
345
            this._syncBackgroundPosition();
346
            this.fireEvent('dragEvent', arguments);
347
            this.fireEvent('moveEvent', { target: 'dragevent' });
348
        },
349
 
350
        /**
351
        * @private
352
        * @method _handleBeforeResizeEvent
353
        * @description Handles the Resize Utilitys beforeResize event
354
        */
355
        _handleBeforeResizeEvent: function(args) {
356
            var region = Dom.getRegion(this.get('element')),
357
                c = this._resize._cache,
358
                ch = this._resize._currentHandle, h = 0, w = 0;
359
 
360
            if (args.top && (args.top < region.top)) {
361
                h = (c.height + c.top) - region.top;
362
                Dom.setY(this._resize.getWrapEl(), region.top);
363
                this._resize.getWrapEl().style.height = h + 'px';
364
                this._resize._cache.height = h;
365
                this._resize._cache.top = region.top;
366
                this._syncBackgroundPosition();
367
                return false;
368
            }
369
            if (args.left && (args.left < region.left)) {
370
                w = (c.width + c.left) - region.left;
371
                Dom.setX(this._resize.getWrapEl(), region.left);
372
                this._resize._cache.left = region.left;
373
                this._resize.getWrapEl().style.width = w + 'px';
374
                this._resize._cache.width = w;
375
                this._syncBackgroundPosition();
376
                return false;
377
            }
378
            if (ch != 'tl' && ch != 'l' && ch != 'bl') {
379
                if (c.left && args.width && ((c.left + args.width) > region.right)) {
380
                    w = (region.right - c.left);
381
                    Dom.setX(this._resize.getWrapEl(), (region.right - w));
382
                    this._resize.getWrapEl().style.width = w + 'px';
383
                    this._resize._cache.left = (region.right - w);
384
                    this._resize._cache.width = w;
385
                    this._syncBackgroundPosition();
386
                    return false;
387
                }
388
            }
389
            if (ch != 't' && ch != 'tr' && ch != 'tl') {
390
                if (c.top && args.height && ((c.top + args.height) > region.bottom)) {
391
                    h = (region.bottom - c.top);
392
                    Dom.setY(this._resize.getWrapEl(), (region.bottom - h));
393
                    this._resize.getWrapEl().style.height = h + 'px';
394
                    this._resize._cache.height = h;
395
                    this._resize._cache.top = (region.bottom - h);
396
                    this._syncBackgroundPosition();
397
                    return false;
398
                }
399
            }
400
        },
401
        /**
402
        * @private
403
        * @method _handleResizeMaskEl
404
        * @description Resizes the inner mask element
405
        */
406
        _handleResizeMaskEl: function() {
407
            var a = this._resize._cache;
408
            this._resizeMaskEl.style.height = Math.floor(a.height) + 'px';
409
            this._resizeMaskEl.style.width = Math.floor(a.width) + 'px';
410
        },
411
        /**
412
        * @private
413
        * @method _handleResizeEvent
414
        * @param Event ev The Resize Utilitys resize event.
415
        * @description Handles the Resize Utilitys Resize event
416
        */
417
        _handleResizeEvent: function(ev) {
418
            this._setConstraints(true);
419
            this._syncBackgroundPosition();
420
            this.fireEvent('resizeEvent', arguments);
421
            this.fireEvent('moveEvent', { target: 'resizeevent' });
422
        },
423
 
424
        /**
425
        * @private
426
        * @method _syncBackgroundPosition
427
        * @description Syncs the packground position of the resize element with the resize elements top and left style position
428
        */
429
        _syncBackgroundPosition: function() {
430
            this._handleResizeMaskEl();
431
            this._setBackgroundPosition(-(parseInt(this._resizeEl.style.left, 10)), -(parseInt(this._resizeEl.style.top, 10)));
432
        },
433
 
434
        /**
435
        * @private
436
        * @method _setBackgroundPosition
437
        * @param Number l The left position
438
        * @param Number t The top position
439
        * @description Sets the background image position to the top and left position
440
        */
441
        _setBackgroundPosition: function(l, t) {
442
            //YAHOO.log('Setting the image background position of the mask to: (' + l + ', ' + t + ')', 'log', 'ImageCropper');
443
            var bl = parseInt(Dom.getStyle(this._resize.get('element'), 'borderLeftWidth'), 10);
444
            var bt = parseInt(Dom.getStyle(this._resize.get('element'), 'borderTopWidth'), 10);
445
            if (isNaN(bl)) {
446
                bl = 0;
447
            }
448
            if (isNaN(bt)) {
449
                bt = 0;
450
            }
451
            var mask = this._resize.getWrapEl().firstChild;
452
            var pos = (l - bl) + 'px ' + (t - bt) + 'px';
453
            this._resizeMaskEl.style.backgroundPosition = pos;
454
        },
455
 
456
        /**
457
        * @private
458
        * @method _setBackgroundImage
459
        * @param String url The url of the image
460
        * @description Sets the background image of the resize element
461
        */
462
        _setBackgroundImage: function(url) {
463
            YAHOO.log('Setting the background image', 'log', 'ImageCropper');
464
            var mask = this._resize.getWrapEl().firstChild;
465
            this._image = url;
466
            mask.style.backgroundImage = 'url(' + url + '#)';
467
        },
468
 
469
        /**
470
        * @private
471
        * @method _handleEndResizeEvent
472
        * @description Handles the Resize Utilitys endResize event
473
        */
474
        _handleEndResizeEvent: function() {
475
            this._setConstraints(true);
476
        },
477
        /**
478
        * @private
479
        * @method _handleStartResizeEvent
480
        * @description Handles the Resize Utilitys startResize event
481
        */
482
        _handleStartResizeEvent: function() {
483
            this._setConstraints(true);
484
 
485
            var h = this._resize._cache.height,
486
                 w = this._resize._cache.width,
487
                 t = parseInt(this._resize.getWrapEl().style.top, 10),
488
                 l = parseInt(this._resize.getWrapEl().style.left, 10),
489
                 maxH = 0, maxW = 0;
490
 
491
            switch (this._resize._currentHandle) {
492
                case 'b':
493
                    maxH = (h + this._resize.dd.bottomConstraint);
494
                    break;
495
                case 'l':
496
                    maxW = (w + this._resize.dd.leftConstraint);
497
                    break;
498
                case 'r':
499
                    maxH = (h + t);
500
                    maxW = (w + this._resize.dd.rightConstraint);
501
                    break;
502
                 case 'br':
503
                     maxH = (h + this._resize.dd.bottomConstraint);
504
                     maxW = (w + this._resize.dd.rightConstraint);
505
                     break;
506
                 case 'tr':
507
                     maxH = (h + t);
508
                     maxW = (w + this._resize.dd.rightConstraint);
509
                     break;
510
 
511
             }
512
 
513
             if (maxH) {
514
                YAHOO.log('Setting the maxHeight on the resize object to: ' + maxH, 'log', 'ImageCropper');
515
                 //this._resize.set('maxHeight', maxH);
516
             }
517
             if (maxW) {
518
                YAHOO.log('Setting the maxWidth on the resize object to: ' + maxW, 'log', 'ImageCropper');
519
                 //this._resize.set('maxWidth', maxW);
520
             }
521
 
522
            this.fireEvent('startResizeEvent', arguments);
523
        },
524
 
525
        /**
526
        * @private
527
        * @method _setConstraints
528
        * @param Boolean inside Used when called from inside a resize event, false by default (dragging)
529
        * @description Set the DragDrop constraints to keep the element inside the crop area.
530
        * @return {Object} Object containing Top, Right, Bottom and Left constraints
531
        */
532
        _setConstraints: function(inside) {
533
            YAHOO.log('Setting Contraints', 'log', 'ImageCropper');
534
            var resize = this._resize;
535
            resize.dd.resetConstraints();
536
            var height = parseInt(resize.get('height'), 10),
537
                width = parseInt(resize.get('width'), 10);
538
            if (inside) {
539
                //Called from inside the resize callback
540
                height = resize._cache.height;
541
                width = resize._cache.width;
542
            }
543
 
544
            //Get the top, right, bottom and left positions
545
            var region = Dom.getRegion(this.get('element'));
546
            //Get the element we are working on
547
            var el = resize.getWrapEl();
548
 
549
            //Get the xy position of it
550
            var xy = Dom.getXY(el);
551
 
552
            //Set left to x minus left
553
            var left = xy[0] - region.left;
554
 
555
            //Set right to right minus x minus width
556
            var right = region.right - xy[0] - width;
557
 
558
            //Set top to y minus top
559
            var top = xy[1] - region.top;
560
 
561
            //Set bottom to bottom minus y minus height
562
            var bottom = region.bottom - xy[1] - height;
563
 
564
            if (top < 0) {
565
                top = 0;
566
            }
567
 
568
            resize.dd.setXConstraint(left, right);
569
            resize.dd.setYConstraint(top, bottom);
570
            YAHOO.log('Constraints: ' + top + ',' + right + ',' + bottom + ',' + left, 'log', 'ImageCropper');
571
 
572
            return {
573
                top: top,
574
                right: right,
575
                bottom: bottom,
576
                left: left
577
            };
578
 
579
 
580
 
581
        },
582
        /**
583
        * @method getCropCoords
584
        * @description Returns the coordinates needed to crop the image
585
        * @return {Object} The top, left, height, width and image url of the image being cropped
586
        */
587
        getCropCoords: function() {
588
            var coords = {
589
                top: parseInt(this._resize.getWrapEl().style.top, 10),
590
                left: parseInt(this._resize.getWrapEl().style.left, 10),
591
                height: this._resize._cache.height,
592
                width: this._resize._cache.width,
593
                image: this._image
594
            };
595
            YAHOO.log('Getting the crop coordinates: ' + Lang.dump(coords), 'log', 'ImageCropper');
596
            return coords;
597
        },
598
        /**
599
        * @method reset
600
        * @description Resets the crop element back to it's original position
601
        * @return {<a href="YAHOO.widget.ImageCropper.html">YAHOO.widget.ImageCropper</a>} The ImageCropper instance
602
        */
603
        reset: function() {
604
            YAHOO.log('Resetting the control', 'log', 'ImageCropper');
605
            this._resize.resize(null, this.get('initHeight'), this.get('initWidth'), 0, 0, true);
606
            this._resizeEl.style.top = this.get('initialXY')[1] + 'px';
607
            this._resizeEl.style.left = this.get('initialXY')[0] + 'px';
608
            this._syncBackgroundPosition();
609
            return this;
610
        },
611
 
612
        /**
613
        * @method getEl
614
        * @description Get the HTML reference for the image element.
615
        * @return {HTMLElement} The image element
616
        */
617
        getEl: function() {
618
            return this.get('element');
619
        },
620
        /**
621
        * @method getResizeEl
622
        * @description Get the HTML reference for the resize element.
623
        * @return {HTMLElement} The resize element
624
        */
625
        getResizeEl: function() {
626
            return this._resizeEl;
627
        },
628
        /**
629
        * @method getWrapEl
630
        * @description Get the HTML reference for the wrap element.
631
        * @return {HTMLElement} The wrap element
632
        */
633
        getWrapEl: function() {
634
            return this._wrap;
635
        },
636
 
637
        /**
638
        * @method getMaskEl
639
        * @description Get the HTML reference for the mask element.
640
        * @return {HTMLElement} The mask element
641
        */
642
        getMaskEl: function() {
643
            return this._mask;
644
        },
645
 
646
        /**
647
        * @method getResizeMaskEl
648
        * @description Get the HTML reference for the resizable object's mask element.
649
        * @return {HTMLElement} The resize objects mask element.
650
        */
651
        getResizeMaskEl: function() {
652
            return this._resizeMaskEl;
653
        },
654
 
655
        /**
656
        * @method getResizeObject
657
        * @description Get the Resize Utility object.
658
        * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
659
        */
660
        getResizeObject: function() {
661
            return this._resize;
662
        },
663
 
664
        /**
665
        * @private
666
        * @method init
667
        * @description The ImageCropper class's initialization method
668
        */
669
        init: function(p_oElement, p_oAttributes) {
670
            YAHOO.log('init', 'info', 'ImageCropper');
671
            Crop.superclass.init.call(this, p_oElement, p_oAttributes);
672
 
673
            var id = p_oElement;
674
 
675
            if (!Lang.isString(id)) {
676
                if (id.tagName && (id.tagName.toLowerCase() == 'img')) {
677
                    id = Dom.generateId(id);
678
                } else {
679
                    YAHOO.log('Element is not an image.', 'error', 'ImageCropper');
680
                    return false;
681
                }
682
            } else {
683
                var el = Dom.get(id);
684
                if (el.tagName && el.tagName.toLowerCase() == 'img') {
685
                    //All good
686
                } else {
687
                    YAHOO.log('Element is not an image.', 'error', 'ImageCropper');
688
                    return false;
689
                }
690
            }
691
 
692
 
693
 
694
            Crop._instances[id] = this;
695
            this._createWrap();
696
            this._createMask();
697
            this._createResize();
698
            this._setConstraints();
699
 
700
        },
701
        /**
702
        * @private
703
        * @method initAttributes
704
        * @description Initializes all of the configuration attributes used to create a croppable element.
705
        * @param {Object} attr Object literal specifying a set of
706
        * configuration attributes used to create the widget.
707
        */
708
 
709
        initAttributes: function(attr) {
710
            Crop.superclass.initAttributes.call(this, attr);
711
 
712
            /**
713
            * @attribute initialXY
714
            * @description Array of the XY position that we need to set the crop element to when we build it. Defaults to [10, 10]
715
            * @type Array
716
            */
717
            this.setAttributeConfig('initialXY', {
718
                validator: YAHOO.lang.isArray,
719
                value: attr.initialXY || [10, 10]
720
            });
721
            /**
722
            * @attribute keyTick
723
            * @description The pixel tick for the arrow keys, defaults to 1
724
            * @type Number
725
            */
726
            this.setAttributeConfig('keyTick', {
727
                validator: YAHOO.lang.isNumber,
728
                value: attr.keyTick || 1
729
            });
730
 
731
            /**
732
            * @attribute shiftKeyTick
733
            * @description The pixel tick for shift + the arrow keys, defaults to 10
734
            * @type Number
735
            */
736
            this.setAttributeConfig('shiftKeyTick', {
737
                validator: YAHOO.lang.isNumber,
738
                value: attr.shiftKeyTick || 10
739
            });
740
 
741
            /**
742
            * @attribute useKeys
743
            * @description Should we use the Arrow keys to position the crop element, defaults to true
744
            * @type Boolean
745
            */
746
            this.setAttributeConfig('useKeys', {
747
                validator: YAHOO.lang.isBoolean,
748
                value: ((attr.useKeys === false) ? false : true)
749
            });
750
 
751
            /**
752
            * @attribute status
753
            * @description Show the Resize Utility status, defaults to true
754
            * @type Boolean
755
            */
756
            this.setAttributeConfig('status', {
757
                validator: YAHOO.lang.isBoolean,
758
                value: ((attr.status === false) ? false : true),
759
                method: function(status) {
760
                    if (this._resize) {
761
                        this._resize.set('status', status);
762
                    }
763
                }
764
            });
765
 
766
            /**
767
            * @attribute minHeight
768
            * @description MinHeight of the crop area, default 50
769
            * @type Number
770
            */
771
            this.setAttributeConfig('minHeight', {
772
                validator: YAHOO.lang.isNumber,
773
                value: attr.minHeight || 50,
774
                method: function(h) {
775
                    if (this._resize) {
776
                        this._resize.set('minHeight', h);
777
                    }
778
                }
779
            });
780
 
781
            /**
782
            * @attribute minWidth
783
            * @description MinWidth of the crop area, default 50.
784
            * @type Number
785
            */
786
            this.setAttributeConfig('minWidth', {
787
                validator: YAHOO.lang.isNumber,
788
                value: attr.minWidth || 50,
789
                method: function(w) {
790
                    if (this._resize) {
791
                        this._resize.set('minWidth', w);
792
                    }
793
                }
794
            });
795
 
796
            /**
797
            * @attribute ratio
798
            * @description Set the ratio config option of the Resize Utlility, default false
799
            * @type Boolean
800
            */
801
            this.setAttributeConfig('ratio', {
802
                validator: YAHOO.lang.isBoolean,
803
                value: attr.ratio || false,
804
                method: function(r) {
805
                    if (this._resize) {
806
                        this._resize.set('ratio', r);
807
                    }
808
                }
809
            });
810
 
811
            /**
812
            * @attribute ratio
813
            * @description Set the autoRatio config option of the Resize Utlility, default true
814
            * @type Boolean
815
            */
816
            this.setAttributeConfig('autoRatio', {
817
                validator: YAHOO.lang.isBoolean,
818
                value: ((attr.autoRatio === false) ? false : true),
819
                method: function(a) {
820
                    if (this._resize) {
821
                        this._resize.set('autoRatio', a);
822
                    }
823
                }
824
            });
825
 
826
            /**
827
            * @attribute initHeight
828
            * @description Set the initlal height of the crop area, defaults to 1/4 of the image height
829
            * @type Number
830
            */
831
            this.setAttributeConfig('initHeight', {
832
                writeOnce: true,
833
                validator: YAHOO.lang.isNumber,
834
                value: attr.initHeight || (this.get('element').height / 4)
835
            });
836
 
837
            /**
838
            * @attribute initWidth
839
            * @description Set the initlal width of the crop area, defaults to 1/4 of the image width
840
            * @type Number
841
            */
842
            this.setAttributeConfig('initWidth', {
843
                validator: YAHOO.lang.isNumber,
844
                writeOnce: true,
845
                value: attr.initWidth || (this.get('element').width / 4)
846
            });
847
 
848
        },
849
        /**
850
        * @method destroy
851
        * @description Destroys the ImageCropper object and all of it's elements & listeners.
852
        */
853
        destroy: function() {
854
            YAHOO.log('Destroying the ImageCropper', 'info', 'ImageCropper');
855
            this._resize.destroy();
856
            this._resizeEl.parentNode.removeChild(this._resizeEl);
857
            this._mask.parentNode.removeChild(this._mask);
858
            Event.purgeElement(this._wrap);
859
            this._wrap.parentNode.replaceChild(this.get('element'), this._wrap);
860
 
861
            //Brutal Object Destroy
862
            for (var i in this) {
863
                if (Lang.hasOwnProperty(this, i)) {
864
                    this[i] = null;
865
                }
866
            }
867
 
868
        },
869
        /**
870
        * @method toString
871
        * @description Returns a string representing the ImageCropper Object.
872
        * @return {String}
873
        */
874
        toString: function() {
875
            if (this.get) {
876
                return 'ImageCropper (#' + this.get('id') + ')';
877
            }
878
            return 'Image Cropper';
879
        }
880
    });
881
 
882
    YAHOO.widget.ImageCropper = Crop;
883
 
884
/**
885
* @event dragEvent
886
* @description Fires when the DragDrop dragEvent
887
* @type YAHOO.util.CustomEvent
888
*/
889
/**
890
* @event startResizeEvent
891
* @description Fires when when a resize action is started.
892
* @type YAHOO.util.CustomEvent
893
*/
894
/**
895
* @event resizeEvent
896
* @description Fires on every element resize.
897
* @type YAHOO.util.CustomEvent
898
*/
899
/**
900
* @event moveEvent
901
* @description Fires on every element move. Inside these methods: _handleKeyPress, _handleDragEvent, _handleResizeEvent
902
* @type YAHOO.util.CustomEvent
903
*/
904
 
905
})();
906
 
907
YAHOO.register("imagecropper", YAHOO.widget.ImageCropper, {version: "2.9.0", build: "2800"});
908
 
909
}, '2.9.0' ,{"requires": ["yui2-yahoo", "yui2-dom", "yui2-event", "yui2-dragdrop", "yui2-element", "yui2-skin-sam-resize", "yui2-resize", "yui2-skin-sam-imagecropper"]});