Projet

Général

Profil

Paste
Télécharger (26,8 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / jquery_update / replace / ui / ui / jquery.ui.resizable.js @ 503b3f7b

1
/*!
2
 * jQuery UI Resizable 1.10.2
3
 * http://jqueryui.com
4
 *
5
 * Copyright 2013 jQuery Foundation and other contributors
6
 * Released under the MIT license.
7
 * http://jquery.org/license
8
 *
9
 * http://api.jqueryui.com/resizable/
10
 *
11
 * Depends:
12
 *        jquery.ui.core.js
13
 *        jquery.ui.mouse.js
14
 *        jquery.ui.widget.js
15
 */
16
(function( $, undefined ) {
17

    
18
function num(v) {
19
        return parseInt(v, 10) || 0;
20
}
21

    
22
function isNumber(value) {
23
        return !isNaN(parseInt(value, 10));
24
}
25

    
26
$.widget("ui.resizable", $.ui.mouse, {
27
        version: "1.10.2",
28
        widgetEventPrefix: "resize",
29
        options: {
30
                alsoResize: false,
31
                animate: false,
32
                animateDuration: "slow",
33
                animateEasing: "swing",
34
                aspectRatio: false,
35
                autoHide: false,
36
                containment: false,
37
                ghost: false,
38
                grid: false,
39
                handles: "e,s,se",
40
                helper: false,
41
                maxHeight: null,
42
                maxWidth: null,
43
                minHeight: 10,
44
                minWidth: 10,
45
                // See #7960
46
                zIndex: 90,
47

    
48
                // callbacks
49
                resize: null,
50
                start: null,
51
                stop: null
52
        },
53
        _create: function() {
54

    
55
                var n, i, handle, axis, hname,
56
                        that = this,
57
                        o = this.options;
58
                this.element.addClass("ui-resizable");
59

    
60
                $.extend(this, {
61
                        _aspectRatio: !!(o.aspectRatio),
62
                        aspectRatio: o.aspectRatio,
63
                        originalElement: this.element,
64
                        _proportionallyResizeElements: [],
65
                        _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
66
                });
67

    
68
                //Wrap the element if it cannot hold child nodes
69
                if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
70

    
71
                        //Create a wrapper element and set the wrapper to the new current internal element
72
                        this.element.wrap(
73
                                $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
74
                                        position: this.element.css("position"),
75
                                        width: this.element.outerWidth(),
76
                                        height: this.element.outerHeight(),
77
                                        top: this.element.css("top"),
78
                                        left: this.element.css("left")
79
                                })
80
                        );
81

    
82
                        //Overwrite the original this.element
83
                        this.element = this.element.parent().data(
84
                                "ui-resizable", this.element.data("ui-resizable")
85
                        );
86

    
87
                        this.elementIsWrapper = true;
88

    
89
                        //Move margins to the wrapper
90
                        this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
91
                        this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
92

    
93
                        //Prevent Safari textarea resize
94
                        this.originalResizeStyle = this.originalElement.css("resize");
95
                        this.originalElement.css("resize", "none");
96

    
97
                        //Push the actual element to our proportionallyResize internal array
98
                        this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
99

    
100
                        // avoid IE jump (hard set the margin)
101
                        this.originalElement.css({ margin: this.originalElement.css("margin") });
102

    
103
                        // fix handlers offset
104
                        this._proportionallyResize();
105

    
106
                }
107

    
108
                this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" });
109
                if(this.handles.constructor === String) {
110

    
111
                        if ( this.handles === "all") {
112
                                this.handles = "n,e,s,w,se,sw,ne,nw";
113
                        }
114

    
115
                        n = this.handles.split(",");
116
                        this.handles = {};
117

    
118
                        for(i = 0; i < n.length; i++) {
119

    
120
                                handle = $.trim(n[i]);
121
                                hname = "ui-resizable-"+handle;
122
                                axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
123

    
124
                                // Apply zIndex to all handles - see #7960
125
                                axis.css({ zIndex: o.zIndex });
126

    
127
                                //TODO : What's going on here?
128
                                if ("se" === handle) {
129
                                        axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
130
                                }
131

    
132
                                //Insert into internal handles object and append to element
133
                                this.handles[handle] = ".ui-resizable-"+handle;
134
                                this.element.append(axis);
135
                        }
136

    
137
                }
138

    
139
                this._renderAxis = function(target) {
140

    
141
                        var i, axis, padPos, padWrapper;
142

    
143
                        target = target || this.element;
144

    
145
                        for(i in this.handles) {
146

    
147
                                if(this.handles[i].constructor === String) {
148
                                        this.handles[i] = $(this.handles[i], this.element).show();
149
                                }
150

    
151
                                //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
152
                                if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
153

    
154
                                        axis = $(this.handles[i], this.element);
155

    
156
                                        //Checking the correct pad and border
157
                                        padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
158

    
159
                                        //The padding type i have to apply...
160
                                        padPos = [ "padding",
161
                                                /ne|nw|n/.test(i) ? "Top" :
162
                                                /se|sw|s/.test(i) ? "Bottom" :
163
                                                /^e$/.test(i) ? "Right" : "Left" ].join("");
164

    
165
                                        target.css(padPos, padWrapper);
166

    
167
                                        this._proportionallyResize();
168

    
169
                                }
170

    
171
                                //TODO: What's that good for? There's not anything to be executed left
172
                                if(!$(this.handles[i]).length) {
173
                                        continue;
174
                                }
175
                        }
176
                };
177

    
178
                //TODO: make renderAxis a prototype function
179
                this._renderAxis(this.element);
180

    
181
                this._handles = $(".ui-resizable-handle", this.element)
182
                        .disableSelection();
183

    
184
                //Matching axis name
185
                this._handles.mouseover(function() {
186
                        if (!that.resizing) {
187
                                if (this.className) {
188
                                        axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
189
                                }
190
                                //Axis, default = se
191
                                that.axis = axis && axis[1] ? axis[1] : "se";
192
                        }
193
                });
194

    
195
                //If we want to auto hide the elements
196
                if (o.autoHide) {
197
                        this._handles.hide();
198
                        $(this.element)
199
                                .addClass("ui-resizable-autohide")
200
                                .mouseenter(function() {
201
                                        if (o.disabled) {
202
                                                return;
203
                                        }
204
                                        $(this).removeClass("ui-resizable-autohide");
205
                                        that._handles.show();
206
                                })
207
                                .mouseleave(function(){
208
                                        if (o.disabled) {
209
                                                return;
210
                                        }
211
                                        if (!that.resizing) {
212
                                                $(this).addClass("ui-resizable-autohide");
213
                                                that._handles.hide();
214
                                        }
215
                                });
216
                }
217

    
218
                //Initialize the mouse interaction
219
                this._mouseInit();
220

    
221
        },
222

    
223
        _destroy: function() {
224

    
225
                this._mouseDestroy();
226

    
227
                var wrapper,
228
                        _destroy = function(exp) {
229
                                $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
230
                                        .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
231
                        };
232

    
233
                //TODO: Unwrap at same DOM position
234
                if (this.elementIsWrapper) {
235
                        _destroy(this.element);
236
                        wrapper = this.element;
237
                        this.originalElement.css({
238
                                position: wrapper.css("position"),
239
                                width: wrapper.outerWidth(),
240
                                height: wrapper.outerHeight(),
241
                                top: wrapper.css("top"),
242
                                left: wrapper.css("left")
243
                        }).insertAfter( wrapper );
244
                        wrapper.remove();
245
                }
246

    
247
                this.originalElement.css("resize", this.originalResizeStyle);
248
                _destroy(this.originalElement);
249

    
250
                return this;
251
        },
252

    
253
        _mouseCapture: function(event) {
254
                var i, handle,
255
                        capture = false;
256

    
257
                for (i in this.handles) {
258
                        handle = $(this.handles[i])[0];
259
                        if (handle === event.target || $.contains(handle, event.target)) {
260
                                capture = true;
261
                        }
262
                }
263

    
264
                return !this.options.disabled && capture;
265
        },
266

    
267
        _mouseStart: function(event) {
268

    
269
                var curleft, curtop, cursor,
270
                        o = this.options,
271
                        iniPos = this.element.position(),
272
                        el = this.element;
273

    
274
                this.resizing = true;
275

    
276
                // bugfix for http://dev.jquery.com/ticket/1749
277
                if ( (/absolute/).test( el.css("position") ) ) {
278
                        el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
279
                } else if (el.is(".ui-draggable")) {
280
                        el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
281
                }
282

    
283
                this._renderProxy();
284

    
285
                curleft = num(this.helper.css("left"));
286
                curtop = num(this.helper.css("top"));
287

    
288
                if (o.containment) {
289
                        curleft += $(o.containment).scrollLeft() || 0;
290
                        curtop += $(o.containment).scrollTop() || 0;
291
                }
292

    
293
                //Store needed variables
294
                this.offset = this.helper.offset();
295
                this.position = { left: curleft, top: curtop };
296
                this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
297
                this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
298
                this.originalPosition = { left: curleft, top: curtop };
299
                this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
300
                this.originalMousePosition = { left: event.pageX, top: event.pageY };
301

    
302
                //Aspect Ratio
303
                this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
304

    
305
                cursor = $(".ui-resizable-" + this.axis).css("cursor");
306
                $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
307

    
308
                el.addClass("ui-resizable-resizing");
309
                this._propagate("start", event);
310
                return true;
311
        },
312

    
313
        _mouseDrag: function(event) {
314

    
315
                //Increase performance, avoid regex
316
                var data,
317
                        el = this.helper, props = {},
318
                        smp = this.originalMousePosition,
319
                        a = this.axis,
320
                        prevTop = this.position.top,
321
                        prevLeft = this.position.left,
322
                        prevWidth = this.size.width,
323
                        prevHeight = this.size.height,
324
                        dx = (event.pageX-smp.left)||0,
325
                        dy = (event.pageY-smp.top)||0,
326
                        trigger = this._change[a];
327

    
328
                if (!trigger) {
329
                        return false;
330
                }
331

    
332
                // Calculate the attrs that will be change
333
                data = trigger.apply(this, [event, dx, dy]);
334

    
335
                // Put this in the mouseDrag handler since the user can start pressing shift while resizing
336
                this._updateVirtualBoundaries(event.shiftKey);
337
                if (this._aspectRatio || event.shiftKey) {
338
                        data = this._updateRatio(data, event);
339
                }
340

    
341
                data = this._respectSize(data, event);
342

    
343
                this._updateCache(data);
344

    
345
                // plugins callbacks need to be called first
346
                this._propagate("resize", event);
347

    
348
                if (this.position.top !== prevTop) {
349
                        props.top = this.position.top + "px";
350
                }
351
                if (this.position.left !== prevLeft) {
352
                        props.left = this.position.left + "px";
353
                }
354
                if (this.size.width !== prevWidth) {
355
                        props.width = this.size.width + "px";
356
                }
357
                if (this.size.height !== prevHeight) {
358
                        props.height = this.size.height + "px";
359
                }
360
                el.css(props);
361

    
362
                if (!this._helper && this._proportionallyResizeElements.length) {
363
                        this._proportionallyResize();
364
                }
365

    
366
                // Call the user callback if the element was resized
367
                if ( ! $.isEmptyObject(props) ) {
368
                        this._trigger("resize", event, this.ui());
369
                }
370

    
371
                return false;
372
        },
373

    
374
        _mouseStop: function(event) {
375

    
376
                this.resizing = false;
377
                var pr, ista, soffseth, soffsetw, s, left, top,
378
                        o = this.options, that = this;
379

    
380
                if(this._helper) {
381

    
382
                        pr = this._proportionallyResizeElements;
383
                        ista = pr.length && (/textarea/i).test(pr[0].nodeName);
384
                        soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
385
                        soffsetw = ista ? 0 : that.sizeDiff.width;
386

    
387
                        s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
388
                        left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
389
                        top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
390

    
391
                        if (!o.animate) {
392
                                this.element.css($.extend(s, { top: top, left: left }));
393
                        }
394

    
395
                        that.helper.height(that.size.height);
396
                        that.helper.width(that.size.width);
397

    
398
                        if (this._helper && !o.animate) {
399
                                this._proportionallyResize();
400
                        }
401
                }
402

    
403
                $("body").css("cursor", "auto");
404

    
405
                this.element.removeClass("ui-resizable-resizing");
406

    
407
                this._propagate("stop", event);
408

    
409
                if (this._helper) {
410
                        this.helper.remove();
411
                }
412

    
413
                return false;
414

    
415
        },
416

    
417
        _updateVirtualBoundaries: function(forceAspectRatio) {
418
                var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
419
                        o = this.options;
420

    
421
                b = {
422
                        minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
423
                        maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
424
                        minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
425
                        maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
426
                };
427

    
428
                if(this._aspectRatio || forceAspectRatio) {
429
                        // We want to create an enclosing box whose aspect ration is the requested one
430
                        // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
431
                        pMinWidth = b.minHeight * this.aspectRatio;
432
                        pMinHeight = b.minWidth / this.aspectRatio;
433
                        pMaxWidth = b.maxHeight * this.aspectRatio;
434
                        pMaxHeight = b.maxWidth / this.aspectRatio;
435

    
436
                        if(pMinWidth > b.minWidth) {
437
                                b.minWidth = pMinWidth;
438
                        }
439
                        if(pMinHeight > b.minHeight) {
440
                                b.minHeight = pMinHeight;
441
                        }
442
                        if(pMaxWidth < b.maxWidth) {
443
                                b.maxWidth = pMaxWidth;
444
                        }
445
                        if(pMaxHeight < b.maxHeight) {
446
                                b.maxHeight = pMaxHeight;
447
                        }
448
                }
449
                this._vBoundaries = b;
450
        },
451

    
452
        _updateCache: function(data) {
453
                this.offset = this.helper.offset();
454
                if (isNumber(data.left)) {
455
                        this.position.left = data.left;
456
                }
457
                if (isNumber(data.top)) {
458
                        this.position.top = data.top;
459
                }
460
                if (isNumber(data.height)) {
461
                        this.size.height = data.height;
462
                }
463
                if (isNumber(data.width)) {
464
                        this.size.width = data.width;
465
                }
466
        },
467

    
468
        _updateRatio: function( data ) {
469

    
470
                var cpos = this.position,
471
                        csize = this.size,
472
                        a = this.axis;
473

    
474
                if (isNumber(data.height)) {
475
                        data.width = (data.height * this.aspectRatio);
476
                } else if (isNumber(data.width)) {
477
                        data.height = (data.width / this.aspectRatio);
478
                }
479

    
480
                if (a === "sw") {
481
                        data.left = cpos.left + (csize.width - data.width);
482
                        data.top = null;
483
                }
484
                if (a === "nw") {
485
                        data.top = cpos.top + (csize.height - data.height);
486
                        data.left = cpos.left + (csize.width - data.width);
487
                }
488

    
489
                return data;
490
        },
491

    
492
        _respectSize: function( data ) {
493

    
494
                var o = this._vBoundaries,
495
                        a = this.axis,
496
                        ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
497
                        isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
498
                        dw = this.originalPosition.left + this.originalSize.width,
499
                        dh = this.position.top + this.size.height,
500
                        cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
501
                if (isminw) {
502
                        data.width = o.minWidth;
503
                }
504
                if (isminh) {
505
                        data.height = o.minHeight;
506
                }
507
                if (ismaxw) {
508
                        data.width = o.maxWidth;
509
                }
510
                if (ismaxh) {
511
                        data.height = o.maxHeight;
512
                }
513

    
514
                if (isminw && cw) {
515
                        data.left = dw - o.minWidth;
516
                }
517
                if (ismaxw && cw) {
518
                        data.left = dw - o.maxWidth;
519
                }
520
                if (isminh && ch) {
521
                        data.top = dh - o.minHeight;
522
                }
523
                if (ismaxh && ch) {
524
                        data.top = dh - o.maxHeight;
525
                }
526

    
527
                // fixing jump error on top/left - bug #2330
528
                if (!data.width && !data.height && !data.left && data.top) {
529
                        data.top = null;
530
                } else if (!data.width && !data.height && !data.top && data.left) {
531
                        data.left = null;
532
                }
533

    
534
                return data;
535
        },
536

    
537
        _proportionallyResize: function() {
538

    
539
                if (!this._proportionallyResizeElements.length) {
540
                        return;
541
                }
542

    
543
                var i, j, borders, paddings, prel,
544
                        element = this.helper || this.element;
545

    
546
                for ( i=0; i < this._proportionallyResizeElements.length; i++) {
547

    
548
                        prel = this._proportionallyResizeElements[i];
549

    
550
                        if (!this.borderDif) {
551
                                this.borderDif = [];
552
                                borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
553
                                paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
554

    
555
                                for ( j = 0; j < borders.length; j++ ) {
556
                                        this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
557
                                }
558
                        }
559

    
560
                        prel.css({
561
                                height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
562
                                width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
563
                        });
564

    
565
                }
566

    
567
        },
568

    
569
        _renderProxy: function() {
570

    
571
                var el = this.element, o = this.options;
572
                this.elementOffset = el.offset();
573

    
574
                if(this._helper) {
575

    
576
                        this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
577

    
578
                        this.helper.addClass(this._helper).css({
579
                                width: this.element.outerWidth() - 1,
580
                                height: this.element.outerHeight() - 1,
581
                                position: "absolute",
582
                                left: this.elementOffset.left +"px",
583
                                top: this.elementOffset.top +"px",
584
                                zIndex: ++o.zIndex //TODO: Don't modify option
585
                        });
586

    
587
                        this.helper
588
                                .appendTo("body")
589
                                .disableSelection();
590

    
591
                } else {
592
                        this.helper = this.element;
593
                }
594

    
595
        },
596

    
597
        _change: {
598
                e: function(event, dx) {
599
                        return { width: this.originalSize.width + dx };
600
                },
601
                w: function(event, dx) {
602
                        var cs = this.originalSize, sp = this.originalPosition;
603
                        return { left: sp.left + dx, width: cs.width - dx };
604
                },
605
                n: function(event, dx, dy) {
606
                        var cs = this.originalSize, sp = this.originalPosition;
607
                        return { top: sp.top + dy, height: cs.height - dy };
608
                },
609
                s: function(event, dx, dy) {
610
                        return { height: this.originalSize.height + dy };
611
                },
612
                se: function(event, dx, dy) {
613
                        return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
614
                },
615
                sw: function(event, dx, dy) {
616
                        return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
617
                },
618
                ne: function(event, dx, dy) {
619
                        return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
620
                },
621
                nw: function(event, dx, dy) {
622
                        return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
623
                }
624
        },
625

    
626
        _propagate: function(n, event) {
627
                $.ui.plugin.call(this, n, [event, this.ui()]);
628
                (n !== "resize" && this._trigger(n, event, this.ui()));
629
        },
630

    
631
        plugins: {},
632

    
633
        ui: function() {
634
                return {
635
                        originalElement: this.originalElement,
636
                        element: this.element,
637
                        helper: this.helper,
638
                        position: this.position,
639
                        size: this.size,
640
                        originalSize: this.originalSize,
641
                        originalPosition: this.originalPosition
642
                };
643
        }
644

    
645
});
646

    
647
/*
648
 * Resizable Extensions
649
 */
650

    
651
$.ui.plugin.add("resizable", "animate", {
652

    
653
        stop: function( event ) {
654
                var that = $(this).data("ui-resizable"),
655
                        o = that.options,
656
                        pr = that._proportionallyResizeElements,
657
                        ista = pr.length && (/textarea/i).test(pr[0].nodeName),
658
                        soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
659
                        soffsetw = ista ? 0 : that.sizeDiff.width,
660
                        style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
661
                        left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
662
                        top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
663

    
664
                that.element.animate(
665
                        $.extend(style, top && left ? { top: top, left: left } : {}), {
666
                                duration: o.animateDuration,
667
                                easing: o.animateEasing,
668
                                step: function() {
669

    
670
                                        var data = {
671
                                                width: parseInt(that.element.css("width"), 10),
672
                                                height: parseInt(that.element.css("height"), 10),
673
                                                top: parseInt(that.element.css("top"), 10),
674
                                                left: parseInt(that.element.css("left"), 10)
675
                                        };
676

    
677
                                        if (pr && pr.length) {
678
                                                $(pr[0]).css({ width: data.width, height: data.height });
679
                                        }
680

    
681
                                        // propagating resize, and updating values for each animation step
682
                                        that._updateCache(data);
683
                                        that._propagate("resize", event);
684

    
685
                                }
686
                        }
687
                );
688
        }
689

    
690
});
691

    
692
$.ui.plugin.add("resizable", "containment", {
693

    
694
        start: function() {
695
                var element, p, co, ch, cw, width, height,
696
                        that = $(this).data("ui-resizable"),
697
                        o = that.options,
698
                        el = that.element,
699
                        oc = o.containment,
700
                        ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
701

    
702
                if (!ce) {
703
                        return;
704
                }
705

    
706
                that.containerElement = $(ce);
707

    
708
                if (/document/.test(oc) || oc === document) {
709
                        that.containerOffset = { left: 0, top: 0 };
710
                        that.containerPosition = { left: 0, top: 0 };
711

    
712
                        that.parentData = {
713
                                element: $(document), left: 0, top: 0,
714
                                width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
715
                        };
716
                }
717

    
718
                // i'm a node, so compute top, left, right, bottom
719
                else {
720
                        element = $(ce);
721
                        p = [];
722
                        $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
723

    
724
                        that.containerOffset = element.offset();
725
                        that.containerPosition = element.position();
726
                        that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
727

    
728
                        co = that.containerOffset;
729
                        ch = that.containerSize.height;
730
                        cw = that.containerSize.width;
731
                        width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
732
                        height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
733

    
734
                        that.parentData = {
735
                                element: ce, left: co.left, top: co.top, width: width, height: height
736
                        };
737
                }
738
        },
739

    
740
        resize: function( event ) {
741
                var woset, hoset, isParent, isOffsetRelative,
742
                        that = $(this).data("ui-resizable"),
743
                        o = that.options,
744
                        co = that.containerOffset, cp = that.position,
745
                        pRatio = that._aspectRatio || event.shiftKey,
746
                        cop = { top:0, left:0 }, ce = that.containerElement;
747

    
748
                if (ce[0] !== document && (/static/).test(ce.css("position"))) {
749
                        cop = co;
750
                }
751

    
752
                if (cp.left < (that._helper ? co.left : 0)) {
753
                        that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
754
                        if (pRatio) {
755
                                that.size.height = that.size.width / that.aspectRatio;
756
                        }
757
                        that.position.left = o.helper ? co.left : 0;
758
                }
759

    
760
                if (cp.top < (that._helper ? co.top : 0)) {
761
                        that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
762
                        if (pRatio) {
763
                                that.size.width = that.size.height * that.aspectRatio;
764
                        }
765
                        that.position.top = that._helper ? co.top : 0;
766
                }
767

    
768
                that.offset.left = that.parentData.left+that.position.left;
769
                that.offset.top = that.parentData.top+that.position.top;
770

    
771
                woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
772
                hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
773

    
774
                isParent = that.containerElement.get(0) === that.element.parent().get(0);
775
                isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
776

    
777
                if(isParent && isOffsetRelative) {
778
                        woset -= that.parentData.left;
779
                }
780

    
781
                if (woset + that.size.width >= that.parentData.width) {
782
                        that.size.width = that.parentData.width - woset;
783
                        if (pRatio) {
784
                                that.size.height = that.size.width / that.aspectRatio;
785
                        }
786
                }
787

    
788
                if (hoset + that.size.height >= that.parentData.height) {
789
                        that.size.height = that.parentData.height - hoset;
790
                        if (pRatio) {
791
                                that.size.width = that.size.height * that.aspectRatio;
792
                        }
793
                }
794
        },
795

    
796
        stop: function(){
797
                var that = $(this).data("ui-resizable"),
798
                        o = that.options,
799
                        co = that.containerOffset,
800
                        cop = that.containerPosition,
801
                        ce = that.containerElement,
802
                        helper = $(that.helper),
803
                        ho = helper.offset(),
804
                        w = helper.outerWidth() - that.sizeDiff.width,
805
                        h = helper.outerHeight() - that.sizeDiff.height;
806

    
807
                if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
808
                        $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
809
                }
810

    
811
                if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
812
                        $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
813
                }
814

    
815
        }
816
});
817

    
818
$.ui.plugin.add("resizable", "alsoResize", {
819

    
820
        start: function () {
821
                var that = $(this).data("ui-resizable"),
822
                        o = that.options,
823
                        _store = function (exp) {
824
                                $(exp).each(function() {
825
                                        var el = $(this);
826
                                        el.data("ui-resizable-alsoresize", {
827
                                                width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
828
                                                left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
829
                                        });
830
                                });
831
                        };
832

    
833
                if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
834
                        if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
835
                        else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
836
                }else{
837
                        _store(o.alsoResize);
838
                }
839
        },
840

    
841
        resize: function (event, ui) {
842
                var that = $(this).data("ui-resizable"),
843
                        o = that.options,
844
                        os = that.originalSize,
845
                        op = that.originalPosition,
846
                        delta = {
847
                                height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
848
                                top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
849
                        },
850

    
851
                        _alsoResize = function (exp, c) {
852
                                $(exp).each(function() {
853
                                        var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
854
                                                css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
855

    
856
                                        $.each(css, function (i, prop) {
857
                                                var sum = (start[prop]||0) + (delta[prop]||0);
858
                                                if (sum && sum >= 0) {
859
                                                        style[prop] = sum || null;
860
                                                }
861
                                        });
862

    
863
                                        el.css(style);
864
                                });
865
                        };
866

    
867
                if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
868
                        $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
869
                }else{
870
                        _alsoResize(o.alsoResize);
871
                }
872
        },
873

    
874
        stop: function () {
875
                $(this).removeData("resizable-alsoresize");
876
        }
877
});
878

    
879
$.ui.plugin.add("resizable", "ghost", {
880

    
881
        start: function() {
882

    
883
                var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
884

    
885
                that.ghost = that.originalElement.clone();
886
                that.ghost
887
                        .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
888
                        .addClass("ui-resizable-ghost")
889
                        .addClass(typeof o.ghost === "string" ? o.ghost : "");
890

    
891
                that.ghost.appendTo(that.helper);
892

    
893
        },
894

    
895
        resize: function(){
896
                var that = $(this).data("ui-resizable");
897
                if (that.ghost) {
898
                        that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
899
                }
900
        },
901

    
902
        stop: function() {
903
                var that = $(this).data("ui-resizable");
904
                if (that.ghost && that.helper) {
905
                        that.helper.get(0).removeChild(that.ghost.get(0));
906
                }
907
        }
908

    
909
});
910

    
911
$.ui.plugin.add("resizable", "grid", {
912

    
913
        resize: function() {
914
                var that = $(this).data("ui-resizable"),
915
                        o = that.options,
916
                        cs = that.size,
917
                        os = that.originalSize,
918
                        op = that.originalPosition,
919
                        a = that.axis,
920
                        grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
921
                        gridX = (grid[0]||1),
922
                        gridY = (grid[1]||1),
923
                        ox = Math.round((cs.width - os.width) / gridX) * gridX,
924
                        oy = Math.round((cs.height - os.height) / gridY) * gridY,
925
                        newWidth = os.width + ox,
926
                        newHeight = os.height + oy,
927
                        isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
928
                        isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
929
                        isMinWidth = o.minWidth && (o.minWidth > newWidth),
930
                        isMinHeight = o.minHeight && (o.minHeight > newHeight);
931

    
932
                o.grid = grid;
933

    
934
                if (isMinWidth) {
935
                        newWidth = newWidth + gridX;
936
                }
937
                if (isMinHeight) {
938
                        newHeight = newHeight + gridY;
939
                }
940
                if (isMaxWidth) {
941
                        newWidth = newWidth - gridX;
942
                }
943
                if (isMaxHeight) {
944
                        newHeight = newHeight - gridY;
945
                }
946

    
947
                if (/^(se|s|e)$/.test(a)) {
948
                        that.size.width = newWidth;
949
                        that.size.height = newHeight;
950
                } else if (/^(ne)$/.test(a)) {
951
                        that.size.width = newWidth;
952
                        that.size.height = newHeight;
953
                        that.position.top = op.top - oy;
954
                } else if (/^(sw)$/.test(a)) {
955
                        that.size.width = newWidth;
956
                        that.size.height = newHeight;
957
                        that.position.left = op.left - ox;
958
                } else {
959
                        that.size.width = newWidth;
960
                        that.size.height = newHeight;
961
                        that.position.top = op.top - oy;
962
                        that.position.left = op.left - ox;
963
                }
964
        }
965

    
966
});
967

    
968
})(jQuery);