menu.js 8.0 KB

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