forked from senchalabs/jsduck
/
HoverMenuButton.js
123 lines (107 loc) · 3.43 KB
/
HoverMenuButton.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* Toolbar button with menu that appears when hovered over.
*/
Ext.define('Docs.view.cls.HoverMenuButton', {
extend: 'Ext.toolbar.TextItem',
componentCls: "hover-menu-button",
/**
* @cfg {[String]} links
* Array of HTML anchor elements to be shown in menu.
*/
links: [],
statics: {
// Global list of all menus.
// So we can hide all other menus while showing a specific one.
menus: []
},
initComponent: function() {
this.addEvents(
/**
* @event click
* Fired when button clicked.
*/
"click"
);
// Append links count to button text
this.text += ' <span class="num">' + this.links.length + '</span>';
this.callParent(arguments);
},
onRender: function() {
this.callParent(arguments);
this.renderMenu();
this.getEl().on({
click: function() {
this.fireEvent("click");
},
mouseover: function() {
// hide other menus
Ext.Array.forEach(Docs.view.cls.HoverMenuButton.menus, function(menu) {
if (menu !== this.menu) {
menu.setStyle({display: "none"});
}
});
// stop pending menuhide process
clearTimeout(this.hideTimeout);
// position menu right below button and show it
var p = this.getEl().getXY();
this.menu.setStyle({
left: (p[0] - 10)+"px",
top: (p[1]+23)+"px",
display: "block"
});
},
mouseout: this.deferHideMenu,
scope: this
});
this.menu.on({
mouseover: function() {
clearTimeout(this.hideTimeout);
},
mouseout: this.deferHideMenu,
scope: this
});
},
onDestroy: function() {
// clean up DOM
this.menu.remove();
// remove from global menu list
Ext.Array.remove(Docs.view.cls.HoverMenuButton.menus, this.menu);
this.callParent(arguments);
},
renderMenu: function() {
this.menu = Ext.get(Ext.core.DomHelper.append(document.body, {
html: this.renderMenuHtml(),
cls: 'hover-menu-menu'
}));
this.menu.addListener('click', function() {
this.menu.setStyle({display: "none"});
}, this);
Docs.view.cls.HoverMenuButton.menus.push(this.menu);
},
renderMenuHtml: function() {
// divide links into columns with at most 25 links in one column
var columns = [];
for (var i=0; i<this.links.length; i+=25) {
columns.push(this.links.slice(i, i+25));
}
var tpl = new Ext.XTemplate(
'<table>',
'<tr>',
'<tpl for="columns">',
'<td>',
'<tpl for=".">',
'{.}',
'</tpl>',
'</td>',
'</tpl>',
'</tr>',
'</table>'
);
return tpl.apply({columns: columns});
},
deferHideMenu: function() {
this.hideTimeout = Ext.Function.defer(function() {
this.menu.setStyle({display: "none"});
}, 200, this);
}
});