mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-25 15:00:58 +01:00
bfc1ccfdf1
Summary: man I sure hate Javascript I removed the ajax-edit and ajax-remove interactions, becuase they were prohibitively complex to get working given that the entire menu has to change too. Instead, the page just reloads. This works perfectly fine in practice. If we want to restore these in the future, we should have the server re-render the entire transaction group or something. I think very little is lost here, though. Test Plan: - Took all the actions. - Used existing dropdown menus. {F150196} Reviewers: chad, btrahan Reviewed By: btrahan Subscribers: epriestley Differential Revision: https://secure.phabricator.com/D8966
206 lines
4 KiB
JavaScript
206 lines
4 KiB
JavaScript
/**
|
|
* @provides phuix-dropdown-menu
|
|
* @requires javelin-install
|
|
* javelin-util
|
|
* javelin-dom
|
|
* javelin-vector
|
|
* javelin-stratcom
|
|
* @javelin
|
|
*/
|
|
|
|
|
|
/**
|
|
* Basic interaction for a dropdown menu.
|
|
*
|
|
* The menu is unaware of the content inside it, so it can not close itself
|
|
* when an item is selected. Callers must make a call to @{method:close} after
|
|
* an item is chosen in order to close the menu.
|
|
*/
|
|
JX.install('PHUIXDropdownMenu', {
|
|
|
|
construct : function(node) {
|
|
this._node = node;
|
|
|
|
JX.DOM.listen(
|
|
this._node,
|
|
'click',
|
|
null,
|
|
JX.bind(this, this._onclick));
|
|
|
|
JX.Stratcom.listen(
|
|
'mousedown',
|
|
null,
|
|
JX.bind(this, this._onanyclick));
|
|
|
|
JX.Stratcom.listen(
|
|
'resize',
|
|
null,
|
|
JX.bind(this, this._adjustposition));
|
|
|
|
JX.Stratcom.listen('phuix.dropdown.open', null, JX.bind(this, this.close));
|
|
|
|
JX.Stratcom.listen('keydown', null, JX.bind(this, this._onkey));
|
|
},
|
|
|
|
events: ['open'],
|
|
|
|
properties: {
|
|
width: null,
|
|
align: 'right',
|
|
offsetX: 0,
|
|
offsetY: 0
|
|
},
|
|
|
|
members: {
|
|
_node: null,
|
|
_menu: null,
|
|
_open: false,
|
|
_content: null,
|
|
|
|
setContent: function(content) {
|
|
JX.DOM.setContent(this._getMenuNode(), content);
|
|
return this;
|
|
},
|
|
|
|
open: function() {
|
|
if (this._open) {
|
|
return;
|
|
}
|
|
|
|
this.invoke('open');
|
|
JX.Stratcom.invoke('phuix.dropdown.open');
|
|
|
|
this._open = true;
|
|
this._show();
|
|
|
|
return this;
|
|
},
|
|
|
|
close: function() {
|
|
if (!this._open) {
|
|
return;
|
|
}
|
|
this._open = false;
|
|
this._hide();
|
|
|
|
return this;
|
|
},
|
|
|
|
_getMenuNode: function() {
|
|
if (!this._menu) {
|
|
var attrs = {
|
|
className: 'phuix-dropdown-menu',
|
|
role: 'button'
|
|
};
|
|
|
|
var menu = JX.$N('div', attrs);
|
|
|
|
this._menu = menu;
|
|
}
|
|
|
|
return this._menu;
|
|
},
|
|
|
|
_onclick : function(e) {
|
|
if (this._open) {
|
|
this.close();
|
|
} else {
|
|
this.open();
|
|
}
|
|
e.prevent();
|
|
},
|
|
|
|
_onanyclick : function(e) {
|
|
if (!this._open) {
|
|
return;
|
|
}
|
|
|
|
if (JX.Stratcom.pass(e)) {
|
|
return;
|
|
}
|
|
|
|
var t = e.getTarget();
|
|
while (t) {
|
|
if (t == this._menu || t == this._node) {
|
|
return;
|
|
}
|
|
t = t.parentNode;
|
|
}
|
|
|
|
this.close();
|
|
},
|
|
|
|
_show : function() {
|
|
document.body.appendChild(this._menu);
|
|
|
|
if (this.getWidth()) {
|
|
new JX.Vector(this.getWidth(), null).setDim(this._menu);
|
|
}
|
|
|
|
this._adjustposition();
|
|
|
|
JX.DOM.alterClass(this._node, 'phuix-dropdown-open', true);
|
|
|
|
this._node.setAttribute('aria-expanded', 'true');
|
|
|
|
// Try to highlight the first link in the menu for assistive technologies.
|
|
var links = JX.DOM.scry(this._menu, 'a');
|
|
if (links[0]) {
|
|
JX.DOM.focus(links[0]);
|
|
}
|
|
},
|
|
|
|
_hide : function() {
|
|
JX.DOM.remove(this._menu);
|
|
|
|
JX.DOM.alterClass(this._node, 'phuix-dropdown-open', false);
|
|
|
|
this._node.setAttribute('aria-expanded', 'false');
|
|
},
|
|
|
|
_adjustposition : function() {
|
|
if (!this._open) {
|
|
return;
|
|
}
|
|
|
|
var m = JX.Vector.getDim(this._menu);
|
|
|
|
var v = JX.$V(this._node);
|
|
var d = JX.Vector.getDim(this._node);
|
|
|
|
switch (this.getAlign()) {
|
|
case 'right':
|
|
v = v.add(d)
|
|
.add(JX.$V(-m.x, 0));
|
|
break;
|
|
default:
|
|
v = v.add(0, d.y);
|
|
break;
|
|
}
|
|
|
|
v = v.add(this.getOffsetX(), this.getOffsetY());
|
|
|
|
v.setPos(this._menu);
|
|
},
|
|
|
|
_onkey: function(e) {
|
|
// When the user presses escape with a menu open, close the menu and
|
|
// refocus the button which activates the menu. In particular, this makes
|
|
// popups more usable with assistive technologies.
|
|
|
|
if (!this._open) {
|
|
return;
|
|
}
|
|
|
|
if (e.getSpecialKey() != 'esc') {
|
|
return;
|
|
}
|
|
|
|
this.close();
|
|
JX.DOM.focus(this._node);
|
|
|
|
e.prevent();
|
|
}
|
|
|
|
}
|
|
});
|