You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

917 lines
29 KiB

10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
  1. /*!
  2. * # Semantic UI 2.2.0 - Sticky
  3. * http://github.com/semantic-org/semantic-ui/
  4. *
  5. *
  6. * Copyright 2015 Contributors
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ($, window, document, undefined) {
  12. "use strict";
  13. window = (typeof window != 'undefined' && window.Math == Math)
  14. ? window
  15. : (typeof self != 'undefined' && self.Math == Math)
  16. ? self
  17. : Function('return this')()
  18. ;
  19. $.fn.sticky = function(parameters) {
  20. var
  21. $allModules = $(this),
  22. moduleSelector = $allModules.selector || '',
  23. time = new Date().getTime(),
  24. performance = [],
  25. query = arguments[0],
  26. methodInvoked = (typeof query == 'string'),
  27. queryArguments = [].slice.call(arguments, 1),
  28. returnedValue
  29. ;
  30. $allModules
  31. .each(function() {
  32. var
  33. settings = ( $.isPlainObject(parameters) )
  34. ? $.extend(true, {}, $.fn.sticky.settings, parameters)
  35. : $.extend({}, $.fn.sticky.settings),
  36. className = settings.className,
  37. namespace = settings.namespace,
  38. error = settings.error,
  39. eventNamespace = '.' + namespace,
  40. moduleNamespace = 'module-' + namespace,
  41. $module = $(this),
  42. $window = $(window),
  43. $scroll = $(settings.scrollContext),
  44. $container,
  45. $context,
  46. selector = $module.selector || '',
  47. instance = $module.data(moduleNamespace),
  48. requestAnimationFrame = window.requestAnimationFrame
  49. || window.mozRequestAnimationFrame
  50. || window.webkitRequestAnimationFrame
  51. || window.msRequestAnimationFrame
  52. || function(callback) { setTimeout(callback, 0); },
  53. element = this,
  54. observer,
  55. module
  56. ;
  57. module = {
  58. initialize: function() {
  59. module.determineContainer();
  60. module.determineContext();
  61. module.verbose('Initializing sticky', settings, $container);
  62. module.save.positions();
  63. module.checkErrors();
  64. module.bind.events();
  65. if(settings.observeChanges) {
  66. module.observeChanges();
  67. }
  68. module.instantiate();
  69. },
  70. instantiate: function() {
  71. module.verbose('Storing instance of module', module);
  72. instance = module;
  73. $module
  74. .data(moduleNamespace, module)
  75. ;
  76. },
  77. destroy: function() {
  78. module.verbose('Destroying previous instance');
  79. module.reset();
  80. if(observer) {
  81. observer.disconnect();
  82. }
  83. $window
  84. .off('load' + eventNamespace, module.event.load)
  85. .off('resize' + eventNamespace, module.event.resize)
  86. ;
  87. $scroll
  88. .off('scrollchange' + eventNamespace, module.event.scrollchange)
  89. ;
  90. $module.removeData(moduleNamespace);
  91. },
  92. observeChanges: function() {
  93. var
  94. context = $context[0]
  95. ;
  96. if('MutationObserver' in window) {
  97. observer = new MutationObserver(function(mutations) {
  98. clearTimeout(module.timer);
  99. module.timer = setTimeout(function() {
  100. module.verbose('DOM tree modified, updating sticky menu', mutations);
  101. module.refresh();
  102. }, 100);
  103. });
  104. observer.observe(element, {
  105. childList : true,
  106. subtree : true
  107. });
  108. observer.observe(context, {
  109. childList : true,
  110. subtree : true
  111. });
  112. module.debug('Setting up mutation observer', observer);
  113. }
  114. },
  115. determineContainer: function() {
  116. $container = $module.offsetParent();
  117. },
  118. determineContext: function() {
  119. if(settings.context) {
  120. $context = $(settings.context);
  121. }
  122. else {
  123. $context = $container;
  124. }
  125. if($context.length === 0) {
  126. module.error(error.invalidContext, settings.context, $module);
  127. return;
  128. }
  129. },
  130. checkErrors: function() {
  131. if( module.is.hidden() ) {
  132. module.error(error.visible, $module);
  133. }
  134. if(module.cache.element.height > module.cache.context.height) {
  135. module.reset();
  136. module.error(error.elementSize, $module);
  137. return;
  138. }
  139. },
  140. bind: {
  141. events: function() {
  142. $window
  143. .on('load' + eventNamespace, module.event.load)
  144. .on('resize' + eventNamespace, module.event.resize)
  145. ;
  146. // pub/sub pattern
  147. $scroll
  148. .off('scroll' + eventNamespace)
  149. .on('scroll' + eventNamespace, module.event.scroll)
  150. .on('scrollchange' + eventNamespace, module.event.scrollchange)
  151. ;
  152. }
  153. },
  154. event: {
  155. load: function() {
  156. module.verbose('Page contents finished loading');
  157. requestAnimationFrame(module.refresh);
  158. },
  159. resize: function() {
  160. module.verbose('Window resized');
  161. requestAnimationFrame(module.refresh);
  162. },
  163. scroll: function() {
  164. requestAnimationFrame(function() {
  165. $scroll.triggerHandler('scrollchange' + eventNamespace, $scroll.scrollTop() );
  166. });
  167. },
  168. scrollchange: function(event, scrollPosition) {
  169. module.stick(scrollPosition);
  170. settings.onScroll.call(element);
  171. }
  172. },
  173. refresh: function(hardRefresh) {
  174. module.reset();
  175. if(!settings.context) {
  176. module.determineContext();
  177. }
  178. if(hardRefresh) {
  179. module.determineContainer();
  180. }
  181. module.save.positions();
  182. module.stick();
  183. settings.onReposition.call(element);
  184. },
  185. supports: {
  186. sticky: function() {
  187. var
  188. $element = $('<div/>'),
  189. element = $element[0]
  190. ;
  191. $element.addClass(className.supported);
  192. return($element.css('position').match('sticky'));
  193. }
  194. },
  195. save: {
  196. lastScroll: function(scroll) {
  197. module.lastScroll = scroll;
  198. },
  199. elementScroll: function(scroll) {
  200. module.elementScroll = scroll;
  201. },
  202. positions: function() {
  203. var
  204. scrollContext = {
  205. height : $scroll.height()
  206. },
  207. element = {
  208. margin: {
  209. top : parseInt($module.css('margin-top'), 10),
  210. bottom : parseInt($module.css('margin-bottom'), 10),
  211. },
  212. offset : $module.offset(),
  213. width : $module.outerWidth(),
  214. height : $module.outerHeight()
  215. },
  216. context = {
  217. offset : $context.offset(),
  218. height : $context.outerHeight()
  219. },
  220. container = {
  221. height: $container.outerHeight()
  222. }
  223. ;
  224. if( !module.is.standardScroll() ) {
  225. module.debug('Non-standard scroll. Removing scroll offset from element offset');
  226. scrollContext.top = $scroll.scrollTop();
  227. scrollContext.left = $scroll.scrollLeft();
  228. element.offset.top += scrollContext.top;
  229. context.offset.top += scrollContext.top;
  230. element.offset.left += scrollContext.left;
  231. context.offset.left += scrollContext.left;
  232. }
  233. module.cache = {
  234. fits : ( element.height < scrollContext.height ),
  235. scrollContext : {
  236. height : scrollContext.height
  237. },
  238. element: {
  239. margin : element.margin,
  240. top : element.offset.top - element.margin.top,
  241. left : element.offset.left,
  242. width : element.width,
  243. height : element.height,
  244. bottom : element.offset.top + element.height
  245. },
  246. context: {
  247. top : context.offset.top,
  248. height : context.height,
  249. bottom : context.offset.top + context.height
  250. }
  251. };
  252. module.set.containerSize();
  253. module.set.size();
  254. module.stick();
  255. module.debug('Caching element positions', module.cache);
  256. }
  257. },
  258. get: {
  259. direction: function(scroll) {
  260. var
  261. direction = 'down'
  262. ;
  263. scroll = scroll || $scroll.scrollTop();
  264. if(module.lastScroll !== undefined) {
  265. if(module.lastScroll < scroll) {
  266. direction = 'down';
  267. }
  268. else if(module.lastScroll > scroll) {
  269. direction = 'up';
  270. }
  271. }
  272. return direction;
  273. },
  274. scrollChange: function(scroll) {
  275. scroll = scroll || $scroll.scrollTop();
  276. return (module.lastScroll)
  277. ? (scroll - module.lastScroll)
  278. : 0
  279. ;
  280. },
  281. currentElementScroll: function() {
  282. if(module.elementScroll) {
  283. return module.elementScroll;
  284. }
  285. return ( module.is.top() )
  286. ? Math.abs(parseInt($module.css('top'), 10)) || 0
  287. : Math.abs(parseInt($module.css('bottom'), 10)) || 0
  288. ;
  289. },
  290. elementScroll: function(scroll) {
  291. scroll = scroll || $scroll.scrollTop();
  292. var
  293. element = module.cache.element,
  294. scrollContext = module.cache.scrollContext,
  295. delta = module.get.scrollChange(scroll),
  296. maxScroll = (element.height - scrollContext.height + settings.offset),
  297. elementScroll = module.get.currentElementScroll(),
  298. possibleScroll = (elementScroll + delta)
  299. ;
  300. if(module.cache.fits || possibleScroll < 0) {
  301. elementScroll = 0;
  302. }
  303. else if(possibleScroll > maxScroll ) {
  304. elementScroll = maxScroll;
  305. }
  306. else {
  307. elementScroll = possibleScroll;
  308. }
  309. return elementScroll;
  310. }
  311. },
  312. remove: {
  313. lastScroll: function() {
  314. delete module.lastScroll;
  315. },
  316. elementScroll: function(scroll) {
  317. delete module.elementScroll;
  318. },
  319. offset: function() {
  320. $module.css('margin-top', '');
  321. }
  322. },
  323. set: {
  324. offset: function() {
  325. module.verbose('Setting offset on element', settings.offset);
  326. $module
  327. .css('margin-top', settings.offset)
  328. ;
  329. },
  330. containerSize: function() {
  331. var
  332. tagName = $container.get(0).tagName
  333. ;
  334. if(tagName === 'HTML' || tagName == 'body') {
  335. // this can trigger for too many reasons
  336. //module.error(error.container, tagName, $module);
  337. module.determineContainer();
  338. }
  339. else {
  340. if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) {
  341. module.debug('Context has padding, specifying exact height for container', module.cache.context.height);
  342. $container.css({
  343. height: module.cache.context.height
  344. });
  345. }
  346. }
  347. },
  348. minimumSize: function() {
  349. var
  350. element = module.cache.element
  351. ;
  352. $container
  353. .css('min-height', element.height)
  354. ;
  355. },
  356. scroll: function(scroll) {
  357. module.debug('Setting scroll on element', scroll);
  358. if(module.elementScroll == scroll) {
  359. return;
  360. }
  361. if( module.is.top() ) {
  362. $module
  363. .css('bottom', '')
  364. .css('top', -scroll)
  365. ;
  366. }
  367. if( module.is.bottom() ) {
  368. $module
  369. .css('top', '')
  370. .css('bottom', scroll)
  371. ;
  372. }
  373. },
  374. size: function() {
  375. if(module.cache.element.height !== 0 && module.cache.element.width !== 0) {
  376. element.style.setProperty('width', module.cache.element.width + 'px', 'important');
  377. element.style.setProperty('height', module.cache.element.height + 'px', 'important');
  378. }
  379. }
  380. },
  381. is: {
  382. standardScroll: function() {
  383. return ($scroll[0] == window);
  384. },
  385. top: function() {
  386. return $module.hasClass(className.top);
  387. },
  388. bottom: function() {
  389. return $module.hasClass(className.bottom);
  390. },
  391. initialPosition: function() {
  392. return (!module.is.fixed() && !module.is.bound());
  393. },
  394. hidden: function() {
  395. return (!$module.is(':visible'));
  396. },
  397. bound: function() {
  398. return $module.hasClass(className.bound);
  399. },
  400. fixed: function() {
  401. return $module.hasClass(className.fixed);
  402. }
  403. },
  404. stick: function(scroll) {
  405. var
  406. cachedPosition = scroll || $scroll.scrollTop(),
  407. cache = module.cache,
  408. fits = cache.fits,
  409. element = cache.element,
  410. scrollContext = cache.scrollContext,
  411. context = cache.context,
  412. offset = (module.is.bottom() && settings.pushing)
  413. ? settings.bottomOffset
  414. : settings.offset,
  415. scroll = {
  416. top : cachedPosition + offset,
  417. bottom : cachedPosition + offset + scrollContext.height
  418. },
  419. direction = module.get.direction(scroll.top),
  420. elementScroll = (fits)
  421. ? 0
  422. : module.get.elementScroll(scroll.top),
  423. // shorthand
  424. doesntFit = !fits,
  425. elementVisible = (element.height !== 0)
  426. ;
  427. if(elementVisible) {
  428. if( module.is.initialPosition() ) {
  429. if(scroll.top >= context.bottom) {
  430. module.debug('Initial element position is bottom of container');
  431. module.bindBottom();
  432. }
  433. else if(scroll.top > element.top) {
  434. if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
  435. module.debug('Initial element position is bottom of container');
  436. module.bindBottom();
  437. }
  438. else {
  439. module.debug('Initial element position is fixed');
  440. module.fixTop();
  441. }
  442. }
  443. }
  444. else if( module.is.fixed() ) {
  445. // currently fixed top
  446. if( module.is.top() ) {
  447. if( scroll.top <= element.top ) {
  448. module.debug('Fixed element reached top of container');
  449. module.setInitialPosition();
  450. }
  451. else if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
  452. module.debug('Fixed element reached bottom of container');
  453. module.bindBottom();
  454. }
  455. // scroll element if larger than screen
  456. else if(doesntFit) {
  457. module.set.scroll(elementScroll);
  458. module.save.lastScroll(scroll.top);
  459. module.save.elementScroll(elementScroll);
  460. }
  461. }
  462. // currently fixed bottom
  463. else if(module.is.bottom() ) {
  464. // top edge
  465. if( (scroll.bottom - element.height) <= element.top) {
  466. module.debug('Bottom fixed rail has reached top of container');
  467. module.setInitialPosition();
  468. }
  469. // bottom edge
  470. else if(scroll.bottom >= context.bottom) {
  471. module.debug('Bottom fixed rail has reached bottom of container');
  472. module.bindBottom();
  473. }
  474. // scroll element if larger than screen
  475. else if(doesntFit) {
  476. module.set.scroll(elementScroll);
  477. module.save.lastScroll(scroll.top);
  478. module.save.elementScroll(elementScroll);
  479. }
  480. }
  481. }
  482. else if( module.is.bottom() ) {
  483. if( scroll.top <= element.top ) {
  484. module.debug('Jumped from bottom fixed to top fixed, most likely used home/end button');
  485. module.setInitialPosition();
  486. }
  487. else {
  488. if(settings.pushing) {
  489. if(module.is.bound() && scroll.bottom <= context.bottom ) {
  490. module.debug('Fixing bottom attached element to bottom of browser.');
  491. module.fixBottom();
  492. }
  493. }
  494. else {
  495. if(module.is.bound() && (scroll.top <= context.bottom - element.height) ) {
  496. module.debug('Fixing bottom attached element to top of browser.');
  497. module.fixTop();
  498. }
  499. }
  500. }
  501. }
  502. }
  503. },
  504. bindTop: function() {
  505. module.debug('Binding element to top of parent container');
  506. module.remove.offset();
  507. $module
  508. .css({
  509. left : '',
  510. top : '',
  511. marginBottom : ''
  512. })
  513. .removeClass(className.fixed)
  514. .removeClass(className.bottom)
  515. .addClass(className.bound)
  516. .addClass(className.top)
  517. ;
  518. settings.onTop.call(element);
  519. settings.onUnstick.call(element);
  520. },
  521. bindBottom: function() {
  522. module.debug('Binding element to bottom of parent container');
  523. module.remove.offset();
  524. $module
  525. .css({
  526. left : '',
  527. top : ''
  528. })
  529. .removeClass(className.fixed)
  530. .removeClass(className.top)
  531. .addClass(className.bound)
  532. .addClass(className.bottom)
  533. ;
  534. settings.onBottom.call(element);
  535. settings.onUnstick.call(element);
  536. },
  537. setInitialPosition: function() {
  538. module.debug('Returning to initial position');
  539. module.unfix();
  540. module.unbind();
  541. },
  542. fixTop: function() {
  543. module.debug('Fixing element to top of page');
  544. module.set.minimumSize();
  545. module.set.offset();
  546. $module
  547. .css({
  548. left : module.cache.element.left,
  549. bottom : '',
  550. marginBottom : ''
  551. })
  552. .removeClass(className.bound)
  553. .removeClass(className.bottom)
  554. .addClass(className.fixed)
  555. .addClass(className.top)
  556. ;
  557. settings.onStick.call(element);
  558. },
  559. fixBottom: function() {
  560. module.debug('Sticking element to bottom of page');
  561. module.set.minimumSize();
  562. module.set.offset();
  563. $module
  564. .css({
  565. left : module.cache.element.left,
  566. bottom : '',
  567. marginBottom : ''
  568. })
  569. .removeClass(className.bound)
  570. .removeClass(className.top)
  571. .addClass(className.fixed)
  572. .addClass(className.bottom)
  573. ;
  574. settings.onStick.call(element);
  575. },
  576. unbind: function() {
  577. if( module.is.bound() ) {
  578. module.debug('Removing container bound position on element');
  579. module.remove.offset();
  580. $module
  581. .removeClass(className.bound)
  582. .removeClass(className.top)
  583. .removeClass(className.bottom)
  584. ;
  585. }
  586. },
  587. unfix: function() {
  588. if( module.is.fixed() ) {
  589. module.debug('Removing fixed position on element');
  590. module.remove.offset();
  591. $module
  592. .removeClass(className.fixed)
  593. .removeClass(className.top)
  594. .removeClass(className.bottom)
  595. ;
  596. settings.onUnstick.call(element);
  597. }
  598. },
  599. reset: function() {
  600. module.debug('Reseting elements position');
  601. module.unbind();
  602. module.unfix();
  603. module.resetCSS();
  604. module.remove.offset();
  605. module.remove.lastScroll();
  606. },
  607. resetCSS: function() {
  608. $module
  609. .css({
  610. width : '',
  611. height : ''
  612. })
  613. ;
  614. $container
  615. .css({
  616. height: ''
  617. })
  618. ;
  619. },
  620. setting: function(name, value) {
  621. if( $.isPlainObject(name) ) {
  622. $.extend(true, settings, name);
  623. }
  624. else if(value !== undefined) {
  625. settings[name] = value;
  626. }
  627. else {
  628. return settings[name];
  629. }
  630. },
  631. internal: function(name, value) {
  632. if( $.isPlainObject(name) ) {
  633. $.extend(true, module, name);
  634. }
  635. else if(value !== undefined) {
  636. module[name] = value;
  637. }
  638. else {
  639. return module[name];
  640. }
  641. },
  642. debug: function() {
  643. if(!settings.silent && settings.debug) {
  644. if(settings.performance) {
  645. module.performance.log(arguments);
  646. }
  647. else {
  648. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  649. module.debug.apply(console, arguments);
  650. }
  651. }
  652. },
  653. verbose: function() {
  654. if(!settings.silent && settings.verbose && settings.debug) {
  655. if(settings.performance) {
  656. module.performance.log(arguments);
  657. }
  658. else {
  659. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  660. module.verbose.apply(console, arguments);
  661. }
  662. }
  663. },
  664. error: function() {
  665. if(!settings.silent) {
  666. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  667. module.error.apply(console, arguments);
  668. }
  669. },
  670. performance: {
  671. log: function(message) {
  672. var
  673. currentTime,
  674. executionTime,
  675. previousTime
  676. ;
  677. if(settings.performance) {
  678. currentTime = new Date().getTime();
  679. previousTime = time || currentTime;
  680. executionTime = currentTime - previousTime;
  681. time = currentTime;
  682. performance.push({
  683. 'Name' : message[0],
  684. 'Arguments' : [].slice.call(message, 1) || '',
  685. 'Element' : element,
  686. 'Execution Time' : executionTime
  687. });
  688. }
  689. clearTimeout(module.performance.timer);
  690. module.performance.timer = setTimeout(module.performance.display, 0);
  691. },
  692. display: function() {
  693. var
  694. title = settings.name + ':',
  695. totalTime = 0
  696. ;
  697. time = false;
  698. clearTimeout(module.performance.timer);
  699. $.each(performance, function(index, data) {
  700. totalTime += data['Execution Time'];
  701. });
  702. title += ' ' + totalTime + 'ms';
  703. if(moduleSelector) {
  704. title += ' \'' + moduleSelector + '\'';
  705. }
  706. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  707. console.groupCollapsed(title);
  708. if(console.table) {
  709. console.table(performance);
  710. }
  711. else {
  712. $.each(performance, function(index, data) {
  713. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  714. });
  715. }
  716. console.groupEnd();
  717. }
  718. performance = [];
  719. }
  720. },
  721. invoke: function(query, passedArguments, context) {
  722. var
  723. object = instance,
  724. maxDepth,
  725. found,
  726. response
  727. ;
  728. passedArguments = passedArguments || queryArguments;
  729. context = element || context;
  730. if(typeof query == 'string' && object !== undefined) {
  731. query = query.split(/[\. ]/);
  732. maxDepth = query.length - 1;
  733. $.each(query, function(depth, value) {
  734. var camelCaseValue = (depth != maxDepth)
  735. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  736. : query
  737. ;
  738. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  739. object = object[camelCaseValue];
  740. }
  741. else if( object[camelCaseValue] !== undefined ) {
  742. found = object[camelCaseValue];
  743. return false;
  744. }
  745. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  746. object = object[value];
  747. }
  748. else if( object[value] !== undefined ) {
  749. found = object[value];
  750. return false;
  751. }
  752. else {
  753. return false;
  754. }
  755. });
  756. }
  757. if ( $.isFunction( found ) ) {
  758. response = found.apply(context, passedArguments);
  759. }
  760. else if(found !== undefined) {
  761. response = found;
  762. }
  763. if($.isArray(returnedValue)) {
  764. returnedValue.push(response);
  765. }
  766. else if(returnedValue !== undefined) {
  767. returnedValue = [returnedValue, response];
  768. }
  769. else if(response !== undefined) {
  770. returnedValue = response;
  771. }
  772. return found;
  773. }
  774. };
  775. if(methodInvoked) {
  776. if(instance === undefined) {
  777. module.initialize();
  778. }
  779. module.invoke(query);
  780. }
  781. else {
  782. if(instance !== undefined) {
  783. instance.invoke('destroy');
  784. }
  785. module.initialize();
  786. }
  787. })
  788. ;
  789. return (returnedValue !== undefined)
  790. ? returnedValue
  791. : this
  792. ;
  793. };
  794. $.fn.sticky.settings = {
  795. name : 'Sticky',
  796. namespace : 'sticky',
  797. silent : false,
  798. debug : false,
  799. verbose : true,
  800. performance : true,
  801. // whether to stick in the opposite direction on scroll up
  802. pushing : false,
  803. context : false,
  804. // Context to watch scroll events
  805. scrollContext : window,
  806. // Offset to adjust scroll
  807. offset : 0,
  808. // Offset to adjust scroll when attached to bottom of screen
  809. bottomOffset : 0,
  810. jitter : 5, // will only set container height if difference between context and container is larger than this number
  811. // Whether to automatically observe changes with Mutation Observers
  812. observeChanges : false,
  813. // Called when position is recalculated
  814. onReposition : function(){},
  815. // Called on each scroll
  816. onScroll : function(){},
  817. // Called when element is stuck to viewport
  818. onStick : function(){},
  819. // Called when element is unstuck from viewport
  820. onUnstick : function(){},
  821. // Called when element reaches top of context
  822. onTop : function(){},
  823. // Called when element reaches bottom of context
  824. onBottom : function(){},
  825. error : {
  826. container : 'Sticky element must be inside a relative container',
  827. visible : 'Element is hidden, you must call refresh after element becomes visible',
  828. method : 'The method you called is not defined.',
  829. invalidContext : 'Context specified does not exist',
  830. elementSize : 'Sticky element is larger than its container, cannot create sticky.'
  831. },
  832. className : {
  833. bound : 'bound',
  834. fixed : 'fixed',
  835. supported : 'native',
  836. top : 'top',
  837. bottom : 'bottom'
  838. }
  839. };
  840. })( jQuery, window, document );