menu.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. ///import core
  2. ///import uicore
  3. ///import ui\popup.js
  4. ///import ui\stateful.js
  5. (function () {
  6. var utils = baidu.editor.utils,
  7. domUtils = baidu.editor.dom.domUtils,
  8. uiUtils = baidu.editor.ui.uiUtils,
  9. UIBase = baidu.editor.ui.UIBase,
  10. Popup = baidu.editor.ui.Popup,
  11. Stateful = baidu.editor.ui.Stateful,
  12. CellAlignPicker = baidu.editor.ui.CellAlignPicker,
  13. Menu = baidu.editor.ui.Menu = function (options) {
  14. this.initOptions(options);
  15. this.initMenu();
  16. };
  17. var menuSeparator = {
  18. renderHtml:function () {
  19. return '<div class="edui-menuitem edui-menuseparator"><div class="edui-menuseparator-inner"></div></div>';
  20. },
  21. postRender:function () {
  22. },
  23. queryAutoHide:function () {
  24. return true;
  25. }
  26. };
  27. Menu.prototype = {
  28. items:null,
  29. uiName:'menu',
  30. initMenu:function () {
  31. this.items = this.items || [];
  32. this.initPopup();
  33. this.initItems();
  34. },
  35. initItems:function () {
  36. for (var i = 0; i < this.items.length; i++) {
  37. var item = this.items[i];
  38. if (item == '-') {
  39. this.items[i] = this.getSeparator();
  40. } else if (!(item instanceof MenuItem)) {
  41. item.editor = this.editor;
  42. item.theme = this.editor.options.theme;
  43. this.items[i] = this.createItem(item);
  44. }
  45. }
  46. },
  47. getSeparator:function () {
  48. return menuSeparator;
  49. },
  50. createItem:function (item) {
  51. //新增一个参数menu, 该参数存储了menuItem所对应的menu引用
  52. item.menu = this;
  53. return new MenuItem(item);
  54. },
  55. _Popup_getContentHtmlTpl:Popup.prototype.getContentHtmlTpl,
  56. getContentHtmlTpl:function () {
  57. if (this.items.length == 0) {
  58. return this._Popup_getContentHtmlTpl();
  59. }
  60. var buff = [];
  61. for (var i = 0; i < this.items.length; i++) {
  62. var item = this.items[i];
  63. buff[i] = item.renderHtml();
  64. }
  65. return ('<div class="%%-body">' + buff.join('') + '</div>');
  66. },
  67. _Popup_postRender:Popup.prototype.postRender,
  68. postRender:function () {
  69. var me = this;
  70. for (var i = 0; i < this.items.length; i++) {
  71. var item = this.items[i];
  72. item.ownerMenu = this;
  73. item.postRender();
  74. }
  75. domUtils.on(this.getDom(), 'mouseover', function (evt) {
  76. evt = evt || event;
  77. var rel = evt.relatedTarget || evt.fromElement;
  78. var el = me.getDom();
  79. if (!uiUtils.contains(el, rel) && el !== rel) {
  80. me.fireEvent('over');
  81. }
  82. });
  83. this._Popup_postRender();
  84. },
  85. queryAutoHide:function (el) {
  86. if (el) {
  87. if (uiUtils.contains(this.getDom(), el)) {
  88. return false;
  89. }
  90. for (var i = 0; i < this.items.length; i++) {
  91. var item = this.items[i];
  92. if (item.queryAutoHide(el) === false) {
  93. return false;
  94. }
  95. }
  96. }
  97. },
  98. clearItems:function () {
  99. for (var i = 0; i < this.items.length; i++) {
  100. var item = this.items[i];
  101. clearTimeout(item._showingTimer);
  102. clearTimeout(item._closingTimer);
  103. if (item.subMenu) {
  104. item.subMenu.destroy();
  105. }
  106. }
  107. this.items = [];
  108. },
  109. destroy:function () {
  110. if (this.getDom()) {
  111. domUtils.remove(this.getDom());
  112. }
  113. this.clearItems();
  114. },
  115. dispose:function () {
  116. this.destroy();
  117. }
  118. };
  119. utils.inherits(Menu, Popup);
  120. /**
  121. * @update 2013/04/03 hancong03 新增一个参数menu, 该参数存储了menuItem所对应的menu引用
  122. * @type {Function}
  123. */
  124. var MenuItem = baidu.editor.ui.MenuItem = function (options) {
  125. this.initOptions(options);
  126. this.initUIBase();
  127. this.Stateful_init();
  128. if (this.subMenu && !(this.subMenu instanceof Menu)) {
  129. if (options.className && options.className.indexOf("aligntd") != -1) {
  130. var me = this;
  131. //获取单元格对齐初始状态
  132. this.subMenu.selected = this.editor.queryCommandValue( 'cellalignment' );
  133. this.subMenu = new Popup({
  134. content:new CellAlignPicker(this.subMenu),
  135. parentMenu:me,
  136. editor:me.editor,
  137. destroy:function () {
  138. if (this.getDom()) {
  139. domUtils.remove(this.getDom());
  140. }
  141. }
  142. });
  143. this.subMenu.addListener("postRenderAfter", function () {
  144. domUtils.on(this.getDom(), "mouseover", function () {
  145. me.addState('opened');
  146. });
  147. });
  148. } else {
  149. this.subMenu = new Menu(this.subMenu);
  150. }
  151. }
  152. };
  153. MenuItem.prototype = {
  154. label:'',
  155. subMenu:null,
  156. ownerMenu:null,
  157. uiName:'menuitem',
  158. alwalysHoverable:true,
  159. getHtmlTpl:function () {
  160. return '<div id="##" class="%%" stateful onclick="$$._onClick(event, this);">' +
  161. '<div class="%%-body">' +
  162. this.renderLabelHtml() +
  163. '</div>' +
  164. '</div>';
  165. },
  166. postRender:function () {
  167. var me = this;
  168. this.addListener('over', function () {
  169. me.ownerMenu.fireEvent('submenuover', me);
  170. if (me.subMenu) {
  171. me.delayShowSubMenu();
  172. }
  173. });
  174. if (this.subMenu) {
  175. this.getDom().className += ' edui-hassubmenu';
  176. this.subMenu.render();
  177. this.addListener('out', function () {
  178. me.delayHideSubMenu();
  179. });
  180. this.subMenu.addListener('over', function () {
  181. clearTimeout(me._closingTimer);
  182. me._closingTimer = null;
  183. me.addState('opened');
  184. });
  185. this.ownerMenu.addListener('hide', function () {
  186. me.hideSubMenu();
  187. });
  188. this.ownerMenu.addListener('submenuover', function (t, subMenu) {
  189. if (subMenu !== me) {
  190. me.delayHideSubMenu();
  191. }
  192. });
  193. this.subMenu._bakQueryAutoHide = this.subMenu.queryAutoHide;
  194. this.subMenu.queryAutoHide = function (el) {
  195. if (el && uiUtils.contains(me.getDom(), el)) {
  196. return false;
  197. }
  198. return this._bakQueryAutoHide(el);
  199. };
  200. }
  201. this.getDom().style.tabIndex = '-1';
  202. uiUtils.makeUnselectable(this.getDom());
  203. this.Stateful_postRender();
  204. },
  205. delayShowSubMenu:function () {
  206. var me = this;
  207. if (!me.isDisabled()) {
  208. me.addState('opened');
  209. clearTimeout(me._showingTimer);
  210. clearTimeout(me._closingTimer);
  211. me._closingTimer = null;
  212. me._showingTimer = setTimeout(function () {
  213. me.showSubMenu();
  214. }, 250);
  215. }
  216. },
  217. delayHideSubMenu:function () {
  218. var me = this;
  219. if (!me.isDisabled()) {
  220. me.removeState('opened');
  221. clearTimeout(me._showingTimer);
  222. if (!me._closingTimer) {
  223. me._closingTimer = setTimeout(function () {
  224. if (!me.hasState('opened')) {
  225. me.hideSubMenu();
  226. }
  227. me._closingTimer = null;
  228. }, 400);
  229. }
  230. }
  231. },
  232. renderLabelHtml:function () {
  233. return '<div class="edui-arrow"></div>' +
  234. '<div class="edui-box edui-icon"></div>' +
  235. '<div class="edui-box edui-label %%-label">' + (this.label || '') + '</div>';
  236. },
  237. getStateDom:function () {
  238. return this.getDom();
  239. },
  240. queryAutoHide:function (el) {
  241. if (this.subMenu && this.hasState('opened')) {
  242. return this.subMenu.queryAutoHide(el);
  243. }
  244. },
  245. _onClick:function (event, this_) {
  246. if (this.hasState('disabled')) return;
  247. if (this.fireEvent('click', event, this_) !== false) {
  248. if (this.subMenu) {
  249. this.showSubMenu();
  250. } else {
  251. Popup.postHide(event);
  252. }
  253. }
  254. },
  255. showSubMenu:function () {
  256. var rect = uiUtils.getClientRect(this.getDom());
  257. rect.right -= 5;
  258. rect.left += 2;
  259. rect.width -= 7;
  260. rect.top -= 4;
  261. rect.bottom += 4;
  262. rect.height += 8;
  263. this.subMenu.showAnchorRect(rect, true, true);
  264. },
  265. hideSubMenu:function () {
  266. this.subMenu.hide();
  267. }
  268. };
  269. utils.inherits(MenuItem, UIBase);
  270. utils.extend(MenuItem.prototype, Stateful, true);
  271. })();