From b3d574271d6445c471dbe7ee00fba413f50125b6 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Mon, 21 Jan 2013 22:34:36 +0100 Subject: [PATCH 01/97] added comment for example --- source/js/examples/simple_with_no_drop.js | 1 + 1 file changed, 1 insertion(+) diff --git a/source/js/examples/simple_with_no_drop.js b/source/js/examples/simple_with_no_drop.js index 9fa42dc..8ee3cfa 100644 --- a/source/js/examples/simple_with_no_drop.js +++ b/source/js/examples/simple_with_no_drop.js @@ -3,6 +3,7 @@ $(function() { group: 'no-drop', handle: 'i.icon-move', onDragStart: function (item, container, _super) { + // Duplicate items of the no drop area if(!container.options.drop) item.clone().insertAfter(item) _super(item) From c57231e6d858c3241fff126a7aa9d9ab11e88000 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 22 Jan 2013 12:03:59 +0100 Subject: [PATCH 02/97] Better readme --- README.mkd | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/README.mkd b/README.mkd index 54ec98e..b5e9052 100644 --- a/README.mkd +++ b/README.mkd @@ -1,11 +1,18 @@ # jQuery Sortable -jQuery Sortable is a flexible, opinionated sorting plugin. Its aim is to do one thing: sorting +jQuery Sortable is a flexible, opinionated sorting plugin. +It enables items in a list (or table etc.) to be sorted horizontally and vertically using the mouse. +Supports nested lists and pure drag/drop containers. + +jQuery Sortable does not depend on jQuery UI and works well with Twitter's Bootstrap (You can even sort the Bootstrap navigation). + +More information can be found on [http://johnny.github.com/jquery-sortable/](http://johnny.github.com/jquery-sortable/). ## Dependencies -jquery +jquery (>= 1.7.0) ## Development Dependencies -See the Gemfile +jQuery Sortable is developed using [middleman](http://middlemanapp.com/). +A **bundle install** shoud pull in everything needed. From 7bf37da5b263f5bab5bed02ca634ce8d75f4b4fc Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sun, 3 Feb 2013 08:13:33 +0100 Subject: [PATCH 03/97] updated docs for #3, #4 and #5 --- source/index.html.haml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/index.html.haml b/source/index.html.haml index f23af90..a2358c2 100644 --- a/source/index.html.haml +++ b/source/index.html.haml @@ -53,8 +53,8 @@ %a(href="#connected") yourself \. %p - Moreover this plugin assumes, that the placeholder has zero height/width. - This way we can cache the item dimensions. + Moreover this plugin assumes that the placeholder has zero height/width. + As a result, the item dimensions may be cached. %small This might change in the future, if need be. %h3 Compatibility %p @@ -75,6 +75,10 @@ Show it to me! %small With default options. + %p + %span.label.label-info Heads Up! + There is no on-the-fly creation of sublists. + Only list items that contain a sublist are drop targets. %ol.default.vertical %li First %li Second From 7e0be9623baa7322bd9a3ee0b102717ae02daeb2 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 26 Feb 2013 18:05:17 +0100 Subject: [PATCH 04/97] Detect changes of position values and support fixed position. closes #7 --- source/js/jquery-sortable.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 7b85342..da52571 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -274,9 +274,11 @@ return element.closest(this.options.containerSelector).data(pluginName) }, getOffsetParent: function () { - if(this.offsetParent === undefined){ + if(this.offsetParent === undefined || this.offsetParentPositionValue !== this.offsetParent.css('position')){ var i = this.containers.length - 1, offsetParent = this.containers[i].getItemOffsetParent() + + this.offsetParentPositionValue = offsetParent.css('position') while(i--){ if(offsetParent[0] != this.containers[i].getItemOffsetParent()[0]){ @@ -431,7 +433,7 @@ el = this.el // Since el might be empty we have to check el itself and // can not do something like el.children().first().offsetParent() - if(el.css("position") === "relative" || el.css("position") === "absolute") + if(el.css("position") === "relative" || el.css("position") === "absolute" || el.css("position") === "fixed") offsetParent = el else offsetParent = el.offsetParent() From 30065dfeafd37b5887c1db7f9c49444d924b7ab9 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 26 Feb 2013 21:52:37 +0100 Subject: [PATCH 05/97] add touch events. as of yet, it is untested closes #2 --- source/js/jquery-sortable.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index da52571..5de85f5 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -183,8 +183,8 @@ ContainerGroup.prototype = { dragInit: function (e, itemContainer) { - $document.on("mousemove", this.dragProxy) - $document.on("mouseup", this.dropProxy) + $document.on("mousemove.sortable touchmove.sortable", this.dragProxy) + $document.on("mouseup.sortable touchend.sortable", this.dropProxy) // get item to drag this.item = $(e.target).closest(this.options.itemSelector) @@ -219,8 +219,8 @@ drop: function (e) { e.preventDefault() - $document.off("mousemove", this.dragProxy) - $document.off("mouseup", this.dropProxy) + $document.off("mousemove.sortable touchmove.sortable") + $document.off("mouseup.sortable touchend.sortable") if(!this.dragging) return; @@ -464,7 +464,7 @@ this.group.addContainer(this) if(!ignoreChildren) processChildContainers(this.el, this.options.containerSelector, "enable", true) - this.el.on("mousedown", this.handle, this.dragInitProxy) + this.el.on("mousedown.sortable touchstart.sortable", this.handle, this.dragInitProxy) }, disable: function (ignoreChildren) { if(this.options.drop) @@ -472,7 +472,7 @@ if(!ignoreChildren) processChildContainers(this.el, this.options.containerSelector, "disable", true) - this.el.off("mousedown", this.handle, this.dragInitProxy) + this.el.off("mousedown.sortable touchstart.sortable", this.handle, this.dragInitProxy) } } From ae85fa258e25054f59a219813ce482415add932e Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 26 Feb 2013 22:43:08 +0100 Subject: [PATCH 06/97] sniff which events to use for #2 --- source/js/jquery-sortable.js | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 5de85f5..d25d2a2 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -28,7 +28,8 @@ * ========================================================== */ !function ( $, window, undefined){ - var pluginName = 'sortable', + var eventNames, + pluginName = 'sortable', document = window.document, $document = $(document), containerDefaults = { @@ -87,6 +88,20 @@ containerGroups = {}, groupCounter = 0 + if('ontouchstart' in window){ + eventNames = { + start: "touchstart", + end: "touchend", + move: "touchmove" + } + } else { + eventNames = { + start: "mousedown", + end: "mouseup", + move: "mousemove" + } + } + /* * a is Array [left, right, top, bottom] * b is array [left, top] @@ -183,8 +198,8 @@ ContainerGroup.prototype = { dragInit: function (e, itemContainer) { - $document.on("mousemove.sortable touchmove.sortable", this.dragProxy) - $document.on("mouseup.sortable touchend.sortable", this.dropProxy) + $document.on(eventNames.move + ".sortable", this.dragProxy) + $document.on(eventNames.end + ".sortable", this.dropProxy) // get item to drag this.item = $(e.target).closest(this.options.itemSelector) @@ -219,8 +234,8 @@ drop: function (e) { e.preventDefault() - $document.off("mousemove.sortable touchmove.sortable") - $document.off("mouseup.sortable touchend.sortable") + $document.off(eventNames.move + ".sortable") + $document.off(eventNames.end + ".sortable") if(!this.dragging) return; @@ -464,7 +479,7 @@ this.group.addContainer(this) if(!ignoreChildren) processChildContainers(this.el, this.options.containerSelector, "enable", true) - this.el.on("mousedown.sortable touchstart.sortable", this.handle, this.dragInitProxy) + this.el.on(eventNames.start + ".sortable", this.handle, this.dragInitProxy) }, disable: function (ignoreChildren) { if(this.options.drop) @@ -472,7 +487,7 @@ if(!ignoreChildren) processChildContainers(this.el, this.options.containerSelector, "disable", true) - this.el.off("mousedown.sortable touchstart.sortable", this.handle, this.dragInitProxy) + this.el.off(eventNames.start + ".sortable", this.handle, this.dragInitProxy) } } From 32e93d3643a26435f145a9b566443135942f8f67 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Wed, 27 Feb 2013 22:53:33 +0100 Subject: [PATCH 07/97] Remove assumption, that the offsetParent and it's position value does not change. Some cleanup closes #7 --- source/js/jquery-sortable.js | 61 +++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index d25d2a2..3bac9d4 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -178,7 +178,7 @@ this.options = $.extend({}, groupDefaults, options) this.containers = [] this.childGroups = [] - this.scrollProxy = $.proxy(this.scrolled, this) + this.scrolledProxy = $.proxy(this.scrolled, this) this.dragProxy = $.proxy(this.drag, this) this.dropProxy = $.proxy(this.drop, this) if(this.options.parentGroup) @@ -198,8 +198,8 @@ ContainerGroup.prototype = { dragInit: function (e, itemContainer) { - $document.on(eventNames.move + ".sortable", this.dragProxy) - $document.on(eventNames.end + ".sortable", this.dropProxy) + $document.on(eventNames.move + "." + pluginName, this.dragProxy) + $document.on(eventNames.end + "." + pluginName, this.dropProxy) // get item to drag this.item = $(e.target).closest(this.options.itemSelector) @@ -234,8 +234,8 @@ drop: function (e) { e.preventDefault() - $document.off(eventNames.move + ".sortable") - $document.off(eventNames.end + ".sortable") + $document.off(eventNames.move + "." + pluginName) + $document.off(eventNames.end + "." + pluginName) if(!this.dragging) return; @@ -245,7 +245,8 @@ processChildContainers(this.item, this.options.containerSelector, "enable", true) // cleanup - this.deleteDimensions() + this.clearDimensions() + this.clearOffsetParent() this.lastAppendedItem = this.sameResultBox = undefined this.dragging = false }, @@ -289,26 +290,32 @@ return element.closest(this.options.containerSelector).data(pluginName) }, getOffsetParent: function () { - if(this.offsetParent === undefined || this.offsetParentPositionValue !== this.offsetParent.css('position')){ + if(this.offsetParent === undefined){ var i = this.containers.length - 1, offsetParent = this.containers[i].getItemOffsetParent() - - this.offsetParentPositionValue = offsetParent.css('position') - - while(i--){ - if(offsetParent[0] != this.containers[i].getItemOffsetParent()[0]){ - // If every container has the same offset parent, - // use position() which is relative to this parent, - // otherwise use offset() - $document.on("scroll", this.scrolledProxy) - offsetParent = false - break; + + if(!this.options.parentGroup){ + while(i--){ + if(offsetParent[0] != this.containers[i].getItemOffsetParent()[0]){ + // If every container has the same offset parent, + // use position() which is relative to this parent, + // otherwise use offset() + // compare #setDimensions + $document.on("scroll." + pluginName, this.scrolledProxy) + offsetParent = false + break; + } } } + this.offsetParent = offsetParent } return this.offsetParent }, + clearOffsetParent: function () { + this.offsetParent = undefined + $document.off("scroll." + pluginName) + }, setPointer: function (e) { var pointer = { left: e.pageX, @@ -327,26 +334,24 @@ }, addContainer: function (container) { this.containers.push(container); - delete this.containerDimensions }, removeContainer: function (container) { var i = this.containers.indexOf(container) this.containers.remove(i); - delete this.containerDimensions }, scrolled: function (e) { - delete this.containerDimensions + this.containerDimensions = undefined }, - deleteDimensions: function () { - // delete centers in every container and containergroup - delete this.containerDimensions + // Recursively clear container and item dimensions + clearDimensions: function () { + this.containerDimensions = undefined var i = this.containers.length while(i--){ - delete this.containers[i].itemDimensions + this.containers[i].itemDimensions = undefined } i = this.childGroups.length while(i--){ - this.childGroups[i].deleteDimensions() + this.childGroups[i].clearDimensions() } } } @@ -479,7 +484,7 @@ this.group.addContainer(this) if(!ignoreChildren) processChildContainers(this.el, this.options.containerSelector, "enable", true) - this.el.on(eventNames.start + ".sortable", this.handle, this.dragInitProxy) + this.el.on(eventNames.start + "." + pluginName, this.handle, this.dragInitProxy) }, disable: function (ignoreChildren) { if(this.options.drop) @@ -487,7 +492,7 @@ if(!ignoreChildren) processChildContainers(this.el, this.options.containerSelector, "disable", true) - this.el.off(eventNames.start + ".sortable", this.handle, this.dragInitProxy) + this.el.off(eventNames.start + "." + pluginName, this.handle, this.dragInitProxy) } } From 5999d68af2e6e4d4fa16981a2db6b977c2905db9 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Wed, 27 Feb 2013 23:16:01 +0100 Subject: [PATCH 08/97] better scroll behavior for #7 --- source/js/jquery-sortable.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 3bac9d4..2f31454 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -200,6 +200,7 @@ dragInit: function (e, itemContainer) { $document.on(eventNames.move + "." + pluginName, this.dragProxy) $document.on(eventNames.end + "." + pluginName, this.dropProxy) + $document.on("scroll." + pluginName, this.scrolledProxy) // get item to drag this.item = $(e.target).closest(this.options.itemSelector) @@ -236,6 +237,7 @@ $document.off(eventNames.move + "." + pluginName) $document.off(eventNames.end + "." + pluginName) + $document.off("scroll." + pluginName) if(!this.dragging) return; @@ -301,7 +303,6 @@ // use position() which is relative to this parent, // otherwise use offset() // compare #setDimensions - $document.on("scroll." + pluginName, this.scrolledProxy) offsetParent = false break; } @@ -314,7 +315,6 @@ }, clearOffsetParent: function () { this.offsetParent = undefined - $document.off("scroll." + pluginName) }, setPointer: function (e) { var pointer = { @@ -340,7 +340,8 @@ this.containers.remove(i); }, scrolled: function (e) { - this.containerDimensions = undefined + this.clearDimensions() + this.clearOffsetParent() }, // Recursively clear container and item dimensions clearDimensions: function () { From 93a921c47153833531152669295e4ea4b8ad92c6 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Thu, 28 Feb 2013 10:48:34 +0100 Subject: [PATCH 09/97] minor change --- source/js/jquery-sortable-min.js | 29 +++++++++++++++-------------- source/js/jquery-sortable.js | 5 ++++- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/source/js/jquery-sortable-min.js b/source/js/jquery-sortable-min.js index 35350e2..d6827db 100644 --- a/source/js/jquery-sortable-min.js +++ b/source/js/jquery-sortable-min.js @@ -1,14 +1,15 @@ -!function(e,w,j){function s(a,b){var c=Math.max(0,a[0]-b[0],b[0]-a[1]),d=Math.max(0,a[2]-b[1],b[1]-a[3]);return c+d}function t(a,b,c){for(var d=a.length,c=c?"offset":"position";d--;){var o=a[d].el?a[d].el:e(a[d]),g=o[c]();b[d]=[g.left,g.left+o.outerWidth(!0),g.top,g.top+o.outerHeight(!0)]}}function k(a,b){var c=b.offset();return{left:a.left-c.left,top:a.top-c.top}}function u(a,b,c){for(var b=[b.left,b.top],c=c&&[c.left,c.top],d,e=a.length,g=[];e--;)d=a[e],g[e]=[e,s(d,b),c&&s(d,c)];g=g.sort(function(a, -b){return a[1]-b[1]||a[2]-b[2]||a[0]-b[0]});return g[0]}function l(a,b,c,d){a=a.find(b);for(b=a.length;b--;){var e=a.eq(b).data(h);if(e)e[c](d)}}function m(a){this.options=e.extend({},n,a);this.containers=[];this.childGroups=[];this.scrollProxy=e.proxy(this.scrolled,this);this.dragProxy=e.proxy(this.drag,this);this.dropProxy=e.proxy(this.drop,this);this.options.parentGroup?this.options.parentGroup.childGroups.push(this):this.placeholder=e(this.options.placeholder)}function p(a,b){this.el=a;this.childGroups= -[];this.floatRight=!1;this.dragInitProxy=e.proxy(this.dragInit,this);this.options=e.extend({},x,b);this.group=m.get(this.options);this.rootGroup=this.options.rootGroup=this.options.rootGroup||this.group;this.parentGroup=this.options.parentGroup=this.options.parentGroup||this.group;this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;this.enable(!0)}var h="sortable",i=e(w.document),x={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},n={afterMove:function(){},containerSelector:"ol, ul", -handle:"",itemSelector:"li",onDrag:function(a,b){a.css(b)},onDragStart:function(a){a.css({height:a.height(),width:a.width()});a.addClass("dragged");e("body").addClass("dragging")},onDrop:function(a){a.removeClass("dragged").attr("style","");e("body").removeClass("dragging")},placeholder:'
  • ',pullPlaceholder:!0},q={},v=0;Array.prototype.remove=function(a,b){var c=this.slice((b||a)+1||this.length);this.length=0>a?this.length+a:a;return this.push.apply(this,c)};m.get=function(a){q[a.group]|| -(a.group||(a.group=v++),q[a.group]=new m(a));return q[a.group]};m.prototype={dragInit:function(a,b){i.on("mousemove",this.dragProxy);i.on("mouseup",this.dropProxy);this.item=e(a.target).closest(this.options.itemSelector);this.itemContainer=b;this.setPointer(a)},drag:function(a){a.preventDefault();this.dragging||(l(this.item,this.options.containerSelector,"disable",!0),this.options.onDragStart(this.item,this.itemContainer,n.onDragStart),this.dragging=!0);if(this.setPointer(a)){this.options.onDrag(this.item, -k(this.pointer,this.item.offsetParent()),n.onDrag);var b=a.pageX,a=a.pageY,c=this.sameResultBox;(!c||c.top>a||c.bottomb||c.right
  • ',pullPlaceholder:!0},s={},y=0;"ontouchstart"in u?(j="touchstart",k="touchend",l="touchmove"):(j="mousedown",k="mouseup",l="mousemove");Array.prototype.remove=function(a,b){var c=this.slice((b|| +a)+1||this.length);this.length=a<0?this.length+a:a;return this.push.apply(this,c)};o.get=function(a){if(!s[a.group]){if(!a.group)a.group=y++;s[a.group]=new o(a)}return s[a.group]};o.prototype={dragInit:function(a,b){i.on(l+"."+f,this.dragProxy);i.on(k+"."+f,this.dropProxy);i.on("scroll."+f,this.scrolledProxy);this.item=e(a.target).closest(this.options.itemSelector);this.itemContainer=b;this.setPointer(a)},drag:function(a){a.preventDefault();if(!this.dragging){n(this.item,this.options.containerSelector, +"disable",true);this.options.onDragStart(this.item,this.itemContainer,p.onDragStart);this.dragging=true}if(this.setPointer(a)){this.options.onDrag(this.item,m(this.pointer,this.item.offsetParent()),p.onDrag);var b=a.pageX,a=a.pageY,c=this.sameResultBox;(!c||c.top>a||c.bottomb||c.right<=(d[0]+d[1])/2!=this.floatRight){f="before";g.right=g.right-h/2}else g.left=g.left+h/2;this.rootGroup.movePlaceholder(this,c,f,g)},getItemDimensions:function(){if(!this.itemDimensions){this.items=this.el.children(this.rootGroup.options.itemSelector).filter(":not(.dragged)").toArray(); +w(this.items,this.itemDimensions=[])}return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return a.css("position")==="relative"||a.css("position")==="absolute"||a.css("position")==="fixed"?a:a.offsetParent()},getContainerGroup:function(a){var b=e.data(this.items[a],"subContainer");if(b===h){var c=e(this.items[a]).children(this.rootGroup.options.containerSelector),b=false;if(c[0]){b=e.extend({},this.options,{parentGroup:this.group,group:y++});b=c[f](b).data(f).group}e.data(this.items[a], +"subContainer",b)}return b}};var t={enable:function(a){this.options.drop&&this.group.addContainer(this);a||n(this.el,this.options.containerSelector,"enable",true);this.el.on(j+"."+f,this.handle,this.dragInitProxy)},disable:function(a){this.options.drop&&this.group.removeContainer(this);a||n(this.el,this.options.containerSelector,"disable",true);this.el.off(j+"."+f,this.handle,this.dragInitProxy)}};e.extend(r.prototype,t);e.fn[f]=function(a){var b=Array.prototype.slice.call(arguments,1);return this.each(function(){var c= +e(this),d=c.data(f);d&&t[a]?t[a].apply(d,b):!d&&(a===h||typeof a==="object")&&c.data(f,new r(c,a))})}}(jQuery,window); diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 2f31454..b3048f2 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -285,9 +285,12 @@ }, getContainerDimensions: function () { if(!this.containerDimensions) - setDimensions(this.containers, this.containerDimensions = [], !this.getOffsetParent()) + setDimensions(this.getContainers(), this.containerDimensions = [], !this.getOffsetParent()) return this.containerDimensions }, + getContainers: function (element) { // TODO build on this to return containers valid for the currently dragged element + return this.containers + }, getContainer: function (element) { return element.closest(this.options.containerSelector).data(pluginName) }, From b01f51b342efed07f96e02c4c774722111cf0839 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Thu, 28 Feb 2013 20:02:19 +0100 Subject: [PATCH 10/97] support iframes closes #6 --- source/js/jquery-sortable.js | 21 +++++++++++---------- update-pages.sh | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 10 deletions(-) create mode 100755 update-pages.sh diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index b3048f2..ecc1bde 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -30,8 +30,6 @@ !function ( $, window, undefined){ var eventNames, pluginName = 'sortable', - document = window.document, - $document = $(document), containerDefaults = { // If true, items can be dragged from this container drag: true, @@ -198,9 +196,9 @@ ContainerGroup.prototype = { dragInit: function (e, itemContainer) { - $document.on(eventNames.move + "." + pluginName, this.dragProxy) - $document.on(eventNames.end + "." + pluginName, this.dropProxy) - $document.on("scroll." + pluginName, this.scrolledProxy) + this.$document = $(itemContainer.el[0].ownerDocument) + + this.toggleListeners('on') // get item to drag this.item = $(e.target).closest(this.options.itemSelector) @@ -234,10 +232,7 @@ }, drop: function (e) { e.preventDefault() - - $document.off(eventNames.move + "." + pluginName) - $document.off(eventNames.end + "." + pluginName) - $document.off("scroll." + pluginName) + this.toggleListeners('off') if(!this.dragging) return; @@ -346,6 +341,11 @@ this.clearDimensions() this.clearOffsetParent() }, + toggleListeners: function (method) { + this.$document[method](eventNames.move + "." + pluginName, this.dragProxy) + [method](eventNames.end + "." + pluginName, this.dropProxy) + [method]("scroll." + pluginName, this.scrolledProxy) + }, // Recursively clear container and item dimensions clearDimensions: function () { this.containerDimensions = undefined @@ -488,6 +488,7 @@ this.group.addContainer(this) if(!ignoreChildren) processChildContainers(this.el, this.options.containerSelector, "enable", true) + this.el.on(eventNames.start + "." + pluginName, this.handle, this.dragInitProxy) }, disable: function (ignoreChildren) { @@ -511,7 +512,7 @@ */ $.fn[pluginName] = function(methodOrOptions) { var args = Array.prototype.slice.call(arguments, 1) - + return this.each(function(){ var $t = $(this), object = $t.data(pluginName) diff --git a/update-pages.sh b/update-pages.sh new file mode 100755 index 0000000..f1da24a --- /dev/null +++ b/update-pages.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +VERSION=`cat VERSION` + +cp README.mkd .. +./bin/middleman build +git stash +git checkout gh-pages +rm -R js css img +mv build/* . +mv ../README.mkd . +git add . +git commit -am 'Update pages. See main branch for changes' +git push origin gh-pages +git checkout master +git stash pop From 03521c9dac124ad99340f6646e187f9cf761f88e Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 2 Mar 2013 16:26:17 +0100 Subject: [PATCH 11/97] Exclude containers from being valid drop targets for the dragged item closes #1 --- source/js/jquery-sortable.js | 95 +++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 33 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index ecc1bde..4e7a886 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -53,6 +53,12 @@ handle: "", // The css selector of the items itemSelector: "li", + // Check if the dragged item may be inside the container. + // Use with care, since the search for a valid container entails a depth first search + // and may be quite expensive. + isValidTarget: function (item, container) { + return true + }, // Executed at the beginning of a mouse move event. // The Placeholder has not been moved yet onDrag: function (item, position, _super) { @@ -140,7 +146,7 @@ } } - function getNearest(dimensions, pointer, lastPointer) { + function sortByDistanceDesc(dimensions, pointer, lastPointer) { pointer = [pointer.left, pointer.top] lastPointer = lastPointer && [lastPointer.left, lastPointer.top] @@ -153,10 +159,11 @@ distances[i] = [i,d(dim,pointer), lastPointer && d(dim, lastPointer)] } distances = distances.sort(function (a,b) { - return a[1] - b[1] || a[2] - b[2] || a[0] - b[0] + return b[1] - a[1] || b[2] - a[2] || b[0] - a[0] }) - return distances[0] + // last entry is the closest + return distances } function processChildContainers(item, containerSelector, method, ignoreChildren) { @@ -179,10 +186,14 @@ this.scrolledProxy = $.proxy(this.scrolled, this) this.dragProxy = $.proxy(this.drag, this) this.dropProxy = $.proxy(this.drop, this) + if(this.options.parentGroup) this.options.parentGroup.childGroups.push(this) - else + else { this.placeholder = $(this.options.placeholder) + if(!options.isValidTarget) + this.options.isValidTarget = undefined + } } ContainerGroup.get = function (options) { @@ -213,6 +224,7 @@ processChildContainers(this.item, this.options.containerSelector, "disable", true) this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart) + this.item.before(this.placeholder) this.dragging = true } @@ -228,7 +240,7 @@ y = e.pageY, box = this.sameResultBox if(!box || box.top > y || box.bottom < y || box.left > x || box.right < x) - this.processMove() + this.searchValidTarget() }, drop: function (e) { e.preventDefault() @@ -247,26 +259,33 @@ this.lastAppendedItem = this.sameResultBox = undefined this.dragging = false }, - processMove: function (pointer, lastPointer) { + searchValidTarget: function (pointer, lastPointer) { if(!pointer){ pointer = this.relativePointer || this.pointer lastPointer = this.lastRelativePointer || this.lastPointer } - var nearest = getNearest(this.getContainerDimensions(), - pointer, - lastPointer) - - if(nearest && (!nearest[1] || this.options.pullPlaceholder)){ - var index = nearest[0], - container = this.containers[index] - if(!this.getOffsetParent()){ - var offsetParent = container.getItemOffsetParent() - pointer = getRelativePosition(pointer, offsetParent) - lastPointer = getRelativePosition(lastPointer, offsetParent) + var distances = sortByDistanceDesc(this.getContainerDimensions(), + pointer, + lastPointer), + i = distances.length + + while(i--){ + var index = distances[i][0], + distance = distances[i][1] + + if(!distance || this.options.pullPlaceholder){ + var container = this.containers[index] + if(!this.getOffsetParent()){ + var offsetParent = container.getItemOffsetParent() + pointer = getRelativePosition(pointer, offsetParent) + lastPointer = getRelativePosition(lastPointer, offsetParent) + } + if(container.searchValidTarget(pointer, lastPointer)) + return true } - container.processMove(pointer, lastPointer) } + }, movePlaceholder: function (container, item, method, sameResultBox) { var lastAppendedItem = this.lastAppendedItem @@ -395,22 +414,32 @@ rootGroup.placeholder.before(item).detach() rootGroup.options.onDrop(item, this, groupDefaults.onDrop) }, - processMove: function (pointer, lastPointer) { - // get Element right below the pointer - var nearest = getNearest(this.getItemDimensions(), - pointer, - lastPointer), - rootGroup = this.rootGroup - if(!nearest) + searchValidTarget: function (pointer, lastPointer) { + var distances = sortByDistanceDesc(this.getItemDimensions(), + pointer, + lastPointer), + i = distances.length, + rootGroup = this.rootGroup, + validTarget = !rootGroup.options.isValidTarget || + rootGroup.options.isValidTarget(rootGroup.item, this) + + if(!i && validTarget){ rootGroup.movePlaceholder(this, this.el, "append") - else { - var index = nearest[0], - distance = nearest[1] - if(!distance && this.options.nested && this.getContainerGroup(index)) - this.getContainerGroup(index).processMove(pointer, lastPointer) - else - this.movePlaceholder(index, pointer) - } + return true + } else + while(i--){ + var index = distances[i][0], + distance = distances[i][1] + if(!distance && this.options.nested && this.getContainerGroup(index)){ + var found = this.getContainerGroup(index).searchValidTarget(pointer, lastPointer) + if(found) + return true + } + else if(validTarget){ + this.movePlaceholder(index, pointer) + return true + } + } }, movePlaceholder: function (index, pointer) { var item = $(this.items[index]), From 782ca38cb0aaf7b9af0beb854fd9421a4c51862f Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 2 Mar 2013 16:45:19 +0100 Subject: [PATCH 12/97] added example for limiting drop targets --- TODO | 1 - source/_limited_drop_targets.html.haml | 24 ++++++++++++++++++++++ source/index.html.haml | 10 +++++++-- source/js/examples/limited_drop_targets.js | 12 +++++++++++ source/js/jquery-sortable-min.js | 15 -------------- source/layouts/layout.haml | 2 ++ 6 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 source/_limited_drop_targets.html.haml create mode 100644 source/js/examples/limited_drop_targets.js diff --git a/TODO b/TODO index e0881f0..7348f51 100644 --- a/TODO +++ b/TODO @@ -5,5 +5,4 @@ - [ ] if containers, break if distance is 0 - [ ] only calculate top/bottom if vertical and left/right if horizontal - [ ] support placeholder with height/width - - [ ] use own cache for childContainers (jQuery knows all the edge cases) - [ ] calculate item/container dimensions relative to the container => Not all centers have to be recalculated diff --git a/source/_limited_drop_targets.html.haml b/source/_limited_drop_targets.html.haml new file mode 100644 index 0000000..56f8b8d --- /dev/null +++ b/source/_limited_drop_targets.html.haml @@ -0,0 +1,24 @@ +%h2 Connected lists with limited drop targets +.row + .span12.example + %pre(lang="js")= example("limited_drop_targets") + .span4 + %ul + %li + %strong Limit the drop targets + of the dragged item + %p= show_code_button + .span4 + %ol.limited_drop_targets.vertical + = iterate(6,"Item") do |i,name| + - if i % 2 == 0 + %li.highlight= name + - else + %li= name + .span4 + %ol.limited_drop_targets.vertical + = iterate(6,"Item") do |i,name| + - if i >= 3 + %li.highlight= name + - else + %li= name diff --git a/source/index.html.haml b/source/index.html.haml index a2358c2..b23857f 100644 --- a/source/index.html.haml +++ b/source/index.html.haml @@ -80,8 +80,12 @@ There is no on-the-fly creation of sublists. Only list items that contain a sublist are drop targets. %ol.default.vertical - %li First - %li Second + %li + First + %ol + %li + Second + %ol %li Third %ol @@ -127,6 +131,8 @@ = partial "simple_with_no_drop" #nested = partial "nested_with_switch" + #limited-target + = partial "limited_drop_targets" #bootstrap = partial "nested_bootstrap" #table diff --git a/source/js/examples/limited_drop_targets.js b/source/js/examples/limited_drop_targets.js new file mode 100644 index 0000000..5ecda01 --- /dev/null +++ b/source/js/examples/limited_drop_targets.js @@ -0,0 +1,12 @@ +$(function () { + $("ol.limited_drop_targets").sortable({ + group: 'limited_drop_targets', + isValidTarget: function (item, container) { + if(item.is(".highlight")) + return true + else { + return item.parent("ol")[0] == container.el[0] + } + } + }) +}) diff --git a/source/js/jquery-sortable-min.js b/source/js/jquery-sortable-min.js index d6827db..e69de29 100644 --- a/source/js/jquery-sortable-min.js +++ b/source/js/jquery-sortable-min.js @@ -1,15 +0,0 @@ -!function(e,u,h){var j,k,l;function v(a,b){var c=Math.max(0,a[0]-b[0],b[0]-a[1]),d=Math.max(0,a[2]-b[1],b[1]-a[3]);return c+d}function w(a,b,c){for(var d=a.length,c=c?"offset":"position";d--;){var q=a[d].el?a[d].el:e(a[d]),f=q[c]();b[d]=[f.left,f.left+q.outerWidth(!0),f.top,f.top+q.outerHeight(!0)]}}function m(a,b){var c=b.offset();return{left:a.left-c.left,top:a.top-c.top}}function x(a,b,c){for(var b=[b.left,b.top],c=c&&[c.left,c.top],d,e=a.length,f=[];e--;)d=a[e],f[e]=[e,v(d,b),c&&v(d,c)];f=f.sort(function(a, -b){return a[1]-b[1]||a[2]-b[2]||a[0]-b[0]});return f[0]}function n(a,b,c,d){a=a.find(b);for(b=a.length;b--;){var e=a.eq(b).data(f);if(e)e[c](d)}}function o(a){this.options=e.extend({},p,a);this.containers=[];this.childGroups=[];this.scrolledProxy=e.proxy(this.scrolled,this);this.dragProxy=e.proxy(this.drag,this);this.dropProxy=e.proxy(this.drop,this);this.options.parentGroup?this.options.parentGroup.childGroups.push(this):this.placeholder=e(this.options.placeholder)}function r(a,b){this.el=a;this.childGroups= -[];this.floatRight=!1;this.dragInitProxy=e.proxy(this.dragInit,this);this.options=e.extend({},z,b);this.group=o.get(this.options);this.rootGroup=this.options.rootGroup=this.options.rootGroup||this.group;this.parentGroup=this.options.parentGroup=this.options.parentGroup||this.group;this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;this.enable(!0)}var f="sortable",i=e(u.document),z={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},p={afterMove:function(){},containerSelector:"ol, ul", -handle:"",itemSelector:"li",onDrag:function(a,b){a.css(b)},onDragStart:function(a){a.css({height:a.height(),width:a.width()});a.addClass("dragged");e("body").addClass("dragging")},onDrop:function(a){a.removeClass("dragged").attr("style","");e("body").removeClass("dragging")},placeholder:'
  • ',pullPlaceholder:!0},s={},y=0;"ontouchstart"in u?(j="touchstart",k="touchend",l="touchmove"):(j="mousedown",k="mouseup",l="mousemove");Array.prototype.remove=function(a,b){var c=this.slice((b|| -a)+1||this.length);this.length=a<0?this.length+a:a;return this.push.apply(this,c)};o.get=function(a){if(!s[a.group]){if(!a.group)a.group=y++;s[a.group]=new o(a)}return s[a.group]};o.prototype={dragInit:function(a,b){i.on(l+"."+f,this.dragProxy);i.on(k+"."+f,this.dropProxy);i.on("scroll."+f,this.scrolledProxy);this.item=e(a.target).closest(this.options.itemSelector);this.itemContainer=b;this.setPointer(a)},drag:function(a){a.preventDefault();if(!this.dragging){n(this.item,this.options.containerSelector, -"disable",true);this.options.onDragStart(this.item,this.itemContainer,p.onDragStart);this.dragging=true}if(this.setPointer(a)){this.options.onDrag(this.item,m(this.pointer,this.item.offsetParent()),p.onDrag);var b=a.pageX,a=a.pageY,c=this.sameResultBox;(!c||c.top>a||c.bottomb||c.right<=(d[0]+d[1])/2!=this.floatRight){f="before";g.right=g.right-h/2}else g.left=g.left+h/2;this.rootGroup.movePlaceholder(this,c,f,g)},getItemDimensions:function(){if(!this.itemDimensions){this.items=this.el.children(this.rootGroup.options.itemSelector).filter(":not(.dragged)").toArray(); -w(this.items,this.itemDimensions=[])}return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return a.css("position")==="relative"||a.css("position")==="absolute"||a.css("position")==="fixed"?a:a.offsetParent()},getContainerGroup:function(a){var b=e.data(this.items[a],"subContainer");if(b===h){var c=e(this.items[a]).children(this.rootGroup.options.containerSelector),b=false;if(c[0]){b=e.extend({},this.options,{parentGroup:this.group,group:y++});b=c[f](b).data(f).group}e.data(this.items[a], -"subContainer",b)}return b}};var t={enable:function(a){this.options.drop&&this.group.addContainer(this);a||n(this.el,this.options.containerSelector,"enable",true);this.el.on(j+"."+f,this.handle,this.dragInitProxy)},disable:function(a){this.options.drop&&this.group.removeContainer(this);a||n(this.el,this.options.containerSelector,"disable",true);this.el.off(j+"."+f,this.handle,this.dragInitProxy)}};e.extend(r.prototype,t);e.fn[f]=function(a){var b=Array.prototype.slice.call(arguments,1);return this.each(function(){var c= -e(this),d=c.data(f);d&&t[a]?t[a].apply(d,b):!d&&(a===h||typeof a==="object")&&c.data(f,new r(c,a))})}}(jQuery,window); diff --git a/source/layouts/layout.haml b/source/layouts/layout.haml index 4c61216..4625f36 100644 --- a/source/layouts/layout.haml +++ b/source/layouts/layout.haml @@ -26,6 +26,8 @@ %a(href="#handle") Sort handle and limited drag/drop %li %a(href="#nested") Toggable nested lists + %li + %a(href="#limited-target") Limited drop targets %li %a(href="#bootstrap") Sorting a bootstrap menu %li From 216b4bc573329f1423f9196e73b754e4377edb72 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 2 Mar 2013 16:46:50 +0100 Subject: [PATCH 13/97] Release 0.9.7 --- VERSION | 2 +- sortable.jquery.json | 4 ++-- source/js/jquery-sortable-min.js | 15 +++++++++++++++ source/js/jquery-sortable.js | 2 +- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index 85b7c69..c81aa44 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.6 +0.9.7 diff --git a/sortable.jquery.json b/sortable.jquery.json index fb415af..2d04d17 100644 --- a/sortable.jquery.json +++ b/sortable.jquery.json @@ -9,14 +9,14 @@ "drag", "drop" ], - "version": "0.9.6", + "version": "0.9.7", "author": { "name": "Jonas von Andrian" }, "licenses": [ { "type": "BSD-3", - "url": "https://github.com/johnny/jquery-sortable/blob/0.9.6/LICENSE" + "url": "https://github.com/johnny/jquery-sortable/blob/0.9.7/LICENSE" } ], "bugs": "https://github.com/johnny/jquery-sortable/issues", diff --git a/source/js/jquery-sortable-min.js b/source/js/jquery-sortable-min.js index e69de29..2d954e7 100644 --- a/source/js/jquery-sortable-min.js +++ b/source/js/jquery-sortable-min.js @@ -0,0 +1,15 @@ +!function(f,y,i){var j,p,q;function u(a,b){var c=Math.max(0,a[0]-b[0],b[0]-a[1]),d=Math.max(0,a[2]-b[1],b[1]-a[3]);return c+d}function v(a,b,c){for(var d=a.length,c=c?"offset":"position";d--;){var e=a[d].el?a[d].el:f(a[d]),k=e[c]();b[d]=[k.left,k.left+e.outerWidth(!0),k.top,k.top+e.outerHeight(!0)]}}function l(a,b){var c=b.offset();return{left:a.left-c.left,top:a.top-c.top}}function w(a,b,c){for(var b=[b.left,b.top],c=c&&[c.left,c.top],d,e=a.length,f=[];e--;)d=a[e],f[e]=[e,u(d,b),c&&u(d,c)];return f= +f.sort(function(a,b){return b[1]-a[1]||b[2]-a[2]||b[0]-a[0]})}function m(a,b,c,d){a=a.find(b);for(b=a.length;b--;){var e=a.eq(b).data(g);if(e)e[c](d)}}function n(a){this.options=f.extend({},o,a);this.containers=[];this.childGroups=[];this.scrolledProxy=f.proxy(this.scrolled,this);this.dragProxy=f.proxy(this.drag,this);this.dropProxy=f.proxy(this.drop,this);this.options.parentGroup?this.options.parentGroup.childGroups.push(this):(this.placeholder=f(this.options.placeholder),a.isValidTarget||(this.options.isValidTarget= +i))}function r(a,b){this.el=a;this.childGroups=[];this.floatRight=!1;this.dragInitProxy=f.proxy(this.dragInit,this);this.options=f.extend({},z,b);this.group=n.get(this.options);this.rootGroup=this.options.rootGroup=this.options.rootGroup||this.group;this.parentGroup=this.options.parentGroup=this.options.parentGroup||this.group;this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;this.enable(!0)}var g="sortable",z={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},o={afterMove:function(){}, +containerSelector:"ol, ul",handle:"",itemSelector:"li",isValidTarget:function(){return!0},onDrag:function(a,b){a.css(b)},onDragStart:function(a){a.css({height:a.height(),width:a.width()});a.addClass("dragged");f("body").addClass("dragging")},onDrop:function(a){a.removeClass("dragged").attr("style","");f("body").removeClass("dragging")},placeholder:'
  • ',pullPlaceholder:!0},s={},x=0;"ontouchstart"in y?(j="touchstart",p="touchend",q="touchmove"):(j="mousedown",p="mouseup",q="mousemove"); +Array.prototype.remove=function(a,b){var c=this.slice((b||a)+1||this.length);this.length=a<0?this.length+a:a;return this.push.apply(this,c)};n.get=function(a){if(!s[a.group]){if(!a.group)a.group=x++;s[a.group]=new n(a)}return s[a.group]};n.prototype={dragInit:function(a,b){this.$document=f(b.el[0].ownerDocument);this.toggleListeners("on");this.item=f(a.target).closest(this.options.itemSelector);this.itemContainer=b;this.setPointer(a)},drag:function(a){a.preventDefault();if(!this.dragging){m(this.item, +this.options.containerSelector,"disable",true);this.options.onDragStart(this.item,this.itemContainer,o.onDragStart);this.item.before(this.placeholder);this.dragging=true}if(this.setPointer(a)){this.options.onDrag(this.item,l(this.pointer,this.item.offsetParent()),o.onDrag);var b=a.pageX,a=a.pageY,c=this.sameResultBox;(!c||c.top>a||c.bottomb||c.right<=(d[0]+d[1])/2!=this.floatRight){e="before";h.right=h.right-g/2}else h.left=h.left+g/2;this.rootGroup.movePlaceholder(this,c,e,h)},getItemDimensions:function(){if(!this.itemDimensions){this.items=this.el.children(this.rootGroup.options.itemSelector).filter(":not(.dragged)").toArray();v(this.items,this.itemDimensions=[])}return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return a.css("position")=== +"relative"||a.css("position")==="absolute"||a.css("position")==="fixed"?a:a.offsetParent()},getContainerGroup:function(a){var b=f.data(this.items[a],"subContainer");if(b===i){var c=f(this.items[a]).children(this.rootGroup.options.containerSelector),b=false;if(c[0]){b=f.extend({},this.options,{parentGroup:this.group,group:x++});b=c[g](b).data(g).group}f.data(this.items[a],"subContainer",b)}return b}};var t={enable:function(a){this.options.drop&&this.group.addContainer(this);a||m(this.el,this.options.containerSelector, +"enable",true);this.el.on(j+"."+g,this.handle,this.dragInitProxy)},disable:function(a){this.options.drop&&this.group.removeContainer(this);a||m(this.el,this.options.containerSelector,"disable",true);this.el.off(j+"."+g,this.handle,this.dragInitProxy)}};f.extend(r.prototype,t);f.fn[g]=function(a){var b=Array.prototype.slice.call(arguments,1);return this.each(function(){var c=f(this),d=c.data(g);d&&t[a]?t[a].apply(d,b):!d&&(a===i||typeof a==="object")&&c.data(g,new r(c,a))})}}(jQuery,window); diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 4e7a886..5b5b71f 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -1,5 +1,5 @@ /* =================================================== - * jquery-sortable.js v0.9.6 + * jquery-sortable.js v0.9.7 * http://johnny.github.com/jquery-sortable/ * =================================================== * Copyright (c) 2012 Jonas von Andrian From 54d35d8fbadb28dd25ca5c167ab84a68728b09b2 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 2 Mar 2013 16:52:13 +0100 Subject: [PATCH 14/97] added new script to push the version tag --- push-tag.sh | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 push-tag.sh diff --git a/push-tag.sh b/push-tag.sh new file mode 100755 index 0000000..8d135d4 --- /dev/null +++ b/push-tag.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +VERSION=`cat VERSION` + +git tag $VERSION +git push origin --tags From 45d358da03e304b6cc95d7585b5b4e8d5ea8c13e Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Mon, 11 Mar 2013 22:55:28 +0100 Subject: [PATCH 15/97] added onCancel method --- TODO | 1 + source/js/jquery-sortable.js | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/TODO b/TODO index 7348f51..3121870 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,6 @@ - [0/0] bugs - [0/5] consider + - [ ] better name for searchValidTarget - [ ] shortcut on getNearest() - [ ] if items, break if distance is growing again - [ ] if containers, break if distance is 0 diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 5b5b71f..c47d59a 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -59,6 +59,10 @@ isValidTarget: function (item, container) { return true }, + // Executed before onDrop if placeholder is detached. + // This happens if pullPlaceholder is set to false and the drop occurs outside a container. + onCancel: function (item, container, _super) { + }, // Executed at the beginning of a mouse move event. // The Placeholder has not been moved yet onDrag: function (item, position, _super) { @@ -240,7 +244,8 @@ y = e.pageY, box = this.sameResultBox if(!box || box.top > y || box.bottom < y || box.left > x || box.right < x) - this.searchValidTarget() + if(!this.searchValidTarget()) + this.placeholder.detach() }, drop: function (e) { e.preventDefault() @@ -249,8 +254,13 @@ if(!this.dragging) return; - // processing Drop - this.getContainer(this.placeholder).receiveDrop() + // processing Drop, check if placeholder is detached + if(this.placeholder.closest("html")[0]) + this.placeholder.before(this.item).detach() + else + this.options.onCancel(this.item, this.itemContainer, groupDefaults.onCancel) + + this.options.onDrop(this.item, this.getContainer(this.item), groupDefaults.onDrop) processChildContainers(this.item, this.options.containerSelector, "enable", true) // cleanup @@ -406,14 +416,6 @@ this.rootGroup.dragInit(e, this) }, - receiveDrop: function () { - var rootGroup = this.rootGroup, - item = rootGroup.item - - // replace placeholder with current item - rootGroup.placeholder.before(item).detach() - rootGroup.options.onDrop(item, this, groupDefaults.onDrop) - }, searchValidTarget: function (pointer, lastPointer) { var distances = sortByDistanceDesc(this.getItemDimensions(), pointer, From 98b5057ede97b2424229d49bf5a693793f9e16cf Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Mon, 11 Mar 2013 23:09:55 +0100 Subject: [PATCH 16/97] added alternative clearer event names --- source/index.html.haml | 2 ++ source/js/jquery-sortable.js | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/source/index.html.haml b/source/index.html.haml index b23857f..eb54752 100644 --- a/source/index.html.haml +++ b/source/index.html.haml @@ -211,6 +211,8 @@ ( uses native dnd events) %li %a(href="http://jqueryui.com/demos/sortable/") jQuery UI sortable + %li + %a(href="http://dbushell.github.com/Nestable/") Nestable (requires no jQuery UI) %li %a(href="http://mjsarfatti.com/sandbox/nestedSortable/") nestedSortable (an extension of jQuery UI) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index c47d59a..025df17 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -98,15 +98,15 @@ if('ontouchstart' in window){ eventNames = { - start: "touchstart", - end: "touchend", - move: "touchmove" + start: "touchstart.sortable", + end: "touchend.sortable touchcancel.sortable", + move: "touchmove.sortable" } } else { eventNames = { - start: "mousedown", - end: "mouseup", - move: "mousemove" + start: "mousedown.sortable", + end: "mouseup.sortable", + move: "mousemove.sortable" } } @@ -371,9 +371,9 @@ this.clearOffsetParent() }, toggleListeners: function (method) { - this.$document[method](eventNames.move + "." + pluginName, this.dragProxy) - [method](eventNames.end + "." + pluginName, this.dropProxy) - [method]("scroll." + pluginName, this.scrolledProxy) + this.$document[method](eventNames.move, this.dragProxy) + [method](eventNames.end, this.dropProxy) + [method]("scroll.sortable", this.scrolledProxy) }, // Recursively clear container and item dimensions clearDimensions: function () { @@ -520,7 +520,7 @@ if(!ignoreChildren) processChildContainers(this.el, this.options.containerSelector, "enable", true) - this.el.on(eventNames.start + "." + pluginName, this.handle, this.dragInitProxy) + this.el.on(eventNames.start, this.handle, this.dragInitProxy) }, disable: function (ignoreChildren) { if(this.options.drop) @@ -528,7 +528,7 @@ if(!ignoreChildren) processChildContainers(this.el, this.options.containerSelector, "disable", true) - this.el.off(eventNames.start + "." + pluginName, this.handle, this.dragInitProxy) + this.el.off(eventNames.start, this.handle, this.dragInitProxy) } } From a16d08d1a7e1737f1d62469b90bbe01d7110dadc Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 12 Mar 2013 22:53:20 +0100 Subject: [PATCH 17/97] Added serialization capabilities Methods that return a jQuery object are prefixed with $ --- source/js/jquery-sortable.js | 80 ++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 025df17..243f55e 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -45,7 +45,7 @@ }, // end container defaults groupDefaults = { // This is executed after the placeholder has been moved. - afterMove: function (placeholder, container) { + afterMove: function ($placeholder, container) { }, // The css selector of the containers containerSelector: "ol, ul", @@ -56,34 +56,34 @@ // Check if the dragged item may be inside the container. // Use with care, since the search for a valid container entails a depth first search // and may be quite expensive. - isValidTarget: function (item, container) { + isValidTarget: function ($item, container) { return true }, // Executed before onDrop if placeholder is detached. // This happens if pullPlaceholder is set to false and the drop occurs outside a container. - onCancel: function (item, container, _super) { + onCancel: function ($item, container, _super) { }, // Executed at the beginning of a mouse move event. // The Placeholder has not been moved yet - onDrag: function (item, position, _super) { - item.css(position) + onDrag: function ($item, position, _super) { + $item.css(position) }, // Called after the drag has been started, // that is the mouse button is beeing held down and // the mouse is moving. // The container is the closest initialized container. // Therefore it might not be the container, that actually contains the item. - onDragStart: function (item, container, _super) { - item.css({ - height: item.height(), - width: item.width() + onDragStart: function ($item, container, _super) { + $item.css({ + height: $item.height(), + width: $item.width() }) - item.addClass("dragged") + $item.addClass("dragged") $("body").addClass("dragging") }, // Called when the mouse button is beeing released - onDrop: function (item, container, _super) { - item.removeClass("dragged").attr("style","") + onDrop: function ($item, container, _super) { + $item.removeClass("dragged").attr("style","") $("body").removeClass("dragging") }, // Template for the placeholder. Can be any valid jQuery input @@ -91,7 +91,18 @@ placeholder: '
  • ', // If true, the position of the placeholder is calculated on every mousemove. // If false, it is only calculated when the mouse is above a container. - pullPlaceholder: true + pullPlaceholder: true, + // Specifies serialization of the container group. + // The pair $parent/$children is either container/items or item/subcontainers + serialize: function ($parent, $children, parentIsContainer) { + var result = $.extend({}, $parent.data()) + + if($children[0]) + result.children = $children + delete result.sortable + + return result + } }, // end group defaults containerGroups = {}, groupCounter = 0 @@ -286,7 +297,7 @@ if(!distance || this.options.pullPlaceholder){ var container = this.containers[index] - if(!this.getOffsetParent()){ + if(!this.$getOffsetParent()){ var offsetParent = container.getItemOffsetParent() pointer = getRelativePosition(pointer, offsetParent) lastPointer = getRelativePosition(lastPointer, offsetParent) @@ -309,16 +320,13 @@ }, getContainerDimensions: function () { if(!this.containerDimensions) - setDimensions(this.getContainers(), this.containerDimensions = [], !this.getOffsetParent()) + setDimensions(this.containers, this.containerDimensions = [], !this.$getOffsetParent()) return this.containerDimensions }, - getContainers: function (element) { // TODO build on this to return containers valid for the currently dragged element - return this.containers - }, getContainer: function (element) { return element.closest(this.options.containerSelector).data(pluginName) }, - getOffsetParent: function () { + $getOffsetParent: function () { if(this.offsetParent === undefined){ var i = this.containers.length - 1, offsetParent = this.containers[i].getItemOffsetParent() @@ -349,8 +357,8 @@ top: e.pageY } - if(this.getOffsetParent()){ - var relativePointer = getRelativePosition(pointer, this.getOffsetParent()) + if(this.$getOffsetParent()){ + var relativePointer = getRelativePosition(pointer, this.$getOffsetParent()) this.lastRelativePointer = this.relativePointer this.relativePointer = relativePointer } @@ -477,8 +485,7 @@ }, getItemDimensions: function () { if(!this.itemDimensions){ - this.items = this.el.children(this.rootGroup.options.itemSelector) - .filter(":not(.dragged)").toArray() + this.items = this.$getChildren(this.el, "item").filter(":not(.dragged)").get() setDimensions(this.items, this.itemDimensions = []) } return this.itemDimensions @@ -497,7 +504,7 @@ getContainerGroup: function (index) { var childGroup = $.data(this.items[index], "subContainer") if( childGroup === undefined){ - var childContainers = $(this.items[index]).children(this.rootGroup.options.containerSelector) + var childContainers = this.$getChildren(this.items[index], "container") childGroup = false if(childContainers[0]){ @@ -510,6 +517,19 @@ $.data(this.items[index], "subContainer", childGroup) } return childGroup + }, + $getChildren: function (parent, type) { + return $(parent).children(this.rootGroup.options[type + "Selector"]) + }, + _serialize: function (parent, isContainer) { + var that = this, + childType = isContainer ? "item" : "container", + + children = this.$getChildren(parent, childType).map(function () { + return that._serialize($(this), !isContainer) + }).get() + + return this.rootGroup.options.serialize(parent, children, isContainer) } } @@ -529,6 +549,9 @@ processChildContainers(this.el, this.options.containerSelector, "disable", true) this.el.off(eventNames.start, this.handle, this.dragInitProxy) + }, + serialize: function () { + return this._serialize(this.el, true) } } @@ -543,15 +566,18 @@ */ $.fn[pluginName] = function(methodOrOptions) { var args = Array.prototype.slice.call(arguments, 1) - - return this.each(function(){ + + return this.map(function(){ var $t = $(this), object = $t.data(pluginName) + if(object && API[methodOrOptions]) - API[methodOrOptions].apply(object, args) + return API[methodOrOptions].apply(object, args) || this else if(!object && (methodOrOptions === undefined || typeof methodOrOptions === "object")) $t.data(pluginName, new Container($t, methodOrOptions)) + + return this }); }; From c1b8298fa7ecf87d0555a4bbc8c10e3ca06561a8 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 12 Mar 2013 23:26:03 +0100 Subject: [PATCH 18/97] added example for serialization --- source/_limited_drop_targets.html.haml | 6 ++++++ source/js/examples/limited_drop_targets.js | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/source/_limited_drop_targets.html.haml b/source/_limited_drop_targets.html.haml index 56f8b8d..0a72c42 100644 --- a/source/_limited_drop_targets.html.haml +++ b/source/_limited_drop_targets.html.haml @@ -7,7 +7,13 @@ %li %strong Limit the drop targets of the dragged item + %li + Customize + %strong serialization + of the lists %p= show_code_button + %h3 Serialize result + %pre#serialize_output .span4 %ol.limited_drop_targets.vertical = iterate(6,"Item") do |i,name| diff --git a/source/js/examples/limited_drop_targets.js b/source/js/examples/limited_drop_targets.js index 5ecda01..bc63587 100644 --- a/source/js/examples/limited_drop_targets.js +++ b/source/js/examples/limited_drop_targets.js @@ -1,5 +1,5 @@ $(function () { - $("ol.limited_drop_targets").sortable({ + var group = $("ol.limited_drop_targets").sortable({ group: 'limited_drop_targets', isValidTarget: function (item, container) { if(item.is(".highlight")) @@ -7,6 +7,13 @@ $(function () { else { return item.parent("ol")[0] == container.el[0] } + }, + onDrop: function (item, container, _super) { + $('#serialize_output').text(group.sortable("serialize").get().join("\n")) + _super(item, container) + }, + serialize: function (parent, children, isContainer) { + return isContainer ? children.join() : parent.text() } }) }) From 135f4a021f84dc74f3f86b5bf482267e33aaf2f7 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 12 Mar 2013 23:33:43 +0100 Subject: [PATCH 19/97] added API entry for serialize --- source/index.html.haml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/index.html.haml b/source/index.html.haml index eb54752..bb76bef 100644 --- a/source/index.html.haml +++ b/source/index.html.haml @@ -172,6 +172,14 @@ %h3 %code .sortable("disable") %p Disable all instantiated sortables in the set of matched elements + %h3 + %code .sortable("serialize") + %p + Serialize all selected containers. Returns a + %code jQuery + object . Use + %code .get() + to retrieve the array, if needed. %h2#group-options Group options %table.table.table-striped.table-bordered.docs %thead From a983b877b6485681e08253ffb695c78ddd8aea80 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 12 Mar 2013 23:38:44 +0100 Subject: [PATCH 20/97] Release 0.9.8 --- VERSION | 2 +- build.sh | 1 - sortable.jquery.json | 4 ++-- source/js/jquery-sortable-min.js | 31 ++++++++++++++++--------------- source/js/jquery-sortable.js | 2 +- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/VERSION b/VERSION index c81aa44..e3e1807 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.7 +0.9.8 diff --git a/build.sh b/build.sh index c1d8d5b..0ca19f6 100755 --- a/build.sh +++ b/build.sh @@ -5,7 +5,6 @@ VERSION=`cat VERSION` cp README.mkd .. ./bin/middleman build git commit -am "Release $VERSION" -git push origin git checkout gh-pages rm -R js css img mv build/* . diff --git a/sortable.jquery.json b/sortable.jquery.json index 2d04d17..05e4379 100644 --- a/sortable.jquery.json +++ b/sortable.jquery.json @@ -9,14 +9,14 @@ "drag", "drop" ], - "version": "0.9.7", + "version": "0.9.8", "author": { "name": "Jonas von Andrian" }, "licenses": [ { "type": "BSD-3", - "url": "https://github.com/johnny/jquery-sortable/blob/0.9.7/LICENSE" + "url": "https://github.com/johnny/jquery-sortable/blob/0.9.8/LICENSE" } ], "bugs": "https://github.com/johnny/jquery-sortable/issues", diff --git a/source/js/jquery-sortable-min.js b/source/js/jquery-sortable-min.js index 2d954e7..3ee8910 100644 --- a/source/js/jquery-sortable-min.js +++ b/source/js/jquery-sortable-min.js @@ -1,15 +1,16 @@ -!function(f,y,i){var j,p,q;function u(a,b){var c=Math.max(0,a[0]-b[0],b[0]-a[1]),d=Math.max(0,a[2]-b[1],b[1]-a[3]);return c+d}function v(a,b,c){for(var d=a.length,c=c?"offset":"position";d--;){var e=a[d].el?a[d].el:f(a[d]),k=e[c]();b[d]=[k.left,k.left+e.outerWidth(!0),k.top,k.top+e.outerHeight(!0)]}}function l(a,b){var c=b.offset();return{left:a.left-c.left,top:a.top-c.top}}function w(a,b,c){for(var b=[b.left,b.top],c=c&&[c.left,c.top],d,e=a.length,f=[];e--;)d=a[e],f[e]=[e,u(d,b),c&&u(d,c)];return f= -f.sort(function(a,b){return b[1]-a[1]||b[2]-a[2]||b[0]-a[0]})}function m(a,b,c,d){a=a.find(b);for(b=a.length;b--;){var e=a.eq(b).data(g);if(e)e[c](d)}}function n(a){this.options=f.extend({},o,a);this.containers=[];this.childGroups=[];this.scrolledProxy=f.proxy(this.scrolled,this);this.dragProxy=f.proxy(this.drag,this);this.dropProxy=f.proxy(this.drop,this);this.options.parentGroup?this.options.parentGroup.childGroups.push(this):(this.placeholder=f(this.options.placeholder),a.isValidTarget||(this.options.isValidTarget= -i))}function r(a,b){this.el=a;this.childGroups=[];this.floatRight=!1;this.dragInitProxy=f.proxy(this.dragInit,this);this.options=f.extend({},z,b);this.group=n.get(this.options);this.rootGroup=this.options.rootGroup=this.options.rootGroup||this.group;this.parentGroup=this.options.parentGroup=this.options.parentGroup||this.group;this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;this.enable(!0)}var g="sortable",z={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},o={afterMove:function(){}, -containerSelector:"ol, ul",handle:"",itemSelector:"li",isValidTarget:function(){return!0},onDrag:function(a,b){a.css(b)},onDragStart:function(a){a.css({height:a.height(),width:a.width()});a.addClass("dragged");f("body").addClass("dragging")},onDrop:function(a){a.removeClass("dragged").attr("style","");f("body").removeClass("dragging")},placeholder:'
  • ',pullPlaceholder:!0},s={},x=0;"ontouchstart"in y?(j="touchstart",p="touchend",q="touchmove"):(j="mousedown",p="mouseup",q="mousemove"); -Array.prototype.remove=function(a,b){var c=this.slice((b||a)+1||this.length);this.length=a<0?this.length+a:a;return this.push.apply(this,c)};n.get=function(a){if(!s[a.group]){if(!a.group)a.group=x++;s[a.group]=new n(a)}return s[a.group]};n.prototype={dragInit:function(a,b){this.$document=f(b.el[0].ownerDocument);this.toggleListeners("on");this.item=f(a.target).closest(this.options.itemSelector);this.itemContainer=b;this.setPointer(a)},drag:function(a){a.preventDefault();if(!this.dragging){m(this.item, -this.options.containerSelector,"disable",true);this.options.onDragStart(this.item,this.itemContainer,o.onDragStart);this.item.before(this.placeholder);this.dragging=true}if(this.setPointer(a)){this.options.onDrag(this.item,l(this.pointer,this.item.offsetParent()),o.onDrag);var b=a.pageX,a=a.pageY,c=this.sameResultBox;(!c||c.top>a||c.bottomb||c.right<=(d[0]+d[1])/2!=this.floatRight){e="before";h.right=h.right-g/2}else h.left=h.left+g/2;this.rootGroup.movePlaceholder(this,c,e,h)},getItemDimensions:function(){if(!this.itemDimensions){this.items=this.el.children(this.rootGroup.options.itemSelector).filter(":not(.dragged)").toArray();v(this.items,this.itemDimensions=[])}return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return a.css("position")=== -"relative"||a.css("position")==="absolute"||a.css("position")==="fixed"?a:a.offsetParent()},getContainerGroup:function(a){var b=f.data(this.items[a],"subContainer");if(b===i){var c=f(this.items[a]).children(this.rootGroup.options.containerSelector),b=false;if(c[0]){b=f.extend({},this.options,{parentGroup:this.group,group:x++});b=c[g](b).data(g).group}f.data(this.items[a],"subContainer",b)}return b}};var t={enable:function(a){this.options.drop&&this.group.addContainer(this);a||m(this.el,this.options.containerSelector, -"enable",true);this.el.on(j+"."+g,this.handle,this.dragInitProxy)},disable:function(a){this.options.drop&&this.group.removeContainer(this);a||m(this.el,this.options.containerSelector,"disable",true);this.el.off(j+"."+g,this.handle,this.dragInitProxy)}};f.extend(r.prototype,t);f.fn[g]=function(a){var b=Array.prototype.slice.call(arguments,1);return this.each(function(){var c=f(this),d=c.data(g);d&&t[a]?t[a].apply(d,b):!d&&(a===i||typeof a==="object")&&c.data(g,new r(c,a))})}}(jQuery,window); +!function(e,y,h){var k,p,q;function u(a,b){var c=Math.max(0,a[0]-b[0],b[0]-a[1]),d=Math.max(0,a[2]-b[1],b[1]-a[3]);return c+d}function v(a,b,c){for(var d=a.length,c=c?"offset":"position";d--;){var f=a[d].el?a[d].el:e(a[d]),l=f[c]();b[d]=[l.left,l.left+f.outerWidth(!0),l.top,l.top+f.outerHeight(!0)]}}function m(a,b){var c=b.offset();return{left:a.left-c.left,top:a.top-c.top}}function w(a,b,c){for(var b=[b.left,b.top],c=c&&[c.left,c.top],d,f=a.length,e=[];f--;)d=a[f],e[f]=[f,u(d,b),c&&u(d,c)];return e= +e.sort(function(a,b){return b[1]-a[1]||b[2]-a[2]||b[0]-a[0]})}function n(a,b,c,d){a=a.find(b);for(b=a.length;b--;){var f=a.eq(b).data(i);if(f)f[c](d)}}function o(a){this.options=e.extend({},j,a);this.containers=[];this.childGroups=[];this.scrolledProxy=e.proxy(this.scrolled,this);this.dragProxy=e.proxy(this.drag,this);this.dropProxy=e.proxy(this.drop,this);this.options.parentGroup?this.options.parentGroup.childGroups.push(this):(this.placeholder=e(this.options.placeholder),a.isValidTarget||(this.options.isValidTarget= +h))}function r(a,b){this.el=a;this.childGroups=[];this.floatRight=!1;this.dragInitProxy=e.proxy(this.dragInit,this);this.options=e.extend({},z,b);this.group=o.get(this.options);this.rootGroup=this.options.rootGroup=this.options.rootGroup||this.group;this.parentGroup=this.options.parentGroup=this.options.parentGroup||this.group;this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;this.enable(!0)}var i="sortable",z={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},j={afterMove:function(){}, +containerSelector:"ol, ul",handle:"",itemSelector:"li",isValidTarget:function(){return!0},onCancel:function(){},onDrag:function(a,b){a.css(b)},onDragStart:function(a){a.css({height:a.height(),width:a.width()});a.addClass("dragged");e("body").addClass("dragging")},onDrop:function(a){a.removeClass("dragged").attr("style","");e("body").removeClass("dragging")},placeholder:'
  • ',pullPlaceholder:!0,serialize:function(a,b){var c=e.extend({},a.data());b[0]&&(c.children=b);delete c.sortable; +return c}},s={},x=0;"ontouchstart"in y?(k="touchstart.sortable",p="touchend.sortable touchcancel.sortable",q="touchmove.sortable"):(k="mousedown.sortable",p="mouseup.sortable",q="mousemove.sortable");Array.prototype.remove=function(a,b){var c=this.slice((b||a)+1||this.length);this.length=a<0?this.length+a:a;return this.push.apply(this,c)};o.get=function(a){if(!s[a.group]){if(!a.group)a.group=x++;s[a.group]=new o(a)}return s[a.group]};o.prototype={dragInit:function(a,b){this.$document=e(b.el[0].ownerDocument); +this.toggleListeners("on");this.item=e(a.target).closest(this.options.itemSelector);this.itemContainer=b;this.setPointer(a)},drag:function(a){a.preventDefault();if(!this.dragging){n(this.item,this.options.containerSelector,"disable",true);this.options.onDragStart(this.item,this.itemContainer,j.onDragStart);this.item.before(this.placeholder);this.dragging=true}if(this.setPointer(a)){this.options.onDrag(this.item,m(this.pointer,this.item.offsetParent()),j.onDrag);var b=a.pageX,a=a.pageY,c=this.sameResultBox; +if(!c||c.top>a||c.bottomb||c.right<=(d[0]+d[1])/2!=this.floatRight){f="before";g.right=g.right-h/2}else g.left=g.left+h/2;this.rootGroup.movePlaceholder(this,c,f,g)},getItemDimensions:function(){if(!this.itemDimensions){this.items=this.$getChildren(this.el, +"item").filter(":not(.dragged)").get();v(this.items,this.itemDimensions=[])}return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return a.css("position")==="relative"||a.css("position")==="absolute"||a.css("position")==="fixed"?a:a.offsetParent()},getContainerGroup:function(a){var b=e.data(this.items[a],"subContainer");if(b===h){var c=this.$getChildren(this.items[a],"container"),b=false;if(c[0]){b=e.extend({},this.options,{parentGroup:this.group,group:x++});b=c[i](b).data(i).group}e.data(this.items[a], +"subContainer",b)}return b},$getChildren:function(a,b){return e(a).children(this.rootGroup.options[b+"Selector"])},_serialize:function(a,b){var c=this,d=this.$getChildren(a,b?"item":"container").map(function(){return c._serialize(e(this),!b)}).get();return this.rootGroup.options.serialize(a,d,b)}};var t={enable:function(a){this.options.drop&&this.group.addContainer(this);a||n(this.el,this.options.containerSelector,"enable",true);this.el.on(k,this.handle,this.dragInitProxy)},disable:function(a){this.options.drop&& +this.group.removeContainer(this);a||n(this.el,this.options.containerSelector,"disable",true);this.el.off(k,this.handle,this.dragInitProxy)},serialize:function(){return this._serialize(this.el,true)}};e.extend(r.prototype,t);e.fn[i]=function(a){var b=Array.prototype.slice.call(arguments,1);return this.map(function(){var c=e(this),d=c.data(i);if(d&&t[a])return t[a].apply(d,b)||this;!d&&(a===h||typeof a==="object")&&c.data(i,new r(c,a));return this})}}(jQuery,window); diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 243f55e..fc75b59 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -1,5 +1,5 @@ /* =================================================== - * jquery-sortable.js v0.9.7 + * jquery-sortable.js v0.9.8 * http://johnny.github.com/jquery-sortable/ * =================================================== * Copyright (c) 2012 Jonas von Andrian From d8997d555de128fd76e6760f98172661d23788e6 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 12 Mar 2013 23:45:22 +0100 Subject: [PATCH 21/97] added changelog --- CHANGELOG | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CHANGELOG diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..4c323ee --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,5 @@ +[0.9.8] Added Serialization + Added onCancel + +[0.9.7] Support iFrame and Touch events + Better behavior if the CSS position changes \ No newline at end of file From f0680d848b5fffc7adb807c2ceb6fe03d5a0ccb1 Mon Sep 17 00:00:00 2001 From: Joaquin Date: Mon, 25 Mar 2013 11:09:53 +0100 Subject: [PATCH 22/97] Do not modify array prototype unnecesarily If possible do not augment the built in prototypes, but if we are going to do it at least do it checking if it is already implemented so that we do not remove crush current implementations and also if it's possible we should do it with the ES5 Object.defineProperty and setting the property as `enumerable: false` For the moment I just changed the function to operate standalone --- source/js/jquery-sortable.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index fc75b59..38a4766 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -131,10 +131,10 @@ return x+y; } - Array.prototype.remove = function(from, to) { - var rest = this.slice((to || from) + 1 || this.length); - this.length = from < 0 ? this.length + from : from; - return this.push.apply(this, rest); + function remove(array, from, to) { + var rest = array.slice((to || from) + 1 || array.length); + array.length = from < 0 ? array.length + from : from; + return array.push.apply(array, rest); } function setDimensions(array, dimensions, useOffset) { @@ -372,7 +372,7 @@ }, removeContainer: function (container) { var i = this.containers.indexOf(container) - this.containers.remove(i); + remove(this.containers, i); }, scrolled: function (e) { this.clearDimensions() From 23a0b10f9eae123ddf1425aeff73419cd1039124 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Fri, 29 Mar 2013 12:15:40 +0100 Subject: [PATCH 23/97] add gzipped file size --- .gitignore | 1 + config.rb | 2 ++ source/index.html.haml | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 88d3fb2..cbaf437 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ /.emacs-project /.irbrc *_out +*.gz diff --git a/config.rb b/config.rb index 127ef2b..2ec07b7 100644 --- a/config.rb +++ b/config.rb @@ -100,6 +100,8 @@ def iterate(length, label = "Item", &block) file.puts closure.compile(updated_file) end + `gzip -c source/js/jquery-sortable-min.js > source/js/jquery-sortable-min.js.gz` + manifest = 'sortable.jquery.json' content = File.read(manifest).gsub(/("version": "|blob\/)[\d\.]+/, '\1' + VERSION) File.open(manifest, 'w') do |file| diff --git a/source/index.html.haml b/source/index.html.haml index bb76bef..383ee62 100644 --- a/source/index.html.haml +++ b/source/index.html.haml @@ -15,7 +15,7 @@ Download %a(href="js/jquery-sortable-min.js") minified version - (#{(File.size("source/js/jquery-sortable-min.js")/100.0).round / 10.0} kb) + (#{(File.size("source/js/jquery-sortable-min.js")/100.0).round / 10.0} kb, gzipped ~#{(File.size("source/js/jquery-sortable-min.js.gz")/100.0).round / 10.0} kb) #features .page-header %h1 Features From 841049e5a437cda80768f0f9536d8c770c5630b1 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 2 Apr 2013 14:41:04 +0200 Subject: [PATCH 24/97] serialize respects exclude --- source/js/jquery-sortable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index fc75b59..7f3c9d8 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -525,7 +525,7 @@ var that = this, childType = isContainer ? "item" : "container", - children = this.$getChildren(parent, childType).map(function () { + children = this.$getChildren(parent, childType).not(this.options.exclude).map(function () { return that._serialize($(this), !isContainer) }).get() From 3898aca7ce11ab6f62c39dea11d34fb2c5699add Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 6 Apr 2013 17:37:29 +0200 Subject: [PATCH 25/97] added example to demonstrate changing the position of the dragged item --- source/js/examples/simple_with_animation.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source/js/examples/simple_with_animation.js b/source/js/examples/simple_with_animation.js index cffdf70..4e6cf71 100644 --- a/source/js/examples/simple_with_animation.js +++ b/source/js/examples/simple_with_animation.js @@ -1,4 +1,6 @@ $(function () { + var adjustment + $("ol.simple_with_animation").sortable({ group: 'simple_with_animation', pullPlaceholder: false, @@ -11,6 +13,23 @@ $(function () { clonedItem.detach() _super(item) }) + }, + onDragStart: function ($item, container, _super) { + var offset = $item.offset(), + pointer = container.rootGroup.pointer + + adjustment = { + left: pointer.left - offset.left, + top: pointer.top - offset.top + } + + _super($item, container) + }, + onDrag: function ($item, position) { + $item.css({ + left: position.left - adjustment.left, + top: position.top - adjustment.top + }) } }) }) From c85b82298d41d70929fd8cf04ded44d1dbca233b Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 6 Apr 2013 17:46:06 +0200 Subject: [PATCH 26/97] added comments to provide hint which callback does what --- source/js/examples/simple_with_animation.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/js/examples/simple_with_animation.js b/source/js/examples/simple_with_animation.js index 4e6cf71..f4311c9 100644 --- a/source/js/examples/simple_with_animation.js +++ b/source/js/examples/simple_with_animation.js @@ -4,6 +4,7 @@ $(function () { $("ol.simple_with_animation").sortable({ group: 'simple_with_animation', pullPlaceholder: false, + // animation on drop onDrop: function (item, targetContainer, _super) { var clonedItem = $('
  • ').css({height: 0}) item.before(clonedItem) @@ -14,6 +15,8 @@ $(function () { _super(item) }) }, + + // set item relative to cursor position onDragStart: function ($item, container, _super) { var offset = $item.offset(), pointer = container.rootGroup.pointer From 089a808b358d5ff961016446136be7ef25e18813 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 30 Apr 2013 22:10:43 +0200 Subject: [PATCH 27/97] fix bug in development use removeAttr --- config.rb | 4 ++++ source/index.html.haml | 2 +- source/js/jquery-sortable.js | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/config.rb b/config.rb index 2ec07b7..764ce94 100644 --- a/config.rb +++ b/config.rb @@ -76,6 +76,10 @@ def iterate(length, label = "Item", &block) out end.join end + + def file_kb(name) + (File.size(name)/100.0).round / 10.0 if File.exists?(name) + end end set :css_dir, 'css' diff --git a/source/index.html.haml b/source/index.html.haml index 383ee62..f146610 100644 --- a/source/index.html.haml +++ b/source/index.html.haml @@ -15,7 +15,7 @@ Download %a(href="js/jquery-sortable-min.js") minified version - (#{(File.size("source/js/jquery-sortable-min.js")/100.0).round / 10.0} kb, gzipped ~#{(File.size("source/js/jquery-sortable-min.js.gz")/100.0).round / 10.0} kb) + (#{file_kb("source/js/jquery-sortable-min.js")} kb, gzipped ~#{file_kb("source/js/jquery-sortable-min.js.gz")} kb) #features .page-header %h1 Features diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 18b2dea..5301402 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -83,7 +83,7 @@ }, // Called when the mouse button is beeing released onDrop: function ($item, container, _super) { - $item.removeClass("dragged").attr("style","") + $item.removeClass("dragged").removeAttr("style") $("body").removeClass("dragging") }, // Template for the placeholder. Can be any valid jQuery input From e63b75b0c0e5bbf9469708c7c3d78378a6fe90f4 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 30 Apr 2013 22:37:32 +0200 Subject: [PATCH 28/97] add new option: tolerance --- source/_limited_drop_targets.html.haml | 2 ++ source/js/examples/limited_drop_targets.js | 3 ++- source/js/jquery-sortable.js | 10 +++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/source/_limited_drop_targets.html.haml b/source/_limited_drop_targets.html.haml index 0a72c42..060893f 100644 --- a/source/_limited_drop_targets.html.haml +++ b/source/_limited_drop_targets.html.haml @@ -11,6 +11,8 @@ Customize %strong serialization of the lists + %li + Decrease sort sensitivity %p= show_code_button %h3 Serialize result %pre#serialize_output diff --git a/source/js/examples/limited_drop_targets.js b/source/js/examples/limited_drop_targets.js index bc63587..068c436 100644 --- a/source/js/examples/limited_drop_targets.js +++ b/source/js/examples/limited_drop_targets.js @@ -14,6 +14,7 @@ $(function () { }, serialize: function (parent, children, isContainer) { return isContainer ? children.join() : parent.text() - } + }, + tolerance: 6 }) }) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 5301402..0e23c02 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -102,7 +102,9 @@ delete result.sortable return result - } + }, + // Set tolerance while dragging. Positive values will decrease sensitivity. + tolerance: 0 }, // end group defaults containerGroups = {}, groupCounter = 0 @@ -253,8 +255,10 @@ var x = e.pageX, y = e.pageY, - box = this.sameResultBox - if(!box || box.top > y || box.bottom < y || box.left > x || box.right < x) + box = this.sameResultBox, + t = this.options.tolerance + + if(!box || box.top - t > y || box.bottom + t < y || box.left - t > x || box.right + t < x) if(!this.searchValidTarget()) this.placeholder.detach() }, From d6076f5437454d2b426babe06fd36eec5def7af2 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Wed, 1 May 2013 21:27:32 +0200 Subject: [PATCH 29/97] cleanup --- source/js/jquery-sortable.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 0e23c02..82d8c2b 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -245,9 +245,7 @@ this.dragging = true } - if(!this.setPointer(e)) - return; - + this.setPointer(e) // place item under the cursor this.options.onDrag(this.item, getRelativePosition(this.pointer, this.item.offsetParent()), @@ -369,7 +367,6 @@ this.lastPointer = this.pointer this.pointer = pointer - return true }, addContainer: function (container) { this.containers.push(container); From 64bbc61fb79b21ddaadce2fcfe489458bb41b1ff Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Wed, 1 May 2013 21:28:07 +0200 Subject: [PATCH 30/97] add distance option --- source/_limited_drop_targets.html.haml | 7 ++++++- source/js/examples/limited_drop_targets.js | 3 ++- source/js/jquery-sortable.js | 10 ++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/source/_limited_drop_targets.html.haml b/source/_limited_drop_targets.html.haml index 060893f..314908a 100644 --- a/source/_limited_drop_targets.html.haml +++ b/source/_limited_drop_targets.html.haml @@ -12,7 +12,12 @@ %strong serialization of the lists %li - Decrease sort sensitivity + Decrease sort + %strong sensitivity + %li + Start dragging after a + %strong distance + has been met %p= show_code_button %h3 Serialize result %pre#serialize_output diff --git a/source/js/examples/limited_drop_targets.js b/source/js/examples/limited_drop_targets.js index 068c436..e342292 100644 --- a/source/js/examples/limited_drop_targets.js +++ b/source/js/examples/limited_drop_targets.js @@ -15,6 +15,7 @@ $(function () { serialize: function (parent, children, isContainer) { return isContainer ? children.join() : parent.text() }, - tolerance: 6 + tolerance: 6, + distance: 10 }) }) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 82d8c2b..4d1a0e8 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -49,6 +49,7 @@ }, // The css selector of the containers containerSelector: "ol, ul", + distance: 0, // The css selector of the drag handle handle: "", // The css selector of the items @@ -238,6 +239,9 @@ e.preventDefault() if(!this.dragging){ + if(!this.distanceMet(e)) + return + processChildContainers(this.item, this.options.containerSelector, "disable", true) this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart) @@ -368,6 +372,12 @@ this.lastPointer = this.pointer this.pointer = pointer }, + distanceMet: function (e) { + return (Math.max( + Math.abs(this.pointer.left - e.pageX), + Math.abs(this.pointer.top - e.pageY) + ) >= this.options.distance) + }, addContainer: function (container) { this.containers.push(container); }, From 3dfab4fbbff408cb4fa39889bade105cae4c4c42 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Wed, 1 May 2013 21:33:35 +0200 Subject: [PATCH 31/97] update Changelog --- CHANGELOG | 4 ++++ source/js/jquery-sortable.js | 1 + 2 files changed, 5 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 4c323ee..671c69d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +[0.9.8] Added options tolerance and distance + Do not modify Array.prototype (by Joakin) + serialize respects exclude option + [0.9.8] Added Serialization Added onCancel diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 4d1a0e8..1ead239 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -49,6 +49,7 @@ }, // The css selector of the containers containerSelector: "ol, ul", + // Distance the mouse has to travel to start dragging distance: 0, // The css selector of the drag handle handle: "", From 5388ae98e5b81aeb421498941e79d5e7505d0747 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Wed, 1 May 2013 21:34:42 +0200 Subject: [PATCH 32/97] Release 0.9.9 --- VERSION | 2 +- sortable.jquery.json | 4 ++-- source/js/jquery-sortable-min.js | 27 ++++++++++++++------------- source/js/jquery-sortable.js | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/VERSION b/VERSION index e3e1807..7e310ba 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.8 +0.9.9 diff --git a/sortable.jquery.json b/sortable.jquery.json index 05e4379..df6c3b0 100644 --- a/sortable.jquery.json +++ b/sortable.jquery.json @@ -9,14 +9,14 @@ "drag", "drop" ], - "version": "0.9.8", + "version": "0.9.9", "author": { "name": "Jonas von Andrian" }, "licenses": [ { "type": "BSD-3", - "url": "https://github.com/johnny/jquery-sortable/blob/0.9.8/LICENSE" + "url": "https://github.com/johnny/jquery-sortable/blob/0.9.9/LICENSE" } ], "bugs": "https://github.com/johnny/jquery-sortable/issues", diff --git a/source/js/jquery-sortable-min.js b/source/js/jquery-sortable-min.js index 3ee8910..4c8bbfe 100644 --- a/source/js/jquery-sortable-min.js +++ b/source/js/jquery-sortable-min.js @@ -1,16 +1,17 @@ !function(e,y,h){var k,p,q;function u(a,b){var c=Math.max(0,a[0]-b[0],b[0]-a[1]),d=Math.max(0,a[2]-b[1],b[1]-a[3]);return c+d}function v(a,b,c){for(var d=a.length,c=c?"offset":"position";d--;){var f=a[d].el?a[d].el:e(a[d]),l=f[c]();b[d]=[l.left,l.left+f.outerWidth(!0),l.top,l.top+f.outerHeight(!0)]}}function m(a,b){var c=b.offset();return{left:a.left-c.left,top:a.top-c.top}}function w(a,b,c){for(var b=[b.left,b.top],c=c&&[c.left,c.top],d,f=a.length,e=[];f--;)d=a[f],e[f]=[f,u(d,b),c&&u(d,c)];return e= e.sort(function(a,b){return b[1]-a[1]||b[2]-a[2]||b[0]-a[0]})}function n(a,b,c,d){a=a.find(b);for(b=a.length;b--;){var f=a.eq(b).data(i);if(f)f[c](d)}}function o(a){this.options=e.extend({},j,a);this.containers=[];this.childGroups=[];this.scrolledProxy=e.proxy(this.scrolled,this);this.dragProxy=e.proxy(this.drag,this);this.dropProxy=e.proxy(this.drop,this);this.options.parentGroup?this.options.parentGroup.childGroups.push(this):(this.placeholder=e(this.options.placeholder),a.isValidTarget||(this.options.isValidTarget= h))}function r(a,b){this.el=a;this.childGroups=[];this.floatRight=!1;this.dragInitProxy=e.proxy(this.dragInit,this);this.options=e.extend({},z,b);this.group=o.get(this.options);this.rootGroup=this.options.rootGroup=this.options.rootGroup||this.group;this.parentGroup=this.options.parentGroup=this.options.parentGroup||this.group;this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;this.enable(!0)}var i="sortable",z={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},j={afterMove:function(){}, -containerSelector:"ol, ul",handle:"",itemSelector:"li",isValidTarget:function(){return!0},onCancel:function(){},onDrag:function(a,b){a.css(b)},onDragStart:function(a){a.css({height:a.height(),width:a.width()});a.addClass("dragged");e("body").addClass("dragging")},onDrop:function(a){a.removeClass("dragged").attr("style","");e("body").removeClass("dragging")},placeholder:'
  • ',pullPlaceholder:!0,serialize:function(a,b){var c=e.extend({},a.data());b[0]&&(c.children=b);delete c.sortable; -return c}},s={},x=0;"ontouchstart"in y?(k="touchstart.sortable",p="touchend.sortable touchcancel.sortable",q="touchmove.sortable"):(k="mousedown.sortable",p="mouseup.sortable",q="mousemove.sortable");Array.prototype.remove=function(a,b){var c=this.slice((b||a)+1||this.length);this.length=a<0?this.length+a:a;return this.push.apply(this,c)};o.get=function(a){if(!s[a.group]){if(!a.group)a.group=x++;s[a.group]=new o(a)}return s[a.group]};o.prototype={dragInit:function(a,b){this.$document=e(b.el[0].ownerDocument); -this.toggleListeners("on");this.item=e(a.target).closest(this.options.itemSelector);this.itemContainer=b;this.setPointer(a)},drag:function(a){a.preventDefault();if(!this.dragging){n(this.item,this.options.containerSelector,"disable",true);this.options.onDragStart(this.item,this.itemContainer,j.onDragStart);this.item.before(this.placeholder);this.dragging=true}if(this.setPointer(a)){this.options.onDrag(this.item,m(this.pointer,this.item.offsetParent()),j.onDrag);var b=a.pageX,a=a.pageY,c=this.sameResultBox; -if(!c||c.top>a||c.bottomb||c.right<=(d[0]+d[1])/2!=this.floatRight){f="before";g.right=g.right-h/2}else g.left=g.left+h/2;this.rootGroup.movePlaceholder(this,c,f,g)},getItemDimensions:function(){if(!this.itemDimensions){this.items=this.$getChildren(this.el, -"item").filter(":not(.dragged)").get();v(this.items,this.itemDimensions=[])}return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return a.css("position")==="relative"||a.css("position")==="absolute"||a.css("position")==="fixed"?a:a.offsetParent()},getContainerGroup:function(a){var b=e.data(this.items[a],"subContainer");if(b===h){var c=this.$getChildren(this.items[a],"container"),b=false;if(c[0]){b=e.extend({},this.options,{parentGroup:this.group,group:x++});b=c[i](b).data(i).group}e.data(this.items[a], -"subContainer",b)}return b},$getChildren:function(a,b){return e(a).children(this.rootGroup.options[b+"Selector"])},_serialize:function(a,b){var c=this,d=this.$getChildren(a,b?"item":"container").map(function(){return c._serialize(e(this),!b)}).get();return this.rootGroup.options.serialize(a,d,b)}};var t={enable:function(a){this.options.drop&&this.group.addContainer(this);a||n(this.el,this.options.containerSelector,"enable",true);this.el.on(k,this.handle,this.dragInitProxy)},disable:function(a){this.options.drop&& -this.group.removeContainer(this);a||n(this.el,this.options.containerSelector,"disable",true);this.el.off(k,this.handle,this.dragInitProxy)},serialize:function(){return this._serialize(this.el,true)}};e.extend(r.prototype,t);e.fn[i]=function(a){var b=Array.prototype.slice.call(arguments,1);return this.map(function(){var c=e(this),d=c.data(i);if(d&&t[a])return t[a].apply(d,b)||this;!d&&(a===h||typeof a==="object")&&c.data(i,new r(c,a));return this})}}(jQuery,window); +containerSelector:"ol, ul",distance:0,handle:"",itemSelector:"li",isValidTarget:function(){return!0},onCancel:function(){},onDrag:function(a,b){a.css(b)},onDragStart:function(a){a.css({height:a.height(),width:a.width()});a.addClass("dragged");e("body").addClass("dragging")},onDrop:function(a){a.removeClass("dragged").removeAttr("style");e("body").removeClass("dragging")},placeholder:'
  • ',pullPlaceholder:!0,serialize:function(a,b){var c=e.extend({},a.data());b[0]&&(c.children= +b);delete c.sortable;return c},tolerance:0},s={},x=0;"ontouchstart"in y?(k="touchstart.sortable",p="touchend.sortable touchcancel.sortable",q="touchmove.sortable"):(k="mousedown.sortable",p="mouseup.sortable",q="mousemove.sortable");o.get=function(a){if(!s[a.group]){if(!a.group)a.group=x++;s[a.group]=new o(a)}return s[a.group]};o.prototype={dragInit:function(a,b){this.$document=e(b.el[0].ownerDocument);this.toggleListeners("on");this.item=e(a.target).closest(this.options.itemSelector);this.itemContainer= +b;this.setPointer(a)},drag:function(a){a.preventDefault();if(!this.dragging){if(!this.distanceMet(a))return;n(this.item,this.options.containerSelector,"disable",true);this.options.onDragStart(this.item,this.itemContainer,j.onDragStart);this.item.before(this.placeholder);this.dragging=true}this.setPointer(a);this.options.onDrag(this.item,m(this.pointer,this.item.offsetParent()),j.onDrag);var b=a.pageX,a=a.pageY,c=this.sameResultBox,d=this.options.tolerance;if(!c||c.top-d>a||c.bottom+d +b||c.right+d=this.options.distance}, +addContainer:function(a){this.containers.push(a)},removeContainer:function(a){var b=this.containers,a=this.containers.indexOf(a),c=b.slice(a+1||b.length);b.length=a<0?b.length+a:a;b.push.apply(b,c)},scrolled:function(){this.clearDimensions();this.clearOffsetParent()},toggleListeners:function(a){this.$document[a](q,this.dragProxy)[a](p,this.dropProxy)[a]("scroll.sortable",this.scrolledProxy)},clearDimensions:function(){this.containerDimensions=h;for(var a=this.containers.length;a--;)this.containers[a].itemDimensions= +h;for(a=this.childGroups.length;a--;)this.childGroups[a].clearDimensions()}};r.prototype={dragInit:function(a){if(!(a.which!==1||!this.options.drag||e(a.target).is(this.options.exclude))){a.preventDefault();a.stopPropagation();this.rootGroup.dragInit(a,this)}},searchValidTarget:function(a,b){var c=w(this.getItemDimensions(),a,b),d=c.length,f=this.rootGroup,e=!f.options.isValidTarget||f.options.isValidTarget(f.item,this);if(!d&&e){f.movePlaceholder(this,this.el,"append");return true}for(;d--;){f=c[d][0]; +if(!c[d][1]&&this.options.nested&&this.getContainerGroup(f)){if(this.getContainerGroup(f).searchValidTarget(a,b))return true}else if(e){this.movePlaceholder(f,a);return true}}},movePlaceholder:function(a,b){var c=e(this.items[a]),d=this.itemDimensions[a],f="after",h=c.outerWidth(),i=c.outerHeight(),g=c.offset(),g={left:g.left,right:g.left+h,top:g.top,bottom:g.top+i};if(this.options.vertical)if(b.top<=(d[2]+d[3])/2){f="before";g.bottom=g.bottom-i/2}else g.top=g.top+i/2;else if(b.left<=(d[0]+d[1])/ +2!=this.floatRight){f="before";g.right=g.right-h/2}else g.left=g.left+h/2;this.rootGroup.movePlaceholder(this,c,f,g)},getItemDimensions:function(){if(!this.itemDimensions){this.items=this.$getChildren(this.el,"item").filter(":not(.dragged)").get();v(this.items,this.itemDimensions=[])}return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return a.css("position")==="relative"||a.css("position")==="absolute"||a.css("position")==="fixed"?a:a.offsetParent()},getContainerGroup:function(a){var b= +e.data(this.items[a],"subContainer");if(b===h){var c=this.$getChildren(this.items[a],"container"),b=false;if(c[0]){b=e.extend({},this.options,{parentGroup:this.group,group:x++});b=c[i](b).data(i).group}e.data(this.items[a],"subContainer",b)}return b},$getChildren:function(a,b){return e(a).children(this.rootGroup.options[b+"Selector"])},_serialize:function(a,b){var c=this,d=this.$getChildren(a,b?"item":"container").not(this.options.exclude).map(function(){return c._serialize(e(this),!b)}).get();return this.rootGroup.options.serialize(a, +d,b)}};var t={enable:function(a){this.options.drop&&this.group.addContainer(this);a||n(this.el,this.options.containerSelector,"enable",true);this.el.on(k,this.handle,this.dragInitProxy)},disable:function(a){this.options.drop&&this.group.removeContainer(this);a||n(this.el,this.options.containerSelector,"disable",true);this.el.off(k,this.handle,this.dragInitProxy)},serialize:function(){return this._serialize(this.el,true)}};e.extend(r.prototype,t);e.fn[i]=function(a){var b=Array.prototype.slice.call(arguments, +1);return this.map(function(){var c=e(this),d=c.data(i);if(d&&t[a])return t[a].apply(d,b)||this;!d&&(a===h||typeof a==="object")&&c.data(i,new r(c,a));return this})}}(jQuery,window); diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 1ead239..e1ee4ee 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -1,5 +1,5 @@ /* =================================================== - * jquery-sortable.js v0.9.8 + * jquery-sortable.js v0.9.9 * http://johnny.github.com/jquery-sortable/ * =================================================== * Copyright (c) 2012 Jonas von Andrian From b88f8516363c756cdf751e71cd88957df37ef746 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 14 May 2013 20:58:35 +0200 Subject: [PATCH 33/97] do not stop propagation on drag init see #17 --- source/js/jquery-sortable.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index e1ee4ee..2b95ff5 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -237,8 +237,6 @@ this.setPointer(e) }, drag: function (e) { - e.preventDefault() - if(!this.dragging){ if(!this.distanceMet(e)) return @@ -266,7 +264,6 @@ this.placeholder.detach() }, drop: function (e) { - e.preventDefault() this.toggleListeners('off') if(!this.dragging) @@ -286,6 +283,7 @@ this.clearOffsetParent() this.lastAppendedItem = this.sameResultBox = undefined this.dragging = false + this.item = undefined }, searchValidTarget: function (pointer, lastPointer) { if(!pointer){ @@ -426,15 +424,16 @@ Container.prototype = { dragInit: function (e) { - if(e.which !== 1 || + var rootGroup = this.rootGroup + if(rootGroup.item || + e.which !== 1 || !this.options.drag || $(e.target).is(this.options.exclude)) return; - + e.preventDefault() - e.stopPropagation() - this.rootGroup.dragInit(e, this) + rootGroup.dragInit(e, this) }, searchValidTarget: function (pointer, lastPointer) { var distances = sortByDistanceDesc(this.getItemDimensions(), From 2991d4a731f25c46deaf2046acaf04c287d0714a Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Tue, 14 May 2013 21:21:16 +0200 Subject: [PATCH 34/97] saner default serialize --- source/js/jquery-sortable.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 2b95ff5..1278176 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -95,12 +95,18 @@ // If false, it is only calculated when the mouse is above a container. pullPlaceholder: true, // Specifies serialization of the container group. - // The pair $parent/$children is either container/items or item/subcontainers + // The pair $parent/$children is either container/items or item/subcontainers. + // Note that this default method only works, if every item only has one subcontainer serialize: function ($parent, $children, parentIsContainer) { var result = $.extend({}, $parent.data()) - - if($children[0]) + + if(parentIsContainer) + return $children + else if ($children[0]){ result.children = $children + delete result.subContainer + } + delete result.sortable return result From 459f365a75e2019cdd8382210ea142ec951df230 Mon Sep 17 00:00:00 2001 From: Dev-Speranza Date: Wed, 15 May 2013 03:34:26 +0300 Subject: [PATCH 35/97] Fix IE9< Array.indexOf() error --- source/js/jquery-sortable.js | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 1278176..95c1398 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -146,6 +146,32 @@ array.length = from < 0 ? array.length + from : from; return array.push.apply(array, rest); } + function indexOf(array, elem) { + var t = Object(array); + var len = t.length >>> 0; + if (len === 0) { + return -1; + } + var n = 0; + if (arguments.length > 1) { + n = Number(arguments[1]); + if (n != n) { // shortcut for verifying if it's NaN + n = 0; + } else if (n != 0 && n != Infinity && n != -Infinity) { + n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } + } + if (n >= len) { + return -1; + } + var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); + for (; k < len; k++) { + if (k in t && t[k] === elem) { + return k; + } + } + return -1; + } function setDimensions(array, dimensions, useOffset) { var i = array.length, @@ -387,7 +413,8 @@ this.containers.push(container); }, removeContainer: function (container) { - var i = this.containers.indexOf(container) + //var i = this.containers.indexOf(container) + var i = indexOf(container,this); remove(this.containers, i); }, scrolled: function (e) { From c078eec7ca25364c7e2d370690b23f15b246b472 Mon Sep 17 00:00:00 2001 From: Dev-Speranza Date: Wed, 15 May 2013 21:35:22 +0300 Subject: [PATCH 36/97] Update jquery-sortable.js --- source/js/jquery-sortable.js | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 95c1398..f122763 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -146,32 +146,6 @@ array.length = from < 0 ? array.length + from : from; return array.push.apply(array, rest); } - function indexOf(array, elem) { - var t = Object(array); - var len = t.length >>> 0; - if (len === 0) { - return -1; - } - var n = 0; - if (arguments.length > 1) { - n = Number(arguments[1]); - if (n != n) { // shortcut for verifying if it's NaN - n = 0; - } else if (n != 0 && n != Infinity && n != -Infinity) { - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - } - if (n >= len) { - return -1; - } - var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); - for (; k < len; k++) { - if (k in t && t[k] === elem) { - return k; - } - } - return -1; - } function setDimensions(array, dimensions, useOffset) { var i = array.length, @@ -413,9 +387,8 @@ this.containers.push(container); }, removeContainer: function (container) { - //var i = this.containers.indexOf(container) - var i = indexOf(container,this); - remove(this.containers, i); + var i = $.inArray(container,this); + i!==-1 && remove(this.containers, i); }, scrolled: function (e) { this.clearDimensions() From b853fbadf0a51c9d1f772991c072f8725c52a72d Mon Sep 17 00:00:00 2001 From: Dev-Speranza Date: Wed, 15 May 2013 21:19:05 +0200 Subject: [PATCH 37/97] Update jquery-sortable.js --- source/js/jquery-sortable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index f122763..9d25e5d 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -387,7 +387,7 @@ this.containers.push(container); }, removeContainer: function (container) { - var i = $.inArray(container,this); + var i = $.inArray(container,this.containers); i!==-1 && remove(this.containers, i); }, scrolled: function (e) { From fab73e746a8c765a844e7a7b02441cec0a13f628 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Fri, 17 May 2013 16:15:09 +0200 Subject: [PATCH 38/97] fix bug introduced by getting rid of stopPropagation --- source/js/jquery-sortable.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 1278176..97b08bd 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -272,23 +272,23 @@ drop: function (e) { this.toggleListeners('off') - if(!this.dragging) - return; - - // processing Drop, check if placeholder is detached - if(this.placeholder.closest("html")[0]) - this.placeholder.before(this.item).detach() - else - this.options.onCancel(this.item, this.itemContainer, groupDefaults.onCancel) - - this.options.onDrop(this.item, this.getContainer(this.item), groupDefaults.onDrop) - processChildContainers(this.item, this.options.containerSelector, "enable", true) - - // cleanup - this.clearDimensions() - this.clearOffsetParent() - this.lastAppendedItem = this.sameResultBox = undefined - this.dragging = false + if(this.dragging){ + // processing Drop, check if placeholder is detached + if(this.placeholder.closest("html")[0]) + this.placeholder.before(this.item).detach() + else + this.options.onCancel(this.item, this.itemContainer, groupDefaults.onCancel) + + this.options.onDrop(this.item, this.getContainer(this.item), groupDefaults.onDrop) + processChildContainers(this.item, this.options.containerSelector, "enable", true) + + // cleanup + this.clearDimensions() + this.clearOffsetParent() + this.lastAppendedItem = this.sameResultBox = undefined + this.dragging = false + } + this.item = undefined }, searchValidTarget: function (pointer, lastPointer) { @@ -565,7 +565,7 @@ if(!ignoreChildren) processChildContainers(this.el, this.options.containerSelector, "disable", true) - this.el.off(eventNames.start, this.handle, this.dragInitProxy) + this.el.off(eventNames.start) }, serialize: function () { return this._serialize(this.el, true) From 10e8bd2ad726c04373ae313274e890a8ea66b7f0 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Fri, 17 May 2013 16:42:57 +0200 Subject: [PATCH 39/97] added Safari to list of working browsers --- source/index.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/index.html.haml b/source/index.html.haml index f146610..987fce3 100644 --- a/source/index.html.haml +++ b/source/index.html.haml @@ -63,9 +63,10 @@ %ul %li Firefox >= 3.5 %li Chrome + %li IE > 7 + %li Safari >= 6 %li Opera %li Konqueror - %li IE > 7 %p If you confirmed, that it works on other browsers please %a(href="mailto:jvadev@gmail.com") tell me From 7069e8fefc2f4e597257c2d00433698c1aa4b694 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 18 May 2013 11:06:00 +0200 Subject: [PATCH 40/97] additional option: onMousedown closes #17 --- source/js/jquery-sortable.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 97b08bd..68d35d3 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -66,7 +66,7 @@ onCancel: function ($item, container, _super) { }, // Executed at the beginning of a mouse move event. - // The Placeholder has not been moved yet + // The Placeholder has not been moved yet. onDrag: function ($item, position, _super) { $item.css(position) }, @@ -88,6 +88,10 @@ $item.removeClass("dragged").removeAttr("style") $("body").removeClass("dragging") }, + // Called on mousedown. + onMousedown: function($item, event, _super) { + event.preventDefault() + }, // Template for the placeholder. Can be any valid jQuery input // e.g. a string, a DOM element placeholder: '
  • ', @@ -241,6 +245,8 @@ this.itemContainer = itemContainer this.setPointer(e) + + this.options.onMousedown(this.item, e, groupDefaults.onMousedown) }, drag: function (e) { if(!this.dragging){ @@ -431,15 +437,12 @@ Container.prototype = { dragInit: function (e) { var rootGroup = this.rootGroup - if(rootGroup.item || - e.which !== 1 || - !this.options.drag || - $(e.target).is(this.options.exclude)) - return; - - e.preventDefault() - rootGroup.dragInit(e, this) + if( !rootGroup.item && + e.which === 1 && + this.options.drag && + !$(e.target).is(this.options.exclude)) + rootGroup.dragInit(e, this) }, searchValidTarget: function (pointer, lastPointer) { var distances = sortByDistanceDesc(this.getItemDimensions(), From cd541dc4a00fee3da848b429c79b981436d44885 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Mon, 20 May 2013 11:10:45 +0200 Subject: [PATCH 41/97] Release 0.9.10 --- CHANGELOG | 7 ++++++- VERSION | 2 +- sortable.jquery.json | 4 ++-- source/js/jquery-sortable-min.js | 28 ++++++++++++++-------------- source/js/jquery-sortable.js | 2 +- 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 671c69d..4b6522a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,9 @@ -[0.9.8] Added options tolerance and distance +[0.9.10]Fix Array.indexOf() error in IE < 9 (Dev-Speranza) + serialize() assumes one subcontainer per item + remove call to stopPropagation() + Added onMousedown() + +[0.9.9] Added options tolerance and distance Do not modify Array.prototype (by Joakin) serialize respects exclude option diff --git a/VERSION b/VERSION index 7e310ba..56f3151 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.9 +0.9.10 diff --git a/sortable.jquery.json b/sortable.jquery.json index df6c3b0..d4550f2 100644 --- a/sortable.jquery.json +++ b/sortable.jquery.json @@ -9,14 +9,14 @@ "drag", "drop" ], - "version": "0.9.9", + "version": "0.9.10", "author": { "name": "Jonas von Andrian" }, "licenses": [ { "type": "BSD-3", - "url": "https://github.com/johnny/jquery-sortable/blob/0.9.9/LICENSE" + "url": "https://github.com/johnny/jquery-sortable/blob/0.9.10/LICENSE" } ], "bugs": "https://github.com/johnny/jquery-sortable/issues", diff --git a/source/js/jquery-sortable-min.js b/source/js/jquery-sortable-min.js index 4c8bbfe..8e9dd92 100644 --- a/source/js/jquery-sortable-min.js +++ b/source/js/jquery-sortable-min.js @@ -1,17 +1,17 @@ !function(e,y,h){var k,p,q;function u(a,b){var c=Math.max(0,a[0]-b[0],b[0]-a[1]),d=Math.max(0,a[2]-b[1],b[1]-a[3]);return c+d}function v(a,b,c){for(var d=a.length,c=c?"offset":"position";d--;){var f=a[d].el?a[d].el:e(a[d]),l=f[c]();b[d]=[l.left,l.left+f.outerWidth(!0),l.top,l.top+f.outerHeight(!0)]}}function m(a,b){var c=b.offset();return{left:a.left-c.left,top:a.top-c.top}}function w(a,b,c){for(var b=[b.left,b.top],c=c&&[c.left,c.top],d,f=a.length,e=[];f--;)d=a[f],e[f]=[f,u(d,b),c&&u(d,c)];return e= e.sort(function(a,b){return b[1]-a[1]||b[2]-a[2]||b[0]-a[0]})}function n(a,b,c,d){a=a.find(b);for(b=a.length;b--;){var f=a.eq(b).data(i);if(f)f[c](d)}}function o(a){this.options=e.extend({},j,a);this.containers=[];this.childGroups=[];this.scrolledProxy=e.proxy(this.scrolled,this);this.dragProxy=e.proxy(this.drag,this);this.dropProxy=e.proxy(this.drop,this);this.options.parentGroup?this.options.parentGroup.childGroups.push(this):(this.placeholder=e(this.options.placeholder),a.isValidTarget||(this.options.isValidTarget= h))}function r(a,b){this.el=a;this.childGroups=[];this.floatRight=!1;this.dragInitProxy=e.proxy(this.dragInit,this);this.options=e.extend({},z,b);this.group=o.get(this.options);this.rootGroup=this.options.rootGroup=this.options.rootGroup||this.group;this.parentGroup=this.options.parentGroup=this.options.parentGroup||this.group;this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;this.enable(!0)}var i="sortable",z={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},j={afterMove:function(){}, -containerSelector:"ol, ul",distance:0,handle:"",itemSelector:"li",isValidTarget:function(){return!0},onCancel:function(){},onDrag:function(a,b){a.css(b)},onDragStart:function(a){a.css({height:a.height(),width:a.width()});a.addClass("dragged");e("body").addClass("dragging")},onDrop:function(a){a.removeClass("dragged").removeAttr("style");e("body").removeClass("dragging")},placeholder:'
  • ',pullPlaceholder:!0,serialize:function(a,b){var c=e.extend({},a.data());b[0]&&(c.children= -b);delete c.sortable;return c},tolerance:0},s={},x=0;"ontouchstart"in y?(k="touchstart.sortable",p="touchend.sortable touchcancel.sortable",q="touchmove.sortable"):(k="mousedown.sortable",p="mouseup.sortable",q="mousemove.sortable");o.get=function(a){if(!s[a.group]){if(!a.group)a.group=x++;s[a.group]=new o(a)}return s[a.group]};o.prototype={dragInit:function(a,b){this.$document=e(b.el[0].ownerDocument);this.toggleListeners("on");this.item=e(a.target).closest(this.options.itemSelector);this.itemContainer= -b;this.setPointer(a)},drag:function(a){a.preventDefault();if(!this.dragging){if(!this.distanceMet(a))return;n(this.item,this.options.containerSelector,"disable",true);this.options.onDragStart(this.item,this.itemContainer,j.onDragStart);this.item.before(this.placeholder);this.dragging=true}this.setPointer(a);this.options.onDrag(this.item,m(this.pointer,this.item.offsetParent()),j.onDrag);var b=a.pageX,a=a.pageY,c=this.sameResultBox,d=this.options.tolerance;if(!c||c.top-d>a||c.bottom+d -b||c.right+d=this.options.distance}, -addContainer:function(a){this.containers.push(a)},removeContainer:function(a){var b=this.containers,a=this.containers.indexOf(a),c=b.slice(a+1||b.length);b.length=a<0?b.length+a:a;b.push.apply(b,c)},scrolled:function(){this.clearDimensions();this.clearOffsetParent()},toggleListeners:function(a){this.$document[a](q,this.dragProxy)[a](p,this.dropProxy)[a]("scroll.sortable",this.scrolledProxy)},clearDimensions:function(){this.containerDimensions=h;for(var a=this.containers.length;a--;)this.containers[a].itemDimensions= -h;for(a=this.childGroups.length;a--;)this.childGroups[a].clearDimensions()}};r.prototype={dragInit:function(a){if(!(a.which!==1||!this.options.drag||e(a.target).is(this.options.exclude))){a.preventDefault();a.stopPropagation();this.rootGroup.dragInit(a,this)}},searchValidTarget:function(a,b){var c=w(this.getItemDimensions(),a,b),d=c.length,f=this.rootGroup,e=!f.options.isValidTarget||f.options.isValidTarget(f.item,this);if(!d&&e){f.movePlaceholder(this,this.el,"append");return true}for(;d--;){f=c[d][0]; -if(!c[d][1]&&this.options.nested&&this.getContainerGroup(f)){if(this.getContainerGroup(f).searchValidTarget(a,b))return true}else if(e){this.movePlaceholder(f,a);return true}}},movePlaceholder:function(a,b){var c=e(this.items[a]),d=this.itemDimensions[a],f="after",h=c.outerWidth(),i=c.outerHeight(),g=c.offset(),g={left:g.left,right:g.left+h,top:g.top,bottom:g.top+i};if(this.options.vertical)if(b.top<=(d[2]+d[3])/2){f="before";g.bottom=g.bottom-i/2}else g.top=g.top+i/2;else if(b.left<=(d[0]+d[1])/ -2!=this.floatRight){f="before";g.right=g.right-h/2}else g.left=g.left+h/2;this.rootGroup.movePlaceholder(this,c,f,g)},getItemDimensions:function(){if(!this.itemDimensions){this.items=this.$getChildren(this.el,"item").filter(":not(.dragged)").get();v(this.items,this.itemDimensions=[])}return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return a.css("position")==="relative"||a.css("position")==="absolute"||a.css("position")==="fixed"?a:a.offsetParent()},getContainerGroup:function(a){var b= -e.data(this.items[a],"subContainer");if(b===h){var c=this.$getChildren(this.items[a],"container"),b=false;if(c[0]){b=e.extend({},this.options,{parentGroup:this.group,group:x++});b=c[i](b).data(i).group}e.data(this.items[a],"subContainer",b)}return b},$getChildren:function(a,b){return e(a).children(this.rootGroup.options[b+"Selector"])},_serialize:function(a,b){var c=this,d=this.$getChildren(a,b?"item":"container").not(this.options.exclude).map(function(){return c._serialize(e(this),!b)}).get();return this.rootGroup.options.serialize(a, -d,b)}};var t={enable:function(a){this.options.drop&&this.group.addContainer(this);a||n(this.el,this.options.containerSelector,"enable",true);this.el.on(k,this.handle,this.dragInitProxy)},disable:function(a){this.options.drop&&this.group.removeContainer(this);a||n(this.el,this.options.containerSelector,"disable",true);this.el.off(k,this.handle,this.dragInitProxy)},serialize:function(){return this._serialize(this.el,true)}};e.extend(r.prototype,t);e.fn[i]=function(a){var b=Array.prototype.slice.call(arguments, -1);return this.map(function(){var c=e(this),d=c.data(i);if(d&&t[a])return t[a].apply(d,b)||this;!d&&(a===h||typeof a==="object")&&c.data(i,new r(c,a));return this})}}(jQuery,window); +containerSelector:"ol, ul",distance:0,handle:"",itemSelector:"li",isValidTarget:function(){return!0},onCancel:function(){},onDrag:function(a,b){a.css(b)},onDragStart:function(a){a.css({height:a.height(),width:a.width()});a.addClass("dragged");e("body").addClass("dragging")},onDrop:function(a){a.removeClass("dragged").removeAttr("style");e("body").removeClass("dragging")},onMousedown:function(a,b){b.preventDefault()},placeholder:'
  • ',pullPlaceholder:!0,serialize:function(a,b, +c){a=e.extend({},a.data());if(c)return b;b[0]&&(a.children=b,delete a.subContainer);delete a.sortable;return a},tolerance:0},s={},x=0;"ontouchstart"in y?(k="touchstart.sortable",p="touchend.sortable touchcancel.sortable",q="touchmove.sortable"):(k="mousedown.sortable",p="mouseup.sortable",q="mousemove.sortable");o.get=function(a){if(!s[a.group]){if(!a.group)a.group=x++;s[a.group]=new o(a)}return s[a.group]};o.prototype={dragInit:function(a,b){this.$document=e(b.el[0].ownerDocument);this.toggleListeners("on"); +this.item=e(a.target).closest(this.options.itemSelector);this.itemContainer=b;this.setPointer(a);this.options.onMousedown(this.item,a,j.onMousedown)},drag:function(a){if(!this.dragging){if(!this.distanceMet(a))return;n(this.item,this.options.containerSelector,"disable",true);this.options.onDragStart(this.item,this.itemContainer,j.onDragStart);this.item.before(this.placeholder);this.dragging=true}this.setPointer(a);this.options.onDrag(this.item,m(this.pointer,this.item.offsetParent()),j.onDrag);var b= +a.pageX,a=a.pageY,c=this.sameResultBox,d=this.options.tolerance;if(!c||c.top-d>a||c.bottom+db||c.right+d=this.options.distance},addContainer:function(a){this.containers.push(a)},removeContainer:function(a){a=e.inArray(a,this.containers);if(a!==-1){var b=this.containers,c=b.slice(a+1||b.length);b.length=a<0?b.length+a:a;b.push.apply(b,c)}},scrolled:function(){this.clearDimensions();this.clearOffsetParent()},toggleListeners:function(a){this.$document[a](q,this.dragProxy)[a](p,this.dropProxy)[a]("scroll.sortable", +this.scrolledProxy)},clearDimensions:function(){this.containerDimensions=h;for(var a=this.containers.length;a--;)this.containers[a].itemDimensions=h;for(a=this.childGroups.length;a--;)this.childGroups[a].clearDimensions()}};r.prototype={dragInit:function(a){var b=this.rootGroup;!b.item&&a.which===1&&this.options.drag&&!e(a.target).is(this.options.exclude)&&b.dragInit(a,this)},searchValidTarget:function(a,b){var c=w(this.getItemDimensions(),a,b),d=c.length,f=this.rootGroup,e=!f.options.isValidTarget|| +f.options.isValidTarget(f.item,this);if(!d&&e){f.movePlaceholder(this,this.el,"append");return true}for(;d--;){f=c[d][0];if(!c[d][1]&&this.options.nested&&this.getContainerGroup(f)){if(this.getContainerGroup(f).searchValidTarget(a,b))return true}else if(e){this.movePlaceholder(f,a);return true}}},movePlaceholder:function(a,b){var c=e(this.items[a]),d=this.itemDimensions[a],f="after",h=c.outerWidth(),i=c.outerHeight(),g=c.offset(),g={left:g.left,right:g.left+h,top:g.top,bottom:g.top+i};if(this.options.vertical)if(b.top<= +(d[2]+d[3])/2){f="before";g.bottom=g.bottom-i/2}else g.top=g.top+i/2;else if(b.left<=(d[0]+d[1])/2!=this.floatRight){f="before";g.right=g.right-h/2}else g.left=g.left+h/2;this.rootGroup.movePlaceholder(this,c,f,g)},getItemDimensions:function(){if(!this.itemDimensions){this.items=this.$getChildren(this.el,"item").filter(":not(.dragged)").get();v(this.items,this.itemDimensions=[])}return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return a.css("position")==="relative"||a.css("position")=== +"absolute"||a.css("position")==="fixed"?a:a.offsetParent()},getContainerGroup:function(a){var b=e.data(this.items[a],"subContainer");if(b===h){var c=this.$getChildren(this.items[a],"container"),b=false;if(c[0]){b=e.extend({},this.options,{parentGroup:this.group,group:x++});b=c[i](b).data(i).group}e.data(this.items[a],"subContainer",b)}return b},$getChildren:function(a,b){return e(a).children(this.rootGroup.options[b+"Selector"])},_serialize:function(a,b){var c=this,d=this.$getChildren(a,b?"item": +"container").not(this.options.exclude).map(function(){return c._serialize(e(this),!b)}).get();return this.rootGroup.options.serialize(a,d,b)}};var t={enable:function(a){this.options.drop&&this.group.addContainer(this);a||n(this.el,this.options.containerSelector,"enable",true);this.el.on(k,this.handle,this.dragInitProxy)},disable:function(a){this.options.drop&&this.group.removeContainer(this);a||n(this.el,this.options.containerSelector,"disable",true);this.el.off(k)},serialize:function(){return this._serialize(this.el, +true)}};e.extend(r.prototype,t);e.fn[i]=function(a){var b=Array.prototype.slice.call(arguments,1);return this.map(function(){var c=e(this),d=c.data(i);if(d&&t[a])return t[a].apply(d,b)||this;!d&&(a===h||typeof a==="object")&&c.data(i,new r(c,a));return this})}}(jQuery,window); diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index efb21e1..7a57fd0 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -1,5 +1,5 @@ /* =================================================== - * jquery-sortable.js v0.9.9 + * jquery-sortable.js v0.9.10 * http://johnny.github.com/jquery-sortable/ * =================================================== * Copyright (c) 2012 Jonas von Andrian From c386d87aa3a0a7d211bf27490497404e6a33f469 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sun, 9 Jun 2013 14:46:20 +0200 Subject: [PATCH 42/97] fix hybrid scenarios (touch + mouse) see #21 --- source/js/jquery-sortable.js | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 7a57fd0..8e7c103 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -119,20 +119,11 @@ tolerance: 0 }, // end group defaults containerGroups = {}, - groupCounter = 0 - - if('ontouchstart' in window){ - eventNames = { - start: "touchstart.sortable", - end: "touchend.sortable touchcancel.sortable", - move: "touchmove.sortable" - } - } else { - eventNames = { - start: "mousedown.sortable", - end: "mouseup.sortable", - move: "mousemove.sortable" - } + groupCounter = 0, + eventNames = { + start: "touchstart.sortable mousedown.sortable", + end: "touchend.sortable touchcancel.sortable mouseup.sortable", + move: "touchmove.sortable mousemove.sortable" } /* From d3de90f8e5f854ccfc1f0b3a4d57acd0649a9110 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Fri, 21 Jun 2013 12:30:49 +0200 Subject: [PATCH 43/97] Margins are no longer part of the element dimension --- source/js/jquery-sortable.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 8e7c103..6696595 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -149,11 +149,13 @@ var el = array[i].el ? array[i].el : $(array[i]), // use fitting method pos = el[offsetMethod]() + pos.left += parseInt(el.css('margin-left'), 10) + pos.right += parseInt(el.css('margin-right'),10) dimensions[i] = [ pos.left, - pos.left + el.outerWidth(true), + pos.left + el.outerWidth(), pos.top, - pos.top + el.outerHeight(true) + pos.top + el.outerHeight() ] } } From e0ecadb1b164909c4cfe61dd626c959223200cf2 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Fri, 21 Jun 2013 13:30:06 +0200 Subject: [PATCH 44/97] tolerance option accepts negative values Items with child containers no longer use sameResultBox closes #22 --- source/js/jquery-sortable.js | 39 +++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 6696595..6080ce0 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -93,7 +93,8 @@ event.preventDefault() }, // Template for the placeholder. Can be any valid jQuery input - // e.g. a string, a DOM element + // e.g. a string, a DOM element. + // The placeholder must have the class "placeholder" placeholder: '
  • ', // If true, the position of the placeholder is calculated on every mousemove. // If false, it is only calculated when the mouse is above a container. @@ -115,11 +116,18 @@ return result }, - // Set tolerance while dragging. Positive values will decrease sensitivity. + // Set tolerance while dragging. Positive values decrease sensitivity, + // negative values increase it. tolerance: 0 }, // end group defaults containerGroups = {}, groupCounter = 0, + emptyBox = { + left: 0, + top: 0, + bottom: 0, + right:0 + } eventNames = { start: "touchstart.sortable mousedown.sortable", end: "touchend.sortable touchcancel.sortable mouseup.sortable", @@ -142,20 +150,22 @@ return array.push.apply(array, rest); } - function setDimensions(array, dimensions, useOffset) { + function setDimensions(array, dimensions, tolerance, useOffset) { var i = array.length, offsetMethod = useOffset ? "offset" : "position" + tolerance = tolerance || 0 + while(i--){ var el = array[i].el ? array[i].el : $(array[i]), // use fitting method pos = el[offsetMethod]() pos.left += parseInt(el.css('margin-left'), 10) - pos.right += parseInt(el.css('margin-right'),10) + pos.top += parseInt(el.css('margin-top'),10) dimensions[i] = [ - pos.left, - pos.left + el.outerWidth(), - pos.top, - pos.top + el.outerHeight() + pos.left - tolerance, + pos.left + el.outerWidth() + tolerance, + pos.top - tolerance, + pos.top + el.outerHeight() + tolerance ] } } @@ -330,7 +340,7 @@ }, getContainerDimensions: function () { if(!this.containerDimensions) - setDimensions(this.containers, this.containerDimensions = [], !this.$getOffsetParent()) + setDimensions(this.containers, this.containerDimensions = [], this.options.tolerance, !this.$getOffsetParent()) return this.containerDimensions }, getContainer: function (element) { @@ -453,7 +463,7 @@ while(i--){ var index = distances[i][0], distance = distances[i][1] - if(!distance && this.options.nested && this.getContainerGroup(index)){ + if(!distance && this.hasChildGroup(index)){ var found = this.getContainerGroup(index).searchValidTarget(pointer, lastPointer) if(found) return true @@ -494,12 +504,14 @@ } else sameResultBox.left += width / 2 } + if(this.hasChildGroup(index)) + sameResultBox = emptyBox this.rootGroup.movePlaceholder(this, item, method, sameResultBox) }, getItemDimensions: function () { if(!this.itemDimensions){ - this.items = this.$getChildren(this.el, "item").filter(":not(.dragged)").get() - setDimensions(this.items, this.itemDimensions = []) + this.items = this.$getChildren(this.el, "item").filter(":not(.placeholder)").get() + setDimensions(this.items, this.itemDimensions = [], this.options.tolerance) } return this.itemDimensions }, @@ -514,6 +526,9 @@ offsetParent = el.offsetParent() return offsetParent }, + hasChildGroup: function (index) { + return this.options.nested && this.getContainerGroup(index) + }, getContainerGroup: function (index) { var childGroup = $.data(this.items[index], "subContainer") if( childGroup === undefined){ From 26d7c4aa1735e3039d31b38a086facf297381c75 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Mon, 15 Jul 2013 15:51:58 +0200 Subject: [PATCH 45/97] Rewrote disable/enable logic closes #27 --- source/js/examples/nested_bootstrap.js | 10 +- source/js/jquery-sortable.js | 145 +++++++++++-------------- 2 files changed, 72 insertions(+), 83 deletions(-) diff --git a/source/js/examples/nested_bootstrap.js b/source/js/examples/nested_bootstrap.js index d978def..7732d6e 100644 --- a/source/js/examples/nested_bootstrap.js +++ b/source/js/examples/nested_bootstrap.js @@ -3,7 +3,15 @@ $(function () { group: 'nav', nested: false, vertical: false, - exclude: '.divider-vertical' + exclude: '.divider-vertical', + onDragStart: function($item, container, _super) { + $item.find('ol.dropdown-menu').sortable('disable') + _super($item, container) + }, + onDrop: function($item, container, _super) { + $item.find('ol.dropdown-menu').sortable('enable') + _super($item, container) + } }) $("ol.dropdown-menu").sortable({ group: 'nav' diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 6080ce0..ac716c9 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -130,8 +130,9 @@ } eventNames = { start: "touchstart.sortable mousedown.sortable", - end: "touchend.sortable touchcancel.sortable mouseup.sortable", - move: "touchmove.sortable mousemove.sortable" + drop: "touchend.sortable touchcancel.sortable mouseup.sortable", + drag: "touchmove.sortable mousemove.sortable", + scroll: "scroll.sortable" } /* @@ -144,12 +145,6 @@ return x+y; } - function remove(array, from, to) { - var rest = array.slice((to || from) + 1 || array.length); - array.length = from < 0 ? array.length + from : from; - return array.push.apply(array, rest); - } - function setDimensions(array, dimensions, tolerance, useOffset) { var i = array.length, offsetMethod = useOffset ? "offset" : "position" @@ -198,30 +193,14 @@ return distances } - function processChildContainers(item, containerSelector, method, ignoreChildren) { - var childContainers = item.find(containerSelector), - i = childContainers.length - - while(i--){ - var container = childContainers.eq(i).data(pluginName) - if(container) - container[method](ignoreChildren) - } - - } - - function ContainerGroup(options) { this.options = $.extend({}, groupDefaults, options) this.containers = [] - this.childGroups = [] - this.scrolledProxy = $.proxy(this.scrolled, this) + this.scrollProxy = $.proxy(this.scroll, this) this.dragProxy = $.proxy(this.drag, this) this.dropProxy = $.proxy(this.drop, this) - if(this.options.parentGroup) - this.options.parentGroup.childGroups.push(this) - else { + if(!this.options.parentContainer){ this.placeholder = $(this.options.placeholder) if(!options.isValidTarget) this.options.isValidTarget = undefined @@ -240,24 +219,27 @@ ContainerGroup.prototype = { dragInit: function (e, itemContainer) { this.$document = $(itemContainer.el[0].ownerDocument) + this.isHandled = true - this.toggleListeners('on') + if(itemContainer.enabled()){ + this.toggleListeners('on') - // get item to drag - this.item = $(e.target).closest(this.options.itemSelector) - this.itemContainer = itemContainer + // get item to drag + this.item = $(e.target).closest(this.options.itemSelector) + this.itemContainer = itemContainer - this.setPointer(e) - - this.options.onMousedown(this.item, e, groupDefaults.onMousedown) + this.setPointer(e) + + this.options.onMousedown(this.item, e, groupDefaults.onMousedown) + } else { + this.toggleListeners('on', ['drop']) + } }, drag: function (e) { if(!this.dragging){ if(!this.distanceMet(e)) return - processChildContainers(this.item, this.options.containerSelector, "disable", true) - this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart) this.item.before(this.placeholder) this.dragging = true @@ -281,6 +263,8 @@ drop: function (e) { this.toggleListeners('off') + this.isHandled = false + if(this.dragging){ // processing Drop, check if placeholder is detached if(this.placeholder.closest("html")[0]) @@ -289,7 +273,6 @@ this.options.onCancel(this.item, this.itemContainer, groupDefaults.onCancel) this.options.onDrop(this.item, this.getContainer(this.item), groupDefaults.onDrop) - processChildContainers(this.item, this.options.containerSelector, "enable", true) // cleanup this.clearDimensions() @@ -297,8 +280,6 @@ this.lastAppendedItem = this.sameResultBox = undefined this.dragging = false } - - this.item = undefined }, searchValidTarget: function (pointer, lastPointer) { if(!pointer){ @@ -317,16 +298,19 @@ if(!distance || this.options.pullPlaceholder){ var container = this.containers[index] - if(!this.$getOffsetParent()){ - var offsetParent = container.getItemOffsetParent() - pointer = getRelativePosition(pointer, offsetParent) - lastPointer = getRelativePosition(lastPointer, offsetParent) + if(!container.disabled){ + if(!this.$getOffsetParent()){ + var offsetParent = container.getItemOffsetParent() + pointer = getRelativePosition(pointer, offsetParent) + lastPointer = getRelativePosition(lastPointer, offsetParent) + } + if(container.searchValidTarget(pointer, lastPointer)) + return true } - if(container.searchValidTarget(pointer, lastPointer)) - return true } } - + if(this.sameResultBox) + this.sameResultBox = undefined }, movePlaceholder: function (container, item, method, sameResultBox) { var lastAppendedItem = this.lastAppendedItem @@ -351,7 +335,7 @@ var i = this.containers.length - 1, offsetParent = this.containers[i].getItemOffsetParent() - if(!this.options.parentGroup){ + if(!this.options.parentContainer){ while(i--){ if(offsetParent[0] != this.containers[i].getItemOffsetParent()[0]){ // If every container has the same offset parent, @@ -392,56 +376,49 @@ Math.abs(this.pointer.top - e.pageY) ) >= this.options.distance) }, - addContainer: function (container) { - this.containers.push(container); - }, - removeContainer: function (container) { - var i = $.inArray(container,this.containers); - i!==-1 && remove(this.containers, i); - }, - scrolled: function (e) { + scroll: function (e) { this.clearDimensions() this.clearOffsetParent() }, - toggleListeners: function (method) { - this.$document[method](eventNames.move, this.dragProxy) - [method](eventNames.end, this.dropProxy) - [method]("scroll.sortable", this.scrolledProxy) + toggleListeners: function (method, events) { + var that = this + events = events || ['drag','drop','scroll'] + + $.each(events,function (i,event) { + that.$document[method](eventNames[event], that[event + 'Proxy']) + }) }, // Recursively clear container and item dimensions clearDimensions: function () { this.containerDimensions = undefined var i = this.containers.length while(i--){ - this.containers[i].itemDimensions = undefined - } - i = this.childGroups.length - while(i--){ - this.childGroups[i].clearDimensions() + this.containers[i].clearDimensions() } } } function Container(element, options) { this.el = element - this.childGroups = [] this.floatRight = false - this.dragInitProxy = $.proxy(this.dragInit, this) this.options = $.extend( {}, containerDefaults, options) this.group = ContainerGroup.get(this.options) this.rootGroup = this.options.rootGroup = this.options.rootGroup || this.group - this.parentGroup = this.options.parentGroup = this.options.parentGroup || this.group + this.parentContainer = this.options.parentContainer this.handle = this.rootGroup.options.handle || this.rootGroup.options.itemSelector - this.enable(true) + this.el.on(eventNames.start, this.handle, $.proxy(this.dragInit, this)) + + if(this.options.drop) + this.group.containers.push(this) } Container.prototype = { dragInit: function (e) { var rootGroup = this.rootGroup - if( !rootGroup.item && + if( !rootGroup.isHandled && e.which === 1 && this.options.drag && !$(e.target).is(this.options.exclude)) @@ -510,7 +487,7 @@ }, getItemDimensions: function () { if(!this.itemDimensions){ - this.items = this.$getChildren(this.el, "item").filter(":not(.placeholder)").get() + this.items = this.$getChildren(this.el, "item").filter(":not(.placeholder, .dragged)").get() setDimensions(this.items, this.itemDimensions = [], this.options.tolerance) } return this.itemDimensions @@ -537,7 +514,7 @@ if(childContainers[0]){ var options = $.extend({}, this.options, { - parentGroup: this.group, + parentContainer: this, group: groupCounter ++ }) childGroup = childContainers[pluginName](options).data(pluginName).group @@ -546,6 +523,9 @@ } return childGroup }, + enabled: function () { + return !this.disabled && (!this.parentContainer || this.parentContainer.enabled()) + }, $getChildren: function (parent, type) { return $(parent).children(this.rootGroup.options[type + "Selector"]) }, @@ -558,25 +538,26 @@ }).get() return this.rootGroup.options.serialize(parent, children, isContainer) + }, + clearDimensions: function () { + this.itemDimensions = undefined + if(this.items && this.items[0]){ + var i = this.items.length + while(i--){ + var group = $.data(this.items[i], "subContainer") + if(group) + group.clearDimensions() + } + } } } var API = { enable: function (ignoreChildren) { - if(this.options.drop) - this.group.addContainer(this) - if(!ignoreChildren) - processChildContainers(this.el, this.options.containerSelector, "enable", true) - - this.el.on(eventNames.start, this.handle, this.dragInitProxy) + this.disabled = false }, disable: function (ignoreChildren) { - if(this.options.drop) - this.group.removeContainer(this) - if(!ignoreChildren) - processChildContainers(this.el, this.options.containerSelector, "disable", true) - - this.el.off(eventNames.start) + this.disabled = true }, serialize: function () { return this._serialize(this.el, true) From 927ff150261642435bb119c3ae167f2695694657 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Mon, 15 Jul 2013 15:53:23 +0200 Subject: [PATCH 46/97] cleanup --- source/js/jquery-sortable.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index ac716c9..b7a3242 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -400,11 +400,10 @@ function Container(element, options) { this.el = element - this.floatRight = false this.options = $.extend( {}, containerDefaults, options) this.group = ContainerGroup.get(this.options) - this.rootGroup = this.options.rootGroup = this.options.rootGroup || this.group + this.rootGroup = this.options.rootGroup || this.group this.parentContainer = this.options.parentContainer this.handle = this.rootGroup.options.handle || this.rootGroup.options.itemSelector @@ -475,7 +474,7 @@ } else { var xCenter = (dim[0] + dim[1]) / 2, inLeftHalf = pointer.left <= xCenter - if(inLeftHalf != this.floatRight){ + if(inLeftHalf){ method = "before" sameResultBox.right -= width / 2 } else From 38ebf09cf390b8d5f5e2f97421374af3bc4351f9 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Mon, 15 Jul 2013 20:56:51 +0200 Subject: [PATCH 47/97] better name --- source/js/jquery-sortable.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index b7a3242..388aaf4 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -219,7 +219,6 @@ ContainerGroup.prototype = { dragInit: function (e, itemContainer) { this.$document = $(itemContainer.el[0].ownerDocument) - this.isHandled = true if(itemContainer.enabled()){ this.toggleListeners('on') @@ -229,11 +228,13 @@ this.itemContainer = itemContainer this.setPointer(e) - + this.options.onMousedown(this.item, e, groupDefaults.onMousedown) } else { this.toggleListeners('on', ['drop']) } + + this.dragInitDone = true }, drag: function (e) { if(!this.dragging){ @@ -263,7 +264,7 @@ drop: function (e) { this.toggleListeners('off') - this.isHandled = false + this.dragInitDone = false if(this.dragging){ // processing Drop, check if placeholder is detached @@ -352,9 +353,6 @@ } return this.offsetParent }, - clearOffsetParent: function () { - this.offsetParent = undefined - }, setPointer: function (e) { var pointer = { left: e.pageX, @@ -388,6 +386,9 @@ that.$document[method](eventNames[event], that[event + 'Proxy']) }) }, + clearOffsetParent: function () { + this.offsetParent = undefined + }, // Recursively clear container and item dimensions clearDimensions: function () { this.containerDimensions = undefined @@ -417,7 +418,7 @@ dragInit: function (e) { var rootGroup = this.rootGroup - if( !rootGroup.isHandled && + if( !rootGroup.dragInitDone && e.which === 1 && this.options.drag && !$(e.target).is(this.options.exclude)) @@ -526,7 +527,7 @@ return !this.disabled && (!this.parentContainer || this.parentContainer.enabled()) }, $getChildren: function (parent, type) { - return $(parent).children(this.rootGroup.options[type + "Selector"]) + return $(parent).find(this.rootGroup.options[type + "Selector"]) }, _serialize: function (parent, isContainer) { var that = this, From 6936bb4d8cde9f553317ab5884ca58d210df7169 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Mon, 15 Jul 2013 21:21:38 +0200 Subject: [PATCH 48/97] added new options: (container|item)Path closes #20 --- source/_table.html.haml | 4 ++-- source/js/examples/table.js | 3 ++- source/js/jquery-sortable.js | 14 +++++++++++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/source/_table.html.haml b/source/_table.html.haml index ac3de91..2e948ef 100644 --- a/source/_table.html.haml +++ b/source/_table.html.haml @@ -19,12 +19,12 @@ %p= show_code_button .span4 %h3 Sortable Rows - %table.table.table-striped.table-bordered + %table.table.table-striped.table-bordered.sorted_table %thead %tr %th A Column %th B Column - %tbody.sorted_table + %tbody = iterate(6) do |i, name| %tr %td A #{name} diff --git a/source/js/examples/table.js b/source/js/examples/table.js index dd10e79..cf5a9b1 100644 --- a/source/js/examples/table.js +++ b/source/js/examples/table.js @@ -1,7 +1,8 @@ $(function () { // Sortable rows $('.sorted_table').sortable({ - containerSelector: 'tbody', + containerSelector: 'table', + itemPath: '> tbody', itemSelector: 'tr', placeholder: '' }) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 388aaf4..f524602 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -47,12 +47,16 @@ // This is executed after the placeholder has been moved. afterMove: function ($placeholder, container) { }, + // The exact css path between the container and its items, e.g. "> tbody" + containerPath: "", // The css selector of the containers containerSelector: "ol, ul", // Distance the mouse has to travel to start dragging distance: 0, // The css selector of the drag handle handle: "", + // The exact css path between the item and its subcontainers + itemPath: "", // The css selector of the items itemSelector: "li", // Check if the dragged item may be inside the container. @@ -527,7 +531,15 @@ return !this.disabled && (!this.parentContainer || this.parentContainer.enabled()) }, $getChildren: function (parent, type) { - return $(parent).find(this.rootGroup.options[type + "Selector"]) + var options = this.rootGroup.options, + path = options[type + "Path"], + selector = options[type + "Selector"] + + parent = $(parent) + if(path) + parent = parent.find(path) + + return parent.children(selector) }, _serialize: function (parent, isContainer) { var that = this, From 2fbc8b2aca7a9569bc7e6fe4083e5c006cc62d68 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Mon, 15 Jul 2013 21:26:01 +0200 Subject: [PATCH 49/97] fix bug introduced by cleanup --- source/js/jquery-sortable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index f524602..c7ddab8 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -408,7 +408,7 @@ this.options = $.extend( {}, containerDefaults, options) this.group = ContainerGroup.get(this.options) - this.rootGroup = this.options.rootGroup || this.group + this.rootGroup = this.options.rootGroup = this.options.rootGroup || this.group this.parentContainer = this.options.parentContainer this.handle = this.rootGroup.options.handle || this.rootGroup.options.itemSelector From 8ad566593295b09d9fe219afc99889594c3cd3d1 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Mon, 15 Jul 2013 21:30:42 +0200 Subject: [PATCH 50/97] Release 0.9.11 --- CHANGELOG | 4 ++++ VERSION | 2 +- sortable.jquery.json | 4 ++-- source/js/jquery-sortable-min.js | 34 ++++++++++++++++---------------- source/js/jquery-sortable.js | 2 +- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4b6522a..3a871ac 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +[0.9.11] option tolerance accepts negative values + rewrote enable/disable logic + added (item|container)Path + [0.9.10]Fix Array.indexOf() error in IE < 9 (Dev-Speranza) serialize() assumes one subcontainer per item remove call to stopPropagation() diff --git a/VERSION b/VERSION index 56f3151..8225a4b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.9.10 +0.9.11 diff --git a/sortable.jquery.json b/sortable.jquery.json index d4550f2..a564193 100644 --- a/sortable.jquery.json +++ b/sortable.jquery.json @@ -9,14 +9,14 @@ "drag", "drop" ], - "version": "0.9.10", + "version": "0.9.11", "author": { "name": "Jonas von Andrian" }, "licenses": [ { "type": "BSD-3", - "url": "https://github.com/johnny/jquery-sortable/blob/0.9.10/LICENSE" + "url": "https://github.com/johnny/jquery-sortable/blob/0.9.11/LICENSE" } ], "bugs": "https://github.com/johnny/jquery-sortable/issues", diff --git a/source/js/jquery-sortable-min.js b/source/js/jquery-sortable-min.js index 8e9dd92..68ecd82 100644 --- a/source/js/jquery-sortable-min.js +++ b/source/js/jquery-sortable-min.js @@ -1,17 +1,17 @@ -!function(e,y,h){var k,p,q;function u(a,b){var c=Math.max(0,a[0]-b[0],b[0]-a[1]),d=Math.max(0,a[2]-b[1],b[1]-a[3]);return c+d}function v(a,b,c){for(var d=a.length,c=c?"offset":"position";d--;){var f=a[d].el?a[d].el:e(a[d]),l=f[c]();b[d]=[l.left,l.left+f.outerWidth(!0),l.top,l.top+f.outerHeight(!0)]}}function m(a,b){var c=b.offset();return{left:a.left-c.left,top:a.top-c.top}}function w(a,b,c){for(var b=[b.left,b.top],c=c&&[c.left,c.top],d,f=a.length,e=[];f--;)d=a[f],e[f]=[f,u(d,b),c&&u(d,c)];return e= -e.sort(function(a,b){return b[1]-a[1]||b[2]-a[2]||b[0]-a[0]})}function n(a,b,c,d){a=a.find(b);for(b=a.length;b--;){var f=a.eq(b).data(i);if(f)f[c](d)}}function o(a){this.options=e.extend({},j,a);this.containers=[];this.childGroups=[];this.scrolledProxy=e.proxy(this.scrolled,this);this.dragProxy=e.proxy(this.drag,this);this.dropProxy=e.proxy(this.drop,this);this.options.parentGroup?this.options.parentGroup.childGroups.push(this):(this.placeholder=e(this.options.placeholder),a.isValidTarget||(this.options.isValidTarget= -h))}function r(a,b){this.el=a;this.childGroups=[];this.floatRight=!1;this.dragInitProxy=e.proxy(this.dragInit,this);this.options=e.extend({},z,b);this.group=o.get(this.options);this.rootGroup=this.options.rootGroup=this.options.rootGroup||this.group;this.parentGroup=this.options.parentGroup=this.options.parentGroup||this.group;this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;this.enable(!0)}var i="sortable",z={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},j={afterMove:function(){}, -containerSelector:"ol, ul",distance:0,handle:"",itemSelector:"li",isValidTarget:function(){return!0},onCancel:function(){},onDrag:function(a,b){a.css(b)},onDragStart:function(a){a.css({height:a.height(),width:a.width()});a.addClass("dragged");e("body").addClass("dragging")},onDrop:function(a){a.removeClass("dragged").removeAttr("style");e("body").removeClass("dragging")},onMousedown:function(a,b){b.preventDefault()},placeholder:'
  • ',pullPlaceholder:!0,serialize:function(a,b, -c){a=e.extend({},a.data());if(c)return b;b[0]&&(a.children=b,delete a.subContainer);delete a.sortable;return a},tolerance:0},s={},x=0;"ontouchstart"in y?(k="touchstart.sortable",p="touchend.sortable touchcancel.sortable",q="touchmove.sortable"):(k="mousedown.sortable",p="mouseup.sortable",q="mousemove.sortable");o.get=function(a){if(!s[a.group]){if(!a.group)a.group=x++;s[a.group]=new o(a)}return s[a.group]};o.prototype={dragInit:function(a,b){this.$document=e(b.el[0].ownerDocument);this.toggleListeners("on"); -this.item=e(a.target).closest(this.options.itemSelector);this.itemContainer=b;this.setPointer(a);this.options.onMousedown(this.item,a,j.onMousedown)},drag:function(a){if(!this.dragging){if(!this.distanceMet(a))return;n(this.item,this.options.containerSelector,"disable",true);this.options.onDragStart(this.item,this.itemContainer,j.onDragStart);this.item.before(this.placeholder);this.dragging=true}this.setPointer(a);this.options.onDrag(this.item,m(this.pointer,this.item.offsetParent()),j.onDrag);var b= -a.pageX,a=a.pageY,c=this.sameResultBox,d=this.options.tolerance;if(!c||c.top-d>a||c.bottom+db||c.right+d=this.options.distance},addContainer:function(a){this.containers.push(a)},removeContainer:function(a){a=e.inArray(a,this.containers);if(a!==-1){var b=this.containers,c=b.slice(a+1||b.length);b.length=a<0?b.length+a:a;b.push.apply(b,c)}},scrolled:function(){this.clearDimensions();this.clearOffsetParent()},toggleListeners:function(a){this.$document[a](q,this.dragProxy)[a](p,this.dropProxy)[a]("scroll.sortable", -this.scrolledProxy)},clearDimensions:function(){this.containerDimensions=h;for(var a=this.containers.length;a--;)this.containers[a].itemDimensions=h;for(a=this.childGroups.length;a--;)this.childGroups[a].clearDimensions()}};r.prototype={dragInit:function(a){var b=this.rootGroup;!b.item&&a.which===1&&this.options.drag&&!e(a.target).is(this.options.exclude)&&b.dragInit(a,this)},searchValidTarget:function(a,b){var c=w(this.getItemDimensions(),a,b),d=c.length,f=this.rootGroup,e=!f.options.isValidTarget|| -f.options.isValidTarget(f.item,this);if(!d&&e){f.movePlaceholder(this,this.el,"append");return true}for(;d--;){f=c[d][0];if(!c[d][1]&&this.options.nested&&this.getContainerGroup(f)){if(this.getContainerGroup(f).searchValidTarget(a,b))return true}else if(e){this.movePlaceholder(f,a);return true}}},movePlaceholder:function(a,b){var c=e(this.items[a]),d=this.itemDimensions[a],f="after",h=c.outerWidth(),i=c.outerHeight(),g=c.offset(),g={left:g.left,right:g.left+h,top:g.top,bottom:g.top+i};if(this.options.vertical)if(b.top<= -(d[2]+d[3])/2){f="before";g.bottom=g.bottom-i/2}else g.top=g.top+i/2;else if(b.left<=(d[0]+d[1])/2!=this.floatRight){f="before";g.right=g.right-h/2}else g.left=g.left+h/2;this.rootGroup.movePlaceholder(this,c,f,g)},getItemDimensions:function(){if(!this.itemDimensions){this.items=this.$getChildren(this.el,"item").filter(":not(.dragged)").get();v(this.items,this.itemDimensions=[])}return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return a.css("position")==="relative"||a.css("position")=== -"absolute"||a.css("position")==="fixed"?a:a.offsetParent()},getContainerGroup:function(a){var b=e.data(this.items[a],"subContainer");if(b===h){var c=this.$getChildren(this.items[a],"container"),b=false;if(c[0]){b=e.extend({},this.options,{parentGroup:this.group,group:x++});b=c[i](b).data(i).group}e.data(this.items[a],"subContainer",b)}return b},$getChildren:function(a,b){return e(a).children(this.rootGroup.options[b+"Selector"])},_serialize:function(a,b){var c=this,d=this.$getChildren(a,b?"item": -"container").not(this.options.exclude).map(function(){return c._serialize(e(this),!b)}).get();return this.rootGroup.options.serialize(a,d,b)}};var t={enable:function(a){this.options.drop&&this.group.addContainer(this);a||n(this.el,this.options.containerSelector,"enable",true);this.el.on(k,this.handle,this.dragInitProxy)},disable:function(a){this.options.drop&&this.group.removeContainer(this);a||n(this.el,this.options.containerSelector,"disable",true);this.el.off(k)},serialize:function(){return this._serialize(this.el, -true)}};e.extend(r.prototype,t);e.fn[i]=function(a){var b=Array.prototype.slice.call(arguments,1);return this.map(function(){var c=e(this),d=c.data(i);if(d&&t[a])return t[a].apply(d,b)||this;!d&&(a===h||typeof a==="object")&&c.data(i,new r(c,a));return this})}}(jQuery,window); +!function(e,x,h){function r(a,b){var c=Math.max(0,a[0]-b[0],b[0]-a[1]),d=Math.max(0,a[2]-b[1],b[1]-a[3]);return c+d}function s(a,b,c,d){for(var f=a.length,d=d?"offset":"position",c=c||0;f--;){var k=a[f].el?a[f].el:e(a[f]),i=k[d]();i.left+=parseInt(k.css("margin-left"),10);i.top+=parseInt(k.css("margin-top"),10);b[f]=[i.left-c,i.left+k.outerWidth()+c,i.top-c,i.top+k.outerHeight()+c]}}function l(a,b){var c=b.offset();return{left:a.left-c.left,top:a.top-c.top}}function t(a,b,c){for(var b=[b.left,b.top], +c=c&&[c.left,c.top],d,f=a.length,e=[];f--;)d=a[f],e[f]=[f,r(d,b),c&&r(d,c)];return e=e.sort(function(a,b){return b[1]-a[1]||b[2]-a[2]||b[0]-a[0]})}function m(a){this.options=e.extend({},j,a);this.containers=[];this.scrollProxy=e.proxy(this.scroll,this);this.dragProxy=e.proxy(this.drag,this);this.dropProxy=e.proxy(this.drop,this);this.options.parentContainer||(this.placeholder=e(this.options.placeholder),a.isValidTarget||(this.options.isValidTarget=h))}function n(a,b){this.el=a;this.options=e.extend({}, +v,b);this.group=m.get(this.options);this.rootGroup=this.options.rootGroup=this.options.rootGroup||this.group;this.parentContainer=this.options.parentContainer;this.handle=this.rootGroup.options.handle||this.rootGroup.options.itemSelector;this.el.on(o.start,this.handle,e.proxy(this.dragInit,this));this.options.drop&&this.group.containers.push(this)}var o,v={drag:!0,drop:!0,exclude:"",nested:!0,vertical:!0},j={afterMove:function(){},containerPath:"",containerSelector:"ol, ul",distance:0,handle:"",itemPath:"", +itemSelector:"li",isValidTarget:function(){return!0},onCancel:function(){},onDrag:function(a,b){a.css(b)},onDragStart:function(a){a.css({height:a.height(),width:a.width()});a.addClass("dragged");e("body").addClass("dragging")},onDrop:function(a){a.removeClass("dragged").removeAttr("style");e("body").removeClass("dragging")},onMousedown:function(a,b){b.preventDefault()},placeholder:'
  • ',pullPlaceholder:!0,serialize:function(a,b,c){a=e.extend({},a.data());if(c)return b;b[0]&& +(a.children=b,delete a.subContainer);delete a.sortable;return a},tolerance:0},p={},u=0,w={left:0,top:0,bottom:0,right:0};o={start:"touchstart.sortable mousedown.sortable",drop:"touchend.sortable touchcancel.sortable mouseup.sortable",drag:"touchmove.sortable mousemove.sortable",scroll:"scroll.sortable"};m.get=function(a){p[a.group]||(a.group||(a.group=u++),p[a.group]=new m(a));return p[a.group]};m.prototype={dragInit:function(a,b){this.$document=e(b.el[0].ownerDocument);b.enabled()?(this.toggleListeners("on"), +this.item=e(a.target).closest(this.options.itemSelector),this.itemContainer=b,this.setPointer(a),this.options.onMousedown(this.item,a,j.onMousedown)):this.toggleListeners("on",["drop"]);this.dragInitDone=!0},drag:function(a){if(!this.dragging){if(!this.distanceMet(a))return;this.options.onDragStart(this.item,this.itemContainer,j.onDragStart);this.item.before(this.placeholder);this.dragging=!0}this.setPointer(a);this.options.onDrag(this.item,l(this.pointer,this.item.offsetParent()),j.onDrag);var b= +a.pageX,a=a.pageY,c=this.sameResultBox,d=this.options.tolerance;if(!c||c.top-d>a||c.bottom+db||c.right+d=this.options.distance},scroll:function(){this.clearDimensions();this.clearOffsetParent()},toggleListeners:function(a,b){var c=this,b=b||["drag","drop","scroll"];e.each(b,function(b,f){c.$document[a](o[f],c[f+"Proxy"])})},clearOffsetParent:function(){this.offsetParent=h},clearDimensions:function(){this.containerDimensions=h;for(var a=this.containers.length;a--;)this.containers[a].clearDimensions()}};n.prototype={dragInit:function(a){var b=this.rootGroup; +!b.dragInitDone&&1===a.which&&this.options.drag&&!e(a.target).is(this.options.exclude)&&b.dragInit(a,this)},searchValidTarget:function(a,b){var c=t(this.getItemDimensions(),a,b),d=c.length,f=this.rootGroup,e=!f.options.isValidTarget||f.options.isValidTarget(f.item,this);if(!d&&e)return f.movePlaceholder(this,this.el,"append"),!0;for(;d--;)if(f=c[d][0],!c[d][1]&&this.hasChildGroup(f)){if(this.getContainerGroup(f).searchValidTarget(a,b))return!0}else if(e)return this.movePlaceholder(f,a),!0},movePlaceholder:function(a, +b){var c=e(this.items[a]),d=this.itemDimensions[a],f="after",h=c.outerWidth(),i=c.outerHeight(),g=c.offset(),g={left:g.left,right:g.left+h,top:g.top,bottom:g.top+i};this.options.vertical?b.top<=(d[2]+d[3])/2?(f="before",g.bottom-=i/2):g.top+=i/2:b.left<=(d[0]+d[1])/2?(f="before",g.right-=h/2):g.left+=h/2;this.hasChildGroup(a)&&(g=w);this.rootGroup.movePlaceholder(this,c,f,g)},getItemDimensions:function(){this.itemDimensions||(this.items=this.$getChildren(this.el,"item").filter(":not(.placeholder, .dragged)").get(), +s(this.items,this.itemDimensions=[],this.options.tolerance));return this.itemDimensions},getItemOffsetParent:function(){var a=this.el;return"relative"===a.css("position")||"absolute"===a.css("position")||"fixed"===a.css("position")?a:a.offsetParent()},hasChildGroup:function(a){return this.options.nested&&this.getContainerGroup(a)},getContainerGroup:function(a){var b=e.data(this.items[a],"subContainer");if(b===h){var c=this.$getChildren(this.items[a],"container"),b=!1;c[0]&&(b=e.extend({},this.options, +{parentContainer:this,group:u++}),b=c.sortable(b).data("sortable").group);e.data(this.items[a],"subContainer",b)}return b},enabled:function(){return!this.disabled&&(!this.parentContainer||this.parentContainer.enabled())},$getChildren:function(a,b){var c=this.rootGroup.options,d=c[b+"Path"],c=c[b+"Selector"],a=e(a);d&&(a=a.find(d));return a.children(c)},_serialize:function(a,b){var c=this,d=this.$getChildren(a,b?"item":"container").not(this.options.exclude).map(function(){return c._serialize(e(this), +!b)}).get();return this.rootGroup.options.serialize(a,d,b)},clearDimensions:function(){this.itemDimensions=h;if(this.items&&this.items[0])for(var a=this.items.length;a--;){var b=e.data(this.items[a],"subContainer");b&&b.clearDimensions()}}};var q={enable:function(){this.disabled=!1},disable:function(){this.disabled=!0},serialize:function(){return this._serialize(this.el,!0)}};e.extend(n.prototype,q);e.fn.sortable=function(a){var b=Array.prototype.slice.call(arguments,1);return this.map(function(){var c= +e(this),d=c.data("sortable");if(d&&q[a])return q[a].apply(d,b)||this;!d&&(a===h||"object"===typeof a)&&c.data("sortable",new n(c,a));return this})}}(jQuery,window); diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index c7ddab8..753061e 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -1,5 +1,5 @@ /* =================================================== - * jquery-sortable.js v0.9.10 + * jquery-sortable.js v0.9.11 * http://johnny.github.com/jquery-sortable/ * =================================================== * Copyright (c) 2012 Jonas von Andrian From 692610c42a17be8885b40fd401f15566dd232871 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Wed, 17 Jul 2013 17:01:55 +0200 Subject: [PATCH 51/97] added destroy method --- source/js/jquery-sortable.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 753061e..6ddcf8d 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -200,12 +200,13 @@ function ContainerGroup(options) { this.options = $.extend({}, groupDefaults, options) this.containers = [] - this.scrollProxy = $.proxy(this.scroll, this) - this.dragProxy = $.proxy(this.drag, this) - this.dropProxy = $.proxy(this.drop, this) if(!this.options.parentContainer){ + this.scrollProxy = $.proxy(this.scroll, this) + this.dragProxy = $.proxy(this.drag, this) + this.dropProxy = $.proxy(this.drop, this) this.placeholder = $(this.options.placeholder) + if(!options.isValidTarget) this.options.isValidTarget = undefined } @@ -400,6 +401,11 @@ while(i--){ this.containers[i].clearDimensions() } + }, + destroy: function () { + // TODO iterate over subgroups and destroy them + // TODO remove all events + containerGroups[this.options.group] = undefined } } @@ -519,6 +525,7 @@ if(childContainers[0]){ var options = $.extend({}, this.options, { parentContainer: this, + rootGroup: this.rootGroup, group: groupCounter ++ }) childGroup = childContainers[pluginName](options).data(pluginName).group @@ -573,6 +580,9 @@ }, serialize: function () { return this._serialize(this.el, true) + }, + destroy: function () { + this.rootGroup.destroy() } } From b5defe9480161a5e27da70f0dc797de790322a19 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Fri, 19 Jul 2013 17:35:16 +0200 Subject: [PATCH 52/97] update alternatives --- source/index.html.haml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/index.html.haml b/source/index.html.haml index 987fce3..48236d7 100644 --- a/source/index.html.haml +++ b/source/index.html.haml @@ -217,11 +217,12 @@ %ul %li %a(href="http://farhadi.ir/projects/html5sortable/") HTML5 Sortable - ( uses native dnd events) + (uses native dnd events) %li %a(href="http://jqueryui.com/demos/sortable/") jQuery UI sortable %li - %a(href="http://dbushell.github.com/Nestable/") Nestable (requires no jQuery UI) + %a(href="http://dbushell.github.com/Nestable/") Nestable + (requires no jQuery UI) %li %a(href="http://mjsarfatti.com/sandbox/nestedSortable/") nestedSortable (an extension of jQuery UI) From 6e6f14b7733652d160fdaeaf0830309564ff57be Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Thu, 29 Aug 2013 20:10:51 +0200 Subject: [PATCH 53/97] dragInit event handler respects itemPath closes #29 --- source/js/jquery-sortable.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 6ddcf8d..1e1a138 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -414,11 +414,14 @@ this.options = $.extend( {}, containerDefaults, options) this.group = ContainerGroup.get(this.options) - this.rootGroup = this.options.rootGroup = this.options.rootGroup || this.group + this.rootGroup = this.options.rootGroup || this.group this.parentContainer = this.options.parentContainer this.handle = this.rootGroup.options.handle || this.rootGroup.options.itemSelector - this.el.on(eventNames.start, this.handle, $.proxy(this.dragInit, this)) + var itemPath = this.rootGroup.options.itemPath, + target = itemPath ? this.el.find(itemPath) : this.el + + target.on(eventNames.start, this.handle, $.proxy(this.dragInit, this)) if(this.options.drop) this.group.containers.push(this) From ccd7d58cdc895f776e56f92f9f9e1a80de7912cc Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Thu, 29 Aug 2013 20:15:50 +0200 Subject: [PATCH 54/97] make mouse events available in configurable event handlers closes #36 --- source/js/jquery-sortable.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 1e1a138..ee5e762 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -67,11 +67,11 @@ }, // Executed before onDrop if placeholder is detached. // This happens if pullPlaceholder is set to false and the drop occurs outside a container. - onCancel: function ($item, container, _super) { + onCancel: function ($item, container, _super, event) { }, // Executed at the beginning of a mouse move event. // The Placeholder has not been moved yet. - onDrag: function ($item, position, _super) { + onDrag: function ($item, position, _super, event) { $item.css(position) }, // Called after the drag has been started, @@ -79,7 +79,7 @@ // the mouse is moving. // The container is the closest initialized container. // Therefore it might not be the container, that actually contains the item. - onDragStart: function ($item, container, _super) { + onDragStart: function ($item, container, _super, event) { $item.css({ height: $item.height(), width: $item.width() @@ -88,12 +88,12 @@ $("body").addClass("dragging") }, // Called when the mouse button is beeing released - onDrop: function ($item, container, _super) { + onDrop: function ($item, container, _super, event) { $item.removeClass("dragged").removeAttr("style") $("body").removeClass("dragging") }, // Called on mousedown. - onMousedown: function($item, event, _super) { + onMousedown: function($item, _super, event) { event.preventDefault() }, // Template for the placeholder. Can be any valid jQuery input @@ -234,7 +234,7 @@ this.setPointer(e) - this.options.onMousedown(this.item, e, groupDefaults.onMousedown) + this.options.onMousedown(this.item, groupDefaults.onMousedown, e) } else { this.toggleListeners('on', ['drop']) } @@ -246,7 +246,7 @@ if(!this.distanceMet(e)) return - this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart) + this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart, e) this.item.before(this.placeholder) this.dragging = true } @@ -255,7 +255,8 @@ // place item under the cursor this.options.onDrag(this.item, getRelativePosition(this.pointer, this.item.offsetParent()), - groupDefaults.onDrag) + groupDefaults.onDrag, + e) var x = e.pageX, y = e.pageY, @@ -276,9 +277,9 @@ if(this.placeholder.closest("html")[0]) this.placeholder.before(this.item).detach() else - this.options.onCancel(this.item, this.itemContainer, groupDefaults.onCancel) + this.options.onCancel(this.item, this.itemContainer, groupDefaults.onCancel, e) - this.options.onDrop(this.item, this.getContainer(this.item), groupDefaults.onDrop) + this.options.onDrop(this.item, this.getContainer(this.item), groupDefaults.onDrop, e) // cleanup this.clearDimensions() From b7996faafe26151a7f1231f6946af4902ac0498a Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 28 Sep 2013 15:15:34 +0200 Subject: [PATCH 55/97] Modify behaviour of onMousedown option Falsy return value prevents dragging --- source/js/jquery-sortable.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index ee5e762..93da0c5 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -92,9 +92,10 @@ $item.removeClass("dragged").removeAttr("style") $("body").removeClass("dragging") }, - // Called on mousedown. + // Called on mousedown. If falsy value is returned, the dragging will not start. onMousedown: function($item, _super, event) { event.preventDefault() + return true }, // Template for the placeholder. Can be any valid jQuery input // e.g. a string, a DOM element. @@ -226,15 +227,15 @@ this.$document = $(itemContainer.el[0].ownerDocument) if(itemContainer.enabled()){ - this.toggleListeners('on') - // get item to drag this.item = $(e.target).closest(this.options.itemSelector) this.itemContainer = itemContainer - this.setPointer(e) + if(!this.options.onMousedown(this.item, groupDefaults.onMousedown, e)) + return - this.options.onMousedown(this.item, groupDefaults.onMousedown, e) + this.setPointer(e) + this.toggleListeners('on') } else { this.toggleListeners('on', ['drop']) } From 474b9a0cb5ccabe041b5eaf393dbfd0c23d6ebcb Mon Sep 17 00:00:00 2001 From: jogaco Date: Wed, 4 Dec 2013 10:56:53 +0100 Subject: [PATCH 56/97] Fixes #53: input elements can still gain focus on click when inside sortable elements --- source/js/jquery-sortable.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 93da0c5..3a3a1db 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -93,9 +93,12 @@ $("body").removeClass("dragging") }, // Called on mousedown. If falsy value is returned, the dragging will not start. - onMousedown: function($item, _super, event) { - event.preventDefault() - return true + // If clicked on input element, ignore + onMousedown: function ($item, _super, event) { + if (event.target.nodeName != 'INPUT') { + event.preventDefault() + return true + } }, // Template for the placeholder. Can be any valid jQuery input // e.g. a string, a DOM element. From 6b99f04f849f62af057db0342887191d69d7a6ae Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Fri, 6 Dec 2013 21:36:47 +0100 Subject: [PATCH 57/97] added debug page to work locally with jsfiddles --- config.rb | 2 +- source/debug.html.erb | 52 +++++++++++++++++++++++++++++++++++++++ source/js/debug.js | 12 +++++++++ source/layouts/debug.haml | 10 ++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 source/debug.html.erb create mode 100644 source/js/debug.js create mode 100644 source/layouts/debug.haml diff --git a/config.rb b/config.rb index 764ce94..746fa4a 100644 --- a/config.rb +++ b/config.rb @@ -21,7 +21,7 @@ # page "/path/to/file.html", :layout => false # # With alternative layout -# page "/path/to/file.html", :layout => :otherlayout +page "/debug.html", :layout => 'debug.haml' # # A path which all have the same layout # with_layout :admin do diff --git a/source/debug.html.erb b/source/debug.html.erb new file mode 100644 index 0000000..25de6b3 --- /dev/null +++ b/source/debug.html.erb @@ -0,0 +1,52 @@ + + +
    +
    + Part 1 +
    +
    +
    +
    + Part 2 +
    +
    +
    +
    + Part 3 +
    +
    + Part 4 +
    +
    +
    +
    + Part 5 +
    +
    \ No newline at end of file diff --git a/source/js/debug.js b/source/js/debug.js new file mode 100644 index 0000000..dfc3754 --- /dev/null +++ b/source/js/debug.js @@ -0,0 +1,12 @@ +//= require "vendor/jquery" +//= require "jquery-sortable" + +$(function () { + $('#root.region').sortable({ + group: 'nested', + itemSelector: '.part, .layout', + containerSelector: '.region', + nested: true, + placeholder: '
    Drop here
    ', + }); +}) diff --git a/source/layouts/debug.haml b/source/layouts/debug.haml new file mode 100644 index 0000000..58c79fa --- /dev/null +++ b/source/layouts/debug.haml @@ -0,0 +1,10 @@ +!!! +%html + %head + %title jQuery Sortable + %link(rel="stylesheet" href="css/vendor.css") + %link(rel="stylesheet" href="css/application.css") + %body + .bootstrap-container + = yield + %script(src="js/debug.js") From 0f221c6e5d545d9fefa83e12d931ec236390df0e Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Thu, 12 Dec 2013 06:58:56 +0100 Subject: [PATCH 58/97] Fix loading of childgroups if index is 0 closes #41 --- TODO | 4 +++- source/js/jquery-sortable.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 3121870..b037987 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,6 @@ -- [0/0] bugs +- [0/2] bugs + - [ ] last Pointer is NaN in search valid target + - [ ] prevent infinite recursion - [0/5] consider - [ ] better name for searchValidTarget - [ ] shortcut on getNearest() diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 93da0c5..ddd8f20 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -215,7 +215,7 @@ ContainerGroup.get = function (options) { if( !containerGroups[options.group]) { - if(!options.group) + if(options.group === undefined) options.group = groupCounter ++ containerGroups[options.group] = new ContainerGroup(options) } From ebe5c2a7e93db48d4fe022313c15d538d2445b7b Mon Sep 17 00:00:00 2001 From: Romain Date: Thu, 12 Dec 2013 19:01:37 +0100 Subject: [PATCH 59/97] Fixed missing ";" --- source/js/jquery-sortable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 0d488b2..9c93335 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -620,4 +620,4 @@ }); }; -}(jQuery, window) +}(jQuery, window); From d1a5f85d14b8f2f2b748b7d06d0db4ee3f4045a1 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Fri, 13 Dec 2013 18:42:03 +0100 Subject: [PATCH 60/97] handle appending a single item respects the itemPath closes #56 --- source/js/jquery-sortable.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 0d488b2..ff5f600 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -452,7 +452,10 @@ rootGroup.options.isValidTarget(rootGroup.item, this) if(!i && validTarget){ - rootGroup.movePlaceholder(this, this.el, "append") + var itemPath = this.rootGroup.options.itemPath, + target = itemPath ? this.el.find(itemPath) : this.el + + rootGroup.movePlaceholder(this, target, "append") return true } else while(i--){ From 34c28dca8a00fe75119a010c415efef3744b65d3 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Wed, 8 Jan 2014 09:02:52 +0100 Subject: [PATCH 61/97] Expose the closest item or container in afterMove closes #48 --- Gemfile | 3 +- Gemfile.lock | 137 ++++++++++++++--------------------- source/js/jquery-sortable.js | 19 +++-- 3 files changed, 69 insertions(+), 90 deletions(-) diff --git a/Gemfile b/Gemfile index c457f7c..2fcf6f5 100644 --- a/Gemfile +++ b/Gemfile @@ -2,8 +2,9 @@ source "http://rubygems.org" gem 'thin' -gem 'sass', :git => 'https://github.com/nex3/sass.git' +gem 'sass', '~> 3.1.0' +gem 'compass' gem 'middleman', '>= 3' gem 'guard-livereload' diff --git a/Gemfile.lock b/Gemfile.lock index 5a71aaf..bd11fa4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,26 +5,20 @@ GIT specs: sass-twitter-bootstrap (2.0.4) -GIT - remote: https://github.com/nex3/sass.git - revision: 1edbe5841971a4cdab0ac63de360973289e700ec - specs: - sass (3.2.0.alpha.0) - GEM remote: http://rubygems.org/ specs: - activesupport (3.2.6) - i18n (~> 0.6) + activesupport (3.2.16) + i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) addressable (2.2.8) - chunky_png (1.2.5) + chunky_png (1.2.9) closure-compiler (1.1.6) coderay (1.0.7) coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.3.3) + coffee-script-source (1.6.3) compass (0.12.2) chunky_png (~> 1.2) fssm (>= 0.2.7) @@ -36,8 +30,8 @@ GEM eventmachine (0.12.10) execjs (1.4.0) multi_json (~> 1.0) - ffi (1.0.11) - fssm (0.2.9) + ffi (1.9.3) + fssm (0.2.10) guard (1.2.3) listen (>= 0.4.2) thor (>= 0.14.6) @@ -45,113 +39,94 @@ GEM em-websocket (>= 0.2.0) guard (>= 1.1.0) multi_json (~> 1.0) - haml (3.1.6) - hike (1.2.1) + haml (4.0.5) + tilt + hike (1.2.3) hpricot (0.8.6) - http_router (0.10.2) - rack (>= 1.0.0) - url_mount (~> 0.2.1) - i18n (0.6.0) - libv8 (3.3.10.4) - listen (0.4.7) - rb-fchange (~> 0.0.5) - rb-fsevent (~> 0.9.1) - rb-inotify (~> 0.8.8) - maruku (0.6.0) - syntax (>= 1.0.0) - middleman (3.0.0) - middleman-core (= 3.0.0) - middleman-more (= 3.0.0) - middleman-sprockets (= 3.0.0) - middleman-core (3.0.0) - activesupport (~> 3.2.6) - bundler (~> 1.1) - listen (~> 0.4.7) - rack (~> 1.4.1) - rack-test (~> 0.6.1) - thor (~> 0.15.4) - tilt (~> 1.3.1) - middleman-more (3.0.0) + i18n (0.6.9) + kramdown (1.3.1) + libv8 (3.16.14.3) + listen (1.1.6) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + rb-kqueue (>= 0.2) + middleman (3.2.1) coffee-script (~> 2.2.0) - coffee-script-source (~> 1.3.3) compass (>= 0.12.2) execjs (~> 1.4.0) haml (>= 3.1.6) - i18n (~> 0.6.0) - maruku (~> 0.6.0) - middleman-core (= 3.0.0) - padrino-helpers (= 0.10.7) + kramdown (~> 1.2) + middleman-core (= 3.2.1) + middleman-sprockets (>= 3.1.2) sass (>= 3.1.20) - uglifier (~> 1.2.6) - middleman-sprockets (3.0.0) - middleman-more (= 3.0.0) + uglifier (~> 2.1.0) + middleman-core (3.2.1) + activesupport (~> 3.2.6) + bundler (~> 1.1) + i18n (~> 0.6.1) + listen (~> 1.1) + rack (>= 1.4.5) + rack-test (~> 0.6.1) + thor (>= 0.15.2, < 2.0) + tilt (~> 1.4.1) + middleman-sprockets (3.2.0) + middleman-core (~> 3.2) sprockets (~> 2.1) - sprockets-sass (~> 0.8.0) - multi_json (1.3.6) - padrino-core (0.10.7) - activesupport (~> 3.2.0) - http_router (~> 0.10.2) - sinatra (~> 1.3.1) - thor (~> 0.15.2) - tilt (~> 1.3.0) - padrino-helpers (0.10.7) - i18n (~> 0.6) - padrino-core (= 0.10.7) - rack (1.4.1) + sprockets-helpers (~> 1.0.0) + sprockets-sass (~> 1.0.0) + multi_json (1.8.2) + rack (1.5.2) rack-coderay (0.2.0) coderay (>= 0.8.312) hpricot (>= 0.8.1) rack (>= 1.0.0) rack-livereload (0.3.6) rack - rack-protection (1.2.0) - rack - rack-test (0.6.1) + rack-test (0.6.2) rack (>= 1.0) - rb-fchange (0.0.5) - ffi - rb-fsevent (0.9.1) - rb-inotify (0.8.8) + rb-fsevent (0.9.4) + rb-inotify (0.9.3) + ffi (>= 0.5.0) + rb-kqueue (0.2.0) ffi (>= 0.5.0) rdiscount (1.6.8) - sinatra (1.3.2) - rack (~> 1.3, >= 1.3.6) - rack-protection (~> 1.2) - tilt (~> 1.3, >= 1.3.3) - sprockets (2.4.5) + ref (1.0.5) + sass (3.1.21) + sprockets (2.10.1) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sprockets-sass (0.8.0) + sprockets-helpers (1.0.1) + sprockets (~> 2.0) + sprockets-sass (1.0.2) sprockets (~> 2.0) tilt (~> 1.1) - syntax (1.0.0) - therubyracer (0.10.1) - libv8 (~> 3.3.10) + therubyracer (0.12.0) + libv8 (~> 3.16.14.0) + ref thin (1.4.1) daemons (>= 1.0.9) eventmachine (>= 0.12.6) rack (>= 1.0.0) - thor (0.15.4) - tilt (1.3.3) - uglifier (1.2.6) + thor (0.18.1) + tilt (1.4.1) + uglifier (2.1.2) execjs (>= 0.3.0) - multi_json (~> 1.3) - url_mount (0.2.1) - rack + multi_json (~> 1.0, >= 1.0.2) PLATFORMS ruby DEPENDENCIES closure-compiler + compass guard-livereload middleman (>= 3) rack-coderay rack-livereload rdiscount - sass! + sass (~> 3.1.0) sass-twitter-bootstrap (= 2.0.4)! therubyracer thin diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index b6ecb40..73ced26 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -45,7 +45,10 @@ }, // end container defaults groupDefaults = { // This is executed after the placeholder has been moved. - afterMove: function ($placeholder, container) { + // $closestItemOrContainer contains the closest item, the placeholder + // has been put at or the closest empty Container, the placeholder has + // been appended to. + afterMove: function ($placeholder, container, $closestItemOrContainer) { }, // The exact css path between the container and its items, e.g. "> tbody" containerPath: "", @@ -112,7 +115,7 @@ // Note that this default method only works, if every item only has one subcontainer serialize: function ($parent, $children, parentIsContainer) { var result = $.extend({}, $parent.data()) - + if(parentIsContainer) return $children else if ($children[0]){ @@ -210,7 +213,7 @@ this.dragProxy = $.proxy(this.drag, this) this.dropProxy = $.proxy(this.drop, this) this.placeholder = $(this.options.placeholder) - + if(!options.isValidTarget) this.options.isValidTarget = undefined } @@ -331,7 +334,7 @@ item[method](this.placeholder) this.lastAppendedItem = item this.sameResultBox = sameResultBox - this.options.afterMove(this.placeholder, container) + this.options.afterMove(this.placeholder, container, item) }, getContainerDimensions: function () { if(!this.containerDimensions) @@ -358,7 +361,7 @@ } } } - + this.offsetParent = offsetParent } return this.offsetParent @@ -562,11 +565,11 @@ _serialize: function (parent, isContainer) { var that = this, childType = isContainer ? "item" : "container", - + children = this.$getChildren(parent, childType).not(this.options.exclude).map(function () { return that._serialize($(this), !isContainer) }).get() - + return this.rootGroup.options.serialize(parent, children, isContainer) }, clearDimensions: function () { @@ -598,7 +601,7 @@ } $.extend(Container.prototype, API) - + /** * jQuery API * From 354e9e3b7c8402275b856c4eb5247026d69a46db Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Wed, 8 Jan 2014 09:12:09 +0100 Subject: [PATCH 62/97] fix css for "Connected lists with drop animation" example closes #59 --- source/css/application.css.sass | 3 +++ source/css/jquery-sortable.css.sass | 1 + 2 files changed, 4 insertions(+) diff --git a/source/css/application.css.sass b/source/css/application.css.sass index 7752796..62ec8e3 100644 --- a/source/css/application.css.sass +++ b/source/css/application.css.sass @@ -48,6 +48,9 @@ ol.nested_with_switch, ol.simple_with_animation, ol.default li cursor: pointer +ol.simple_with_animation + border: 1px solid $grayLight + .switch-container display: block margin-left: auto diff --git a/source/css/jquery-sortable.css.sass b/source/css/jquery-sortable.css.sass index 2a9ef5d..655ab43 100644 --- a/source/css/jquery-sortable.css.sass +++ b/source/css/jquery-sortable.css.sass @@ -9,6 +9,7 @@ body.dragging, body.dragging * ol.vertical margin: 0 0 9px 0 + min-height: 10px li display: block margin: 5px From f5387c1fb91c46695beda3d8bb3da9981af30c79 Mon Sep 17 00:00:00 2001 From: troggy <7r0ggy@gmail.com> Date: Mon, 3 Feb 2014 17:50:23 +0300 Subject: [PATCH 63/97] Ability to specify certain delay before drag start to be captured #64 --- source/js/jquery-sortable.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 73ced26..9b33968 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -56,6 +56,9 @@ containerSelector: "ol, ul", // Distance the mouse has to travel to start dragging distance: 0, + // Time in milliseconds after mousedown until dragging should start. + // This option can be used to prevent unwanted drags when clicking on an element. + delay: 0, // The css selector of the drag handle handle: "", // The exact css path between the item and its subcontainers @@ -247,12 +250,26 @@ } this.dragInitDone = true + + // init delay timer if needed + var that = this + this.isDelayMet = !this.options.delay + if (!this.isDelayMet) { + clearTimeout(this._mouseDelayTimer); + this._mouseDelayTimer = setTimeout(function() { + that.isDelayMet = true + }, this.options.delay) + } + }, drag: function (e) { if(!this.dragging){ if(!this.distanceMet(e)) return + if (!this.delayMet()) + return + this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart, e) this.item.before(this.placeholder) this.dragging = true @@ -387,6 +404,9 @@ Math.abs(this.pointer.top - e.pageY) ) >= this.options.distance) }, + delayMet: function () { + return this.isDelayMet; + }, scroll: function (e) { this.clearDimensions() this.clearOffsetParent() From c77bafd32539c3f3154ac66f2d520578c56a95f2 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Wed, 19 Feb 2014 21:40:28 +0100 Subject: [PATCH 64/97] some polish --- TODO | 3 +++ source/js/jquery-sortable.js | 30 +++++++++++++----------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/TODO b/TODO index b037987..9b72f62 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,9 @@ +- [0/1] exampels + - [ ] delay - [0/2] bugs - [ ] last Pointer is NaN in search valid target - [ ] prevent infinite recursion + - [ ] bootstrap example jumps up on drop - [0/5] consider - [ ] better name for searchValidTarget - [ ] shortcut on getNearest() diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 9b33968..398f3a8 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -249,25 +249,12 @@ this.toggleListeners('on', ['drop']) } + this.setupDelayTimer() this.dragInitDone = true - - // init delay timer if needed - var that = this - this.isDelayMet = !this.options.delay - if (!this.isDelayMet) { - clearTimeout(this._mouseDelayTimer); - this._mouseDelayTimer = setTimeout(function() { - that.isDelayMet = true - }, this.options.delay) - } - }, drag: function (e) { if(!this.dragging){ - if(!this.distanceMet(e)) - return - - if (!this.delayMet()) + if(!this.distanceMet(e) || !this.delayMet) return this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart, e) @@ -404,8 +391,17 @@ Math.abs(this.pointer.top - e.pageY) ) >= this.options.distance) }, - delayMet: function () { - return this.isDelayMet; + setupDelayTimer: function () { + var that = this + this.delayMet = !this.options.delay + + // init delay timer if needed + if (!this.delayMet) { + clearTimeout(this._mouseDelayTimer); + this._mouseDelayTimer = setTimeout(function() { + that.delayMet = true + }, this.options.delay) + } }, scroll: function (e) { this.clearDimensions() From 828d4c145c4ea1d2f5ba1a949f9d708c7e0f2f86 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Wed, 19 Feb 2014 22:06:40 +0100 Subject: [PATCH 65/97] fix exclusion of items closes #66 --- source/js/jquery-sortable.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 398f3a8..801fd80 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -240,8 +240,10 @@ this.item = $(e.target).closest(this.options.itemSelector) this.itemContainer = itemContainer - if(!this.options.onMousedown(this.item, groupDefaults.onMousedown, e)) + if(this.item.is(this.options.exclude) || + !this.options.onMousedown(this.item, groupDefaults.onMousedown, e)){ return + } this.setPointer(e) this.toggleListeners('on') @@ -457,9 +459,9 @@ if( !rootGroup.dragInitDone && e.which === 1 && - this.options.drag && - !$(e.target).is(this.options.exclude)) + this.options.drag) { rootGroup.dragInit(e, this) + } }, searchValidTarget: function (pointer, lastPointer) { var distances = sortByDistanceDesc(this.getItemDimensions(), From 4909b48241b6c20f4cdef584fe91ee9b1a603d4c Mon Sep 17 00:00:00 2001 From: Abi Narayan Date: Sun, 9 Mar 2014 23:05:43 +0600 Subject: [PATCH 66/97] If clicked on select element, ignore Added ignore for select form element --- source/js/jquery-sortable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 801fd80..8c93d4d 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -101,7 +101,7 @@ // Called on mousedown. If falsy value is returned, the dragging will not start. // If clicked on input element, ignore onMousedown: function ($item, _super, event) { - if (event.target.nodeName != 'INPUT') { + if (event.target.nodeName != 'INPUT' && event.target.nodeName != 'SELECT') { event.preventDefault() return true } From 1563f32858cfe250051ad0a573425569c49d631f Mon Sep 17 00:00:00 2001 From: Prateek Jadhwani Date: Fri, 18 Apr 2014 14:59:22 -0400 Subject: [PATCH 67/97] Issue #84 Fix Fix for TouchEvents are not working on Mobile web (iphone's safari browser) --- source/js/jquery-sortable.js | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 8c93d4d..9555ff3 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -271,8 +271,8 @@ groupDefaults.onDrag, e) - var x = e.pageX, - y = e.pageY, + var x = e.pageX || e.originalEvent.pageX, + y = e.pageY || e.originalEvent.pageY, box = this.sameResultBox, t = this.options.tolerance @@ -374,8 +374,8 @@ }, setPointer: function (e) { var pointer = { - left: e.pageX, - top: e.pageY + left: e.pageX || e.originalEvent.pageX, + top: e.pageY || e.originalEvent.pageX } if(this.$getOffsetParent()){ @@ -388,10 +388,18 @@ this.pointer = pointer }, distanceMet: function (e) { - return (Math.max( - Math.abs(this.pointer.left - e.pageX), - Math.abs(this.pointer.top - e.pageY) - ) >= this.options.distance) + if(e.pageX == undefined || e.pageY == undefined) { + return (Math.max( + Math.abs(this.pointer.left - e.originalEvent.pageX), + Math.abs(this.pointer.top - e.originalEvent.pageY) + ) >= this.options.distance) + } + else { + return (Math.max( + Math.abs(this.pointer.left - e.pageX), + Math.abs(this.pointer.top - e.pageY) + ) >= this.options.distance) + } }, setupDelayTimer: function () { var that = this From 224d806ea576d63db9dd72d25dc0cfb8ffd017bb Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 19 Apr 2014 13:05:09 +0200 Subject: [PATCH 68/97] add serialization example smaller improvements closes #44 --- TODO | 2 ++ source/_serialization.html.haml | 27 +++++++++++++++++++++++++++ source/index.html.haml | 3 ++- source/js/examples/serialization.js | 10 ++++++++++ source/js/jquery-sortable.js | 12 +++++------- 5 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 source/_serialization.html.haml create mode 100644 source/js/examples/serialization.js diff --git a/TODO b/TODO index 9b72f62..2b63bc0 100644 --- a/TODO +++ b/TODO @@ -4,6 +4,8 @@ - [ ] last Pointer is NaN in search valid target - [ ] prevent infinite recursion - [ ] bootstrap example jumps up on drop + - (only sometimes. preventDefault() does not work if called inside drop or on containing element. Look up where the on handler attaches itself) + - only firefox, chrome works - [0/5] consider - [ ] better name for searchValidTarget - [ ] shortcut on getNearest() diff --git a/source/_serialization.html.haml b/source/_serialization.html.haml new file mode 100644 index 0000000..2812aa4 --- /dev/null +++ b/source/_serialization.html.haml @@ -0,0 +1,27 @@ +%h2 Serialization and delay +.row + .span12.example + %pre(lang="js")= example("serialization") + .span4 + %ul + %li + Uses the default + %strong serialize + implementation, that reads out the + %strong data attributes + %p= show_code_button + %h3 Serialize result + %pre#serialize_output2 + .span4 + %ol.serialization.vertical + = iterate(6) do |i,name| + %li(data-id=i data-name=name) + = name + - if i == 3 + %ol + = iterate(6) do |j, name| + %li(data-id="#{i}-#{j}" data-name=name)= name + .span4 + %ol.serialization.vertical + = iterate(6,"Item") do |i,name| + %li(data-id=i data-name=name)= name diff --git a/source/index.html.haml b/source/index.html.haml index 48236d7..e014255 100644 --- a/source/index.html.haml +++ b/source/index.html.haml @@ -136,6 +136,8 @@ = partial "limited_drop_targets" #bootstrap = partial "nested_bootstrap" + #serialization + = partial "serialization" #table = partial "table" #docs @@ -239,4 +241,3 @@ Built with [Bootstrap](http://twitter.github.com/bootstrap/). Icons from [Glyphicons Free](http://glyphicons.com/). - diff --git a/source/js/examples/serialization.js b/source/js/examples/serialization.js new file mode 100644 index 0000000..741fdfb --- /dev/null +++ b/source/js/examples/serialization.js @@ -0,0 +1,10 @@ +$(function () { + var group = $("ol.serialization").sortable({ + group: 'serialization', + delay: 1000, + onDrop: function (item, container, _super) { + $('#serialize_output2').text(group.sortable("serialize").get().join("\n")) + _super(item, container) + } + }) +}) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 8c93d4d..e6b6780 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -27,9 +27,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ========================================================== */ -!function ( $, window, undefined){ +!function ( $, window, pluginName, undefined){ var eventNames, - pluginName = 'sortable', containerDefaults = { // If true, items can be dragged from this container drag: true, @@ -101,7 +100,7 @@ // Called on mousedown. If falsy value is returned, the dragging will not start. // If clicked on input element, ignore onMousedown: function ($item, _super, event) { - if (event.target.nodeName != 'INPUT' && event.target.nodeName != 'SELECT') { + if (!event.target.nodeName.match(/^(input|select)$/i)) { event.preventDefault() return true } @@ -115,12 +114,11 @@ pullPlaceholder: true, // Specifies serialization of the container group. // The pair $parent/$children is either container/items or item/subcontainers. - // Note that this default method only works, if every item only has one subcontainer serialize: function ($parent, $children, parentIsContainer) { var result = $.extend({}, $parent.data()) if(parentIsContainer) - return $children + return [$children] else if ($children[0]){ result.children = $children delete result.subContainer @@ -407,7 +405,7 @@ }, scroll: function (e) { this.clearDimensions() - this.clearOffsetParent() + this.clearOffsetParent() // TODO is this needed? }, toggleListeners: function (method, events) { var that = this @@ -644,4 +642,4 @@ }); }; -}(jQuery, window); +}(jQuery, window, 'sortable'); From 561facdbe3c8f50ea13f183ba47254b77c3ecda9 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 19 Apr 2014 13:54:42 +0200 Subject: [PATCH 69/97] improve fix --- source/js/jquery-sortable.js | 37 +++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index 9555ff3..608d2e5 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -373,10 +373,7 @@ return this.offsetParent }, setPointer: function (e) { - var pointer = { - left: e.pageX || e.originalEvent.pageX, - top: e.pageY || e.originalEvent.pageX - } + var pointer = this.getPointer(e) if(this.$getOffsetParent()){ var relativePointer = getRelativePosition(pointer, this.$getOffsetParent()) @@ -388,17 +385,16 @@ this.pointer = pointer }, distanceMet: function (e) { - if(e.pageX == undefined || e.pageY == undefined) { - return (Math.max( - Math.abs(this.pointer.left - e.originalEvent.pageX), - Math.abs(this.pointer.top - e.originalEvent.pageY) - ) >= this.options.distance) - } - else { - return (Math.max( - Math.abs(this.pointer.left - e.pageX), - Math.abs(this.pointer.top - e.pageY) - ) >= this.options.distance) + var currentPointer = this.getPointer(e) + return (Math.max( + Math.abs(this.pointer.left - currentPointer.left), + Math.abs(this.pointer.top - currentPointer.top) + ) >= this.options.distance) + }, + getPointer: function(e) { + return { + left: e.pageX || e.originalEvent.pageX, + top: e.pageY || e.originalEvent.pageY } }, setupDelayTimer: function () { @@ -466,11 +462,18 @@ var rootGroup = this.rootGroup if( !rootGroup.dragInitDone && - e.which === 1 && - this.options.drag) { + this.options.drag && + this.isValidDrag(e)) { rootGroup.dragInit(e, this) } }, + isValidDrag: function(e) { + if(e.type == "touchstart"){ + return e.originalEvent.touches.length == 1; + } else { + return e.which == 1 + } + }, searchValidTarget: function (pointer, lastPointer) { var distances = sortByDistanceDesc(this.getItemDimensions(), pointer, From 2ea62e1840456cf1cb7f2f820fb895028d791309 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 19 Apr 2014 14:25:47 +0200 Subject: [PATCH 70/97] improve serialization example added refresh method closes #70 --- source/css/application.css.sass | 2 +- source/index.html.haml | 6 ++++++ source/js/examples/serialization.js | 8 ++++++-- source/js/jquery-sortable.js | 14 +++++++------- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/source/css/application.css.sass b/source/css/application.css.sass index 62ec8e3..5f0c9b5 100644 --- a/source/css/application.css.sass +++ b/source/css/application.css.sass @@ -44,7 +44,7 @@ ol.nested_with_switch, ol.nested_with_switch ol &.active border: 1px solid $grayDark -ol.nested_with_switch, ol.simple_with_animation, ol.default +ol.nested_with_switch, ol.simple_with_animation, ol.serialization, ol.default li cursor: pointer diff --git a/source/index.html.haml b/source/index.html.haml index e014255..56c89a5 100644 --- a/source/index.html.haml +++ b/source/index.html.haml @@ -175,6 +175,12 @@ %h3 %code .sortable("disable") %p Disable all instantiated sortables in the set of matched elements + %h3 + %code .sortable("refresh") + %p Reset all cached element dimensions + %h3 + %code .sortable("destroy") + %p Remove the sortable plugin from the set of matched elements %h3 %code .sortable("serialize") %p diff --git a/source/js/examples/serialization.js b/source/js/examples/serialization.js index 741fdfb..34a265c 100644 --- a/source/js/examples/serialization.js +++ b/source/js/examples/serialization.js @@ -1,9 +1,13 @@ $(function () { var group = $("ol.serialization").sortable({ group: 'serialization', - delay: 1000, + delay: 500, onDrop: function (item, container, _super) { - $('#serialize_output2').text(group.sortable("serialize").get().join("\n")) + var data = group.sortable("serialize").get(); + + var jsonString = JSON.stringify(data, null, ' '); + + $('#serialize_output2').text(jsonString); _super(item, container) } }) diff --git a/source/js/jquery-sortable.js b/source/js/jquery-sortable.js index dec5652..c728c72 100644 --- a/source/js/jquery-sortable.js +++ b/source/js/jquery-sortable.js @@ -121,10 +121,10 @@ return [$children] else if ($children[0]){ result.children = $children - delete result.subContainer } - delete result.sortable + delete result.subContainer + delete result[pluginName] return result }, @@ -466,11 +466,8 @@ } }, isValidDrag: function(e) { - if(e.type == "touchstart"){ - return e.originalEvent.touches.length == 1; - } else { - return e.which == 1 - } + return e.which == 1 || + e.type == "touchstart" && e.originalEvent.touches.length == 1 }, searchValidTarget: function (pointer, lastPointer) { var distances = sortByDistanceDesc(this.getItemDimensions(), @@ -622,6 +619,9 @@ serialize: function () { return this._serialize(this.el, true) }, + refresh: function() { + this.clearDimensions() + }, destroy: function () { this.rootGroup.destroy() } From 71eeb5acd5b06d50f8e1cd7c6574c3bc8c400ad5 Mon Sep 17 00:00:00 2001 From: Jonas von Andrian Date: Sat, 19 Apr 2014 16:25:35 +0200 Subject: [PATCH 71/97] update jquery to 1.11 --- source/js/vendor/jquery.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/js/vendor/jquery.js b/source/js/vendor/jquery.js index 16ad06c..73f33fb 100644 --- a/source/js/vendor/jquery.js +++ b/source/js/vendor/jquery.js @@ -1,4 +1,4 @@ -/*! jQuery v1.7.2 jquery.com | jquery.org/license */ -(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"":"")+""),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;e=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
    a",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="
    "+""+"
    ",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="
    t
    ",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="
    ",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function( -a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

    ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
    ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*",""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
    ","
    "]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f -.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(;d1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]===""&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
    ").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file +/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="
    ",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f +}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML="
    a",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<(?:"+fb+")[\\s/>]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/\s*$/g,sb={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:l.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?""!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("