source: trunk/themes/default/js/ui/jquery.ui.resizable.js @ 18630

Last change on this file since 18630 was 18630, checked in by rvelices, 12 years ago

feature 2771: upgrade jquery from 1.7.2 to 1.8.2 and jquery.ui from 1.8.16 to 1.9.0
Attention plugins: jquery ui effect script ids change when using combine_script because file names changed ...

File size: 25.6 KB
Line 
1/*!
2 * jQuery UI Resizable 1.9.0
3 * http://jqueryui.com
4 *
5 * Copyright 2012 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$.widget("ui.resizable", $.ui.mouse, {
19        version: "1.9.0",
20        widgetEventPrefix: "resize",
21        options: {
22                alsoResize: false,
23                animate: false,
24                animateDuration: "slow",
25                animateEasing: "swing",
26                aspectRatio: false,
27                autoHide: false,
28                containment: false,
29                ghost: false,
30                grid: false,
31                handles: "e,s,se",
32                helper: false,
33                maxHeight: null,
34                maxWidth: null,
35                minHeight: 10,
36                minWidth: 10,
37                zIndex: 1000
38        },
39        _create: function() {
40
41                var that = this, o = this.options;
42                this.element.addClass("ui-resizable");
43
44                $.extend(this, {
45                        _aspectRatio: !!(o.aspectRatio),
46                        aspectRatio: o.aspectRatio,
47                        originalElement: this.element,
48                        _proportionallyResizeElements: [],
49                        _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
50                });
51
52                //Wrap the element if it cannot hold child nodes
53                if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
54
55                        //Create a wrapper element and set the wrapper to the new current internal element
56                        this.element.wrap(
57                                $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
58                                        position: this.element.css('position'),
59                                        width: this.element.outerWidth(),
60                                        height: this.element.outerHeight(),
61                                        top: this.element.css('top'),
62                                        left: this.element.css('left')
63                                })
64                        );
65
66                        //Overwrite the original this.element
67                        this.element = this.element.parent().data(
68                                "resizable", this.element.data('resizable')
69                        );
70
71                        this.elementIsWrapper = true;
72
73                        //Move margins to the wrapper
74                        this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
75                        this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
76
77                        //Prevent Safari textarea resize
78                        this.originalResizeStyle = this.originalElement.css('resize');
79                        this.originalElement.css('resize', 'none');
80
81                        //Push the actual element to our proportionallyResize internal array
82                        this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
83
84                        // avoid IE jump (hard set the margin)
85                        this.originalElement.css({ margin: this.originalElement.css('margin') });
86
87                        // fix handlers offset
88                        this._proportionallyResize();
89
90                }
91
92                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' });
93                if(this.handles.constructor == String) {
94
95                        if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
96                        var n = this.handles.split(","); this.handles = {};
97
98                        for(var i = 0; i < n.length; i++) {
99
100                                var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
101                                var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
102
103                                // Apply zIndex to all handles - see #7960
104                                axis.css({ zIndex: o.zIndex });
105
106                                //TODO : What's going on here?
107                                if ('se' == handle) {
108                                        axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
109                                };
110
111                                //Insert into internal handles object and append to element
112                                this.handles[handle] = '.ui-resizable-'+handle;
113                                this.element.append(axis);
114                        }
115
116                }
117
118                this._renderAxis = function(target) {
119
120                        target = target || this.element;
121
122                        for(var i in this.handles) {
123
124                                if(this.handles[i].constructor == String)
125                                        this.handles[i] = $(this.handles[i], this.element).show();
126
127                                //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
128                                if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
129
130                                        var axis = $(this.handles[i], this.element), padWrapper = 0;
131
132                                        //Checking the correct pad and border
133                                        padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
134
135                                        //The padding type i have to apply...
136                                        var padPos = [ 'padding',
137                                                /ne|nw|n/.test(i) ? 'Top' :
138                                                /se|sw|s/.test(i) ? 'Bottom' :
139                                                /^e$/.test(i) ? 'Right' : 'Left' ].join("");
140
141                                        target.css(padPos, padWrapper);
142
143                                        this._proportionallyResize();
144
145                                }
146
147                                //TODO: What's that good for? There's not anything to be executed left
148                                if(!$(this.handles[i]).length)
149                                        continue;
150
151                        }
152                };
153
154                //TODO: make renderAxis a prototype function
155                this._renderAxis(this.element);
156
157                this._handles = $('.ui-resizable-handle', this.element)
158                        .disableSelection();
159
160                //Matching axis name
161                this._handles.mouseover(function() {
162                        if (!that.resizing) {
163                                if (this.className)
164                                        var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
165                                //Axis, default = se
166                                that.axis = axis && axis[1] ? axis[1] : 'se';
167                        }
168                });
169
170                //If we want to auto hide the elements
171                if (o.autoHide) {
172                        this._handles.hide();
173                        $(this.element)
174                                .addClass("ui-resizable-autohide")
175                                .mouseenter(function() {
176                                        if (o.disabled) return;
177                                        $(this).removeClass("ui-resizable-autohide");
178                                        that._handles.show();
179                                })
180                                .mouseleave(function(){
181                                        if (o.disabled) return;
182                                        if (!that.resizing) {
183                                                $(this).addClass("ui-resizable-autohide");
184                                                that._handles.hide();
185                                        }
186                                });
187                }
188
189                //Initialize the mouse interaction
190                this._mouseInit();
191
192        },
193
194        _destroy: function() {
195
196                this._mouseDestroy();
197
198                var _destroy = function(exp) {
199                        $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
200                                .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
201                };
202
203                //TODO: Unwrap at same DOM position
204                if (this.elementIsWrapper) {
205                        _destroy(this.element);
206                        var wrapper = this.element;
207                        wrapper.after(
208                                this.originalElement.css({
209                                        position: wrapper.css('position'),
210                                        width: wrapper.outerWidth(),
211                                        height: wrapper.outerHeight(),
212                                        top: wrapper.css('top'),
213                                        left: wrapper.css('left')
214                                })
215                        ).remove();
216                }
217
218                this.originalElement.css('resize', this.originalResizeStyle);
219                _destroy(this.originalElement);
220
221                return this;
222        },
223
224        _mouseCapture: function(event) {
225                var handle = false;
226                for (var i in this.handles) {
227                        if ($(this.handles[i])[0] == event.target) {
228                                handle = true;
229                        }
230                }
231
232                return !this.options.disabled && handle;
233        },
234
235        _mouseStart: function(event) {
236
237                var o = this.options, iniPos = this.element.position(), el = this.element;
238
239                this.resizing = true;
240                this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
241
242                // bugfix for http://dev.jquery.com/ticket/1749
243                if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
244                        el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
245                }
246
247                this._renderProxy();
248
249                var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
250
251                if (o.containment) {
252                        curleft += $(o.containment).scrollLeft() || 0;
253                        curtop += $(o.containment).scrollTop() || 0;
254                }
255
256                //Store needed variables
257                this.offset = this.helper.offset();
258                this.position = { left: curleft, top: curtop };
259                this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
260                this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
261                this.originalPosition = { left: curleft, top: curtop };
262                this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
263                this.originalMousePosition = { left: event.pageX, top: event.pageY };
264
265                //Aspect Ratio
266                this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
267
268                var cursor = $('.ui-resizable-' + this.axis).css('cursor');
269                $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
270
271                el.addClass("ui-resizable-resizing");
272                this._propagate("start", event);
273                return true;
274        },
275
276        _mouseDrag: function(event) {
277
278                //Increase performance, avoid regex
279                var el = this.helper, o = this.options, props = {},
280                        that = this, smp = this.originalMousePosition, a = this.axis;
281
282                var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
283                var trigger = this._change[a];
284                if (!trigger) return false;
285
286                // Calculate the attrs that will be change
287                var data = trigger.apply(this, [event, dx, dy]);
288
289                // Put this in the mouseDrag handler since the user can start pressing shift while resizing
290                this._updateVirtualBoundaries(event.shiftKey);
291                if (this._aspectRatio || event.shiftKey)
292                        data = this._updateRatio(data, event);
293
294                data = this._respectSize(data, event);
295
296                // plugins callbacks need to be called first
297                this._propagate("resize", event);
298
299                el.css({
300                        top: this.position.top + "px", left: this.position.left + "px",
301                        width: this.size.width + "px", height: this.size.height + "px"
302                });
303
304                if (!this._helper && this._proportionallyResizeElements.length)
305                        this._proportionallyResize();
306
307                this._updateCache(data);
308
309                // calling the user callback at the end
310                this._trigger('resize', event, this.ui());
311
312                return false;
313        },
314
315        _mouseStop: function(event) {
316
317                this.resizing = false;
318                var o = this.options, that = this;
319
320                if(this._helper) {
321                        var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
322                                soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
323                                soffsetw = ista ? 0 : that.sizeDiff.width;
324
325                        var s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) },
326                                left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
327                                top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
328
329                        if (!o.animate)
330                                this.element.css($.extend(s, { top: top, left: left }));
331
332                        that.helper.height(that.size.height);
333                        that.helper.width(that.size.width);
334
335                        if (this._helper && !o.animate) this._proportionallyResize();
336                }
337
338                $('body').css('cursor', 'auto');
339
340                this.element.removeClass("ui-resizable-resizing");
341
342                this._propagate("stop", event);
343
344                if (this._helper) this.helper.remove();
345                return false;
346
347        },
348
349        _updateVirtualBoundaries: function(forceAspectRatio) {
350                var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
351
352                b = {
353                        minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
354                        maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
355                        minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
356                        maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
357                };
358
359                if(this._aspectRatio || forceAspectRatio) {
360                        // We want to create an enclosing box whose aspect ration is the requested one
361                        // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
362                        pMinWidth = b.minHeight * this.aspectRatio;
363                        pMinHeight = b.minWidth / this.aspectRatio;
364                        pMaxWidth = b.maxHeight * this.aspectRatio;
365                        pMaxHeight = b.maxWidth / this.aspectRatio;
366
367                        if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
368                        if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
369                        if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
370                        if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
371                }
372                this._vBoundaries = b;
373        },
374
375        _updateCache: function(data) {
376                var o = this.options;
377                this.offset = this.helper.offset();
378                if (isNumber(data.left)) this.position.left = data.left;
379                if (isNumber(data.top)) this.position.top = data.top;
380                if (isNumber(data.height)) this.size.height = data.height;
381                if (isNumber(data.width)) this.size.width = data.width;
382        },
383
384        _updateRatio: function(data, event) {
385
386                var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
387
388                if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
389                else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
390
391                if (a == 'sw') {
392                        data.left = cpos.left + (csize.width - data.width);
393                        data.top = null;
394                }
395                if (a == 'nw') {
396                        data.top = cpos.top + (csize.height - data.height);
397                        data.left = cpos.left + (csize.width - data.width);
398                }
399
400                return data;
401        },
402
403        _respectSize: function(data, event) {
404
405                var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
406                                ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
407                                        isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
408
409                if (isminw) data.width = o.minWidth;
410                if (isminh) data.height = o.minHeight;
411                if (ismaxw) data.width = o.maxWidth;
412                if (ismaxh) data.height = o.maxHeight;
413
414                var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
415                var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
416
417                if (isminw && cw) data.left = dw - o.minWidth;
418                if (ismaxw && cw) data.left = dw - o.maxWidth;
419                if (isminh && ch)       data.top = dh - o.minHeight;
420                if (ismaxh && ch)       data.top = dh - o.maxHeight;
421
422                // fixing jump error on top/left - bug #2330
423                var isNotwh = !data.width && !data.height;
424                if (isNotwh && !data.left && data.top) data.top = null;
425                else if (isNotwh && !data.top && data.left) data.left = null;
426
427                return data;
428        },
429
430        _proportionallyResize: function() {
431
432                var o = this.options;
433                if (!this._proportionallyResizeElements.length) return;
434                var element = this.helper || this.element;
435
436                for (var i=0; i < this._proportionallyResizeElements.length; i++) {
437
438                        var prel = this._proportionallyResizeElements[i];
439
440                        if (!this.borderDif) {
441                                var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
442                                        p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
443
444                                this.borderDif = $.map(b, function(v, i) {
445                                        var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
446                                        return border + padding;
447                                });
448                        }
449
450                        prel.css({
451                                height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
452                                width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
453                        });
454
455                };
456
457        },
458
459        _renderProxy: function() {
460
461                var el = this.element, o = this.options;
462                this.elementOffset = el.offset();
463
464                if(this._helper) {
465
466                        this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
467
468                        // fix ie6 offset TODO: This seems broken
469                        var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
470                        pxyoffset = ( ie6 ? 2 : -1 );
471
472                        this.helper.addClass(this._helper).css({
473                                width: this.element.outerWidth() + pxyoffset,
474                                height: this.element.outerHeight() + pxyoffset,
475                                position: 'absolute',
476                                left: this.elementOffset.left - ie6offset +'px',
477                                top: this.elementOffset.top - ie6offset +'px',
478                                zIndex: ++o.zIndex //TODO: Don't modify option
479                        });
480
481                        this.helper
482                                .appendTo("body")
483                                .disableSelection();
484
485                } else {
486                        this.helper = this.element;
487                }
488
489        },
490
491        _change: {
492                e: function(event, dx, dy) {
493                        return { width: this.originalSize.width + dx };
494                },
495                w: function(event, dx, dy) {
496                        var o = this.options, cs = this.originalSize, sp = this.originalPosition;
497                        return { left: sp.left + dx, width: cs.width - dx };
498                },
499                n: function(event, dx, dy) {
500                        var o = this.options, cs = this.originalSize, sp = this.originalPosition;
501                        return { top: sp.top + dy, height: cs.height - dy };
502                },
503                s: function(event, dx, dy) {
504                        return { height: this.originalSize.height + dy };
505                },
506                se: function(event, dx, dy) {
507                        return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
508                },
509                sw: function(event, dx, dy) {
510                        return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
511                },
512                ne: function(event, dx, dy) {
513                        return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
514                },
515                nw: function(event, dx, dy) {
516                        return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
517                }
518        },
519
520        _propagate: function(n, event) {
521                $.ui.plugin.call(this, n, [event, this.ui()]);
522                (n != "resize" && this._trigger(n, event, this.ui()));
523        },
524
525        plugins: {},
526
527        ui: function() {
528                return {
529                        originalElement: this.originalElement,
530                        element: this.element,
531                        helper: this.helper,
532                        position: this.position,
533                        size: this.size,
534                        originalSize: this.originalSize,
535                        originalPosition: this.originalPosition
536                };
537        }
538
539});
540
541/*
542 * Resizable Extensions
543 */
544
545$.ui.plugin.add("resizable", "alsoResize", {
546
547        start: function (event, ui) {
548                var that = $(this).data("resizable"), o = that.options;
549
550                var _store = function (exp) {
551                        $(exp).each(function() {
552                                var el = $(this);
553                                el.data("resizable-alsoresize", {
554                                        width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
555                                        left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
556                                });
557                        });
558                };
559
560                if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
561                        if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
562                        else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
563                }else{
564                        _store(o.alsoResize);
565                }
566        },
567
568        resize: function (event, ui) {
569                var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
570
571                var delta = {
572                        height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
573                        top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
574                },
575
576                _alsoResize = function (exp, c) {
577                        $(exp).each(function() {
578                                var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 
579                                        css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
580
581                                $.each(css, function (i, prop) {
582                                        var sum = (start[prop]||0) + (delta[prop]||0);
583                                        if (sum && sum >= 0)
584                                                style[prop] = sum || null;
585                                });
586
587                                el.css(style);
588                        });
589                };
590
591                if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
592                        $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
593                }else{
594                        _alsoResize(o.alsoResize);
595                }
596        },
597
598        stop: function (event, ui) {
599                $(this).removeData("resizable-alsoresize");
600        }
601});
602
603$.ui.plugin.add("resizable", "animate", {
604
605        stop: function(event, ui) {
606                var that = $(this).data("resizable"), o = that.options;
607
608                var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
609                                        soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
610                                                soffsetw = ista ? 0 : that.sizeDiff.width;
611
612                var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
613                                        left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
614                                                top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
615
616                that.element.animate(
617                        $.extend(style, top && left ? { top: top, left: left } : {}), {
618                                duration: o.animateDuration,
619                                easing: o.animateEasing,
620                                step: function() {
621
622                                        var data = {
623                                                width: parseInt(that.element.css('width'), 10),
624                                                height: parseInt(that.element.css('height'), 10),
625                                                top: parseInt(that.element.css('top'), 10),
626                                                left: parseInt(that.element.css('left'), 10)
627                                        };
628
629                                        if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
630
631                                        // propagating resize, and updating values for each animation step
632                                        that._updateCache(data);
633                                        that._propagate("resize", event);
634
635                                }
636                        }
637                );
638        }
639
640});
641
642$.ui.plugin.add("resizable", "containment", {
643
644        start: function(event, ui) {
645                var that = $(this).data("resizable"), o = that.options, el = that.element;
646                var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
647                if (!ce) return;
648
649                that.containerElement = $(ce);
650
651                if (/document/.test(oc) || oc == document) {
652                        that.containerOffset = { left: 0, top: 0 };
653                        that.containerPosition = { left: 0, top: 0 };
654
655                        that.parentData = {
656                                element: $(document), left: 0, top: 0,
657                                width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
658                        };
659                }
660
661                // i'm a node, so compute top, left, right, bottom
662                else {
663                        var element = $(ce), p = [];
664                        $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
665
666                        that.containerOffset = element.offset();
667                        that.containerPosition = element.position();
668                        that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
669
670                        var co = that.containerOffset, ch = that.containerSize.height,  cw = that.containerSize.width,
671                                                width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
672
673                        that.parentData = {
674                                element: ce, left: co.left, top: co.top, width: width, height: height
675                        };
676                }
677        },
678
679        resize: function(event, ui) {
680                var that = $(this).data("resizable"), o = that.options,
681                                ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
682                                pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
683
684                if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
685
686                if (cp.left < (that._helper ? co.left : 0)) {
687                        that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
688                        if (pRatio) that.size.height = that.size.width / that.aspectRatio;
689                        that.position.left = o.helper ? co.left : 0;
690                }
691
692                if (cp.top < (that._helper ? co.top : 0)) {
693                        that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
694                        if (pRatio) that.size.width = that.size.height * that.aspectRatio;
695                        that.position.top = that._helper ? co.top : 0;
696                }
697
698                that.offset.left = that.parentData.left+that.position.left;
699                that.offset.top = that.parentData.top+that.position.top;
700
701                var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
702                                        hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
703
704                var isParent = that.containerElement.get(0) == that.element.parent().get(0),
705                        isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));
706
707                if(isParent && isOffsetRelative) woset -= that.parentData.left;
708
709                if (woset + that.size.width >= that.parentData.width) {
710                        that.size.width = that.parentData.width - woset;
711                        if (pRatio) that.size.height = that.size.width / that.aspectRatio;
712                }
713
714                if (hoset + that.size.height >= that.parentData.height) {
715                        that.size.height = that.parentData.height - hoset;
716                        if (pRatio) that.size.width = that.size.height * that.aspectRatio;
717                }
718        },
719
720        stop: function(event, ui){
721                var that = $(this).data("resizable"), o = that.options, cp = that.position,
722                                co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
723
724                var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
725
726                if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
727                        $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
728
729                if (that._helper && !o.animate && (/static/).test(ce.css('position')))
730                        $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
731
732        }
733});
734
735$.ui.plugin.add("resizable", "ghost", {
736
737        start: function(event, ui) {
738
739                var that = $(this).data("resizable"), o = that.options, cs = that.size;
740
741                that.ghost = that.originalElement.clone();
742                that.ghost
743                        .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
744                        .addClass('ui-resizable-ghost')
745                        .addClass(typeof o.ghost == 'string' ? o.ghost : '');
746
747                that.ghost.appendTo(that.helper);
748
749        },
750
751        resize: function(event, ui){
752                var that = $(this).data("resizable"), o = that.options;
753                if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width });
754        },
755
756        stop: function(event, ui){
757                var that = $(this).data("resizable"), o = that.options;
758                if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
759        }
760
761});
762
763$.ui.plugin.add("resizable", "grid", {
764
765        resize: function(event, ui) {
766                var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey;
767                o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
768                var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
769
770                if (/^(se|s|e)$/.test(a)) {
771                        that.size.width = os.width + ox;
772                        that.size.height = os.height + oy;
773                }
774                else if (/^(ne)$/.test(a)) {
775                        that.size.width = os.width + ox;
776                        that.size.height = os.height + oy;
777                        that.position.top = op.top - oy;
778                }
779                else if (/^(sw)$/.test(a)) {
780                        that.size.width = os.width + ox;
781                        that.size.height = os.height + oy;
782                        that.position.left = op.left - ox;
783                }
784                else {
785                        that.size.width = os.width + ox;
786                        that.size.height = os.height + oy;
787                        that.position.top = op.top - oy;
788                        that.position.left = op.left - ox;
789                }
790        }
791
792});
793
794var num = function(v) {
795        return parseInt(v, 10) || 0;
796};
797
798var isNumber = function(value) {
799        return !isNaN(parseInt(value, 10));
800};
801
802})(jQuery);
Note: See TracBrowser for help on using the repository browser.