Style.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /***
  2. MochiKit.Style 1.4
  3. See <http://mochikit.com/> for documentation, downloads, license, etc.
  4. (c) 2005-2006 Bob Ippolito, Beau Hartshorne. All rights Reserved.
  5. ***/
  6. if (typeof(dojo) != 'undefined') {
  7. dojo.provide('MochiKit.Style');
  8. dojo.require('MochiKit.Base');
  9. dojo.require('MochiKit.DOM');
  10. }
  11. if (typeof(JSAN) != 'undefined') {
  12. JSAN.use('MochiKit.Base', []);
  13. }
  14. try {
  15. if (typeof(MochiKit.Base) == 'undefined') {
  16. throw '';
  17. }
  18. } catch (e) {
  19. throw 'MochiKit.Style depends on MochiKit.Base!';
  20. }
  21. try {
  22. if (typeof(MochiKit.DOM) == 'undefined') {
  23. throw '';
  24. }
  25. } catch (e) {
  26. throw 'MochiKit.Style depends on MochiKit.DOM!';
  27. }
  28. if (typeof(MochiKit.Style) == 'undefined') {
  29. MochiKit.Style = {};
  30. }
  31. MochiKit.Style.NAME = 'MochiKit.Style';
  32. MochiKit.Style.VERSION = '1.4';
  33. MochiKit.Style.__repr__ = function () {
  34. return '[' + this.NAME + ' ' + this.VERSION + ']';
  35. };
  36. MochiKit.Style.toString = function () {
  37. return this.__repr__();
  38. };
  39. MochiKit.Style.EXPORT_OK = [];
  40. MochiKit.Style.EXPORT = [
  41. 'setOpacity',
  42. 'getOpacity',
  43. 'setStyle',
  44. 'getStyle', // temporary
  45. 'computedStyle',
  46. 'getElementDimensions',
  47. 'elementDimensions', // deprecated
  48. 'setElementDimensions',
  49. 'getElementPosition',
  50. 'elementPosition', // deprecated
  51. 'setElementPosition',
  52. 'setDisplayForElement',
  53. 'hideElement',
  54. 'showElement',
  55. 'getViewportDimensions',
  56. 'getViewportPosition',
  57. 'Dimensions',
  58. 'Coordinates'
  59. ];
  60. /*
  61. Dimensions
  62. */
  63. /** @id MochiKit.Style.Dimensions */
  64. MochiKit.Style.Dimensions = function (w, h) {
  65. this.w = w;
  66. this.h = h;
  67. };
  68. MochiKit.Style.Dimensions.prototype.__repr__ = function () {
  69. var repr = MochiKit.Base.repr;
  70. return '{w: ' + repr(this.w) + ', h: ' + repr(this.h) + '}';
  71. };
  72. MochiKit.Style.Dimensions.prototype.toString = function () {
  73. return this.__repr__();
  74. };
  75. /*
  76. Coordinates
  77. */
  78. /** @id MochiKit.Style.Coordinates */
  79. MochiKit.Style.Coordinates = function (x, y) {
  80. this.x = x;
  81. this.y = y;
  82. };
  83. MochiKit.Style.Coordinates.prototype.__repr__ = function () {
  84. var repr = MochiKit.Base.repr;
  85. return '{x: ' + repr(this.x) + ', y: ' + repr(this.y) + '}';
  86. };
  87. MochiKit.Style.Coordinates.prototype.toString = function () {
  88. return this.__repr__();
  89. };
  90. MochiKit.Base.update(MochiKit.Style, {
  91. /** @id MochiKit.Style.computedStyle */
  92. computedStyle: function (elem, cssProperty) {
  93. var dom = MochiKit.DOM;
  94. var d = dom._document;
  95. elem = dom.getElement(elem);
  96. cssProperty = MochiKit.Base.camelize(cssProperty);
  97. if (!elem || elem == d) {
  98. return undefined;
  99. }
  100. /* from YUI 0.10.0 */
  101. if (cssProperty == 'opacity' && elem.filters) { // IE opacity
  102. try {
  103. return elem.filters.item('DXImageTransform.Microsoft.Alpha'
  104. ).opacity / 100;
  105. } catch(e) {
  106. try {
  107. return elem.filters.item('alpha').opacity / 100;
  108. } catch(e) {}
  109. }
  110. }
  111. if (elem.currentStyle) {
  112. return elem.currentStyle[cssProperty];
  113. }
  114. if (typeof(d.defaultView) == 'undefined') {
  115. return undefined;
  116. }
  117. if (d.defaultView === null) {
  118. return undefined;
  119. }
  120. var style = d.defaultView.getComputedStyle(elem, null);
  121. if (typeof(style) == 'undefined' || style === null) {
  122. return undefined;
  123. }
  124. var selectorCase = cssProperty.replace(/([A-Z])/g, '-$1'
  125. ).toLowerCase(); // from dojo.style.toSelectorCase
  126. return style.getPropertyValue(selectorCase);
  127. },
  128. /** @id MochiKit.Style.getStyle */
  129. getStyle: function (elem, style) {
  130. elem = MochiKit.DOM.getElement(elem);
  131. var value = elem.style[MochiKit.Base.camelize(style)];
  132. if (!value) {
  133. if (document.defaultView && document.defaultView.getComputedStyle) {
  134. var css = document.defaultView.getComputedStyle(elem, null);
  135. value = css ? css.getPropertyValue(style) : null;
  136. } else if (elem.currentStyle) {
  137. value = elem.currentStyle[MochiKit.Base.camelize(style)];
  138. }
  139. }
  140. if (/Opera/.test(navigator.userAgent) && (MochiKit.Base.find(['left', 'top', 'right', 'bottom'], style) != -1)) {
  141. if (MochiKit.Style.getStyle(elem, 'position') == 'static') {
  142. value = 'auto';
  143. }
  144. }
  145. return value == 'auto' ? null : value;
  146. },
  147. /** @id MochiKit.Style.setStyle */
  148. setStyle: function (elem, style) {
  149. elem = MochiKit.DOM.getElement(elem);
  150. for (name in style) {
  151. elem.style[MochiKit.Base.camelize(name)] = style[name];
  152. }
  153. },
  154. /** @id MochiKit.Style.getOpacity */
  155. getOpacity: function (elem) {
  156. var opacity;
  157. if (opacity = MochiKit.Style.getStyle(elem, 'opacity')) {
  158. return parseFloat(opacity);
  159. }
  160. if (opacity = (MochiKit.Style.getStyle(elem, 'filter') || '').match(/alpha\(opacity=(.*)\)/)) {
  161. if (opacity[1]) {
  162. return parseFloat(opacity[1]) / 100;
  163. }
  164. }
  165. return 1.0;
  166. },
  167. /** @id MochiKit.Style.setOpacity */
  168. setOpacity: function(elem, o) {
  169. elem = MochiKit.DOM.getElement(elem);
  170. var self = MochiKit.Style;
  171. if (o == 1) {
  172. var toSet = /Gecko/.test(navigator.userAgent) && !(/Konqueror|Safari|KHTML/.test(navigator.userAgent));
  173. self.setStyle(elem, {opacity: toSet ? 0.999999 : 1.0});
  174. if (/MSIE/.test(navigator.userAgent)) {
  175. self.setStyle(elem, {filter:
  176. self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '')});
  177. }
  178. } else {
  179. if (o < 0.00001) {
  180. o = 0;
  181. }
  182. self.setStyle(elem, {opacity: o});
  183. if (/MSIE/.test(navigator.userAgent)) {
  184. self.setStyle(elem,
  185. {filter: self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '') + 'alpha(opacity=' + o * 100 + ')' });
  186. }
  187. }
  188. },
  189. /*
  190. getElementPosition is adapted from YAHOO.util.Dom.getXY v0.9.0.
  191. Copyright: Copyright (c) 2006, Yahoo! Inc. All rights reserved.
  192. License: BSD, http://developer.yahoo.net/yui/license.txt
  193. */
  194. /** @id MochiKit.Style.getElementPosition */
  195. getElementPosition: function (elem, /* optional */relativeTo) {
  196. var self = MochiKit.Style;
  197. var dom = MochiKit.DOM;
  198. elem = dom.getElement(elem);
  199. if (!elem ||
  200. (!(elem.x && elem.y) &&
  201. (!elem.parentNode == null ||
  202. self.computedStyle(elem, 'display') == 'none'))) {
  203. return undefined;
  204. }
  205. var c = new self.Coordinates(0, 0);
  206. var box = null;
  207. var parent = null;
  208. var d = MochiKit.DOM._document;
  209. var de = d.documentElement;
  210. var b = d.body;
  211. if (!elem.parentNode && elem.x && elem.y) {
  212. /* it's just a MochiKit.Style.Coordinates object */
  213. c.x += elem.x || 0;
  214. c.y += elem.y || 0;
  215. } else if (elem.getBoundingClientRect) { // IE shortcut
  216. /*
  217. The IE shortcut can be off by two. We fix it. See:
  218. http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
  219. This is similar to the method used in
  220. MochiKit.Signal.Event.mouse().
  221. */
  222. box = elem.getBoundingClientRect();
  223. c.x += box.left +
  224. (de.scrollLeft || b.scrollLeft) -
  225. (de.clientLeft || 0);
  226. c.y += box.top +
  227. (de.scrollTop || b.scrollTop) -
  228. (de.clientTop || 0);
  229. } else if (elem.offsetParent) {
  230. c.x += elem.offsetLeft;
  231. c.y += elem.offsetTop;
  232. parent = elem.offsetParent;
  233. if (parent != elem) {
  234. while (parent) {
  235. c.x += parent.offsetLeft;
  236. c.y += parent.offsetTop;
  237. parent = parent.offsetParent;
  238. }
  239. }
  240. /*
  241. Opera < 9 and old Safari (absolute) incorrectly account for
  242. body offsetTop and offsetLeft.
  243. */
  244. var ua = navigator.userAgent.toLowerCase();
  245. if ((typeof(opera) != 'undefined' &&
  246. parseFloat(opera.version()) < 9) ||
  247. (ua.indexOf('safari') != -1 &&
  248. self.computedStyle(elem, 'position') == 'absolute')) {
  249. c.x -= b.offsetLeft;
  250. c.y -= b.offsetTop;
  251. }
  252. }
  253. if (typeof(relativeTo) != 'undefined') {
  254. relativeTo = arguments.callee(relativeTo);
  255. if (relativeTo) {
  256. c.x -= (relativeTo.x || 0);
  257. c.y -= (relativeTo.y || 0);
  258. }
  259. }
  260. if (elem.parentNode) {
  261. parent = elem.parentNode;
  262. } else {
  263. parent = null;
  264. }
  265. while (parent) {
  266. var tagName = parent.tagName.toUpperCase();
  267. if (tagName === 'BODY' || tagName === 'HTML') {
  268. break;
  269. }
  270. c.x -= parent.scrollLeft;
  271. c.y -= parent.scrollTop;
  272. if (parent.parentNode) {
  273. parent = parent.parentNode;
  274. } else {
  275. parent = null;
  276. }
  277. }
  278. return c;
  279. },
  280. /** @id MochiKit.Style.setElementPosition */
  281. setElementPosition: function (elem, newPos/* optional */, units) {
  282. elem = MochiKit.DOM.getElement(elem);
  283. if (typeof(units) == 'undefined') {
  284. units = 'px';
  285. }
  286. var newStyle = {};
  287. var isUndefNull = MochiKit.Base.isUndefinedOrNull;
  288. if (!isUndefNull(newPos.x)) {
  289. newStyle['left'] = newPos.x + units;
  290. }
  291. if (!isUndefNull(newPos.y)) {
  292. newStyle['top'] = newPos.y + units;
  293. }
  294. MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
  295. },
  296. /** @id MochiKit.Style.getElementDimensions */
  297. getElementDimensions: function (elem) {
  298. var self = MochiKit.Style;
  299. var dom = MochiKit.DOM;
  300. if (typeof(elem.w) == 'number' || typeof(elem.h) == 'number') {
  301. return new self.Dimensions(elem.w || 0, elem.h || 0);
  302. }
  303. elem = dom.getElement(elem);
  304. if (!elem) {
  305. return undefined;
  306. }
  307. var disp = self.computedStyle(elem, 'display');
  308. // display can be empty/undefined on WebKit/KHTML
  309. if (disp != 'none' && disp != '' && typeof(disp) != 'undefined') {
  310. return new self.Dimensions(elem.offsetWidth || 0,
  311. elem.offsetHeight || 0);
  312. }
  313. var s = elem.style;
  314. var originalVisibility = s.visibility;
  315. var originalPosition = s.position;
  316. s.visibility = 'hidden';
  317. s.position = 'absolute';
  318. s.display = '';
  319. var originalWidth = elem.offsetWidth;
  320. var originalHeight = elem.offsetHeight;
  321. s.display = 'none';
  322. s.position = originalPosition;
  323. s.visibility = originalVisibility;
  324. return new self.Dimensions(originalWidth, originalHeight);
  325. },
  326. /** @id MochiKit.Style.setElementDimensions */
  327. setElementDimensions: function (elem, newSize/* optional */, units) {
  328. elem = MochiKit.DOM.getElement(elem);
  329. if (typeof(units) == 'undefined') {
  330. units = 'px';
  331. }
  332. var newStyle = {};
  333. var isUndefNull = MochiKit.Base.isUndefinedOrNull;
  334. if (!isUndefNull(newSize.w)) {
  335. newStyle['width'] = newSize.w + units;
  336. }
  337. if (!isUndefNull(newSize.h)) {
  338. newStyle['height'] = newSize.h + units;
  339. }
  340. MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
  341. },
  342. /** @id MochiKit.Style.setDisplayForElement */
  343. setDisplayForElement: function (display, element/*, ...*/) {
  344. var elements = MochiKit.Base.extend(null, arguments, 1);
  345. var getElement = MochiKit.DOM.getElement;
  346. for (var i = 0; i < elements.length; i++) {
  347. var element = getElement(elements[i]);
  348. if (element) {
  349. element.style.display = display;
  350. }
  351. }
  352. },
  353. /** @id MochiKit.Style.getViewportDimensions */
  354. getViewportDimensions: function () {
  355. var d = new MochiKit.Style.Dimensions();
  356. var w = MochiKit.DOM._window;
  357. var b = MochiKit.DOM._document.body;
  358. if (w.innerWidth) {
  359. d.w = w.innerWidth;
  360. d.h = w.innerHeight;
  361. } else if (b.parentElement.clientWidth) {
  362. d.w = b.parentElement.clientWidth;
  363. d.h = b.parentElement.clientHeight;
  364. } else if (b && b.clientWidth) {
  365. d.w = b.clientWidth;
  366. d.h = b.clientHeight;
  367. }
  368. return d;
  369. },
  370. /** @id MochiKit.Style.getViewportPosition */
  371. getViewportPosition: function () {
  372. var c = new MochiKit.Style.Coordinates(0, 0);
  373. var d = MochiKit.DOM._document;
  374. var de = d.documentElement;
  375. var db = d.body;
  376. if (de && (de.scrollTop || de.scrollLeft)) {
  377. c.x = de.scrollLeft;
  378. c.y = de.scrollTop;
  379. } else if (db) {
  380. c.x = db.scrollLeft;
  381. c.y = db.scrollTop;
  382. }
  383. return c;
  384. },
  385. __new__: function () {
  386. var m = MochiKit.Base;
  387. this.elementPosition = this.getElementPosition;
  388. this.elementDimensions = this.getElementDimensions;
  389. this.hideElement = m.partial(this.setDisplayForElement, 'none');
  390. this.showElement = m.partial(this.setDisplayForElement, 'block');
  391. this.EXPORT_TAGS = {
  392. ':common': this.EXPORT,
  393. ':all': m.concat(this.EXPORT, this.EXPORT_OK)
  394. };
  395. m.nameFunctions(this);
  396. }
  397. });
  398. MochiKit.Style.__new__();
  399. MochiKit.Base._exportSymbols(this, MochiKit.Style);