New.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. MochiKit.Base.update(MochiKit.Base, {
  2. isIE: function () {
  3. return /MSIE/.test(navigator.userAgent);
  4. },
  5. isGecko: function () {
  6. return /Gecko/.test(navigator.userAgent);
  7. },
  8. isKHTML: function () {
  9. return /Konqueror|Safari|KHTML/.test(navigator.userAgent)
  10. },
  11. isSafari: function () {
  12. return /AppleWebKit'/.test(navigator.appVersion);
  13. },
  14. isOpera: function () {
  15. return /Opera/.test(navigator.userAgent);
  16. }
  17. });
  18. MochiKit.Base.update(MochiKit.DOM, {
  19. getStyle: function (element, style) {
  20. element = MochiKit.DOM.getElement(element);
  21. var value = element.style[MochiKit.Base.camelize(style)];
  22. if (!value) {
  23. if (document.defaultView && document.defaultView.getComputedStyle) {
  24. var css = document.defaultView.getComputedStyle(element, null);
  25. value = css ? css.getPropertyValue(style) : null;
  26. } else if (element.currentStyle) {
  27. value = element.currentStyle[MochiKit.Base.camelize(style)];
  28. }
  29. }
  30. if (MochiKit.Base.isOpera() && (MochiKit.Base.find(['left', 'top', 'right', 'bottom'], style))) {
  31. if (MochiKit.DOM.getStyle(element, 'position') == 'static') {
  32. value = 'auto';
  33. }
  34. }
  35. return value == 'auto' ? null : value;
  36. },
  37. setStyle: function (element, style) {
  38. element = MochiKit.DOM.getElement(element);
  39. for (name in style) {
  40. element.style[MochiKit.Base.camelize(name)] = style[name];
  41. }
  42. },
  43. getOpacity: function (element) {
  44. var opacity;
  45. if (opacity = MochiKit.DOM.getStyle(element, 'opacity')) {
  46. return parseFloat(opacity);
  47. }
  48. if (opacity = (MochiKit.DOM.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/)) {
  49. if (opacity[1]) {
  50. return parseFloat(opacity[1]) / 100;
  51. }
  52. }
  53. return 1.0;
  54. },
  55. getInlineOpacity: function (element) {
  56. return MochiKit.DOM.getElement(element).style.opacity || '';
  57. },
  58. setOpacity: function (element, value) {
  59. element = MochiKit.DOM.getElement(element);
  60. if (value == 1) {
  61. MochiKit.DOM.setStyle(element, {opacity:
  62. (MochiKit.Base.isGecko() && !MochiKit.Base.isKHTML()) ?
  63. 0.999999 : null});
  64. if (MochiKit.Base.isIE())
  65. MochiKit.DOM.setStyle(element, {filter:
  66. MochiKit.DOM.getStyle(element, 'filter').replace(/alpha\([^\)]*\)/gi, '')});
  67. } else {
  68. if (value < 0.00001) {
  69. value = 0;
  70. }
  71. MochiKit.DOM.setStyle(element, {opacity: value});
  72. if (MochiKit.Base.isIE()) {
  73. MochiKit.DOM.setStyle(element,
  74. {filter: MochiKit.DOM.getStyle(element, 'filter').replace(/alpha\([^\)]*\)/gi, '') + 'alpha(opacity=' + value * 100 + ')' });
  75. }
  76. }
  77. },
  78. isVisible: function (element) {
  79. return MochiKit.DOM.getElement(element).style.display != 'none';
  80. },
  81. makeClipping: function (element) {
  82. element = MochiKit.DOM.getElement(element);
  83. if (element._overflow) {
  84. return;
  85. }
  86. element._overflow = element.style.overflow;
  87. if ((MochiKit.DOM.getStyle(element, 'overflow') || 'visible') != 'hidden') {
  88. element.style.overflow = 'hidden';
  89. }
  90. },
  91. undoClipping: function (element) {
  92. element = MochiKit.DOM.getElement(element);
  93. if (!element._overflow) {
  94. return;
  95. }
  96. element.style.overflow = element._overflow;
  97. element._overflow = undefined;
  98. },
  99. makePositioned: function (element) {
  100. element = MochiKit.DOM.getElement(element);
  101. /*if (!element.style) {
  102. alert(element);
  103. }*/
  104. var pos = MochiKit.DOM.getStyle(element, 'position');
  105. if ((pos == 'static' || !pos) && !element._madePositioned) {
  106. element._madePositioned = true;
  107. element.style.position = 'relative';
  108. // Opera returns the offset relative to the positioning context,
  109. // when an element is position relative but top and left have
  110. // not been defined
  111. if (MochiKit.Base.isOpera()) {
  112. element.style.top = 0;
  113. element.style.left = 0;
  114. }
  115. }
  116. },
  117. undoPositioned: function (element) {
  118. element = MochiKit.DOM.getElement(element);
  119. if (element._madePositioned) {
  120. element._madePositioned = undefined;
  121. element.style.position = element.style.top = element.style.left = element.style.bottom = element.style.right = '';
  122. }
  123. },
  124. getFirstElementByTagAndClassName: function (tagName, className,
  125. /* optional */parent) {
  126. var self = MochiKit.DOM;
  127. if (typeof(tagName) == 'undefined' || tagName === null) {
  128. tagName = '*';
  129. }
  130. if (typeof(parent) == 'undefined' || parent === null) {
  131. parent = self._document;
  132. }
  133. parent = self.getElement(parent);
  134. var children = (parent.getElementsByTagName(tagName)
  135. || self._document.all);
  136. if (typeof(className) == 'undefined' || className === null) {
  137. return MochiKit.Base.extend(null, children);
  138. }
  139. for (var i = 0; i < children.length; i++) {
  140. var child = children[i];
  141. var classNames = child.className.split(' ');
  142. for (var j = 0; j < classNames.length; j++) {
  143. if (classNames[j] == className) {
  144. return child;
  145. }
  146. }
  147. }
  148. },
  149. isParent: function (child, element) {
  150. if (!child.parentNode || child == element) {
  151. return false;
  152. }
  153. if (child.parentNode == element) {
  154. return true;
  155. }
  156. return MochiKit.DOM.isParent(child.parentNode, element);
  157. }
  158. });
  159. MochiKit.Position = {
  160. // set to true if needed, warning: firefox performance problems
  161. // NOT neeeded for page scrolling, only if draggable contained in
  162. // scrollable elements
  163. includeScrollOffsets: false,
  164. prepare: function () {
  165. var deltaX = window.pageXOffset
  166. || document.documentElement.scrollLeft
  167. || document.body.scrollLeft
  168. || 0;
  169. var deltaY = window.pageYOffset
  170. || document.documentElement.scrollTop
  171. || document.body.scrollTop
  172. || 0;
  173. this.windowOffset = new MochiKit.Style.Coordinates(deltaX, deltaY);
  174. },
  175. cumulativeOffset: function (element) {
  176. var valueT = 0;
  177. var valueL = 0;
  178. do {
  179. valueT += element.offsetTop || 0;
  180. valueL += element.offsetLeft || 0;
  181. element = element.offsetParent;
  182. } while (element);
  183. return new MochiKit.Style.Coordinates(valueL, valueT);
  184. },
  185. realOffset: function (element) {
  186. var valueT = 0;
  187. var valueL = 0;
  188. do {
  189. valueT += element.scrollTop || 0;
  190. valueL += element.scrollLeft || 0;
  191. element = element.parentNode;
  192. } while (element);
  193. return new MochiKit.Style.Coordinates(valueL, valueT);
  194. },
  195. within: function (element, x, y) {
  196. if (this.includeScrollOffsets) {
  197. return this.withinIncludingScrolloffsets(element, x, y);
  198. }
  199. this.xcomp = x;
  200. this.ycomp = y;
  201. this.offset = this.cumulativeOffset(element);
  202. if (element.style.position == "fixed") {
  203. this.offset.x += this.windowOffset.x;
  204. this.offset.y += this.windowOffset.y;
  205. }
  206. return (y >= this.offset.y &&
  207. y < this.offset.y + element.offsetHeight &&
  208. x >= this.offset.x &&
  209. x < this.offset.x + element.offsetWidth);
  210. },
  211. withinIncludingScrolloffsets: function (element, x, y) {
  212. var offsetcache = this.realOffset(element);
  213. this.xcomp = x + offsetcache.x - this.windowOffset.x;
  214. this.ycomp = y + offsetcache.y - this.windowOffset.y;
  215. this.offset = this.cumulativeOffset(element);
  216. return (this.ycomp >= this.offset.y &&
  217. this.ycomp < this.offset.y + element.offsetHeight &&
  218. this.xcomp >= this.offset.x &&
  219. this.xcomp < this.offset.x + element.offsetWidth);
  220. },
  221. // within must be called directly before
  222. overlap: function (mode, element) {
  223. if (!mode) {
  224. return 0;
  225. }
  226. if (mode == 'vertical') {
  227. return ((this.offset.y + element.offsetHeight) - this.ycomp) /
  228. element.offsetHeight;
  229. }
  230. if (mode == 'horizontal') {
  231. return ((this.offset.x + element.offsetWidth) - this.xcomp) /
  232. element.offsetWidth;
  233. }
  234. },
  235. absolutize: function (element) {
  236. element = MochiKit.DOM.getElement(element);
  237. if (element.style.position == 'absolute') {
  238. return;
  239. }
  240. MochiKit.Position.prepare();
  241. var offsets = MochiKit.Position.positionedOffset(element);
  242. var width = element.clientWidth;
  243. var height = element.clientHeight;
  244. var oldStyle = {
  245. 'position': element.style.position,
  246. 'left': offsets.x - parseFloat(element.style.left || 0),
  247. 'top': offsets.y - parseFloat(element.style.top || 0),
  248. 'width': element.style.width,
  249. 'height': element.style.height
  250. };
  251. element.style.position = 'absolute';
  252. element.style.top = offsets.y + 'px';
  253. element.style.left = offsets.x + 'px';
  254. element.style.width = width + 'px';
  255. element.style.height = height + 'px';
  256. return oldStyle;
  257. },
  258. positionedOffset: function (element) {
  259. var valueT = 0, valueL = 0;
  260. do {
  261. valueT += element.offsetTop || 0;
  262. valueL += element.offsetLeft || 0;
  263. element = element.offsetParent;
  264. if (element) {
  265. p = MochiKit.DOM.getStyle(element, 'position');
  266. if (p == 'relative' || p == 'absolute') {
  267. break;
  268. }
  269. }
  270. } while (element);
  271. return new MochiKit.Style.Coordinates(valueL, valueT);
  272. },
  273. relativize: function (element, oldPos) {
  274. element = MochiKit.DOM.getElement(element);
  275. if (element.style.position == 'relative') {
  276. return;
  277. }
  278. MochiKit.Position.prepare();
  279. var top = parseFloat(element.style.top || 0) -
  280. (oldPos['top'] || 0);
  281. var left = parseFloat(element.style.left || 0) -
  282. (oldPos['left'] || 0);
  283. element.style.position = oldPos['position'];
  284. element.style.top = top + 'px';
  285. element.style.left = left + 'px';
  286. element.style.width = oldPos['width'];
  287. element.style.height = oldPos['height'];
  288. },
  289. clone: function (source, target) {
  290. source = MochiKit.DOM.getElement(source);
  291. target = MochiKit.DOM.getElement(target);
  292. target.style.position = 'absolute';
  293. var offsets = this.cumulativeOffset(source);
  294. target.style.top = offsets.y + 'px';
  295. target.style.left = offsets.x + 'px';
  296. target.style.width = source.offsetWidth + 'px';
  297. target.style.height = source.offsetHeight + 'px';
  298. },
  299. page: function (forElement) {
  300. var valueT = 0;
  301. var valueL = 0;
  302. var element = forElement;
  303. do {
  304. valueT += element.offsetTop || 0;
  305. valueL += element.offsetLeft || 0;
  306. // Safari fix
  307. if (element.offsetParent == document.body && MochiKit.DOM.getStyle(element, 'position') == 'absolute') {
  308. break;
  309. }
  310. } while (element = element.offsetParent);
  311. element = forElement;
  312. do {
  313. valueT -= element.scrollTop || 0;
  314. valueL -= element.scrollLeft || 0;
  315. } while (element = element.parentNode);
  316. return new MochiKit.Style.Coordinates(valueL, valueT);
  317. }
  318. };