Item.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  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-menu-Item'>/**
  19. </span> * A base class for all menu items that require menu-related functionality such as click handling,
  20. * sub-menus, icons, etc.
  21. *
  22. * @example
  23. * Ext.create('Ext.menu.Menu', {
  24. * width: 100,
  25. * height: 100,
  26. * floating: false, // usually you want this set to True (default)
  27. * renderTo: Ext.getBody(), // usually rendered by it's containing component
  28. * items: [{
  29. * text: 'icon item',
  30. * iconCls: 'add16'
  31. * },{
  32. * text: 'text item'
  33. * },{
  34. * text: 'plain item',
  35. * plain: true
  36. * }]
  37. * });
  38. */
  39. Ext.define('Ext.menu.Item', {
  40. extend: 'Ext.Component',
  41. alias: 'widget.menuitem',
  42. alternateClassName: 'Ext.menu.TextItem',
  43. <span id='Ext-menu-Item-property-activated'> /**
  44. </span> * @property {Boolean} activated
  45. * Whether or not this item is currently activated
  46. */
  47. <span id='Ext-menu-Item-property-parentMenu'> /**
  48. </span> * @property {Ext.menu.Menu} parentMenu
  49. * The parent Menu of this item.
  50. */
  51. <span id='Ext-menu-Item-cfg-activeCls'> /**
  52. </span> * @cfg {String} activeCls
  53. * The CSS class added to the menu item when the item is activated (focused/mouseover).
  54. */
  55. activeCls: Ext.baseCSSPrefix + 'menu-item-active',
  56. <span id='Ext-menu-Item-cfg-ariaRole'> /**
  57. </span> * @cfg {String} ariaRole
  58. * @private
  59. */
  60. ariaRole: 'menuitem',
  61. <span id='Ext-menu-Item-cfg-canActivate'> /**
  62. </span> * @cfg {Boolean} canActivate
  63. * Whether or not this menu item can be activated when focused/mouseovered.
  64. */
  65. canActivate: true,
  66. <span id='Ext-menu-Item-cfg-clickHideDelay'> /**
  67. </span> * @cfg {Number} clickHideDelay
  68. * The delay in milliseconds to wait before hiding the menu after clicking the menu item.
  69. * This only has an effect when `hideOnClick: true`.
  70. */
  71. clickHideDelay: 1,
  72. <span id='Ext-menu-Item-cfg-destroyMenu'> /**
  73. </span> * @cfg {Boolean} destroyMenu
  74. * Whether or not to destroy any associated sub-menu when this item is destroyed.
  75. */
  76. destroyMenu: true,
  77. <span id='Ext-menu-Item-cfg-disabledCls'> /**
  78. </span> * @cfg {String} disabledCls
  79. * The CSS class added to the menu item when the item is disabled.
  80. */
  81. disabledCls: Ext.baseCSSPrefix + 'menu-item-disabled',
  82. <span id='Ext-menu-Item-cfg-href'> /**
  83. </span> * @cfg {String} [href='#']
  84. * The href attribute to use for the underlying anchor link.
  85. */
  86. <span id='Ext-menu-Item-cfg-hrefTarget'> /**
  87. </span> * @cfg {String} hrefTarget
  88. * The target attribute to use for the underlying anchor link.
  89. */
  90. <span id='Ext-menu-Item-cfg-hideOnClick'> /**
  91. </span> * @cfg {Boolean} hideOnClick
  92. * Whether to not to hide the owning menu when this item is clicked.
  93. */
  94. hideOnClick: true,
  95. <span id='Ext-menu-Item-cfg-icon'> /**
  96. </span> * @cfg {String} icon
  97. * The path to an icon to display in this item.
  98. *
  99. * Defaults to `Ext.BLANK_IMAGE_URL`.
  100. */
  101. <span id='Ext-menu-Item-cfg-iconCls'> /**
  102. </span> * @cfg {String} iconCls
  103. * A CSS class that specifies a `background-image` to use as the icon for this item.
  104. */
  105. isMenuItem: true,
  106. <span id='Ext-menu-Item-cfg-menu'> /**
  107. </span> * @cfg {Ext.menu.Menu/Object} menu
  108. * Either an instance of {@link Ext.menu.Menu} or a config object for an {@link Ext.menu.Menu}
  109. * which will act as a sub-menu to this item.
  110. */
  111. <span id='Ext-menu-Item-property-menu'> /**
  112. </span> * @property {Ext.menu.Menu} menu The sub-menu associated with this item, if one was configured.
  113. */
  114. <span id='Ext-menu-Item-cfg-menuAlign'> /**
  115. </span> * @cfg {String} menuAlign
  116. * The default {@link Ext.Element#getAlignToXY Ext.Element.getAlignToXY} anchor position value for this
  117. * item's sub-menu relative to this item's position.
  118. */
  119. menuAlign: 'tl-tr?',
  120. <span id='Ext-menu-Item-cfg-menuExpandDelay'> /**
  121. </span> * @cfg {Number} menuExpandDelay
  122. * The delay in milliseconds before this item's sub-menu expands after this item is moused over.
  123. */
  124. menuExpandDelay: 200,
  125. <span id='Ext-menu-Item-cfg-menuHideDelay'> /**
  126. </span> * @cfg {Number} menuHideDelay
  127. * The delay in milliseconds before this item's sub-menu hides after this item is moused out.
  128. */
  129. menuHideDelay: 200,
  130. <span id='Ext-menu-Item-cfg-plain'> /**
  131. </span> * @cfg {Boolean} plain
  132. * Whether or not this item is plain text/html with no icon or visual activation.
  133. */
  134. <span id='Ext-menu-Item-cfg-tooltip'> /**
  135. </span> * @cfg {String/Object} tooltip
  136. * The tooltip for the button - can be a string to be used as innerHTML (html tags are accepted) or
  137. * QuickTips config object.
  138. */
  139. <span id='Ext-menu-Item-cfg-tooltipType'> /**
  140. </span> * @cfg {String} tooltipType
  141. * The type of tooltip to use. Either 'qtip' for QuickTips or 'title' for title attribute.
  142. */
  143. tooltipType: 'qtip',
  144. arrowCls: Ext.baseCSSPrefix + 'menu-item-arrow',
  145. childEls: [
  146. 'itemEl', 'iconEl', 'textEl', 'arrowEl'
  147. ],
  148. renderTpl: [
  149. '&lt;tpl if=&quot;plain&quot;&gt;',
  150. '{text}',
  151. '&lt;tpl else&gt;',
  152. '&lt;a id=&quot;{id}-itemEl&quot; class=&quot;' + Ext.baseCSSPrefix + 'menu-item-link&quot; href=&quot;{href}&quot; &lt;tpl if=&quot;hrefTarget&quot;&gt;target=&quot;{hrefTarget}&quot;&lt;/tpl&gt; hidefocus=&quot;true&quot; unselectable=&quot;on&quot;&gt;',
  153. '&lt;img id=&quot;{id}-iconEl&quot; src=&quot;{icon}&quot; class=&quot;' + Ext.baseCSSPrefix + 'menu-item-icon {iconCls}&quot; /&gt;',
  154. '&lt;span id=&quot;{id}-textEl&quot; class=&quot;' + Ext.baseCSSPrefix + 'menu-item-text&quot; &lt;tpl if=&quot;arrowCls&quot;&gt;style=&quot;margin-right: 17px;&quot;&lt;/tpl&gt; &gt;{text}&lt;/span&gt;',
  155. '&lt;img id=&quot;{id}-arrowEl&quot; src=&quot;{blank}&quot; class=&quot;{arrowCls}&quot; /&gt;',
  156. '&lt;/a&gt;',
  157. '&lt;/tpl&gt;'
  158. ],
  159. maskOnDisable: false,
  160. <span id='Ext-menu-Item-cfg-text'> /**
  161. </span> * @cfg {String} text
  162. * The text/html to display in this item.
  163. */
  164. <span id='Ext-menu-Item-cfg-handler'> /**
  165. </span> * @cfg {Function} handler
  166. * A function called when the menu item is clicked (can be used instead of {@link #click} event).
  167. * @cfg {Ext.menu.Item} handler.item The item that was clicked
  168. * @cfg {Ext.EventObject} handler.e The underyling {@link Ext.EventObject}.
  169. */
  170. activate: function() {
  171. var me = this;
  172. if (!me.activated &amp;&amp; me.canActivate &amp;&amp; me.rendered &amp;&amp; !me.isDisabled() &amp;&amp; me.isVisible()) {
  173. me.el.addCls(me.activeCls);
  174. me.focus();
  175. me.activated = true;
  176. me.fireEvent('activate', me);
  177. }
  178. },
  179. getFocusEl: function() {
  180. return this.itemEl;
  181. },
  182. deactivate: function() {
  183. var me = this;
  184. if (me.activated) {
  185. me.el.removeCls(me.activeCls);
  186. me.blur();
  187. me.hideMenu();
  188. me.activated = false;
  189. me.fireEvent('deactivate', me);
  190. }
  191. },
  192. deferExpandMenu: function() {
  193. var me = this;
  194. if (me.activated &amp;&amp; (!me.menu.rendered || !me.menu.isVisible())) {
  195. me.parentMenu.activeChild = me.menu;
  196. me.menu.parentItem = me;
  197. me.menu.parentMenu = me.menu.ownerCt = me.parentMenu;
  198. me.menu.showBy(me, me.menuAlign);
  199. }
  200. },
  201. deferHideMenu: function() {
  202. if (this.menu.isVisible()) {
  203. this.menu.hide();
  204. }
  205. },
  206. cancelDeferHide: function(){
  207. clearTimeout(this.hideMenuTimer);
  208. },
  209. deferHideParentMenus: function() {
  210. var ancestor;
  211. Ext.menu.Manager.hideAll();
  212. if (!Ext.Element.getActiveElement()) {
  213. // If we have just hidden all Menus, and there is no currently focused element in the dom, transfer focus to the first visible ancestor if any.
  214. ancestor = this.up(':not([hidden])');
  215. if (ancestor) {
  216. ancestor.focus();
  217. }
  218. }
  219. },
  220. expandMenu: function(delay) {
  221. var me = this;
  222. if (me.menu) {
  223. me.cancelDeferHide();
  224. if (delay === 0) {
  225. me.deferExpandMenu();
  226. } else {
  227. me.expandMenuTimer = Ext.defer(me.deferExpandMenu, Ext.isNumber(delay) ? delay : me.menuExpandDelay, me);
  228. }
  229. }
  230. },
  231. getRefItems: function(deep){
  232. var menu = this.menu,
  233. items;
  234. if (menu) {
  235. items = menu.getRefItems(deep);
  236. items.unshift(menu);
  237. }
  238. return items || [];
  239. },
  240. hideMenu: function(delay) {
  241. var me = this;
  242. if (me.menu) {
  243. clearTimeout(me.expandMenuTimer);
  244. me.hideMenuTimer = Ext.defer(me.deferHideMenu, Ext.isNumber(delay) ? delay : me.menuHideDelay, me);
  245. }
  246. },
  247. initComponent: function() {
  248. var me = this,
  249. prefix = Ext.baseCSSPrefix,
  250. cls = [prefix + 'menu-item'],
  251. menu;
  252. me.addEvents(
  253. <span id='Ext-menu-Item-event-activate'> /**
  254. </span> * @event activate
  255. * Fires when this item is activated
  256. * @param {Ext.menu.Item} item The activated item
  257. */
  258. 'activate',
  259. <span id='Ext-menu-Item-event-click'> /**
  260. </span> * @event click
  261. * Fires when this item is clicked
  262. * @param {Ext.menu.Item} item The item that was clicked
  263. * @param {Ext.EventObject} e The underyling {@link Ext.EventObject}.
  264. */
  265. 'click',
  266. <span id='Ext-menu-Item-event-deactivate'> /**
  267. </span> * @event deactivate
  268. * Fires when this tiem is deactivated
  269. * @param {Ext.menu.Item} item The deactivated item
  270. */
  271. 'deactivate'
  272. );
  273. if (me.plain) {
  274. cls.push(prefix + 'menu-item-plain');
  275. }
  276. if (me.cls) {
  277. cls.push(me.cls);
  278. }
  279. me.cls = cls.join(' ');
  280. if (me.menu) {
  281. menu = me.menu;
  282. delete me.menu;
  283. me.setMenu(menu);
  284. }
  285. me.callParent(arguments);
  286. },
  287. onClick: function(e) {
  288. var me = this;
  289. if (!me.href) {
  290. e.stopEvent();
  291. }
  292. if (me.disabled) {
  293. return;
  294. }
  295. if (me.hideOnClick) {
  296. me.deferHideParentMenusTimer = Ext.defer(me.deferHideParentMenus, me.clickHideDelay, me);
  297. }
  298. Ext.callback(me.handler, me.scope || me, [me, e]);
  299. me.fireEvent('click', me, e);
  300. if (!me.hideOnClick) {
  301. me.focus();
  302. }
  303. },
  304. onRemoved: function() {
  305. var me = this;
  306. // Removing the active item, must deactivate it.
  307. if (me.activated &amp;&amp; me.parentMenu.activeItem === me) {
  308. me.parentMenu.deactivateActiveItem();
  309. }
  310. me.callParent(arguments);
  311. delete me.parentMenu;
  312. delete me.ownerButton;
  313. },
  314. // private
  315. beforeDestroy: function() {
  316. var me = this;
  317. if (me.rendered) {
  318. me.clearTip();
  319. }
  320. me.callParent();
  321. },
  322. onDestroy: function() {
  323. var me = this;
  324. clearTimeout(me.expandMenuTimer);
  325. me.cancelDeferHide();
  326. clearTimeout(me.deferHideParentMenusTimer);
  327. me.setMenu(null);
  328. me.callParent(arguments);
  329. },
  330. beforeRender: function() {
  331. var me = this,
  332. blank = Ext.BLANK_IMAGE_URL,
  333. iconCls,
  334. arrowCls;
  335. me.callParent();
  336. if (me.iconAlign === 'right') {
  337. iconCls = me.checkChangeDisabled ? me.disabledCls : '';
  338. arrowCls = Ext.baseCSSPrefix + 'menu-item-icon-right ' + me.iconCls;
  339. } else {
  340. iconCls = me.iconCls + (me.checkChangeDisabled ? ' ' + me.disabledCls : '');
  341. arrowCls = me.menu ? me.arrowCls : '';
  342. }
  343. Ext.applyIf(me.renderData, {
  344. href: me.href || '#',
  345. hrefTarget: me.hrefTarget,
  346. icon: me.icon || blank,
  347. iconCls: iconCls,
  348. plain: me.plain,
  349. text: me.text,
  350. arrowCls: arrowCls,
  351. blank: blank
  352. });
  353. },
  354. onRender: function() {
  355. var me = this;
  356. me.callParent(arguments);
  357. if (me.tooltip) {
  358. me.setTooltip(me.tooltip, true);
  359. }
  360. },
  361. <span id='Ext-menu-Item-method-setMenu'> /**
  362. </span> * Set a child menu for this item. See the {@link #cfg-menu} configuration.
  363. * @param {Ext.menu.Menu/Object} menu A menu, or menu configuration. null may be
  364. * passed to remove the menu.
  365. * @param {Boolean} [destroyMenu] True to destroy any existing menu. False to
  366. * prevent destruction. If not specified, the {@link #destroyMenu} configuration
  367. * will be used.
  368. */
  369. setMenu: function(menu, destroyMenu) {
  370. var me = this,
  371. oldMenu = me.menu,
  372. arrowEl = me.arrowEl;
  373. if (oldMenu) {
  374. delete oldMenu.parentItem;
  375. delete oldMenu.parentMenu;
  376. delete oldMenu.ownerCt;
  377. delete oldMenu.ownerItem;
  378. if (destroyMenu === true || (destroyMenu !== false &amp;&amp; me.destroyMenu)) {
  379. Ext.destroy(oldMenu);
  380. }
  381. }
  382. if (menu) {
  383. me.menu = Ext.menu.Manager.get(menu);
  384. me.menu.ownerItem = me;
  385. } else {
  386. me.menu = null;
  387. }
  388. if (me.rendered &amp;&amp; !me.destroying &amp;&amp; arrowEl) {
  389. arrowEl[me.menu ? 'addCls' : 'removeCls'](me.arrowCls);
  390. }
  391. },
  392. <span id='Ext-menu-Item-method-setHandler'> /**
  393. </span> * Sets the {@link #click} handler of this item
  394. * @param {Function} fn The handler function
  395. * @param {Object} [scope] The scope of the handler function
  396. */
  397. setHandler: function(fn, scope) {
  398. this.handler = fn || null;
  399. this.scope = scope;
  400. },
  401. <span id='Ext-menu-Item-method-setIcon'> /**
  402. </span> * Sets the {@link #icon} on this item.
  403. * @param {String} icon The new icon
  404. */
  405. setIcon: function(icon){
  406. var iconEl = this.iconEl;
  407. if (iconEl) {
  408. iconEl.src = icon || Ext.BLANK_IMAGE_URL;
  409. }
  410. this.icon = icon;
  411. },
  412. <span id='Ext-menu-Item-method-setIconCls'> /**
  413. </span> * Sets the {@link #iconCls} of this item
  414. * @param {String} iconCls The CSS class to set to {@link #iconCls}
  415. */
  416. setIconCls: function(iconCls) {
  417. var me = this,
  418. iconEl = me.iconEl;
  419. if (iconEl) {
  420. if (me.iconCls) {
  421. iconEl.removeCls(me.iconCls);
  422. }
  423. if (iconCls) {
  424. iconEl.addCls(iconCls);
  425. }
  426. }
  427. me.iconCls = iconCls;
  428. },
  429. <span id='Ext-menu-Item-method-setText'> /**
  430. </span> * Sets the {@link #text} of this item
  431. * @param {String} text The {@link #text}
  432. */
  433. setText: function(text) {
  434. var me = this,
  435. el = me.textEl || me.el;
  436. me.text = text;
  437. if (me.rendered) {
  438. el.update(text || '');
  439. // cannot just call layout on the component due to stretchmax
  440. me.ownerCt.updateLayout();
  441. }
  442. },
  443. getTipAttr: function(){
  444. return this.tooltipType == 'qtip' ? 'data-qtip' : 'title';
  445. },
  446. //private
  447. clearTip: function() {
  448. if (Ext.isObject(this.tooltip)) {
  449. Ext.tip.QuickTipManager.unregister(this.itemEl);
  450. }
  451. },
  452. <span id='Ext-menu-Item-method-setTooltip'> /**
  453. </span> * Sets the tooltip for this menu item.
  454. *
  455. * @param {String/Object} tooltip This may be:
  456. *
  457. * - **String** : A string to be used as innerHTML (html tags are accepted) to show in a tooltip
  458. * - **Object** : A configuration object for {@link Ext.tip.QuickTipManager#register}.
  459. *
  460. * @return {Ext.menu.Item} this
  461. */
  462. setTooltip: function(tooltip, initial) {
  463. var me = this;
  464. if (me.rendered) {
  465. if (!initial) {
  466. me.clearTip();
  467. }
  468. if (Ext.isObject(tooltip)) {
  469. Ext.tip.QuickTipManager.register(Ext.apply({
  470. target: me.itemEl.id
  471. },
  472. tooltip));
  473. me.tooltip = tooltip;
  474. } else {
  475. me.itemEl.dom.setAttribute(me.getTipAttr(), tooltip);
  476. }
  477. } else {
  478. me.tooltip = tooltip;
  479. }
  480. return me;
  481. }
  482. });
  483. </pre>
  484. </body>
  485. </html>