Element.style.html 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-dom-Element'>/**
  19. </span> * @class Ext.dom.Element
  20. */
  21. (function() {
  22. var Element = Ext.dom.Element,
  23. view = document.defaultView,
  24. adjustDirect2DTableRe = /table-row|table-.*-group/,
  25. INTERNAL = '_internal',
  26. HIDDEN = 'hidden',
  27. HEIGHT = 'height',
  28. WIDTH = 'width',
  29. ISCLIPPED = 'isClipped',
  30. OVERFLOW = 'overflow',
  31. OVERFLOWX = 'overflow-x',
  32. OVERFLOWY = 'overflow-y',
  33. ORIGINALCLIP = 'originalClip',
  34. DOCORBODYRE = /#document|body/i,
  35. // This reduces the lookup of 'me.styleHooks' by one hop in the prototype chain. It is
  36. // the same object.
  37. styleHooks,
  38. edges, k, edge, borderWidth;
  39. if (!view || !view.getComputedStyle) {
  40. Element.prototype.getStyle = function (property, inline) {
  41. var me = this,
  42. dom = me.dom,
  43. multiple = typeof property != 'string',
  44. hooks = me.styleHooks,
  45. prop = property,
  46. props = prop,
  47. len = 1,
  48. isInline = inline,
  49. camel, domStyle, values, hook, out, style, i;
  50. if (multiple) {
  51. values = {};
  52. prop = props[0];
  53. i = 0;
  54. if (!(len = props.length)) {
  55. return values;
  56. }
  57. }
  58. if (!dom || dom.documentElement) {
  59. return values || '';
  60. }
  61. domStyle = dom.style;
  62. if (inline) {
  63. style = domStyle;
  64. } else {
  65. style = dom.currentStyle;
  66. // fallback to inline style if rendering context not available
  67. if (!style) {
  68. isInline = true;
  69. style = domStyle;
  70. }
  71. }
  72. do {
  73. hook = hooks[prop];
  74. if (!hook) {
  75. hooks[prop] = hook = { name: Element.normalize(prop) };
  76. }
  77. if (hook.get) {
  78. out = hook.get(dom, me, isInline, style);
  79. } else {
  80. camel = hook.name;
  81. // In some cases, IE6 will throw Invalid Argument exceptions for properties
  82. // like fontSize (/examples/tabs/tabs.html in 4.0 used to exhibit this but
  83. // no longer does due to font style changes). There is a real cost to a try
  84. // block, so we avoid it where possible...
  85. if (hook.canThrow) {
  86. try {
  87. out = style[camel];
  88. } catch (e) {
  89. out = '';
  90. }
  91. } else {
  92. // EXTJSIV-5657 - In IE9 quirks mode there is a chance that VML root element
  93. // has neither `currentStyle` nor `style`. Return '' this case.
  94. out = style ? style[camel] : '';
  95. }
  96. }
  97. if (!multiple) {
  98. return out;
  99. }
  100. values[prop] = out;
  101. prop = props[++i];
  102. } while (i &lt; len);
  103. return values;
  104. };
  105. }
  106. Element.override({
  107. getHeight: function(contentHeight, preciseHeight) {
  108. var me = this,
  109. dom = me.dom,
  110. hidden = me.isStyle('display', 'none'),
  111. height,
  112. floating;
  113. if (hidden) {
  114. return 0;
  115. }
  116. height = Math.max(dom.offsetHeight, dom.clientHeight) || 0;
  117. // IE9 Direct2D dimension rounding bug
  118. if (Ext.supports.Direct2DBug) {
  119. floating = me.adjustDirect2DDimension(HEIGHT);
  120. if (preciseHeight) {
  121. height += floating;
  122. }
  123. else if (floating &gt; 0 &amp;&amp; floating &lt; 0.5) {
  124. height++;
  125. }
  126. }
  127. if (contentHeight) {
  128. height -= me.getBorderWidth(&quot;tb&quot;) + me.getPadding(&quot;tb&quot;);
  129. }
  130. return (height &lt; 0) ? 0 : height;
  131. },
  132. getWidth: function(contentWidth, preciseWidth) {
  133. var me = this,
  134. dom = me.dom,
  135. hidden = me.isStyle('display', 'none'),
  136. rect, width, floating;
  137. if (hidden) {
  138. return 0;
  139. }
  140. // Gecko will in some cases report an offsetWidth that is actually less than the width of the
  141. // text contents, because it measures fonts with sub-pixel precision but rounds the calculated
  142. // value down. Using getBoundingClientRect instead of offsetWidth allows us to get the precise
  143. // subpixel measurements so we can force them to always be rounded up. See
  144. // https://bugzilla.mozilla.org/show_bug.cgi?id=458617
  145. // Rounding up ensures that the width includes the full width of the text contents.
  146. if (Ext.supports.BoundingClientRect) {
  147. rect = dom.getBoundingClientRect();
  148. width = rect.right - rect.left;
  149. width = preciseWidth ? width : Math.ceil(width);
  150. } else {
  151. width = dom.offsetWidth;
  152. }
  153. width = Math.max(width, dom.clientWidth) || 0;
  154. // IE9 Direct2D dimension rounding bug
  155. if (Ext.supports.Direct2DBug) {
  156. // get the fractional portion of the sub-pixel precision width of the element's text contents
  157. floating = me.adjustDirect2DDimension(WIDTH);
  158. if (preciseWidth) {
  159. width += floating;
  160. }
  161. // IE9 also measures fonts with sub-pixel precision, but unlike Gecko, instead of rounding the offsetWidth down,
  162. // it rounds to the nearest integer. This means that in order to ensure that the width includes the full
  163. // width of the text contents we need to increment the width by 1 only if the fractional portion is less than 0.5
  164. else if (floating &gt; 0 &amp;&amp; floating &lt; 0.5) {
  165. width++;
  166. }
  167. }
  168. if (contentWidth) {
  169. width -= me.getBorderWidth(&quot;lr&quot;) + me.getPadding(&quot;lr&quot;);
  170. }
  171. return (width &lt; 0) ? 0 : width;
  172. },
  173. setWidth: function(width, animate) {
  174. var me = this;
  175. width = me.adjustWidth(width);
  176. if (!animate || !me.anim) {
  177. me.dom.style.width = me.addUnits(width);
  178. }
  179. else {
  180. if (!Ext.isObject(animate)) {
  181. animate = {};
  182. }
  183. me.animate(Ext.applyIf({
  184. to: {
  185. width: width
  186. }
  187. }, animate));
  188. }
  189. return me;
  190. },
  191. setHeight : function(height, animate) {
  192. var me = this;
  193. height = me.adjustHeight(height);
  194. if (!animate || !me.anim) {
  195. me.dom.style.height = me.addUnits(height);
  196. }
  197. else {
  198. if (!Ext.isObject(animate)) {
  199. animate = {};
  200. }
  201. me.animate(Ext.applyIf({
  202. to: {
  203. height: height
  204. }
  205. }, animate));
  206. }
  207. return me;
  208. },
  209. applyStyles: function(style) {
  210. Ext.DomHelper.applyStyles(this.dom, style);
  211. return this;
  212. },
  213. setSize: function(width, height, animate) {
  214. var me = this;
  215. if (Ext.isObject(width)) { // in case of object from getSize()
  216. animate = height;
  217. height = width.height;
  218. width = width.width;
  219. }
  220. width = me.adjustWidth(width);
  221. height = me.adjustHeight(height);
  222. if (!animate || !me.anim) {
  223. me.dom.style.width = me.addUnits(width);
  224. me.dom.style.height = me.addUnits(height);
  225. }
  226. else {
  227. if (animate === true) {
  228. animate = {};
  229. }
  230. me.animate(Ext.applyIf({
  231. to: {
  232. width: width,
  233. height: height
  234. }
  235. }, animate));
  236. }
  237. return me;
  238. },
  239. getViewSize : function() {
  240. var me = this,
  241. dom = me.dom,
  242. isDoc = DOCORBODYRE.test(dom.nodeName),
  243. ret;
  244. // If the body, use static methods
  245. if (isDoc) {
  246. ret = {
  247. width : Element.getViewWidth(),
  248. height : Element.getViewHeight()
  249. };
  250. } else {
  251. ret = {
  252. width : dom.clientWidth,
  253. height : dom.clientHeight
  254. };
  255. }
  256. return ret;
  257. },
  258. getSize: function(contentSize) {
  259. return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
  260. },
  261. // TODO: Look at this
  262. // private ==&gt; used by Fx
  263. adjustWidth : function(width) {
  264. var me = this,
  265. isNum = (typeof width == 'number');
  266. if (isNum &amp;&amp; me.autoBoxAdjust &amp;&amp; !me.isBorderBox()) {
  267. width -= (me.getBorderWidth(&quot;lr&quot;) + me.getPadding(&quot;lr&quot;));
  268. }
  269. return (isNum &amp;&amp; width &lt; 0) ? 0 : width;
  270. },
  271. // private ==&gt; used by Fx
  272. adjustHeight : function(height) {
  273. var me = this,
  274. isNum = (typeof height == &quot;number&quot;);
  275. if (isNum &amp;&amp; me.autoBoxAdjust &amp;&amp; !me.isBorderBox()) {
  276. height -= (me.getBorderWidth(&quot;tb&quot;) + me.getPadding(&quot;tb&quot;));
  277. }
  278. return (isNum &amp;&amp; height &lt; 0) ? 0 : height;
  279. },
  280. <span id='Ext-dom-Element-method-getColor'> /**
  281. </span> * Return the CSS color for the specified CSS attribute. rgb, 3 digit (like `#fff`) and valid values
  282. * are convert to standard 6 digit hex color.
  283. * @param {String} attr The css attribute
  284. * @param {String} defaultValue The default value to use when a valid color isn't found
  285. * @param {String} [prefix] defaults to #. Use an empty string when working with
  286. * color anims.
  287. */
  288. getColor : function(attr, defaultValue, prefix) {
  289. var v = this.getStyle(attr),
  290. color = prefix || prefix === '' ? prefix : '#',
  291. h, len, i=0;
  292. if (!v || (/transparent|inherit/.test(v))) {
  293. return defaultValue;
  294. }
  295. if (/^r/.test(v)) {
  296. v = v.slice(4, v.length - 1).split(',');
  297. len = v.length;
  298. for (; i&lt;len; i++) {
  299. h = parseInt(v[i], 10);
  300. color += (h &lt; 16 ? '0' : '') + h.toString(16);
  301. }
  302. } else {
  303. v = v.replace('#', '');
  304. color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
  305. }
  306. return(color.length &gt; 5 ? color.toLowerCase() : defaultValue);
  307. },
  308. <span id='Ext-dom-Element-method-setOpacity'> /**
  309. </span> * Set the opacity of the element
  310. * @param {Number} opacity The new opacity. 0 = transparent, .5 = 50% visibile, 1 = fully visible, etc
  311. * @param {Boolean/Object} [animate] a standard Element animation config object or `true` for
  312. * the default animation (`{duration: 350, easing: 'easeIn'}`)
  313. * @return {Ext.dom.Element} this
  314. */
  315. setOpacity: function(opacity, animate) {
  316. var me = this;
  317. if (!me.dom) {
  318. return me;
  319. }
  320. if (!animate || !me.anim) {
  321. me.setStyle('opacity', opacity);
  322. }
  323. else {
  324. if (typeof animate != 'object') {
  325. animate = {
  326. duration: 350,
  327. easing: 'ease-in'
  328. };
  329. }
  330. me.animate(Ext.applyIf({
  331. to: {
  332. opacity: opacity
  333. }
  334. }, animate));
  335. }
  336. return me;
  337. },
  338. <span id='Ext-dom-Element-method-clearOpacity'> /**
  339. </span> * Clears any opacity settings from this element. Required in some cases for IE.
  340. * @return {Ext.dom.Element} this
  341. */
  342. clearOpacity : function() {
  343. return this.setOpacity('');
  344. },
  345. <span id='Ext-dom-Element-method-adjustDirect2DDimension'> /**
  346. </span> * @private
  347. * Returns 1 if the browser returns the subpixel dimension rounded to the lowest pixel.
  348. * @return {Number} 0 or 1
  349. */
  350. adjustDirect2DDimension: function(dimension) {
  351. var me = this,
  352. dom = me.dom,
  353. display = me.getStyle('display'),
  354. inlineDisplay = dom.style.display,
  355. inlinePosition = dom.style.position,
  356. originIndex = dimension === WIDTH ? 0 : 1,
  357. currentStyle = dom.currentStyle,
  358. floating;
  359. if (display === 'inline') {
  360. dom.style.display = 'inline-block';
  361. }
  362. dom.style.position = display.match(adjustDirect2DTableRe) ? 'absolute' : 'static';
  363. // floating will contain digits that appears after the decimal point
  364. // if height or width are set to auto we fallback to msTransformOrigin calculation
  365. // Use currentStyle here instead of getStyle. In some difficult to reproduce
  366. // instances it resets the scrollWidth of the element
  367. floating = (parseFloat(currentStyle[dimension]) || parseFloat(currentStyle.msTransformOrigin.split(' ')[originIndex]) * 2) % 1;
  368. dom.style.position = inlinePosition;
  369. if (display === 'inline') {
  370. dom.style.display = inlineDisplay;
  371. }
  372. return floating;
  373. },
  374. <span id='Ext-dom-Element-method-clip'> /**
  375. </span> * Store the current overflow setting and clip overflow on the element - use {@link #unclip} to remove
  376. * @return {Ext.dom.Element} this
  377. */
  378. clip : function() {
  379. var me = this,
  380. data = (me.$cache || me.getCache()).data,
  381. style;
  382. if (!data[ISCLIPPED]) {
  383. data[ISCLIPPED] = true;
  384. style = me.getStyle([OVERFLOW, OVERFLOWX, OVERFLOWY]);
  385. data[ORIGINALCLIP] = {
  386. o: style[OVERFLOW],
  387. x: style[OVERFLOWX],
  388. y: style[OVERFLOWY]
  389. };
  390. me.setStyle(OVERFLOW, HIDDEN);
  391. me.setStyle(OVERFLOWX, HIDDEN);
  392. me.setStyle(OVERFLOWY, HIDDEN);
  393. }
  394. return me;
  395. },
  396. <span id='Ext-dom-Element-method-unclip'> /**
  397. </span> * Return clipping (overflow) to original clipping before {@link #clip} was called
  398. * @return {Ext.dom.Element} this
  399. */
  400. unclip : function() {
  401. var me = this,
  402. data = (me.$cache || me.getCache()).data,
  403. clip;
  404. if (data[ISCLIPPED]) {
  405. data[ISCLIPPED] = false;
  406. clip = data[ORIGINALCLIP];
  407. if (clip.o) {
  408. me.setStyle(OVERFLOW, clip.o);
  409. }
  410. if (clip.x) {
  411. me.setStyle(OVERFLOWX, clip.x);
  412. }
  413. if (clip.y) {
  414. me.setStyle(OVERFLOWY, clip.y);
  415. }
  416. }
  417. return me;
  418. },
  419. <span id='Ext-dom-Element-method-boxWrap'> /**
  420. </span> * Wraps the specified element with a special 9 element markup/CSS block that renders by default as
  421. * a gray container with a gradient background, rounded corners and a 4-way shadow.
  422. *
  423. * This special markup is used throughout Ext when box wrapping elements ({@link Ext.button.Button},
  424. * {@link Ext.panel.Panel} when {@link Ext.panel.Panel#frame frame=true}, {@link Ext.window.Window}).
  425. * The markup is of this form:
  426. *
  427. * Ext.dom.Element.boxMarkup =
  428. * '&lt;div class=&quot;{0}-tl&quot;&gt;&lt;div class=&quot;{0}-tr&quot;&gt;&lt;div class=&quot;{0}-tc&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
  429. * &lt;div class=&quot;{0}-ml&quot;&gt;&lt;div class=&quot;{0}-mr&quot;&gt;&lt;div class=&quot;{0}-mc&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
  430. * &lt;div class=&quot;{0}-bl&quot;&gt;&lt;div class=&quot;{0}-br&quot;&gt;&lt;div class=&quot;{0}-bc&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;';
  431. *
  432. * Example usage:
  433. *
  434. * // Basic box wrap
  435. * Ext.get(&quot;foo&quot;).boxWrap();
  436. *
  437. * // You can also add a custom class and use CSS inheritance rules to customize the box look.
  438. * // 'x-box-blue' is a built-in alternative -- look at the related CSS definitions as an example
  439. * // for how to create a custom box wrap style.
  440. * Ext.get(&quot;foo&quot;).boxWrap().addCls(&quot;x-box-blue&quot;);
  441. *
  442. * @param {String} [class='x-box'] A base CSS class to apply to the containing wrapper element.
  443. * Note that there are a number of CSS rules that are dependent on this name to make the overall effect work,
  444. * so if you supply an alternate base class, make sure you also supply all of the necessary rules.
  445. * @return {Ext.dom.Element} The outermost wrapping element of the created box structure.
  446. */
  447. boxWrap : function(cls) {
  448. cls = cls || Ext.baseCSSPrefix + 'box';
  449. var el = Ext.get(this.insertHtml(&quot;beforeBegin&quot;, &quot;&lt;div class='&quot; + cls + &quot;'&gt;&quot; + Ext.String.format(Element.boxMarkup, cls) + &quot;&lt;/div&gt;&quot;));
  450. Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
  451. return el;
  452. },
  453. <span id='Ext-dom-Element-method-getComputedHeight'> /**
  454. </span> * Returns either the offsetHeight or the height of this element based on CSS height adjusted by padding or borders
  455. * when needed to simulate offsetHeight when offsets aren't available. This may not work on display:none elements
  456. * if a height has not been set using CSS.
  457. * @return {Number}
  458. */
  459. getComputedHeight : function() {
  460. var me = this,
  461. h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
  462. if (!h) {
  463. h = parseFloat(me.getStyle(HEIGHT)) || 0;
  464. if (!me.isBorderBox()) {
  465. h += me.getFrameWidth('tb');
  466. }
  467. }
  468. return h;
  469. },
  470. <span id='Ext-dom-Element-method-getComputedWidth'> /**
  471. </span> * Returns either the offsetWidth or the width of this element based on CSS width adjusted by padding or borders
  472. * when needed to simulate offsetWidth when offsets aren't available. This may not work on display:none elements
  473. * if a width has not been set using CSS.
  474. * @return {Number}
  475. */
  476. getComputedWidth : function() {
  477. var me = this,
  478. w = Math.max(me.dom.offsetWidth, me.dom.clientWidth);
  479. if (!w) {
  480. w = parseFloat(me.getStyle(WIDTH)) || 0;
  481. if (!me.isBorderBox()) {
  482. w += me.getFrameWidth('lr');
  483. }
  484. }
  485. return w;
  486. },
  487. <span id='Ext-dom-Element-method-getFrameWidth'> /**
  488. </span> * Returns the sum width of the padding and borders for the passed &quot;sides&quot;. See getBorderWidth()
  489. * for more information about the sides.
  490. * @param {String} sides
  491. * @return {Number}
  492. */
  493. getFrameWidth : function(sides, onlyContentBox) {
  494. return (onlyContentBox &amp;&amp; this.isBorderBox()) ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
  495. },
  496. <span id='Ext-dom-Element-method-addClsOnOver'> /**
  497. </span> * Sets up event handlers to add and remove a css class when the mouse is over this element
  498. * @param {String} className The class to add
  499. * @param {Function} [testFn] A test function to execute before adding the class. The passed parameter
  500. * will be the Element instance. If this functions returns false, the class will not be added.
  501. * @param {Object} [scope] The scope to execute the testFn in.
  502. * @return {Ext.dom.Element} this
  503. */
  504. addClsOnOver : function(className, testFn, scope) {
  505. var me = this,
  506. dom = me.dom,
  507. hasTest = Ext.isFunction(testFn);
  508. me.hover(
  509. function() {
  510. if (hasTest &amp;&amp; testFn.call(scope || me, me) === false) {
  511. return;
  512. }
  513. Ext.fly(dom, INTERNAL).addCls(className);
  514. },
  515. function() {
  516. Ext.fly(dom, INTERNAL).removeCls(className);
  517. }
  518. );
  519. return me;
  520. },
  521. <span id='Ext-dom-Element-method-addClsOnFocus'> /**
  522. </span> * Sets up event handlers to add and remove a css class when this element has the focus
  523. * @param {String} className The class to add
  524. * @param {Function} [testFn] A test function to execute before adding the class. The passed parameter
  525. * will be the Element instance. If this functions returns false, the class will not be added.
  526. * @param {Object} [scope] The scope to execute the testFn in.
  527. * @return {Ext.dom.Element} this
  528. */
  529. addClsOnFocus : function(className, testFn, scope) {
  530. var me = this,
  531. dom = me.dom,
  532. hasTest = Ext.isFunction(testFn);
  533. me.on(&quot;focus&quot;, function() {
  534. if (hasTest &amp;&amp; testFn.call(scope || me, me) === false) {
  535. return false;
  536. }
  537. Ext.fly(dom, INTERNAL).addCls(className);
  538. });
  539. me.on(&quot;blur&quot;, function() {
  540. Ext.fly(dom, INTERNAL).removeCls(className);
  541. });
  542. return me;
  543. },
  544. <span id='Ext-dom-Element-method-addClsOnClick'> /**
  545. </span> * Sets up event handlers to add and remove a css class when the mouse is down and then up on this element (a click effect)
  546. * @param {String} className The class to add
  547. * @param {Function} [testFn] A test function to execute before adding the class. The passed parameter
  548. * will be the Element instance. If this functions returns false, the class will not be added.
  549. * @param {Object} [scope] The scope to execute the testFn in.
  550. * @return {Ext.dom.Element} this
  551. */
  552. addClsOnClick : function(className, testFn, scope) {
  553. var me = this,
  554. dom = me.dom,
  555. hasTest = Ext.isFunction(testFn);
  556. me.on(&quot;mousedown&quot;, function() {
  557. if (hasTest &amp;&amp; testFn.call(scope || me, me) === false) {
  558. return false;
  559. }
  560. Ext.fly(dom, INTERNAL).addCls(className);
  561. var d = Ext.getDoc(),
  562. fn = function() {
  563. Ext.fly(dom, INTERNAL).removeCls(className);
  564. d.removeListener(&quot;mouseup&quot;, fn);
  565. };
  566. d.on(&quot;mouseup&quot;, fn);
  567. });
  568. return me;
  569. },
  570. <span id='Ext-dom-Element-method-getStyleSize'> /**
  571. </span> * Returns the dimensions of the element available to lay content out in.
  572. *
  573. * getStyleSize utilizes prefers style sizing if present, otherwise it chooses the larger of offsetHeight/clientHeight and
  574. * offsetWidth/clientWidth. To obtain the size excluding scrollbars, use getViewSize.
  575. *
  576. * Sizing of the document body is handled at the adapter level which handles special cases for IE and strict modes, etc.
  577. *
  578. * @return {Object} Object describing width and height.
  579. * @return {Number} return.width
  580. * @return {Number} return.height
  581. */
  582. getStyleSize : function() {
  583. var me = this,
  584. d = this.dom,
  585. isDoc = DOCORBODYRE.test(d.nodeName),
  586. s ,
  587. w, h;
  588. // If the body, use static methods
  589. if (isDoc) {
  590. return {
  591. width : Element.getViewWidth(),
  592. height : Element.getViewHeight()
  593. };
  594. }
  595. s = me.getStyle([HEIGHT, WIDTH], true); //seek inline
  596. // Use Styles if they are set
  597. if (s.width &amp;&amp; s.width != 'auto') {
  598. w = parseFloat(s.width);
  599. if (me.isBorderBox()) {
  600. w -= me.getFrameWidth('lr');
  601. }
  602. }
  603. // Use Styles if they are set
  604. if (s.height &amp;&amp; s.height != 'auto') {
  605. h = parseFloat(s.height);
  606. if (me.isBorderBox()) {
  607. h -= me.getFrameWidth('tb');
  608. }
  609. }
  610. // Use getWidth/getHeight if style not set.
  611. return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
  612. },
  613. <span id='Ext-dom-Element-method-selectable'> /**
  614. </span> * Enable text selection for this element (normalized across browsers)
  615. * @return {Ext.Element} this
  616. */
  617. selectable : function() {
  618. var me = this;
  619. me.dom.unselectable = &quot;off&quot;;
  620. // Prevent it from bubles up and enables it to be selectable
  621. me.on('selectstart', function (e) {
  622. e.stopPropagation();
  623. return true;
  624. });
  625. me.applyStyles(&quot;-moz-user-select: text; -khtml-user-select: text;&quot;);
  626. me.removeCls(Ext.baseCSSPrefix + 'unselectable');
  627. return me;
  628. },
  629. <span id='Ext-dom-Element-method-unselectable'> /**
  630. </span> * Disables text selection for this element (normalized across browsers)
  631. * @return {Ext.dom.Element} this
  632. */
  633. unselectable : function() {
  634. var me = this;
  635. me.dom.unselectable = &quot;on&quot;;
  636. me.swallowEvent(&quot;selectstart&quot;, true);
  637. me.applyStyles(&quot;-moz-user-select:-moz-none;-khtml-user-select:none;&quot;);
  638. me.addCls(Ext.baseCSSPrefix + 'unselectable');
  639. return me;
  640. }
  641. });
  642. Element.prototype.styleHooks = styleHooks = Ext.dom.AbstractElement.prototype.styleHooks;
  643. if (Ext.isIE6 || Ext.isIE7) {
  644. styleHooks.fontSize = styleHooks['font-size'] = {
  645. name: 'fontSize',
  646. canThrow: true
  647. };
  648. styleHooks.fontStyle = styleHooks['font-style'] = {
  649. name: 'fontStyle',
  650. canThrow: true
  651. };
  652. styleHooks.fontFamily = styleHooks['font-family'] = {
  653. name: 'fontFamily',
  654. canThrow: true
  655. };
  656. }
  657. // override getStyle for border-*-width
  658. if (Ext.isIEQuirks || Ext.isIE &amp;&amp; Ext.ieVersion &lt;= 8) {
  659. function getBorderWidth (dom, el, inline, style) {
  660. if (style[this.styleName] == 'none') {
  661. return '0px';
  662. }
  663. return style[this.name];
  664. }
  665. edges = ['Top','Right','Bottom','Left'];
  666. k = edges.length;
  667. while (k--) {
  668. edge = edges[k];
  669. borderWidth = 'border' + edge + 'Width';
  670. styleHooks['border-'+edge.toLowerCase()+'-width'] = styleHooks[borderWidth] = {
  671. name: borderWidth,
  672. styleName: 'border' + edge + 'Style',
  673. get: getBorderWidth
  674. };
  675. }
  676. }
  677. }());
  678. Ext.onReady(function () {
  679. var opacityRe = /alpha\(opacity=(.*)\)/i,
  680. trimRe = /^\s+|\s+$/g,
  681. hooks = Ext.dom.Element.prototype.styleHooks;
  682. // Ext.supports flags are not populated until onReady...
  683. hooks.opacity = {
  684. name: 'opacity',
  685. afterSet: function(dom, value, el) {
  686. if (el.isLayer) {
  687. el.onOpacitySet(value);
  688. }
  689. }
  690. };
  691. if (!Ext.supports.Opacity &amp;&amp; Ext.isIE) {
  692. Ext.apply(hooks.opacity, {
  693. get: function (dom) {
  694. var filter = dom.style.filter,
  695. match, opacity;
  696. if (filter.match) {
  697. match = filter.match(opacityRe);
  698. if (match) {
  699. opacity = parseFloat(match[1]);
  700. if (!isNaN(opacity)) {
  701. return opacity ? opacity / 100 : 0;
  702. }
  703. }
  704. }
  705. return 1;
  706. },
  707. set: function (dom, value) {
  708. var style = dom.style,
  709. val = style.filter.replace(opacityRe, '').replace(trimRe, '');
  710. style.zoom = 1; // ensure dom.hasLayout
  711. // value can be a number or '' or null... so treat falsey as no opacity
  712. if (typeof(value) == 'number' &amp;&amp; value &gt;= 0 &amp;&amp; value &lt; 1) {
  713. value *= 100;
  714. style.filter = val + (val.length ? ' ' : '') + 'alpha(opacity='+value+')';
  715. } else {
  716. style.filter = val;
  717. }
  718. }
  719. });
  720. }
  721. // else there is no work around for the lack of opacity support. Should not be a
  722. // problem given that this has been supported for a long time now...
  723. });
  724. </pre>
  725. </body>
  726. </html>