Layer.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  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-Layer'>/**
  19. </span> * An extended {@link Ext.Element} object that supports a shadow and shim, constrain to viewport and
  20. * automatic maintaining of shadow/shim positions.
  21. */
  22. Ext.define('Ext.Layer', {
  23. extend: 'Ext.Element',
  24. uses: ['Ext.Shadow'],
  25. <span id='Ext-Layer-cfg-shim'> /**
  26. </span> * @cfg {Boolean} [shim=true]
  27. * False to disable the iframe shim in browsers which need one.
  28. */
  29. <span id='Ext-Layer-cfg-shadow'> /**
  30. </span> * @cfg {String/Boolean} [shadow=false]
  31. * True to automatically create an {@link Ext.Shadow}, or a string indicating the
  32. * shadow's display {@link Ext.Shadow#mode}. False to disable the shadow.
  33. */
  34. <span id='Ext-Layer-cfg-dh'> /**
  35. </span> * @cfg {Object} [dh={tag: 'div', cls: 'x-layer'}]
  36. * DomHelper object config to create element with.
  37. */
  38. <span id='Ext-Layer-cfg-constrain'> /**
  39. </span> * @cfg {Boolean} [constrain=true]
  40. * False to disable constrain to viewport.
  41. */
  42. <span id='Ext-Layer-cfg-cls'> /**
  43. </span> * @cfg {String} cls
  44. * CSS class to add to the element
  45. */
  46. <span id='Ext-Layer-cfg-zindex'> /**
  47. </span> * @cfg {Number} [zindex=11000]
  48. * Starting z-index.
  49. */
  50. <span id='Ext-Layer-cfg-shadowOffset'> /**
  51. </span> * @cfg {Number} [shadowOffset=4]
  52. * Number of pixels to offset the shadow
  53. */
  54. <span id='Ext-Layer-cfg-useDisplay'> /**
  55. </span> * @cfg {Boolean} [useDisplay=false]
  56. * Defaults to use css offsets to hide the Layer. Specify &lt;tt&gt;true&lt;/tt&gt;
  57. * to use css style &lt;tt&gt;'display:none;'&lt;/tt&gt; to hide the Layer.
  58. */
  59. <span id='Ext-Layer-cfg-visibilityCls'> /**
  60. </span> * @cfg {String} visibilityCls
  61. * The CSS class name to add in order to hide this Layer if this layer
  62. * is configured with &lt;code&gt;{@link #hideMode}: 'asclass'&lt;/code&gt;
  63. */
  64. <span id='Ext-Layer-cfg-hideMode'> /**
  65. </span> * @cfg {String} hideMode
  66. * A String which specifies how this Layer will be hidden.
  67. * Values may be:
  68. *
  69. * - `'display'` : The Component will be hidden using the `display: none` style.
  70. * - `'visibility'` : The Component will be hidden using the `visibility: hidden` style.
  71. * - `'offsets'` : The Component will be hidden by absolutely positioning it out of the visible area
  72. * of the document. This is useful when a hidden Component must maintain measurable dimensions.
  73. * Hiding using `display` results in a Component having zero dimensions.
  74. */
  75. // shims are shared among layer to keep from having 100 iframes
  76. statics: {
  77. shims: []
  78. },
  79. isLayer: true,
  80. <span id='Ext-Layer-method-constructor'> /**
  81. </span> * Creates new Layer.
  82. * @param {Object} [config] An object with config options.
  83. * @param {String/HTMLElement} [existingEl] Uses an existing DOM element.
  84. * If the element is not found it creates it.
  85. */
  86. constructor: function(config, existingEl) {
  87. config = config || {};
  88. var me = this,
  89. dh = Ext.DomHelper,
  90. cp = config.parentEl,
  91. pel = cp ? Ext.getDom(cp) : document.body,
  92. hm = config.hideMode;
  93. if (existingEl) {
  94. me.dom = Ext.getDom(existingEl);
  95. }
  96. if (!me.dom) {
  97. me.dom = dh.append(pel, config.dh || {
  98. tag: 'div',
  99. cls: Ext.baseCSSPrefix + 'layer' // primarily to give el 'position:absolute'
  100. });
  101. } else {
  102. me.addCls(Ext.baseCSSPrefix + 'layer');
  103. if (!me.dom.parentNode) {
  104. pel.appendChild(me.dom);
  105. }
  106. }
  107. if (config.id) {
  108. me.id = me.dom.id = config.id;
  109. } else {
  110. me.id = Ext.id(me.dom);
  111. }
  112. Ext.Element.addToCache(me);
  113. if (config.cls) {
  114. me.addCls(config.cls);
  115. }
  116. me.constrain = config.constrain !== false;
  117. // Allow Components to pass their hide mode down to the Layer if they are floating.
  118. // Otherwise, allow useDisplay to override the default hiding method which is visibility.
  119. // TODO: Have ExtJS's Element implement visibilityMode by using classes as in Mobile.
  120. if (hm) {
  121. me.setVisibilityMode(Ext.Element[hm.toUpperCase()]);
  122. if (me.visibilityMode == Ext.Element.ASCLASS) {
  123. me.visibilityCls = config.visibilityCls;
  124. }
  125. } else if (config.useDisplay) {
  126. me.setVisibilityMode(Ext.Element.DISPLAY);
  127. } else {
  128. me.setVisibilityMode(Ext.Element.VISIBILITY);
  129. }
  130. if (config.shadow) {
  131. me.shadowOffset = config.shadowOffset || 4;
  132. me.shadow = new Ext.Shadow({
  133. offset: me.shadowOffset,
  134. mode: config.shadow
  135. });
  136. me.disableShadow();
  137. } else {
  138. me.shadowOffset = 0;
  139. }
  140. me.useShim = config.shim !== false &amp;&amp; Ext.useShims;
  141. if (config.hidden === true) {
  142. me.hide();
  143. } else {
  144. me.show();
  145. }
  146. },
  147. getZIndex: function() {
  148. return parseInt((this.getShim() || this).getStyle('z-index'), 10);
  149. },
  150. getShim: function() {
  151. var me = this,
  152. shim, pn;
  153. if (!me.useShim) {
  154. return null;
  155. }
  156. if (!me.shim) {
  157. shim = me.self.shims.shift();
  158. if (!shim) {
  159. shim = me.createShim();
  160. shim.enableDisplayMode('block');
  161. shim.hide();
  162. }
  163. pn = me.dom.parentNode;
  164. if (shim.dom.parentNode != pn) {
  165. pn.insertBefore(shim.dom, me.dom);
  166. }
  167. me.shim = shim;
  168. }
  169. return me.shim;
  170. },
  171. hideShim: function() {
  172. var me = this;
  173. if (me.shim) {
  174. me.shim.setDisplayed(false);
  175. me.self.shims.push(me.shim);
  176. delete me.shim;
  177. }
  178. },
  179. disableShadow: function() {
  180. var me = this;
  181. if (me.shadow &amp;&amp; !me.shadowDisabled) {
  182. me.shadowDisabled = true;
  183. me.shadow.hide();
  184. me.lastShadowOffset = me.shadowOffset;
  185. me.shadowOffset = 0;
  186. }
  187. },
  188. enableShadow: function(show) {
  189. var me = this;
  190. if (me.shadow &amp;&amp; me.shadowDisabled) {
  191. me.shadowDisabled = false;
  192. me.shadowOffset = me.lastShadowOffset;
  193. delete me.lastShadowOffset;
  194. if (show) {
  195. me.sync(true);
  196. }
  197. }
  198. },
  199. <span id='Ext-Layer-method-sync'> /**
  200. </span> * @private
  201. * Synchronize this Layer's associated elements, the shadow, and possibly the shim.
  202. *
  203. * This code can execute repeatedly in milliseconds,
  204. * eg: dragging a Component configured liveDrag: true, or which has no ghost method
  205. * so code size was sacrificed for efficiency (e.g. no getBox/setBox, no XY calls)
  206. *
  207. * @param {Boolean} doShow Pass true to ensure that the shadow is shown.
  208. */
  209. sync: function(doShow) {
  210. var me = this,
  211. shadow = me.shadow,
  212. shadowPos, shimStyle, shadowSize,
  213. shim, l, t, w, h, shimIndex;
  214. if (!me.updating &amp;&amp; me.isVisible() &amp;&amp; (shadow || me.useShim)) {
  215. shim = me.getShim();
  216. l = me.getLocalX();
  217. t = me.getLocalY();
  218. w = me.dom.offsetWidth;
  219. h = me.dom.offsetHeight;
  220. if (shadow &amp;&amp; !me.shadowDisabled) {
  221. if (doShow &amp;&amp; !shadow.isVisible()) {
  222. shadow.show(me);
  223. } else {
  224. shadow.realign(l, t, w, h);
  225. }
  226. if (shim) {
  227. // TODO: Determine how the shims zIndex is above the layer zIndex at this point
  228. shimIndex = shim.getStyle('z-index');
  229. if (shimIndex &gt; me.zindex) {
  230. me.shim.setStyle('z-index', me.zindex - 2);
  231. }
  232. shim.show();
  233. // fit the shim behind the shadow, so it is shimmed too
  234. if (shadow.isVisible()) {
  235. shadowPos = shadow.el.getXY();
  236. shimStyle = shim.dom.style;
  237. shadowSize = shadow.el.getSize();
  238. if (Ext.supports.CSS3BoxShadow) {
  239. shadowSize.height += 6;
  240. shadowSize.width += 4;
  241. shadowPos[0] -= 2;
  242. shadowPos[1] -= 4;
  243. }
  244. shimStyle.left = (shadowPos[0]) + 'px';
  245. shimStyle.top = (shadowPos[1]) + 'px';
  246. shimStyle.width = (shadowSize.width) + 'px';
  247. shimStyle.height = (shadowSize.height) + 'px';
  248. } else {
  249. shim.setSize(w, h);
  250. shim.setLeftTop(l, t);
  251. }
  252. }
  253. } else if (shim) {
  254. // TODO: Determine how the shims zIndex is above the layer zIndex at this point
  255. shimIndex = shim.getStyle('z-index');
  256. if (shimIndex &gt; me.zindex) {
  257. me.shim.setStyle('z-index', me.zindex - 2);
  258. }
  259. shim.show();
  260. shim.setSize(w, h);
  261. shim.setLeftTop(l, t);
  262. }
  263. }
  264. return me;
  265. },
  266. remove: function() {
  267. this.hideUnders();
  268. this.callParent();
  269. },
  270. // private
  271. beginUpdate: function() {
  272. this.updating = true;
  273. },
  274. // private
  275. endUpdate: function() {
  276. this.updating = false;
  277. this.sync(true);
  278. },
  279. // private
  280. hideUnders: function() {
  281. if (this.shadow) {
  282. this.shadow.hide();
  283. }
  284. this.hideShim();
  285. },
  286. // private
  287. constrainXY: function() {
  288. if (this.constrain) {
  289. var vw = Ext.Element.getViewWidth(),
  290. vh = Ext.Element.getViewHeight(),
  291. s = Ext.getDoc().getScroll(),
  292. xy = this.getXY(),
  293. x = xy[0],
  294. y = xy[1],
  295. so = this.shadowOffset,
  296. w = this.dom.offsetWidth + so,
  297. h = this.dom.offsetHeight + so,
  298. moved = false; // only move it if it needs it
  299. // first validate right/bottom
  300. if ((x + w) &gt; vw + s.left) {
  301. x = vw - w - so;
  302. moved = true;
  303. }
  304. if ((y + h) &gt; vh + s.top) {
  305. y = vh - h - so;
  306. moved = true;
  307. }
  308. // then make sure top/left isn't negative
  309. if (x &lt; s.left) {
  310. x = s.left;
  311. moved = true;
  312. }
  313. if (y &lt; s.top) {
  314. y = s.top;
  315. moved = true;
  316. }
  317. if (moved) {
  318. Ext.Layer.superclass.setXY.call(this, [x, y]);
  319. this.sync();
  320. }
  321. }
  322. return this;
  323. },
  324. getConstrainOffset: function() {
  325. return this.shadowOffset;
  326. },
  327. // overridden Element method
  328. setVisible: function(visible, animate, duration, callback, easing) {
  329. var me = this,
  330. cb;
  331. // post operation processing
  332. cb = function() {
  333. if (visible) {
  334. me.sync(true);
  335. }
  336. if (callback) {
  337. callback();
  338. }
  339. };
  340. // Hide shadow and shim if hiding
  341. if (!visible) {
  342. me.hideUnders(true);
  343. }
  344. me.callParent([visible, animate, duration, callback, easing]);
  345. if (!animate) {
  346. cb();
  347. }
  348. return me;
  349. },
  350. // private
  351. beforeFx: function() {
  352. this.beforeAction();
  353. return this.callParent(arguments);
  354. },
  355. // private
  356. afterFx: function() {
  357. this.callParent(arguments);
  358. this.sync(this.isVisible());
  359. },
  360. // private
  361. beforeAction: function() {
  362. if (!this.updating &amp;&amp; this.shadow) {
  363. this.shadow.hide();
  364. }
  365. },
  366. // overridden Element method
  367. setLeft: function(left) {
  368. this.callParent(arguments);
  369. return this.sync();
  370. },
  371. setTop: function(top) {
  372. this.callParent(arguments);
  373. return this.sync();
  374. },
  375. setLeftTop: function(left, top) {
  376. this.callParent(arguments);
  377. return this.sync();
  378. },
  379. setXY: function(xy, animate, duration, callback, easing) {
  380. var me = this;
  381. // Callback will restore shadow state and call the passed callback
  382. callback = me.createCB(callback);
  383. me.fixDisplay();
  384. me.beforeAction();
  385. me.callParent([xy, animate, duration, callback, easing]);
  386. if (!animate) {
  387. callback();
  388. }
  389. return me;
  390. },
  391. // private
  392. createCB: function(callback) {
  393. var me = this,
  394. showShadow = me.shadow &amp;&amp; me.shadow.isVisible();
  395. return function() {
  396. me.constrainXY();
  397. me.sync(showShadow);
  398. if (callback) {
  399. callback();
  400. }
  401. };
  402. },
  403. // overridden Element method
  404. setX: function(x, animate, duration, callback, easing) {
  405. this.setXY([x, this.getY()], animate, duration, callback, easing);
  406. return this;
  407. },
  408. // overridden Element method
  409. setY: function(y, animate, duration, callback, easing) {
  410. this.setXY([this.getX(), y], animate, duration, callback, easing);
  411. return this;
  412. },
  413. // overridden Element method
  414. setSize: function(w, h, animate, duration, callback, easing) {
  415. var me = this;
  416. // Callback will restore shadow state and call the passed callback
  417. callback = me.createCB(callback);
  418. me.beforeAction();
  419. me.callParent([w, h, animate, duration, callback, easing]);
  420. if (!animate) {
  421. callback();
  422. }
  423. return me;
  424. },
  425. // overridden Element method
  426. setWidth: function(w, animate, duration, callback, easing) {
  427. var me = this;
  428. // Callback will restore shadow state and call the passed callback
  429. callback = me.createCB(callback);
  430. me.beforeAction();
  431. me.callParent([w, animate, duration, callback, easing]);
  432. if (!animate) {
  433. callback();
  434. }
  435. return me;
  436. },
  437. // overridden Element method
  438. setHeight: function(h, animate, duration, callback, easing) {
  439. var me = this;
  440. // Callback will restore shadow state and call the passed callback
  441. callback = me.createCB(callback);
  442. me.beforeAction();
  443. me.callParent([h, animate, duration, callback, easing]);
  444. if (!animate) {
  445. callback();
  446. }
  447. return me;
  448. },
  449. // overridden Element method
  450. setBounds: function(x, y, width, height, animate, duration, callback, easing) {
  451. var me = this;
  452. // Callback will restore shadow state and call the passed callback
  453. callback = me.createCB(callback);
  454. me.beforeAction();
  455. if (!animate) {
  456. Ext.Layer.superclass.setXY.call(me, [x, y]);
  457. Ext.Layer.superclass.setSize.call(me, width, height);
  458. callback();
  459. } else {
  460. me.callParent([x, y, width, height, animate, duration, callback, easing]);
  461. }
  462. return me;
  463. },
  464. <span id='Ext-Layer-method-setZIndex'> /**
  465. </span> * Sets the z-index of this layer and adjusts any shadow and shim z-indexes. The layer
  466. * z-index is automatically incremented depending upon the presence of a shim or a
  467. * shadow in so that it always shows above those two associated elements.
  468. *
  469. * Any shim, will be assigned the passed z-index. A shadow will be assigned the next
  470. * highet z-index, and the Layer's element will receive the highest z-index.
  471. *
  472. * @param {Number} zindex The new z-index to set
  473. * @return {Ext.Layer} The Layer
  474. */
  475. setZIndex: function(zindex) {
  476. var me = this;
  477. me.zindex = zindex;
  478. if (me.getShim()) {
  479. me.shim.setStyle('z-index', zindex++);
  480. }
  481. if (me.shadow) {
  482. me.shadow.setZIndex(zindex++);
  483. }
  484. return me.setStyle('z-index', zindex);
  485. },
  486. onOpacitySet: function(opacity){
  487. var shadow = this.shadow;
  488. if (shadow) {
  489. shadow.setOpacity(opacity);
  490. }
  491. }
  492. });
  493. </pre>
  494. </body>
  495. </html>