timesheet source code
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

241 lignes
10KB

  1. /*!
  2. * jQuery scrollintoview() plugin and :scrollable selector filter
  3. *
  4. * Version 1.9.4 (06 April 2016)
  5. * Requires jQuery 1.4 or newer
  6. *
  7. * Copyright (c) 2011 Robert Koritnik
  8. * Licensed under the terms of the MIT license
  9. * http://www.opensource.org/licenses/mit-license.php
  10. */
  11. !function(root, factory) {
  12. if (typeof define === 'function' && define.amd) {
  13. define(['jquery'], factory);
  14. } else if (typeof exports === 'object') {
  15. factory(require('jquery'));
  16. } else {
  17. factory(root.jQuery);
  18. }
  19. }
  20. (this, function($) {
  21. var converter = {
  22. vertical: { x: false, y: true },
  23. horizontal: { x: true, y: false },
  24. both: { x: true, y: true },
  25. x: { x: true, y: false },
  26. y: { x: false, y: true }
  27. };
  28. var settings = {
  29. duration: "fast",
  30. direction: "both",
  31. viewPadding: 0
  32. };
  33. var rootrx = /^(?:html)$/i;
  34. // gets border dimensions
  35. var borders = function(domElement, styles) {
  36. styles = styles || (document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(domElement, null) : domElement.currentStyle);
  37. var px = document.defaultView && document.defaultView.getComputedStyle ? true : false;
  38. var b = {
  39. top: (parseFloat(px ? styles.borderTopWidth : $.css(domElement, "borderTopWidth")) || 0),
  40. left: (parseFloat(px ? styles.borderLeftWidth : $.css(domElement, "borderLeftWidth")) || 0),
  41. bottom: (parseFloat(px ? styles.borderBottomWidth : $.css(domElement, "borderBottomWidth")) || 0),
  42. right: (parseFloat(px ? styles.borderRightWidth : $.css(domElement, "borderRightWidth")) || 0)
  43. };
  44. return {
  45. top: b.top,
  46. left: b.left,
  47. bottom: b.bottom,
  48. right: b.right,
  49. vertical: b.top + b.bottom,
  50. horizontal: b.left + b.right
  51. };
  52. };
  53. var dimensions = function($element) {
  54. var elem = $element[0],
  55. isRoot = rootrx.test(elem.nodeName),
  56. $elem = isRoot ? $(window) : $element;
  57. return {
  58. border: isRoot ? { top: 0, left: 0, bottom: 0, right: 0 } : borders(elem),
  59. scroll: {
  60. top: $elem.scrollTop(),
  61. left: $elem.scrollLeft(),
  62. maxtop: elem.scrollHeight - elem.clientHeight,
  63. maxleft: elem.scrollWidth - elem.clientWidth
  64. },
  65. scrollbar: isRoot
  66. ? { right: 0, bottom: 0 }
  67. : {
  68. right: $elem.innerWidth() - elem.clientWidth,
  69. bottom: $elem.innerHeight() - elem.clientHeight
  70. },
  71. rect: isRoot ? { top: 0, left: 0, bottom: elem.clientHeight, right: elem.clientWidth } : elem.getBoundingClientRect()
  72. };
  73. };
  74. $.fn.extend({
  75. scrollintoview: function(options) {
  76. /// <summary>Scrolls the first element in the set into view by scrolling its closest scrollable parent.</summary>
  77. /// <param name="options" type="Object">Additional options that can configure scrolling:
  78. /// duration (default: "fast") - jQuery animation speed (can be a duration string or number of milliseconds)
  79. /// direction (default: "both") - select possible scrollings ("vertical" or "y", "horizontal" or "x", "both")
  80. /// complete (default: none) - a function to call when scrolling completes (called in context of the DOM element being scrolled)
  81. /// </param>
  82. /// <return type="jQuery">Returns the same jQuery set that this function was run on.</return>
  83. options = $.extend({}, settings, options);
  84. options.direction = converter[typeof (options.direction) === "string" && options.direction.toLowerCase()] || converter.both;
  85. if (typeof options.viewPadding == "number") {
  86. options.viewPadding = { x: options.viewPadding, y: options.viewPadding };
  87. } else if (typeof options.viewPadding == "object") {
  88. if (options.viewPadding.x == undefined) {
  89. options.viewPadding.x = 0;
  90. }
  91. if (options.viewPadding.y == undefined) {
  92. options.viewPadding.y = 0;
  93. }
  94. }
  95. var dirStr = "";
  96. if (options.direction.x === true) dirStr = "horizontal";
  97. if (options.direction.y === true) dirStr = dirStr ? "both" : "vertical";
  98. var el = this.eq(0);
  99. var scroller = el.parent().closest(":scrollable(" + dirStr + ")");
  100. // check if there's anything to scroll in the first place
  101. if (scroller.length > 0) {
  102. scroller = scroller.eq(0);
  103. var dim = {
  104. e: dimensions(el),
  105. s: dimensions(scroller)
  106. };
  107. var rel = {
  108. top: dim.e.rect.top - (dim.s.rect.top + dim.s.border.top),
  109. bottom: dim.s.rect.bottom - dim.s.border.bottom - dim.s.scrollbar.bottom - dim.e.rect.bottom,
  110. left: dim.e.rect.left - (dim.s.rect.left + dim.s.border.left),
  111. right: dim.s.rect.right - dim.s.border.right - dim.s.scrollbar.right - dim.e.rect.right
  112. };
  113. var animProperties = {};
  114. // vertical scroll
  115. if (options.direction.y === true) {
  116. if (rel.top < 0) {
  117. animProperties.scrollTop = Math.max(0, dim.s.scroll.top + rel.top - options.viewPadding.y);
  118. } else if (rel.top > 0 && rel.bottom < 0) {
  119. animProperties.scrollTop = Math.min(dim.s.scroll.top + Math.min(rel.top, -rel.bottom) + options.viewPadding.y, dim.s.scroll.maxtop);
  120. }
  121. }
  122. // horizontal scroll
  123. if (options.direction.x === true) {
  124. if (rel.left < 0) {
  125. animProperties.scrollLeft = Math.max(0, dim.s.scroll.left + rel.left - options.viewPadding.x);
  126. } else if (rel.left > 0 && rel.right < 0) {
  127. animProperties.scrollLeft = Math.min(dim.s.scroll.left + Math.min(rel.left, -rel.right) + options.viewPadding.x, dim.s.scroll.maxleft);
  128. }
  129. }
  130. // scroll if needed
  131. if (!$.isEmptyObject(animProperties)) {
  132. var scrollExpect = {},
  133. scrollListener = scroller;
  134. if (rootrx.test(scroller[0].nodeName)) {
  135. scroller = $("html,body");
  136. scrollListener = $(window);
  137. }
  138. function animateStep(now, tween) {
  139. scrollExpect[tween.prop] = Math.floor(now);
  140. };
  141. function onscroll(event) {
  142. $.each(scrollExpect, function(key, value) {
  143. if (Math.floor(scrollListener[key]()) != Math.floor(value)) {
  144. options.complete = null; // don't run complete function if the scrolling was interrupted
  145. scroller.stop('scrollintoview');
  146. }
  147. });
  148. }
  149. scrollListener.on('scroll', onscroll);
  150. scroller
  151. .stop('scrollintoview')
  152. .animate(animProperties, { duration: options.duration, step: animateStep, queue: 'scrollintoview' })
  153. .eq(0) // we want function to be called just once (ref. "html,body")
  154. .queue('scrollintoview', function(next) {
  155. scrollListener.off('scroll', onscroll);
  156. $.isFunction(options.complete) && options.complete.call(scroller[0]);
  157. next();
  158. })
  159. scroller.dequeue('scrollintoview');
  160. } else {
  161. // when there's nothing to scroll, just call the "complete" function
  162. $.isFunction(options.complete) && options.complete.call(scroller[0]);
  163. }
  164. }
  165. // return set back
  166. return this;
  167. }
  168. });
  169. var scrollValue = {
  170. auto: true,
  171. scroll: true,
  172. visible: false,
  173. hidden: false
  174. };
  175. var scroll = function(element, direction) {
  176. direction = converter[typeof (direction) === "string" && direction.toLowerCase()] || converter.both;
  177. var styles = (document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(element, null) : element.currentStyle);
  178. var overflow = {
  179. x: scrollValue[styles.overflowX.toLowerCase()] || false,
  180. y: scrollValue[styles.overflowY.toLowerCase()] || false,
  181. isRoot: rootrx.test(element.nodeName)
  182. };
  183. // check if completely unscrollable (exclude HTML element because it's special)
  184. if (!overflow.x && !overflow.y && !overflow.isRoot) {
  185. return false;
  186. }
  187. var size = {
  188. height: {
  189. scroll: element.scrollHeight,
  190. client: element.clientHeight
  191. },
  192. width: {
  193. scroll: element.scrollWidth,
  194. client: element.clientWidth
  195. },
  196. // check overflow.x/y because iPad (and possibly other tablets) don't dislay scrollbars
  197. scrollableX: function() {
  198. return (overflow.x || overflow.isRoot) && this.width.scroll > this.width.client;
  199. },
  200. scrollableY: function() {
  201. return (overflow.y || overflow.isRoot) && this.height.scroll > this.height.client;
  202. }
  203. };
  204. return direction.y && size.scrollableY() || direction.x && size.scrollableX();
  205. };
  206. $.expr[":"].scrollable = $.expr.createPseudo(function(direction) {
  207. return function(element) {
  208. return scroll(element, direction);
  209. };
  210. });
  211. });