AbstractElement.static.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  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-AbstractElement'>/**
  19. </span> * @class Ext.dom.AbstractElement
  20. */
  21. Ext.dom.AbstractElement.addInheritableStatics({
  22. unitRe: /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
  23. camelRe: /(-[a-z])/gi,
  24. cssRe: /([a-z0-9\-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
  25. opacityRe: /alpha\(opacity=(.*)\)/i,
  26. propertyCache: {},
  27. defaultUnit : &quot;px&quot;,
  28. borders: {l: 'border-left-width', r: 'border-right-width', t: 'border-top-width', b: 'border-bottom-width'},
  29. paddings: {l: 'padding-left', r: 'padding-right', t: 'padding-top', b: 'padding-bottom'},
  30. margins: {l: 'margin-left', r: 'margin-right', t: 'margin-top', b: 'margin-bottom'},
  31. <span id='Ext-dom-AbstractElement-static-method-addUnits'> /**
  32. </span> * Test if size has a unit, otherwise appends the passed unit string, or the default for this Element.
  33. * @param size {Object} The size to set
  34. * @param units {String} The units to append to a numeric size value
  35. * @private
  36. * @static
  37. */
  38. addUnits: function(size, units) {
  39. // Most common case first: Size is set to a number
  40. if (typeof size == 'number') {
  41. return size + (units || this.defaultUnit || 'px');
  42. }
  43. // Size set to a value which means &quot;auto&quot;
  44. if (size === &quot;&quot; || size == &quot;auto&quot; || size === undefined || size === null) {
  45. return size || '';
  46. }
  47. // Otherwise, warn if it's not a valid CSS measurement
  48. if (!this.unitRe.test(size)) {
  49. //&lt;debug&gt;
  50. if (Ext.isDefined(Ext.global.console)) {
  51. Ext.global.console.warn(&quot;Warning, size detected as NaN on Element.addUnits.&quot;);
  52. }
  53. //&lt;/debug&gt;
  54. return size || '';
  55. }
  56. return size;
  57. },
  58. <span id='Ext-dom-AbstractElement-static-method-isAncestor'> /**
  59. </span> * @static
  60. * @private
  61. */
  62. isAncestor: function(p, c) {
  63. var ret = false;
  64. p = Ext.getDom(p);
  65. c = Ext.getDom(c);
  66. if (p &amp;&amp; c) {
  67. if (p.contains) {
  68. return p.contains(c);
  69. } else if (p.compareDocumentPosition) {
  70. return !!(p.compareDocumentPosition(c) &amp; 16);
  71. } else {
  72. while ((c = c.parentNode)) {
  73. ret = c == p || ret;
  74. }
  75. }
  76. }
  77. return ret;
  78. },
  79. <span id='Ext-dom-AbstractElement-static-method-parseBox'> /**
  80. </span> * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations
  81. * (e.g. 10, &quot;10&quot;, &quot;10 10&quot;, &quot;10 10 10&quot; and &quot;10 10 10 10&quot; are all valid options and would return the same result)
  82. * @static
  83. * @param {Number/String} box The encoded margins
  84. * @return {Object} An object with margin sizes for top, right, bottom and left
  85. */
  86. parseBox: function(box) {
  87. if (typeof box != 'string') {
  88. box = box.toString();
  89. }
  90. var parts = box.split(' '),
  91. ln = parts.length;
  92. if (ln == 1) {
  93. parts[1] = parts[2] = parts[3] = parts[0];
  94. }
  95. else if (ln == 2) {
  96. parts[2] = parts[0];
  97. parts[3] = parts[1];
  98. }
  99. else if (ln == 3) {
  100. parts[3] = parts[1];
  101. }
  102. return {
  103. top :parseFloat(parts[0]) || 0,
  104. right :parseFloat(parts[1]) || 0,
  105. bottom:parseFloat(parts[2]) || 0,
  106. left :parseFloat(parts[3]) || 0
  107. };
  108. },
  109. <span id='Ext-dom-AbstractElement-static-method-unitizeBox'> /**
  110. </span> * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations
  111. * (e.g. 10, &quot;10&quot;, &quot;10 10&quot;, &quot;10 10 10&quot; and &quot;10 10 10 10&quot; are all valid options and would return the same result)
  112. * @static
  113. * @param {Number/String} box The encoded margins
  114. * @param {String} units The type of units to add
  115. * @return {String} An string with unitized (px if units is not specified) metrics for top, right, bottom and left
  116. */
  117. unitizeBox: function(box, units) {
  118. var a = this.addUnits,
  119. b = this.parseBox(box);
  120. return a(b.top, units) + ' ' +
  121. a(b.right, units) + ' ' +
  122. a(b.bottom, units) + ' ' +
  123. a(b.left, units);
  124. },
  125. // private
  126. camelReplaceFn: function(m, a) {
  127. return a.charAt(1).toUpperCase();
  128. },
  129. <span id='Ext-dom-AbstractElement-static-method-normalize'> /**
  130. </span> * Normalizes CSS property keys from dash delimited to camel case JavaScript Syntax.
  131. * For example:
  132. *
  133. * - border-width -&gt; borderWidth
  134. * - padding-top -&gt; paddingTop
  135. *
  136. * @static
  137. * @param {String} prop The property to normalize
  138. * @return {String} The normalized string
  139. */
  140. normalize: function(prop) {
  141. // TODO: Mobile optimization?
  142. if (prop == 'float') {
  143. prop = Ext.supports.Float ? 'cssFloat' : 'styleFloat';
  144. }
  145. return this.propertyCache[prop] || (this.propertyCache[prop] = prop.replace(this.camelRe, this.camelReplaceFn));
  146. },
  147. <span id='Ext-dom-AbstractElement-static-method-getDocumentHeight'> /**
  148. </span> * Retrieves the document height
  149. * @static
  150. * @return {Number} documentHeight
  151. */
  152. getDocumentHeight: function() {
  153. return Math.max(!Ext.isStrict ? document.body.scrollHeight : document.documentElement.scrollHeight, this.getViewportHeight());
  154. },
  155. <span id='Ext-dom-AbstractElement-static-method-getDocumentWidth'> /**
  156. </span> * Retrieves the document width
  157. * @static
  158. * @return {Number} documentWidth
  159. */
  160. getDocumentWidth: function() {
  161. return Math.max(!Ext.isStrict ? document.body.scrollWidth : document.documentElement.scrollWidth, this.getViewportWidth());
  162. },
  163. <span id='Ext-dom-AbstractElement-static-method-getViewportHeight'> /**
  164. </span> * Retrieves the viewport height of the window.
  165. * @static
  166. * @return {Number} viewportHeight
  167. */
  168. getViewportHeight: function(){
  169. return window.innerHeight;
  170. },
  171. <span id='Ext-dom-AbstractElement-static-method-getViewportWidth'> /**
  172. </span> * Retrieves the viewport width of the window.
  173. * @static
  174. * @return {Number} viewportWidth
  175. */
  176. getViewportWidth: function() {
  177. return window.innerWidth;
  178. },
  179. <span id='Ext-dom-AbstractElement-static-method-getViewSize'> /**
  180. </span> * Retrieves the viewport size of the window.
  181. * @static
  182. * @return {Object} object containing width and height properties
  183. */
  184. getViewSize: function() {
  185. return {
  186. width: window.innerWidth,
  187. height: window.innerHeight
  188. };
  189. },
  190. <span id='Ext-dom-AbstractElement-static-method-getOrientation'> /**
  191. </span> * Retrieves the current orientation of the window. This is calculated by
  192. * determing if the height is greater than the width.
  193. * @static
  194. * @return {String} Orientation of window: 'portrait' or 'landscape'
  195. */
  196. getOrientation: function() {
  197. if (Ext.supports.OrientationChange) {
  198. return (window.orientation == 0) ? 'portrait' : 'landscape';
  199. }
  200. return (window.innerHeight &gt; window.innerWidth) ? 'portrait' : 'landscape';
  201. },
  202. <span id='Ext-dom-AbstractElement-static-method-fromPoint'> /**
  203. </span> * Returns the top Element that is located at the passed coordinates
  204. * @static
  205. * @param {Number} x The x coordinate
  206. * @param {Number} y The y coordinate
  207. * @return {String} The found Element
  208. */
  209. fromPoint: function(x, y) {
  210. return Ext.get(document.elementFromPoint(x, y));
  211. },
  212. <span id='Ext-dom-AbstractElement-static-method-parseStyles'> /**
  213. </span> * Converts a CSS string into an object with a property for each style.
  214. *
  215. * The sample code below would return an object with 2 properties, one
  216. * for background-color and one for color.
  217. *
  218. * var css = 'background-color: red;color: blue; ';
  219. * console.log(Ext.dom.Element.parseStyles(css));
  220. *
  221. * @static
  222. * @param {String} styles A CSS string
  223. * @return {Object} styles
  224. */
  225. parseStyles: function(styles){
  226. var out = {},
  227. cssRe = this.cssRe,
  228. matches;
  229. if (styles) {
  230. // Since we're using the g flag on the regex, we need to set the lastIndex.
  231. // This automatically happens on some implementations, but not others, see:
  232. // http://stackoverflow.com/questions/2645273/javascript-regular-expression-literal-persists-between-function-calls
  233. // http://blog.stevenlevithan.com/archives/fixing-javascript-regexp
  234. cssRe.lastIndex = 0;
  235. while ((matches = cssRe.exec(styles))) {
  236. out[matches[1]] = matches[2];
  237. }
  238. }
  239. return out;
  240. }
  241. });
  242. //TODO Need serious cleanups
  243. (function(){
  244. var doc = document,
  245. AbstractElement = Ext.dom.AbstractElement,
  246. activeElement = null,
  247. isCSS1 = doc.compatMode == &quot;CSS1Compat&quot;,
  248. flyInstance,
  249. fly = function (el) {
  250. if (!flyInstance) {
  251. flyInstance = new AbstractElement.Fly();
  252. }
  253. flyInstance.attach(el);
  254. return flyInstance;
  255. };
  256. // If the browser does not support document.activeElement we need some assistance.
  257. // This covers old Safari 3.2 (4.0 added activeElement along with just about all
  258. // other browsers). We need this support to handle issues with old Safari.
  259. if (!('activeElement' in doc) &amp;&amp; doc.addEventListener) {
  260. doc.addEventListener('focus',
  261. function (ev) {
  262. if (ev &amp;&amp; ev.target) {
  263. activeElement = (ev.target == doc) ? null : ev.target;
  264. }
  265. }, true);
  266. }
  267. /*
  268. * Helper function to create the function that will restore the selection.
  269. */
  270. function makeSelectionRestoreFn (activeEl, start, end) {
  271. return function () {
  272. activeEl.selectionStart = start;
  273. activeEl.selectionEnd = end;
  274. };
  275. }
  276. AbstractElement.addInheritableStatics({
  277. <span id='Ext-dom-AbstractElement-method-getActiveElement'> /**
  278. </span> * Returns the active element in the DOM. If the browser supports activeElement
  279. * on the document, this is returned. If not, the focus is tracked and the active
  280. * element is maintained internally.
  281. * @return {HTMLElement} The active (focused) element in the document.
  282. */
  283. getActiveElement: function () {
  284. return doc.activeElement || activeElement;
  285. },
  286. <span id='Ext-dom-AbstractElement-method-getRightMarginFixCleaner'> /**
  287. </span> * Creates a function to call to clean up problems with the work-around for the
  288. * WebKit RightMargin bug. The work-around is to add &quot;display: 'inline-block'&quot; to
  289. * the element before calling getComputedStyle and then to restore its original
  290. * display value. The problem with this is that it corrupts the selection of an
  291. * INPUT or TEXTAREA element (as in the &quot;I-beam&quot; goes away but ths focus remains).
  292. * To cleanup after this, we need to capture the selection of any such element and
  293. * then restore it after we have restored the display style.
  294. *
  295. * @param {Ext.dom.Element} target The top-most element being adjusted.
  296. * @private
  297. */
  298. getRightMarginFixCleaner: function (target) {
  299. var supports = Ext.supports,
  300. hasInputBug = supports.DisplayChangeInputSelectionBug,
  301. hasTextAreaBug = supports.DisplayChangeTextAreaSelectionBug,
  302. activeEl,
  303. tag,
  304. start,
  305. end;
  306. if (hasInputBug || hasTextAreaBug) {
  307. activeEl = doc.activeElement || activeElement; // save a call
  308. tag = activeEl &amp;&amp; activeEl.tagName;
  309. if ((hasTextAreaBug &amp;&amp; tag == 'TEXTAREA') ||
  310. (hasInputBug &amp;&amp; tag == 'INPUT' &amp;&amp; activeEl.type == 'text')) {
  311. if (Ext.dom.Element.isAncestor(target, activeEl)) {
  312. start = activeEl.selectionStart;
  313. end = activeEl.selectionEnd;
  314. if (Ext.isNumber(start) &amp;&amp; Ext.isNumber(end)) { // to be safe...
  315. // We don't create the raw closure here inline because that
  316. // will be costly even if we don't want to return it (nested
  317. // function decls and exprs are often instantiated on entry
  318. // regardless of whether execution ever reaches them):
  319. return makeSelectionRestoreFn(activeEl, start, end);
  320. }
  321. }
  322. }
  323. }
  324. return Ext.emptyFn; // avoid special cases, just return a nop
  325. },
  326. getViewWidth: function(full) {
  327. return full ? Ext.dom.Element.getDocumentWidth() : Ext.dom.Element.getViewportWidth();
  328. },
  329. getViewHeight: function(full) {
  330. return full ? Ext.dom.Element.getDocumentHeight() : Ext.dom.Element.getViewportHeight();
  331. },
  332. getDocumentHeight: function() {
  333. return Math.max(!isCSS1 ? doc.body.scrollHeight : doc.documentElement.scrollHeight, Ext.dom.Element.getViewportHeight());
  334. },
  335. getDocumentWidth: function() {
  336. return Math.max(!isCSS1 ? doc.body.scrollWidth : doc.documentElement.scrollWidth, Ext.dom.Element.getViewportWidth());
  337. },
  338. getViewportHeight: function(){
  339. return Ext.isIE ?
  340. (Ext.isStrict ? doc.documentElement.clientHeight : doc.body.clientHeight) :
  341. self.innerHeight;
  342. },
  343. getViewportWidth: function() {
  344. return (!Ext.isStrict &amp;&amp; !Ext.isOpera) ? doc.body.clientWidth :
  345. Ext.isIE ? doc.documentElement.clientWidth : self.innerWidth;
  346. },
  347. getY: function(el) {
  348. return Ext.dom.Element.getXY(el)[1];
  349. },
  350. getX: function(el) {
  351. return Ext.dom.Element.getXY(el)[0];
  352. },
  353. getXY: function(el) {
  354. var bd = doc.body,
  355. docEl = doc.documentElement,
  356. leftBorder = 0,
  357. topBorder = 0,
  358. ret = [0,0],
  359. round = Math.round,
  360. box,
  361. scroll;
  362. el = Ext.getDom(el);
  363. if(el != doc &amp;&amp; el != bd){
  364. // IE has the potential to throw when getBoundingClientRect called
  365. // on element not attached to dom
  366. if (Ext.isIE) {
  367. try {
  368. box = el.getBoundingClientRect();
  369. // In some versions of IE, the documentElement (HTML element) will have a 2px border that gets included, so subtract it off
  370. topBorder = docEl.clientTop || bd.clientTop;
  371. leftBorder = docEl.clientLeft || bd.clientLeft;
  372. } catch (ex) {
  373. box = { left: 0, top: 0 };
  374. }
  375. } else {
  376. box = el.getBoundingClientRect();
  377. }
  378. scroll = fly(document).getScroll();
  379. ret = [round(box.left + scroll.left - leftBorder), round(box.top + scroll.top - topBorder)];
  380. }
  381. return ret;
  382. },
  383. setXY: function(el, xy) {
  384. (el = Ext.fly(el, '_setXY')).position();
  385. var pts = el.translatePoints(xy),
  386. style = el.dom.style,
  387. pos;
  388. for (pos in pts) {
  389. if (!isNaN(pts[pos])) {
  390. style[pos] = pts[pos] + &quot;px&quot;;
  391. }
  392. }
  393. },
  394. setX: function(el, x) {
  395. Ext.dom.Element.setXY(el, [x, false]);
  396. },
  397. setY: function(el, y) {
  398. Ext.dom.Element.setXY(el, [false, y]);
  399. },
  400. <span id='Ext-dom-AbstractElement-method-serializeForm'> /**
  401. </span> * Serializes a DOM form into a url encoded string
  402. * @param {Object} form The form
  403. * @return {String} The url encoded form
  404. */
  405. serializeForm: function(form) {
  406. var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,
  407. hasSubmit = false,
  408. encoder = encodeURIComponent,
  409. data = '',
  410. eLen = fElements.length,
  411. element, name, type, options, hasValue, e,
  412. o, oLen, opt;
  413. for (e = 0; e &lt; eLen; e++) {
  414. element = fElements[e];
  415. name = element.name;
  416. type = element.type;
  417. options = element.options;
  418. if (!element.disabled &amp;&amp; name) {
  419. if (/select-(one|multiple)/i.test(type)) {
  420. oLen = options.length;
  421. for (o = 0; o &lt; oLen; o++) {
  422. opt = options[o];
  423. if (opt.selected) {
  424. hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified;
  425. data += Ext.String.format(&quot;{0}={1}&amp;&quot;, encoder(name), encoder(hasValue ? opt.value : opt.text));
  426. }
  427. }
  428. } else if (!(/file|undefined|reset|button/i.test(type))) {
  429. if (!(/radio|checkbox/i.test(type) &amp;&amp; !element.checked) &amp;&amp; !(type == 'submit' &amp;&amp; hasSubmit)) {
  430. data += encoder(name) + '=' + encoder(element.value) + '&amp;';
  431. hasSubmit = /submit/i.test(type);
  432. }
  433. }
  434. }
  435. }
  436. return data.substr(0, data.length - 1);
  437. }
  438. });
  439. }());
  440. </pre>
  441. </body>
  442. </html>