From f27e29a40664b893636d5582ccd4e68b995e605d Mon Sep 17 00:00:00 2001 From: Pusher Robot Date: Thu, 6 Oct 2022 13:59:09 -0400 Subject: [PATCH] Updated component to version 2.5.0 --- RELEASE-NOTES.md | 7 +++++++ bower.json | 24 ++++-------------------- composer.json | 11 +++-------- index.js | 24 +++++++++++++++++++++--- package.json | 2 +- sticky.css | 3 +-- sticky.js | 24 +++++++++++++++++++++--- sticky.min.css | 4 ++-- sticky.min.js | 2 +- 9 files changed, 61 insertions(+), 40 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 2e3c40e..15a9f75 100755 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,3 +1,10 @@ +### Version 2.5.0 - Oct 6, 2022 + +- **Sticky** - Adds new example for sticky to highlight behavior when sticky/context height varies +- **Dropdown** - Fix issue where dropdown menu could not open to right when in `right menu` inside a `ui menu` (See examples/sticky.html) for use-case +- **Sticky** - Fix issue where element might be `bound bottom` (fixed to bottom of context) if the sticky element is larger than the context +- **Sticky** - Fix issue when sticky size is larger than context size caused context `min-height` not to be set correctly. + ### Version 2.2.11 - July 11, 2017 - **Sticky** - Fix issue where sticky would cause page to shift when `context` height was determined by sticky's height in `position: static;` [#3430](https://github.com/Semantic-Org/Semantic-UI/issues/3430) diff --git a/bower.json b/bower.json index 3a2621e..5b22e84 100755 --- a/bower.json +++ b/bower.json @@ -6,24 +6,8 @@ "name": "Jack Lukic", "web": "http://www.jacklukic.com" }, - "ignore": [ - "docs", - "node", - "server", - "spec", - "src", - "test" - ], - "keywords": [ - "semantic", - "ui", - "css3", - "framework" - ], - "license": [ - "http://semantic-ui.mit-license.org/" - ], - "main": [ - "sticky.css" - ] + "ignore": ["docs", "node", "server", "spec", "src", "test"], + "keywords": ["semantic", "ui", "css3", "framework"], + "license": ["http://semantic-ui.mit-license.org/"], + "main": ["sticky.css"] } \ No newline at end of file diff --git a/composer.json b/composer.json index d9ab444..d6b4e9d 100755 --- a/composer.json +++ b/composer.json @@ -5,15 +5,10 @@ "authors": [{ "name": "Jack Lukic", "email": "jacklukic@gmail.com", - "web": "http://www.jacklukic.com", + "homepage": "http://www.jacklukic.com", "role": "Creator" }], - "keywords": [ - "semantic", - "ui", - "css", - "framework" - ], + "keywords": ["semantic", "ui", "css", "framework"], "license": "MIT", - "version": "2.4.0" + "version": "2.5.0" } \ No newline at end of file diff --git a/index.js b/index.js index db83c66..f3f253a 100755 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ /*! - * # Semantic UI 2.4.0 - Sticky + * # Semantic UI 2.5.0 - Sticky * http://github.com/semantic-org/semantic-ui/ * * @@ -403,6 +403,18 @@ module.exports = function(parameters) { module.determineContainer(); } else { + var tallestHeight = Math.max(module.cache.context.height, module.cache.element.height); + if(tallestHeight - $container.outerHeight() > settings.jitter) { + module.debug('Context is taller than container. Specifying exact height for container', module.cache.context.height); + $container.css({ + height: tallestHeight, + }); + } + else { + $container.css({ + height: '', + }); + } if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) { module.debug('Context has padding, specifying exact height for container', module.cache.context.height); $container.css({ @@ -439,7 +451,7 @@ module.exports = function(parameters) { }, size: function() { if(module.cache.element.height !== 0 && module.cache.element.width !== 0) { - element.style.setProperty('width', module.cache.element.width + 'px', 'important'); + element.style.setProperty('width', module.cache.element.width + 'px', 'important'); element.style.setProperty('height', module.cache.element.height + 'px', 'important'); } } @@ -502,7 +514,7 @@ module.exports = function(parameters) { module.bindBottom(); } else if(scroll.top > element.top) { - if( (element.height + scroll.top - elementScroll) >= context.bottom ) { + if((element.height + scroll.top - elementScroll) >= context.bottom && element.height < context.height) { module.debug('Initial element position is bottom of container'); module.bindBottom(); } @@ -581,6 +593,9 @@ module.exports = function(parameters) { bindTop: function() { module.debug('Binding element to top of parent container'); module.remove.offset(); + if(settings.setSize) { + module.set.size(); + } $module .css({ left : '', @@ -598,6 +613,9 @@ module.exports = function(parameters) { bindBottom: function() { module.debug('Binding element to bottom of parent container'); module.remove.offset(); + if(settings.setSize) { + module.set.size(); + } $module .css({ left : '', diff --git a/package.json b/package.json index 4d4dd51..6568ffe 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "semantic-ui-sticky", - "version": "2.4.0", + "version": "2.5.0", "title": "Semantic UI - Sticky", "description": "Single component release of sticky", "homepage": "http://www.semantic-ui.com", diff --git a/sticky.css b/sticky.css index 19aca17..bbc2c71 100755 --- a/sticky.css +++ b/sticky.css @@ -1,5 +1,5 @@ /*! - * # Semantic UI 2.4.0 - Sticky + * # Semantic UI 2.5.0 - Sticky * http://github.com/semantic-org/semantic-ui/ * * @@ -15,7 +15,6 @@ .ui.sticky { position: static; - -webkit-transition: none; transition: none; z-index: 800; } diff --git a/sticky.js b/sticky.js index 0d04084..c9295cc 100755 --- a/sticky.js +++ b/sticky.js @@ -1,5 +1,5 @@ /*! - * # Semantic UI 2.4.0 - Sticky + * # Semantic UI 2.5.0 - Sticky * http://github.com/semantic-org/semantic-ui/ * * @@ -402,6 +402,18 @@ $.fn.sticky = function(parameters) { module.determineContainer(); } else { + var tallestHeight = Math.max(module.cache.context.height, module.cache.element.height); + if(tallestHeight - $container.outerHeight() > settings.jitter) { + module.debug('Context is taller than container. Specifying exact height for container', module.cache.context.height); + $container.css({ + height: tallestHeight, + }); + } + else { + $container.css({ + height: '', + }); + } if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) { module.debug('Context has padding, specifying exact height for container', module.cache.context.height); $container.css({ @@ -438,7 +450,7 @@ $.fn.sticky = function(parameters) { }, size: function() { if(module.cache.element.height !== 0 && module.cache.element.width !== 0) { - element.style.setProperty('width', module.cache.element.width + 'px', 'important'); + element.style.setProperty('width', module.cache.element.width + 'px', 'important'); element.style.setProperty('height', module.cache.element.height + 'px', 'important'); } } @@ -501,7 +513,7 @@ $.fn.sticky = function(parameters) { module.bindBottom(); } else if(scroll.top > element.top) { - if( (element.height + scroll.top - elementScroll) >= context.bottom ) { + if((element.height + scroll.top - elementScroll) >= context.bottom && element.height < context.height) { module.debug('Initial element position is bottom of container'); module.bindBottom(); } @@ -580,6 +592,9 @@ $.fn.sticky = function(parameters) { bindTop: function() { module.debug('Binding element to top of parent container'); module.remove.offset(); + if(settings.setSize) { + module.set.size(); + } $module .css({ left : '', @@ -597,6 +612,9 @@ $.fn.sticky = function(parameters) { bindBottom: function() { module.debug('Binding element to bottom of parent container'); module.remove.offset(); + if(settings.setSize) { + module.set.size(); + } $module .css({ left : '', diff --git a/sticky.min.css b/sticky.min.css index 2fcb95b..1b5610d 100755 --- a/sticky.min.css +++ b/sticky.min.css @@ -1,9 +1,9 @@ /*! - * # Semantic UI 2.4.0 - Sticky + * # Semantic UI 2.5.0 - Sticky * http://github.com/semantic-org/semantic-ui/ * * * Released under the MIT license * http://opensource.org/licenses/MIT * - */.ui.sticky{position:static;-webkit-transition:none;transition:none;z-index:800}.ui.sticky.bound{position:absolute;left:auto;right:auto}.ui.sticky.fixed{position:fixed;left:auto;right:auto}.ui.sticky.bound.top,.ui.sticky.fixed.top{top:0;bottom:auto}.ui.sticky.bound.bottom,.ui.sticky.fixed.bottom{top:auto;bottom:0}.ui.native.sticky{position:-webkit-sticky;position:-moz-sticky;position:-ms-sticky;position:-o-sticky;position:sticky} \ No newline at end of file + */.ui.sticky{position:static;transition:none;z-index:800}.ui.sticky.bound{position:absolute;left:auto;right:auto}.ui.sticky.fixed{position:fixed;left:auto;right:auto}.ui.sticky.bound.top,.ui.sticky.fixed.top{top:0;bottom:auto}.ui.sticky.bound.bottom,.ui.sticky.fixed.bottom{top:auto;bottom:0}.ui.native.sticky{position:-webkit-sticky;position:-moz-sticky;position:-ms-sticky;position:-o-sticky;position:sticky} \ No newline at end of file diff --git a/sticky.min.js b/sticky.min.js index 773e967..9a79ca8 100755 --- a/sticky.min.js +++ b/sticky.min.js @@ -1 +1 @@ -!function(e,t,o,n){"use strict";t=void 0!==t&&t.Math==Math?t:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")(),e.fn.sticky=function(i){var s,r=e(this),c=r.selector||"",l=(new Date).getTime(),a=[],f=arguments[0],m="string"==typeof f,u=[].slice.call(arguments,1);return r.each(function(){var r,d,h,g,p,b=e.isPlainObject(i)?e.extend(!0,{},e.fn.sticky.settings,i):e.extend({},e.fn.sticky.settings),v=b.className,x=b.namespace,C=b.error,S="."+x,y="module-"+x,k=e(this),z=e(t),T=e(b.scrollContext),w=(k.selector,k.data(y)),B=t.requestAnimationFrame||t.mozRequestAnimationFrame||t.webkitRequestAnimationFrame||t.msRequestAnimationFrame||function(e){setTimeout(e,0)},P=this;p={initialize:function(){p.determineContainer(),p.determineContext(),p.verbose("Initializing sticky",b,r),p.save.positions(),p.checkErrors(),p.bind.events(),b.observeChanges&&p.observeChanges(),p.instantiate()},instantiate:function(){p.verbose("Storing instance of module",p),w=p,k.data(y,p)},destroy:function(){p.verbose("Destroying previous instance"),p.reset(),h&&h.disconnect(),g&&g.disconnect(),z.off("load"+S,p.event.load).off("resize"+S,p.event.resize),T.off("scrollchange"+S,p.event.scrollchange),k.removeData(y)},observeChanges:function(){"MutationObserver"in t&&(h=new MutationObserver(p.event.documentChanged),g=new MutationObserver(p.event.changed),h.observe(o,{childList:!0,subtree:!0}),g.observe(P,{childList:!0,subtree:!0}),g.observe(d[0],{childList:!0,subtree:!0}),p.debug("Setting up mutation observer",g))},determineContainer:function(){r=b.container?e(b.container):k.offsetParent()},determineContext:function(){0!==(d=b.context?e(b.context):r).length||p.error(C.invalidContext,b.context,k)},checkErrors:function(){if(p.is.hidden()&&p.error(C.visible,k),p.cache.element.height>p.cache.context.height)return p.reset(),void p.error(C.elementSize,k)},bind:{events:function(){z.on("load"+S,p.event.load).on("resize"+S,p.event.resize),T.off("scroll"+S).on("scroll"+S,p.event.scroll).on("scrollchange"+S,p.event.scrollchange)}},event:{changed:function(e){clearTimeout(p.timer),p.timer=setTimeout(function(){p.verbose("DOM tree modified, updating sticky menu",e),p.refresh()},100)},documentChanged:function(t){[].forEach.call(t,function(t){t.removedNodes&&[].forEach.call(t.removedNodes,function(t){(t==P||e(t).find(P).length>0)&&(p.debug("Element removed from DOM, tearing down events"),p.destroy())})})},load:function(){p.verbose("Page contents finished loading"),B(p.refresh)},resize:function(){p.verbose("Window resized"),B(p.refresh)},scroll:function(){B(function(){T.triggerHandler("scrollchange"+S,T.scrollTop())})},scrollchange:function(e,t){p.stick(t),b.onScroll.call(P)}},refresh:function(e){p.reset(),b.context||p.determineContext(),e&&p.determineContainer(),p.save.positions(),p.stick(),b.onReposition.call(P)},supports:{sticky:function(){var t=e("
");t[0];return t.addClass(v.supported),t.css("position").match("sticky")}},save:{lastScroll:function(e){p.lastScroll=e},elementScroll:function(e){p.elementScroll=e},positions:function(){var e={height:T.height()},t={margin:{top:parseInt(k.css("margin-top"),10),bottom:parseInt(k.css("margin-bottom"),10)},offset:k.offset(),width:k.outerWidth(),height:k.outerHeight()},o={offset:d.offset(),height:d.outerHeight()};r.outerHeight();p.is.standardScroll()||(p.debug("Non-standard scroll. Removing scroll offset from element offset"),e.top=T.scrollTop(),e.left=T.scrollLeft(),t.offset.top+=e.top,o.offset.top+=e.top,t.offset.left+=e.left,o.offset.left+=e.left),p.cache={fits:t.height+b.offset<=e.height,sameHeight:t.height==o.height,scrollContext:{height:e.height},element:{margin:t.margin,top:t.offset.top-t.margin.top,left:t.offset.left,width:t.width,height:t.height,bottom:t.offset.top+t.height},context:{top:o.offset.top,height:o.height,bottom:o.offset.top+o.height}},p.set.containerSize(),p.stick(),p.debug("Caching element positions",p.cache)}},get:{direction:function(e){var t="down";return e=e||T.scrollTop(),p.lastScroll!==n&&(p.lastScrolle&&(t="up")),t},scrollChange:function(e){return e=e||T.scrollTop(),p.lastScroll?e-p.lastScroll:0},currentElementScroll:function(){return p.elementScroll?p.elementScroll:p.is.top()?Math.abs(parseInt(k.css("top"),10))||0:Math.abs(parseInt(k.css("bottom"),10))||0},elementScroll:function(e){e=e||T.scrollTop();var t=p.cache.element,o=p.cache.scrollContext,n=p.get.scrollChange(e),i=t.height-o.height+b.offset,s=p.get.currentElementScroll(),r=s+n;return s=p.cache.fits||r<0?0:r>i?i:r}},remove:{lastScroll:function(){delete p.lastScroll},elementScroll:function(e){delete p.elementScroll},minimumSize:function(){r.css("min-height","")},offset:function(){k.css("margin-top","")}},set:{offset:function(){p.verbose("Setting offset on element",b.offset),k.css("margin-top",b.offset)},containerSize:function(){var e=r.get(0).tagName;"HTML"===e||"body"==e?p.determineContainer():Math.abs(r.outerHeight()-p.cache.context.height)>b.jitter&&(p.debug("Context has padding, specifying exact height for container",p.cache.context.height),r.css({height:p.cache.context.height}))},minimumSize:function(){var e=p.cache.element;r.css("min-height",e.height)},scroll:function(e){p.debug("Setting scroll on element",e),p.elementScroll!=e&&(p.is.top()&&k.css("bottom","").css("top",-e),p.is.bottom()&&k.css("top","").css("bottom",e))},size:function(){0!==p.cache.element.height&&0!==p.cache.element.width&&(P.style.setProperty("width",p.cache.element.width+"px","important"),P.style.setProperty("height",p.cache.element.height+"px","important"))}},is:{standardScroll:function(){return T[0]==t},top:function(){return k.hasClass(v.top)},bottom:function(){return k.hasClass(v.bottom)},initialPosition:function(){return!p.is.fixed()&&!p.is.bound()},hidden:function(){return!k.is(":visible")},bound:function(){return k.hasClass(v.bound)},fixed:function(){return k.hasClass(v.fixed)}},stick:function(e){var t=e||T.scrollTop(),o=p.cache,n=o.fits,i=o.sameHeight,s=o.element,r=o.scrollContext,c=o.context,l=p.is.bottom()&&b.pushing?b.bottomOffset:b.offset,a=(e={top:t+l,bottom:t+l+r.height},p.get.direction(e.top),n?0:p.get.elementScroll(e.top)),f=!n;0!==s.height&&!i&&(p.is.initialPosition()?e.top>=c.bottom?(p.debug("Initial element position is bottom of container"),p.bindBottom()):e.top>s.top&&(s.height+e.top-a>=c.bottom?(p.debug("Initial element position is bottom of container"),p.bindBottom()):(p.debug("Initial element position is fixed"),p.fixTop())):p.is.fixed()?p.is.top()?e.top<=s.top?(p.debug("Fixed element reached top of container"),p.setInitialPosition()):s.height+e.top-a>=c.bottom?(p.debug("Fixed element reached bottom of container"),p.bindBottom()):f&&(p.set.scroll(a),p.save.lastScroll(e.top),p.save.elementScroll(a)):p.is.bottom()&&(e.bottom-s.height<=s.top?(p.debug("Bottom fixed rail has reached top of container"),p.setInitialPosition()):e.bottom>=c.bottom?(p.debug("Bottom fixed rail has reached bottom of container"),p.bindBottom()):f&&(p.set.scroll(a),p.save.lastScroll(e.top),p.save.elementScroll(a))):p.is.bottom()&&(e.top<=s.top?(p.debug("Jumped from bottom fixed to top fixed, most likely used home/end button"),p.setInitialPosition()):b.pushing?p.is.bound()&&e.bottom<=c.bottom&&(p.debug("Fixing bottom attached element to bottom of browser."),p.fixBottom()):p.is.bound()&&e.top<=c.bottom-s.height&&(p.debug("Fixing bottom attached element to top of browser."),p.fixTop())))},bindTop:function(){p.debug("Binding element to top of parent container"),p.remove.offset(),k.css({left:"",top:"",marginBottom:""}).removeClass(v.fixed).removeClass(v.bottom).addClass(v.bound).addClass(v.top),b.onTop.call(P),b.onUnstick.call(P)},bindBottom:function(){p.debug("Binding element to bottom of parent container"),p.remove.offset(),k.css({left:"",top:""}).removeClass(v.fixed).removeClass(v.top).addClass(v.bound).addClass(v.bottom),b.onBottom.call(P),b.onUnstick.call(P)},setInitialPosition:function(){p.debug("Returning to initial position"),p.unfix(),p.unbind()},fixTop:function(){p.debug("Fixing element to top of page"),b.setSize&&p.set.size(),p.set.minimumSize(),p.set.offset(),k.css({left:p.cache.element.left,bottom:"",marginBottom:""}).removeClass(v.bound).removeClass(v.bottom).addClass(v.fixed).addClass(v.top),b.onStick.call(P)},fixBottom:function(){p.debug("Sticking element to bottom of page"),b.setSize&&p.set.size(),p.set.minimumSize(),p.set.offset(),k.css({left:p.cache.element.left,bottom:"",marginBottom:""}).removeClass(v.bound).removeClass(v.top).addClass(v.fixed).addClass(v.bottom),b.onStick.call(P)},unbind:function(){p.is.bound()&&(p.debug("Removing container bound position on element"),p.remove.offset(),k.removeClass(v.bound).removeClass(v.top).removeClass(v.bottom))},unfix:function(){p.is.fixed()&&(p.debug("Removing fixed position on element"),p.remove.minimumSize(),p.remove.offset(),k.removeClass(v.fixed).removeClass(v.top).removeClass(v.bottom),b.onUnstick.call(P))},reset:function(){p.debug("Resetting elements position"),p.unbind(),p.unfix(),p.resetCSS(),p.remove.offset(),p.remove.lastScroll()},resetCSS:function(){k.css({width:"",height:""}),r.css({height:""})},setting:function(t,o){if(e.isPlainObject(t))e.extend(!0,b,t);else{if(o===n)return b[t];b[t]=o}},internal:function(t,o){if(e.isPlainObject(t))e.extend(!0,p,t);else{if(o===n)return p[t];p[t]=o}},debug:function(){!b.silent&&b.debug&&(b.performance?p.performance.log(arguments):(p.debug=Function.prototype.bind.call(console.info,console,b.name+":"),p.debug.apply(console,arguments)))},verbose:function(){!b.silent&&b.verbose&&b.debug&&(b.performance?p.performance.log(arguments):(p.verbose=Function.prototype.bind.call(console.info,console,b.name+":"),p.verbose.apply(console,arguments)))},error:function(){b.silent||(p.error=Function.prototype.bind.call(console.error,console,b.name+":"),p.error.apply(console,arguments))},performance:{log:function(e){var t,o;b.performance&&(o=(t=(new Date).getTime())-(l||t),l=t,a.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:P,"Execution Time":o})),clearTimeout(p.performance.timer),p.performance.timer=setTimeout(p.performance.display,0)},display:function(){var t=b.name+":",o=0;l=!1,clearTimeout(p.performance.timer),e.each(a,function(e,t){o+=t["Execution Time"]}),t+=" "+o+"ms",c&&(t+=" '"+c+"'"),(console.group!==n||console.table!==n)&&a.length>0&&(console.groupCollapsed(t),console.table?console.table(a):e.each(a,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),a=[]}},invoke:function(t,o,i){var r,c,l,a=w;return o=o||u,i=P||i,"string"==typeof t&&a!==n&&(t=t.split(/[\. ]/),r=t.length-1,e.each(t,function(o,i){var s=o!=r?i+t[o+1].charAt(0).toUpperCase()+t[o+1].slice(1):t;if(e.isPlainObject(a[s])&&o!=r)a=a[s];else{if(a[s]!==n)return c=a[s],!1;if(!e.isPlainObject(a[i])||o==r)return a[i]!==n&&(c=a[i],!1);a=a[i]}})),e.isFunction(c)?l=c.apply(i,o):c!==n&&(l=c),e.isArray(s)?s.push(l):s!==n?s=[s,l]:l!==n&&(s=l),c}},m?(w===n&&p.initialize(),p.invoke(f)):(w!==n&&w.invoke("destroy"),p.initialize())}),s!==n?s:this},e.fn.sticky.settings={name:"Sticky",namespace:"sticky",silent:!1,debug:!1,verbose:!0,performance:!0,pushing:!1,context:!1,container:!1,scrollContext:t,offset:0,bottomOffset:0,jitter:5,setSize:!0,observeChanges:!1,onReposition:function(){},onScroll:function(){},onStick:function(){},onUnstick:function(){},onTop:function(){},onBottom:function(){},error:{container:"Sticky element must be inside a relative container",visible:"Element is hidden, you must call refresh after element becomes visible. Use silent setting to surpress this warning in production.",method:"The method you called is not defined.",invalidContext:"Context specified does not exist",elementSize:"Sticky element is larger than its container, cannot create sticky."},className:{bound:"bound",fixed:"fixed",supported:"native",top:"top",bottom:"bottom"}}}(jQuery,window,document); \ No newline at end of file +!function(T,w,B,P){"use strict";w=void 0!==w&&w.Math==Math?w:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")(),T.fn.sticky=function(b){var v,e=T(this),x=e.selector||"",S=(new Date).getTime(),C=[],y=b,k="string"==typeof y,z=[].slice.call(arguments,1);return e.each(function(){var n,i,e,t,m=T.isPlainObject(b)?T.extend(!0,{},T.fn.sticky.settings,b):T.extend({},T.fn.sticky.settings),o=m.className,s=m.namespace,r=m.error,c="."+s,l="module-"+s,a=T(this),f=T(w),u=T(m.scrollContext),h=(a.selector,a.data(l)),d=w.requestAnimationFrame||w.mozRequestAnimationFrame||w.webkitRequestAnimationFrame||w.msRequestAnimationFrame||function(e){setTimeout(e,0)},g=this,p={initialize:function(){p.determineContainer(),p.determineContext(),p.verbose("Initializing sticky",m,n),p.save.positions(),p.checkErrors(),p.bind.events(),m.observeChanges&&p.observeChanges(),p.instantiate()},instantiate:function(){p.verbose("Storing instance of module",p),h=p,a.data(l,p)},destroy:function(){p.verbose("Destroying previous instance"),p.reset(),e&&e.disconnect(),t&&t.disconnect(),f.off("load"+c,p.event.load).off("resize"+c,p.event.resize),u.off("scrollchange"+c,p.event.scrollchange),a.removeData(l)},observeChanges:function(){"MutationObserver"in w&&(e=new MutationObserver(p.event.documentChanged),t=new MutationObserver(p.event.changed),e.observe(B,{childList:!0,subtree:!0}),t.observe(g,{childList:!0,subtree:!0}),t.observe(i[0],{childList:!0,subtree:!0}),p.debug("Setting up mutation observer",t))},determineContainer:function(){n=m.container?T(m.container):a.offsetParent()},determineContext:function(){0!==(i=m.context?T(m.context):n).length||p.error(r.invalidContext,m.context,a)},checkErrors:function(){if(p.is.hidden()&&p.error(r.visible,a),p.cache.element.height>p.cache.context.height)return p.reset(),void p.error(r.elementSize,a)},bind:{events:function(){f.on("load"+c,p.event.load).on("resize"+c,p.event.resize),u.off("scroll"+c).on("scroll"+c,p.event.scroll).on("scrollchange"+c,p.event.scrollchange)}},event:{changed:function(e){clearTimeout(p.timer),p.timer=setTimeout(function(){p.verbose("DOM tree modified, updating sticky menu",e),p.refresh()},100)},documentChanged:function(e){[].forEach.call(e,function(e){e.removedNodes&&[].forEach.call(e.removedNodes,function(e){(e==g||0");e[0];return e.addClass(o.supported),e.css("position").match("sticky")}},save:{lastScroll:function(e){p.lastScroll=e},elementScroll:function(e){p.elementScroll=e},positions:function(){var e={height:u.height()},t={margin:{top:parseInt(a.css("margin-top"),10),bottom:parseInt(a.css("margin-bottom"),10)},offset:a.offset(),width:a.outerWidth(),height:a.outerHeight()},o={offset:i.offset(),height:i.outerHeight()};n.outerHeight();p.is.standardScroll()||(p.debug("Non-standard scroll. Removing scroll offset from element offset"),e.top=u.scrollTop(),e.left=u.scrollLeft(),t.offset.top+=e.top,o.offset.top+=e.top,t.offset.left+=e.left,o.offset.left+=e.left),p.cache={fits:t.height+m.offset<=e.height,sameHeight:t.height==o.height,scrollContext:{height:e.height},element:{margin:t.margin,top:t.offset.top-t.margin.top,left:t.offset.left,width:t.width,height:t.height,bottom:t.offset.top+t.height},context:{top:o.offset.top,height:o.height,bottom:o.offset.top+o.height}},p.set.containerSize(),p.stick(),p.debug("Caching element positions",p.cache)}},get:{direction:function(e){var t="down";return e=e||u.scrollTop(),p.lastScroll!==P&&(p.lastScrolle&&(t="up")),t},scrollChange:function(e){return e=e||u.scrollTop(),p.lastScroll?e-p.lastScroll:0},currentElementScroll:function(){return p.elementScroll?p.elementScroll:p.is.top()?Math.abs(parseInt(a.css("top"),10))||0:Math.abs(parseInt(a.css("bottom"),10))||0},elementScroll:function(e){e=e||u.scrollTop();var t=p.cache.element,o=p.cache.scrollContext,n=p.get.scrollChange(e),i=t.height-o.height+m.offset,s=p.get.currentElementScroll(),r=s+n;return s=p.cache.fits||r<0?0:im.jitter?(p.debug("Context is taller than container. Specifying exact height for container",p.cache.context.height),n.css({height:e})):n.css({height:""}),Math.abs(n.outerHeight()-p.cache.context.height)>m.jitter&&(p.debug("Context has padding, specifying exact height for container",p.cache.context.height),n.css({height:p.cache.context.height})))},minimumSize:function(){var e=p.cache.element;n.css("min-height",e.height)},scroll:function(e){p.debug("Setting scroll on element",e),p.elementScroll!=e&&(p.is.top()&&a.css("bottom","").css("top",-e),p.is.bottom()&&a.css("top","").css("bottom",e))},size:function(){0!==p.cache.element.height&&0!==p.cache.element.width&&(g.style.setProperty("width",p.cache.element.width+"px","important"),g.style.setProperty("height",p.cache.element.height+"px","important"))}},is:{standardScroll:function(){return u[0]==w},top:function(){return a.hasClass(o.top)},bottom:function(){return a.hasClass(o.bottom)},initialPosition:function(){return!p.is.fixed()&&!p.is.bound()},hidden:function(){return!a.is(":visible")},bound:function(){return a.hasClass(o.bound)},fixed:function(){return a.hasClass(o.fixed)}},stick:function(e){var t=e||u.scrollTop(),o=p.cache,n=o.fits,i=o.sameHeight,s=o.element,r=o.scrollContext,c=o.context,l=p.is.bottom()&&m.pushing?m.bottomOffset:m.offset,e={top:t+l,bottom:t+l+r.height},a=(p.get.direction(e.top),n?0:p.get.elementScroll(e.top)),f=!n;0===s.height||i||(p.is.initialPosition()?e.top>=c.bottom?(p.debug("Initial element position is bottom of container"),p.bindBottom()):e.top>s.top&&(s.height+e.top-a>=c.bottom&&s.height=c.bottom?(p.debug("Fixed element reached bottom of container"),p.bindBottom()):f&&(p.set.scroll(a),p.save.lastScroll(e.top),p.save.elementScroll(a)):p.is.bottom()&&(e.bottom-s.height<=s.top?(p.debug("Bottom fixed rail has reached top of container"),p.setInitialPosition()):e.bottom>=c.bottom?(p.debug("Bottom fixed rail has reached bottom of container"),p.bindBottom()):f&&(p.set.scroll(a),p.save.lastScroll(e.top),p.save.elementScroll(a))):p.is.bottom()&&(e.top<=s.top?(p.debug("Jumped from bottom fixed to top fixed, most likely used home/end button"),p.setInitialPosition()):m.pushing?p.is.bound()&&e.bottom<=c.bottom&&(p.debug("Fixing bottom attached element to bottom of browser."),p.fixBottom()):p.is.bound()&&e.top<=c.bottom-s.height&&(p.debug("Fixing bottom attached element to top of browser."),p.fixTop())))},bindTop:function(){p.debug("Binding element to top of parent container"),p.remove.offset(),m.setSize&&p.set.size(),a.css({left:"",top:"",marginBottom:""}).removeClass(o.fixed).removeClass(o.bottom).addClass(o.bound).addClass(o.top),m.onTop.call(g),m.onUnstick.call(g)},bindBottom:function(){p.debug("Binding element to bottom of parent container"),p.remove.offset(),m.setSize&&p.set.size(),a.css({left:"",top:""}).removeClass(o.fixed).removeClass(o.top).addClass(o.bound).addClass(o.bottom),m.onBottom.call(g),m.onUnstick.call(g)},setInitialPosition:function(){p.debug("Returning to initial position"),p.unfix(),p.unbind()},fixTop:function(){p.debug("Fixing element to top of page"),m.setSize&&p.set.size(),p.set.minimumSize(),p.set.offset(),a.css({left:p.cache.element.left,bottom:"",marginBottom:""}).removeClass(o.bound).removeClass(o.bottom).addClass(o.fixed).addClass(o.top),m.onStick.call(g)},fixBottom:function(){p.debug("Sticking element to bottom of page"),m.setSize&&p.set.size(),p.set.minimumSize(),p.set.offset(),a.css({left:p.cache.element.left,bottom:"",marginBottom:""}).removeClass(o.bound).removeClass(o.top).addClass(o.fixed).addClass(o.bottom),m.onStick.call(g)},unbind:function(){p.is.bound()&&(p.debug("Removing container bound position on element"),p.remove.offset(),a.removeClass(o.bound).removeClass(o.top).removeClass(o.bottom))},unfix:function(){p.is.fixed()&&(p.debug("Removing fixed position on element"),p.remove.minimumSize(),p.remove.offset(),a.removeClass(o.fixed).removeClass(o.top).removeClass(o.bottom),m.onUnstick.call(g))},reset:function(){p.debug("Resetting elements position"),p.unbind(),p.unfix(),p.resetCSS(),p.remove.offset(),p.remove.lastScroll()},resetCSS:function(){a.css({width:"",height:""}),n.css({height:""})},setting:function(e,t){if(T.isPlainObject(e))T.extend(!0,m,e);else{if(t===P)return m[e];m[e]=t}},internal:function(e,t){if(T.isPlainObject(e))T.extend(!0,p,e);else{if(t===P)return p[e];p[e]=t}},debug:function(){!m.silent&&m.debug&&(m.performance?p.performance.log(arguments):(p.debug=Function.prototype.bind.call(console.info,console,m.name+":"),p.debug.apply(console,arguments)))},verbose:function(){!m.silent&&m.verbose&&m.debug&&(m.performance?p.performance.log(arguments):(p.verbose=Function.prototype.bind.call(console.info,console,m.name+":"),p.verbose.apply(console,arguments)))},error:function(){m.silent||(p.error=Function.prototype.bind.call(console.error,console,m.name+":"),p.error.apply(console,arguments))},performance:{log:function(e){var t,o;m.performance&&(o=(t=(new Date).getTime())-(S||t),S=t,C.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:g,"Execution Time":o})),clearTimeout(p.performance.timer),p.performance.timer=setTimeout(p.performance.display,0)},display:function(){var e=m.name+":",o=0;S=!1,clearTimeout(p.performance.timer),T.each(C,function(e,t){o+=t["Execution Time"]}),e+=" "+o+"ms",x&&(e+=" '"+x+"'"),(console.group!==P||console.table!==P)&&0