menu.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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. return new MenuItem(item);
  52. },
  53. _Popup_getContentHtmlTpl:Popup.prototype.getContentHtmlTpl,
  54. getContentHtmlTpl:function () {
  55. if (this.items.length == 0) {
  56. return this._Popup_getContentHtmlTpl();
  57. }
  58. var buff = [];
  59. for (var i = 0; i < this.items.length; i++) {
  60. var item = this.items[i];
  61. buff[i] = item.renderHtml();
  62. }
  63. return ('<div class="%%-body">' + buff.join('') + '</div>');
  64. },
  65. _Popup_postRender:Popup.prototype.postRender,
  66. postRender:function () {
  67. var me = this;
  68. for (var i = 0; i < this.items.length; i++) {
  69. var item = this.items[i];
  70. item.ownerMenu = this;
  71. item.postRender();
  72. }
  73. domUtils.on(this.getDom(), 'mouseover', function (evt) {
  74. evt = evt || event;
  75. var rel = evt.relatedTarget || evt.fromElement;
  76. var el = me.getDom();
  77. if (!uiUtils.contains(el, rel) && el !== rel) {
  78. me.fireEvent('over');
  79. }
  80. });
  81. this._Popup_postRender();
  82. },
  83. queryAutoHide:function (el) {
  84. if (el) {
  85. if (uiUtils.contains(this.getDom(), el)) {
  86. return false;
  87. }
  88. for (var i = 0; i < this.items.length; i++) {
  89. var item = this.items[i];
  90. if (item.queryAutoHide(el) === false) {
  91. return false;
  92. }
  93. }
  94. }
  95. },
  96. clearItems:function () {
  97. for (var i = 0; i < this.items.length; i++) {
  98. var item = this.items[i];
  99. clearTimeout(item._showingTimer);
  100. clearTimeout(item._closingTimer);
  101. if (item.subMenu) {
  102. item.subMenu.destroy();
  103. }
  104. }
  105. this.items = [];
  106. },
  107. destroy:function () {
  108. if (this.getDom()) {
  109. domUtils.remove(this.getDom());
  110. }
  111. this.clearItems();
  112. },
  113. dispose:function () {
  114. this.destroy();
  115. }
  116. };
  117. utils.inherits(Menu, Popup);
  118. var MenuItem = baidu.editor.ui.MenuItem = function (options) {
  119. this.initOptions(options);
  120. this.initUIBase();
  121. this.Stateful_init();
  122. if (this.subMenu && !(this.subMenu instanceof Menu)) {
  123. if (options.className && options.className.indexOf("aligntd") != -1) {
  124. var me = this;
  125. this.subMenu = new Popup({
  126. content:new CellAlignPicker(this.subMenu),
  127. parentMenu:me,
  128. editor:me.editor,
  129. destroy:function () {
  130. if (this.getDom()) {
  131. domUtils.remove(this.getDom());
  132. }
  133. }
  134. });
  135. this.subMenu.addListener("postRenderAfter", function () {
  136. domUtils.on(this.getDom(), "mouseover", function () {
  137. me.addState('opened');
  138. });
  139. });
  140. } else {
  141. this.subMenu = new Menu(this.subMenu);
  142. }
  143. }
  144. };
  145. MenuItem.prototype = {
  146. label:'',
  147. subMenu:null,
  148. ownerMenu:null,
  149. uiName:'menuitem',
  150. alwalysHoverable:true,
  151. getHtmlTpl:function () {
  152. return '<div id="##" class="%%" stateful onclick="$$._onClick(event, this);">' +
  153. '<div class="%%-body">' +
  154. this.renderLabelHtml() +
  155. '</div>' +
  156. '</div>';
  157. },
  158. postRender:function () {
  159. var me = this;
  160. this.addListener('over', function () {
  161. me.ownerMenu.fireEvent('submenuover', me);
  162. if (me.subMenu) {
  163. me.delayShowSubMenu();
  164. }
  165. });
  166. if (this.subMenu) {
  167. this.getDom().className += ' edui-hassubmenu';
  168. this.subMenu.render();
  169. this.addListener('out', function () {
  170. me.delayHideSubMenu();
  171. });
  172. this.subMenu.addListener('over', function () {
  173. clearTimeout(me._closingTimer);
  174. me._closingTimer = null;
  175. me.addState('opened');
  176. });
  177. this.ownerMenu.addListener('hide', function () {
  178. me.hideSubMenu();
  179. });
  180. this.ownerMenu.addListener('submenuover', function (t, subMenu) {
  181. if (subMenu !== me) {
  182. me.delayHideSubMenu();
  183. }
  184. });
  185. this.subMenu._bakQueryAutoHide = this.subMenu.queryAutoHide;
  186. this.subMenu.queryAutoHide = function (el) {
  187. if (el && uiUtils.contains(me.getDom(), el)) {
  188. return false;
  189. }
  190. return this._bakQueryAutoHide(el);
  191. };
  192. }
  193. this.getDom().style.tabIndex = '-1';
  194. uiUtils.makeUnselectable(this.getDom());
  195. this.Stateful_postRender();
  196. },
  197. delayShowSubMenu:function () {
  198. var me = this;
  199. if (!me.isDisabled()) {
  200. me.addState('opened');
  201. clearTimeout(me._showingTimer);
  202. clearTimeout(me._closingTimer);
  203. me._closingTimer = null;
  204. me._showingTimer = setTimeout(function () {
  205. me.showSubMenu();
  206. }, 250);
  207. }
  208. },
  209. delayHideSubMenu:function () {
  210. var me = this;
  211. if (!me.isDisabled()) {
  212. me.removeState('opened');
  213. clearTimeout(me._showingTimer);
  214. if (!me._closingTimer) {
  215. me._closingTimer = setTimeout(function () {
  216. if (!me.hasState('opened')) {
  217. me.hideSubMenu();
  218. }
  219. me._closingTimer = null;
  220. }, 400);
  221. }
  222. }
  223. },
  224. renderLabelHtml:function () {
  225. return '<div class="edui-arrow"></div>' +
  226. '<div class="edui-box edui-icon"></div>' +
  227. '<div class="edui-box edui-label %%-label">' + (this.label || '') + '</div>';
  228. },
  229. getStateDom:function () {
  230. return this.getDom();
  231. },
  232. queryAutoHide:function (el) {
  233. if (this.subMenu && this.hasState('opened')) {
  234. return this.subMenu.queryAutoHide(el);
  235. }
  236. },
  237. _onClick:function (event, this_) {
  238. if (this.hasState('disabled')) return;
  239. if (this.fireEvent('click', event, this_) !== false) {
  240. if (this.subMenu) {
  241. this.showSubMenu();
  242. } else {
  243. Popup.postHide(event);
  244. }
  245. }
  246. },
  247. showSubMenu:function () {
  248. var rect = uiUtils.getClientRect(this.getDom());
  249. rect.right -= 5;
  250. rect.left += 2;
  251. rect.width -= 7;
  252. rect.top -= 4;
  253. rect.bottom += 4;
  254. rect.height += 8;
  255. this.subMenu.showAnchorRect(rect, true, true);
  256. },
  257. hideSubMenu:function () {
  258. this.subMenu.hide();
  259. }
  260. };
  261. utils.inherits(MenuItem, UIBase);
  262. utils.extend(MenuItem.prototype, Stateful, true);
  263. })();