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.

970 lines
31 KiB

  1. /*
  2. * # Semantic - Visibility
  3. * http://github.com/semantic-org/semantic-ui/
  4. *
  5. *
  6. * Copyright 2014 Contributor
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ( $, window, document, undefined ) {
  12. $.fn.visibility = function(parameters) {
  13. var
  14. $allModules = $(this),
  15. moduleSelector = $allModules.selector || '',
  16. time = new Date().getTime(),
  17. performance = [],
  18. query = arguments[0],
  19. methodInvoked = (typeof query == 'string'),
  20. queryArguments = [].slice.call(arguments, 1),
  21. returnedValue
  22. ;
  23. $allModules
  24. .each(function() {
  25. var
  26. settings = $.extend(true, {}, $.fn.visibility.settings, parameters),
  27. className = settings.className,
  28. namespace = settings.namespace,
  29. error = settings.error,
  30. eventNamespace = '.' + namespace,
  31. moduleNamespace = 'module-' + namespace,
  32. $window = $(window),
  33. $module = $(this),
  34. $context = $(settings.context),
  35. $container = $module.offsetParent(),
  36. selector = $module.selector || '',
  37. instance = $module.data(moduleNamespace),
  38. requestAnimationFrame = window.requestAnimationFrame
  39. || window.mozRequestAnimationFrame
  40. || window.webkitRequestAnimationFrame
  41. || window.msRequestAnimationFrame
  42. || function(callback) { setTimeout(callback, 0); },
  43. element = this,
  44. module
  45. ;
  46. module = {
  47. initialize: function() {
  48. module.verbose('Initializing visibility', settings);
  49. module.setup.cache();
  50. module.save.position();
  51. if( module.should.trackChanges() ) {
  52. module.bindEvents();
  53. if(settings.type == 'image') {
  54. module.setup.image();
  55. }
  56. if(settings.type == 'fixed') {
  57. module.setup.fixed();
  58. }
  59. }
  60. module.checkVisibility();
  61. module.instantiate();
  62. },
  63. instantiate: function() {
  64. module.verbose('Storing instance of module', module);
  65. instance = module;
  66. $module
  67. .data(moduleNamespace, module)
  68. ;
  69. },
  70. destroy: function() {
  71. module.verbose('Destroying previous module');
  72. $module
  73. .off(eventNamespace)
  74. .removeData(moduleNamespace)
  75. ;
  76. },
  77. bindEvents: function() {
  78. module.verbose('Binding visibility events to scroll and resize');
  79. $window
  80. .on('resize' + eventNamespace, module.event.refresh)
  81. ;
  82. $context
  83. .on('scroll' + eventNamespace, module.event.scroll)
  84. ;
  85. },
  86. event: {
  87. refresh: function() {
  88. requestAnimationFrame(module.refresh);
  89. },
  90. scroll: function() {
  91. module.verbose('Scroll position changed');
  92. if(settings.throttle) {
  93. clearTimeout(module.timer);
  94. module.timer = setTimeout(module.checkVisibility, settings.throttle);
  95. }
  96. else {
  97. requestAnimationFrame(module.checkVisibility);
  98. }
  99. }
  100. },
  101. precache: function(images, callback) {
  102. if (!(images instanceof Array)) {
  103. images = [images];
  104. }
  105. var
  106. imagesLength = images.length,
  107. loadedCounter = 0,
  108. cache = [],
  109. cacheImage = document.createElement('img'),
  110. handleLoad = function() {
  111. loadedCounter++;
  112. if (loadedCounter >= images.length) {
  113. if ($.isFunction(callback)) {
  114. callback();
  115. }
  116. }
  117. }
  118. ;
  119. while (imagesLength--) {
  120. cacheImage = document.createElement('img');
  121. cacheImage.onload = handleLoad;
  122. cacheImage.onerror = handleLoad;
  123. cacheImage.src = images[imagesLength];
  124. cache.push(cacheImage);
  125. }
  126. },
  127. should: {
  128. trackChanges: function() {
  129. if(methodInvoked && queryArguments.length > 0) {
  130. module.debug('One time query, no need to bind events');
  131. return false;
  132. }
  133. module.debug('Query is attaching callbacks, watching for changes with scroll');
  134. return true;
  135. }
  136. },
  137. setup: {
  138. cache: function() {
  139. module.cache = {
  140. occurred : {},
  141. screen : {},
  142. element : {},
  143. };
  144. },
  145. image: function() {
  146. var
  147. src = $module.data('src')
  148. ;
  149. if(src) {
  150. module.verbose('Lazy loading image', src);
  151. // show when top visible
  152. module.topVisible(function() {
  153. module.precache(src, function() {
  154. module.set.image(src);
  155. settings.onTopVisible = false;
  156. });
  157. });
  158. }
  159. },
  160. fixed: function() {
  161. module.verbose('Setting up fixed on element pass');
  162. $module
  163. .visibility({
  164. once: false,
  165. continuous: false,
  166. onTopPassed: function() {
  167. $module
  168. .addClass(className.fixed)
  169. .css({
  170. position: 'fixed',
  171. top: settings.offset + 'px'
  172. })
  173. ;
  174. if(settings.animation && $.fn.transition !== undefined) {
  175. $module.transition(settings.transition, settings.duration);
  176. }
  177. },
  178. onTopPassedReverse: function() {
  179. $module
  180. .removeClass(className.fixed)
  181. .css({
  182. position: '',
  183. top: ''
  184. })
  185. ;
  186. }
  187. })
  188. ;
  189. }
  190. },
  191. set: {
  192. image: function(src) {
  193. var
  194. offScreen = (module.cache.screen.bottom < module.cache.element.top)
  195. ;
  196. $module
  197. .attr('src', src)
  198. ;
  199. if(offScreen) {
  200. module.verbose('Image outside browser, no show animation');
  201. $module.show();
  202. }
  203. else {
  204. if(settings.transition && $.fn.transition !== undefined) {
  205. $module.transition(settings.transition, settings.duration);
  206. }
  207. else {
  208. $module.fadeIn(settings.duration);
  209. }
  210. }
  211. }
  212. },
  213. refresh: function() {
  214. module.debug('Refreshing constants (element width/height)');
  215. module.reset();
  216. module.save.position();
  217. module.checkVisibility();
  218. $.proxy(settings.onRefresh, element)();
  219. },
  220. reset: function() {
  221. module.verbose('Reseting all cached values');
  222. if( $.isPlainObject(module.cache) ) {
  223. module.cache.screen = {};
  224. module.cache.element = {};
  225. }
  226. },
  227. checkVisibility: function() {
  228. module.verbose('Checking visibility of element', module.cache.element);
  229. module.save.calculations();
  230. // percentage
  231. module.passed();
  232. // reverse (must be first)
  233. module.passingReverse();
  234. module.topVisibleReverse();
  235. module.bottomVisibleReverse();
  236. module.topPassedReverse();
  237. module.bottomPassedReverse();
  238. // one time
  239. module.passing();
  240. module.topVisible();
  241. module.bottomVisible();
  242. module.topPassed();
  243. module.bottomPassed();
  244. },
  245. passed: function(amount, newCallback) {
  246. var
  247. calculations = module.get.elementCalculations(),
  248. amountInPixels
  249. ;
  250. // assign callback
  251. if(amount !== undefined && newCallback !== undefined) {
  252. settings.onPassed[amount] = newCallback;
  253. }
  254. else if(amount !== undefined) {
  255. return (module.get.pixelsPassed(amount) > calculations.pixelsPassed);
  256. }
  257. else if(calculations.passing) {
  258. $.each(settings.onPassed, function(amount, callback) {
  259. if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) {
  260. module.execute(callback, amount);
  261. }
  262. else if(!settings.once) {
  263. module.remove.occurred(callback);
  264. }
  265. });
  266. }
  267. },
  268. passing: function(newCallback) {
  269. var
  270. calculations = module.get.elementCalculations(),
  271. callback = newCallback || settings.onPassing,
  272. callbackName = 'passing'
  273. ;
  274. if(newCallback) {
  275. module.debug('Adding callback for passing', newCallback);
  276. settings.onPassing = newCallback;
  277. }
  278. if(calculations.passing) {
  279. module.execute(callback, callbackName);
  280. }
  281. else if(!settings.once) {
  282. module.remove.occurred(callbackName);
  283. }
  284. if(newCallback !== undefined) {
  285. return calculations.passing;
  286. }
  287. },
  288. topVisible: function(newCallback) {
  289. var
  290. calculations = module.get.elementCalculations(),
  291. callback = newCallback || settings.onTopVisible,
  292. callbackName = 'topVisible'
  293. ;
  294. if(newCallback) {
  295. module.debug('Adding callback for top visible', newCallback);
  296. settings.onTopVisible = newCallback;
  297. }
  298. if(calculations.topVisible) {
  299. module.execute(callback, callbackName);
  300. }
  301. else if(!settings.once) {
  302. module.remove.occurred(callbackName);
  303. }
  304. if(newCallback === undefined) {
  305. return calculations.topVisible;
  306. }
  307. },
  308. bottomVisible: function(newCallback) {
  309. var
  310. calculations = module.get.elementCalculations(),
  311. callback = newCallback || settings.onBottomVisible,
  312. callbackName = 'bottomVisible'
  313. ;
  314. if(newCallback) {
  315. module.debug('Adding callback for bottom visible', newCallback);
  316. settings.onBottomVisible = newCallback;
  317. }
  318. if(calculations.bottomVisible) {
  319. module.execute(callback, callbackName);
  320. }
  321. else if(!settings.once) {
  322. module.remove.occurred(callbackName);
  323. }
  324. if(newCallback === undefined) {
  325. return calculations.bottomVisible;
  326. }
  327. },
  328. topPassed: function(newCallback) {
  329. var
  330. calculations = module.get.elementCalculations(),
  331. callback = newCallback || settings.onTopPassed,
  332. callbackName = 'topPassed'
  333. ;
  334. if(newCallback) {
  335. module.debug('Adding callback for top passed', newCallback);
  336. settings.onTopPassed = newCallback;
  337. }
  338. if(calculations.topPassed) {
  339. module.execute(callback, callbackName);
  340. }
  341. else if(!settings.once) {
  342. module.remove.occurred(callbackName);
  343. }
  344. if(newCallback === undefined) {
  345. return calculations.topPassed;
  346. }
  347. },
  348. bottomPassed: function(newCallback) {
  349. var
  350. calculations = module.get.elementCalculations(),
  351. callback = newCallback || settings.onBottomPassed,
  352. callbackName = 'bottomPassed'
  353. ;
  354. if(newCallback) {
  355. module.debug('Adding callback for bottom passed', newCallback);
  356. settings.onBottomPassed = newCallback;
  357. }
  358. if(calculations.bottomPassed) {
  359. module.execute(callback, callbackName);
  360. }
  361. else if(!settings.once) {
  362. module.remove.occurred(callbackName);
  363. }
  364. if(newCallback === undefined) {
  365. return calculations.bottomPassed;
  366. }
  367. },
  368. passingReverse: function(newCallback) {
  369. var
  370. calculations = module.get.elementCalculations(),
  371. callback = newCallback || settings.onPassingReverse,
  372. callbackName = 'passingReverse'
  373. ;
  374. if(newCallback) {
  375. module.debug('Adding callback for passing reverse', newCallback);
  376. settings.onPassingReverse = newCallback;
  377. }
  378. if(!calculations.passing) {
  379. if(module.get.occurred('passing')) {
  380. module.execute(callback, callbackName);
  381. }
  382. }
  383. else if(!settings.once) {
  384. module.remove.occurred(callbackName);
  385. }
  386. if(newCallback !== undefined) {
  387. return !calculations.passing;
  388. }
  389. },
  390. topVisibleReverse: function(newCallback) {
  391. var
  392. calculations = module.get.elementCalculations(),
  393. callback = newCallback || settings.onTopVisibleReverse,
  394. callbackName = 'topVisibleReverse'
  395. ;
  396. if(newCallback) {
  397. module.debug('Adding callback for top visible reverse', newCallback);
  398. settings.onTopVisibleReverse = newCallback;
  399. }
  400. if(!calculations.topVisible) {
  401. if(module.get.occurred('topVisible')) {
  402. module.execute(callback, callbackName);
  403. }
  404. }
  405. else if(!settings.once) {
  406. module.remove.occurred(callbackName);
  407. }
  408. if(newCallback === undefined) {
  409. return !calculations.topVisible;
  410. }
  411. },
  412. bottomVisibleReverse: function(newCallback) {
  413. var
  414. calculations = module.get.elementCalculations(),
  415. callback = newCallback || settings.onBottomVisibleReverse,
  416. callbackName = 'bottomVisibleReverse'
  417. ;
  418. if(newCallback) {
  419. module.debug('Adding callback for bottom visible reverse', newCallback);
  420. settings.onBottomVisibleReverse = newCallback;
  421. }
  422. if(!calculations.bottomVisible) {
  423. if(module.get.occurred('bottomVisible')) {
  424. module.execute(callback, callbackName);
  425. }
  426. }
  427. else if(!settings.once) {
  428. module.remove.occurred(callbackName);
  429. }
  430. if(newCallback === undefined) {
  431. return !calculations.bottomVisible;
  432. }
  433. },
  434. topPassedReverse: function(newCallback) {
  435. var
  436. calculations = module.get.elementCalculations(),
  437. callback = newCallback || settings.onTopPassedReverse,
  438. callbackName = 'topPassedReverse'
  439. ;
  440. if(newCallback) {
  441. module.debug('Adding callback for top passed reverse', newCallback);
  442. settings.onTopPassedReverse = newCallback;
  443. }
  444. if(!calculations.topPassed) {
  445. if(module.get.occurred('topPassed')) {
  446. module.execute(callback, callbackName);
  447. }
  448. }
  449. else if(!settings.once) {
  450. module.remove.occurred(callbackName);
  451. }
  452. if(newCallback === undefined) {
  453. return !calculations.onTopPassed;
  454. }
  455. },
  456. bottomPassedReverse: function(newCallback) {
  457. var
  458. calculations = module.get.elementCalculations(),
  459. callback = newCallback || settings.onBottomPassedReverse,
  460. callbackName = 'bottomPassedReverse'
  461. ;
  462. if(newCallback) {
  463. module.debug('Adding callback for bottom passed reverse', newCallback);
  464. settings.onBottomPassedReverse = newCallback;
  465. }
  466. if(!calculations.bottomPassed) {
  467. if(module.get.occurred('bottomPassed')) {
  468. module.execute(callback, callbackName);
  469. }
  470. }
  471. else if(!settings.once) {
  472. module.remove.occurred(callbackName);
  473. }
  474. if(newCallback === undefined) {
  475. return !calculations.bottomPassed;
  476. }
  477. },
  478. execute: function(callback, callbackName) {
  479. var
  480. calculations = module.get.elementCalculations(),
  481. screen = module.get.screenCalculations()
  482. ;
  483. callback = callback || false;
  484. if(callback) {
  485. if(settings.continuous) {
  486. module.debug('Callback being called continuously', callbackName, calculations);
  487. $.proxy(callback, element)(calculations, screen);
  488. }
  489. else if(!module.get.occurred(callbackName)) {
  490. module.debug('Conditions met', callbackName, calculations);
  491. $.proxy(callback, element)(calculations, screen);
  492. }
  493. }
  494. module.save.occurred(callbackName);
  495. },
  496. remove: {
  497. occurred: function(callback) {
  498. if(callback) {
  499. if(module.cache.occurred[callback] !== undefined && module.cache.occurred[callback] === true) {
  500. module.debug('Callback can now be called again', callback);
  501. module.cache.occurred[callback] = false;
  502. }
  503. }
  504. else {
  505. module.cache.occurred = {};
  506. }
  507. }
  508. },
  509. save: {
  510. calculations: function() {
  511. module.verbose('Saving all calculations necessary to determine positioning');
  512. module.save.scroll();
  513. module.save.direction();
  514. module.save.screenCalculations();
  515. module.save.elementCalculations();
  516. },
  517. occurred: function(callback) {
  518. if(callback) {
  519. if(module.cache.occurred[callback] === undefined || (module.cache.occurred[callback] !== true)) {
  520. module.verbose('Saving callback occurred', callback);
  521. module.cache.occurred[callback] = true;
  522. }
  523. }
  524. },
  525. scroll: function() {
  526. module.cache.scroll = $context.scrollTop() + settings.offset;
  527. },
  528. direction: function() {
  529. var
  530. scroll = module.get.scroll(),
  531. lastScroll = module.get.lastScroll(),
  532. direction
  533. ;
  534. if(scroll > lastScroll && lastScroll) {
  535. direction = 'down';
  536. }
  537. else if(scroll < lastScroll && lastScroll) {
  538. direction = 'up';
  539. }
  540. else {
  541. direction = 'static';
  542. }
  543. module.cache.direction = direction;
  544. return module.cache.direction;
  545. },
  546. elementPosition: function() {
  547. var
  548. screen = module.get.screenSize()
  549. ;
  550. module.verbose('Saving element position');
  551. $.extend(module.cache.element, {
  552. margin : {
  553. top : parseInt($module.css('margin-top'), 10),
  554. bottom : parseInt($module.css('margin-bottom'), 10)
  555. },
  556. fits : (element.height < screen.height),
  557. offset : $module.offset(),
  558. width : $module.outerWidth(),
  559. height : $module.outerHeight()
  560. });
  561. return module.cache.element;
  562. },
  563. elementCalculations: function() {
  564. var
  565. screen = module.get.screenCalculations(),
  566. element = module.get.elementPosition()
  567. ;
  568. // offset
  569. if(settings.includeMargin) {
  570. $.extend(module.cache.element, {
  571. top : element.offset.top - element.margin.top,
  572. bottom : element.offset.top + element.height + element.margin.bottom
  573. });
  574. }
  575. else {
  576. $.extend(module.cache.element, {
  577. top : element.offset.top,
  578. bottom : element.offset.top + element.height
  579. });
  580. }
  581. // visibility
  582. $.extend(module.cache.element, {
  583. topVisible : (screen.bottom >= element.top),
  584. topPassed : (screen.top >= element.top),
  585. bottomVisible : (screen.bottom >= element.bottom),
  586. bottomPassed : (screen.top >= element.bottom),
  587. pixelsPassed : 0,
  588. percentagePassed : 0
  589. });
  590. // meta calculations
  591. $.extend(module.cache.element, {
  592. visible : (module.cache.element.topVisible || module.cache.element.bottomVisible),
  593. passing : (module.cache.element.topPassed && !module.cache.element.bottomPassed),
  594. hidden : (!module.cache.element.topVisible && !module.cache.element.bottomVisible)
  595. });
  596. if(module.cache.element.passing) {
  597. module.cache.element.pixelsPassed = (screen.top - element.top);
  598. module.cache.element.percentagePassed = (screen.top - element.top) / element.height;
  599. }
  600. module.verbose('Updated element calculations', module.cache.element);
  601. },
  602. screenCalculations: function() {
  603. var
  604. scroll = $context.scrollTop() + settings.offset
  605. ;
  606. if(module.cache.scroll === undefined) {
  607. module.cache.scroll = $context.scrollTop() + settings.offset;
  608. }
  609. module.save.direction();
  610. $.extend(module.cache.screen, {
  611. top : scroll,
  612. bottom : scroll + module.cache.screen.height
  613. });
  614. return module.cache.screen;
  615. },
  616. screenSize: function() {
  617. module.verbose('Saving window position');
  618. module.cache.screen = {
  619. height: $context.height()
  620. };
  621. },
  622. position: function() {
  623. module.save.screenSize();
  624. module.save.elementPosition();
  625. }
  626. },
  627. get: {
  628. pixelsPassed: function(amount) {
  629. var
  630. element = module.get.elementCalculations()
  631. ;
  632. if(amount.search('%') > -1) {
  633. return ( element.height * (parseInt(amount, 10) / 100) );
  634. }
  635. return parseInt(amount, 10);
  636. },
  637. occurred: function(callback) {
  638. return (module.cache.occurred !== undefined)
  639. ? module.cache.occurred[callback] || false
  640. : false
  641. ;
  642. },
  643. direction: function() {
  644. if(module.cache.direction === undefined) {
  645. module.save.direction();
  646. }
  647. return module.cache.direction;
  648. },
  649. elementPosition: function() {
  650. if(module.cache.element === undefined) {
  651. module.save.elementPosition();
  652. }
  653. return module.cache.element;
  654. },
  655. elementCalculations: function() {
  656. if(module.cache.element === undefined) {
  657. module.save.elementCalculations();
  658. }
  659. return module.cache.element;
  660. },
  661. screenCalculations: function() {
  662. if(module.cache.screen === undefined) {
  663. module.save.screenCalculations();
  664. }
  665. return module.cache.screen;
  666. },
  667. screenSize: function() {
  668. if(module.cache.screen === undefined) {
  669. module.save.screenSize();
  670. }
  671. return module.cache.screen;
  672. },
  673. scroll: function() {
  674. if(module.cache.scroll === undefined) {
  675. module.save.scroll();
  676. }
  677. return module.cache.scroll;
  678. },
  679. lastScroll: function() {
  680. if(module.cache.screen === undefined) {
  681. module.debug('First scroll event, no last scroll could be found');
  682. return false;
  683. }
  684. return module.cache.screen.top;
  685. }
  686. },
  687. setting: function(name, value) {
  688. if( $.isPlainObject(name) ) {
  689. $.extend(true, settings, name);
  690. }
  691. else if(value !== undefined) {
  692. settings[name] = value;
  693. }
  694. else {
  695. return settings[name];
  696. }
  697. },
  698. internal: function(name, value) {
  699. if( $.isPlainObject(name) ) {
  700. $.extend(true, module, name);
  701. }
  702. else if(value !== undefined) {
  703. module[name] = value;
  704. }
  705. else {
  706. return module[name];
  707. }
  708. },
  709. debug: function() {
  710. if(settings.debug) {
  711. if(settings.performance) {
  712. module.performance.log(arguments);
  713. }
  714. else {
  715. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  716. module.debug.apply(console, arguments);
  717. }
  718. }
  719. },
  720. verbose: function() {
  721. if(settings.verbose && settings.debug) {
  722. if(settings.performance) {
  723. module.performance.log(arguments);
  724. }
  725. else {
  726. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  727. module.verbose.apply(console, arguments);
  728. }
  729. }
  730. },
  731. error: function() {
  732. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  733. module.error.apply(console, arguments);
  734. },
  735. performance: {
  736. log: function(message) {
  737. var
  738. currentTime,
  739. executionTime,
  740. previousTime
  741. ;
  742. if(settings.performance) {
  743. currentTime = new Date().getTime();
  744. previousTime = time || currentTime;
  745. executionTime = currentTime - previousTime;
  746. time = currentTime;
  747. performance.push({
  748. 'Name' : message[0],
  749. 'Arguments' : [].slice.call(message, 1) || '',
  750. 'Element' : element,
  751. 'Execution Time' : executionTime
  752. });
  753. }
  754. clearTimeout(module.performance.timer);
  755. module.performance.timer = setTimeout(module.performance.display, 100);
  756. },
  757. display: function() {
  758. var
  759. title = settings.name + ':',
  760. totalTime = 0
  761. ;
  762. time = false;
  763. clearTimeout(module.performance.timer);
  764. $.each(performance, function(index, data) {
  765. totalTime += data['Execution Time'];
  766. });
  767. title += ' ' + totalTime + 'ms';
  768. if(moduleSelector) {
  769. title += ' \'' + moduleSelector + '\'';
  770. }
  771. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  772. console.groupCollapsed(title);
  773. if(console.table) {
  774. console.table(performance);
  775. }
  776. else {
  777. $.each(performance, function(index, data) {
  778. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  779. });
  780. }
  781. console.groupEnd();
  782. }
  783. performance = [];
  784. }
  785. },
  786. invoke: function(query, passedArguments, context) {
  787. var
  788. object = instance,
  789. maxDepth,
  790. found,
  791. response
  792. ;
  793. passedArguments = passedArguments || queryArguments;
  794. context = element || context;
  795. if(typeof query == 'string' && object !== undefined) {
  796. query = query.split(/[\. ]/);
  797. maxDepth = query.length - 1;
  798. $.each(query, function(depth, value) {
  799. var camelCaseValue = (depth != maxDepth)
  800. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  801. : query
  802. ;
  803. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  804. object = object[camelCaseValue];
  805. }
  806. else if( object[camelCaseValue] !== undefined ) {
  807. found = object[camelCaseValue];
  808. return false;
  809. }
  810. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  811. object = object[value];
  812. }
  813. else if( object[value] !== undefined ) {
  814. found = object[value];
  815. return false;
  816. }
  817. else {
  818. module.error(error.method, query);
  819. return false;
  820. }
  821. });
  822. }
  823. if ( $.isFunction( found ) ) {
  824. response = found.apply(context, passedArguments);
  825. }
  826. else if(found !== undefined) {
  827. response = found;
  828. }
  829. if($.isArray(returnedValue)) {
  830. returnedValue.push(response);
  831. }
  832. else if(returnedValue !== undefined) {
  833. returnedValue = [returnedValue, response];
  834. }
  835. else if(response !== undefined) {
  836. returnedValue = response;
  837. }
  838. return found;
  839. }
  840. };
  841. if(methodInvoked) {
  842. if(instance === undefined) {
  843. module.initialize();
  844. }
  845. module.invoke(query);
  846. }
  847. else {
  848. if(instance !== undefined) {
  849. module.destroy();
  850. }
  851. module.initialize();
  852. }
  853. })
  854. ;
  855. return (returnedValue !== undefined)
  856. ? returnedValue
  857. : this
  858. ;
  859. };
  860. $.fn.visibility.settings = {
  861. name : 'Visibility',
  862. namespace : 'visibility',
  863. className: {
  864. fixed: 'fixed'
  865. },
  866. debug : false,
  867. verbose : false,
  868. performance : true,
  869. offset : 0,
  870. includeMargin : false,
  871. context : window,
  872. // visibility check delay in ms (defaults to animationFrame)
  873. throttle : false,
  874. // special visibility type (image, fixed)
  875. type : false,
  876. // image only animation settings
  877. transition : false,
  878. duration : 500,
  879. // array of callbacks for percentage
  880. onPassed : {},
  881. // standard callbacks
  882. onPassing : false,
  883. onTopVisible : false,
  884. onBottomVisible : false,
  885. onTopPassed : false,
  886. onBottomPassed : false,
  887. // reverse callbacks
  888. onPassingReverse : false,
  889. onTopVisibleReverse : false,
  890. onBottomVisibleReverse : false,
  891. onTopPassedReverse : false,
  892. onBottomPassedReverse : false,
  893. once : true,
  894. continuous : false,
  895. // utility callbacks
  896. onRefresh : function(){},
  897. onScroll : function(){},
  898. error : {
  899. method : 'The method you called is not defined.'
  900. }
  901. };
  902. })( jQuery, window , document );