mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-27 07:50:57 +01:00
Fold task-relationship actions into an accordion dropdown
Summary: Ref T11179. Alternative to D16152. I think this turned out a bit better than the other one did. Currently, we render two copies of the menu (one for mobile, one for desktop). A big chunk of this is sharing the nodes instead: when you open the mobile dropdown menu, it steals the nodes from the document. When you close it, it puts them back. Magic! Sneaky! Test Plan: {F1695499} {F1695500} Reviewers: chad Reviewed By: chad Maniphest Tasks: T11179 Differential Revision: https://secure.phabricator.com/D16157
This commit is contained in:
parent
3198aa1659
commit
56d3197fe0
13 changed files with 318 additions and 58 deletions
|
@ -7,8 +7,8 @@
|
|||
*/
|
||||
return array(
|
||||
'names' => array(
|
||||
'core.pkg.css' => 'b9e2e1e5',
|
||||
'core.pkg.js' => '80f86a0a',
|
||||
'core.pkg.css' => 'f577cd20',
|
||||
'core.pkg.js' => 'f2139810',
|
||||
'darkconsole.pkg.js' => 'e7393ebb',
|
||||
'differential.pkg.css' => 'b3eea3f5',
|
||||
'differential.pkg.js' => '4b7d8f19',
|
||||
|
@ -124,7 +124,7 @@ return array(
|
|||
'rsrc/css/phui/phui-badge.css' => '3baef8db',
|
||||
'rsrc/css/phui/phui-big-info-view.css' => 'bd903741',
|
||||
'rsrc/css/phui/phui-box.css' => '5c8387cf',
|
||||
'rsrc/css/phui/phui-button.css' => 'a64a8de6',
|
||||
'rsrc/css/phui/phui-button.css' => 'e266e0bc',
|
||||
'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
|
||||
'rsrc/css/phui/phui-crumbs-view.css' => '6b813619',
|
||||
'rsrc/css/phui/phui-curtain-view.css' => '7148ae25',
|
||||
|
@ -516,14 +516,15 @@ return array(
|
|||
'rsrc/js/core/behavior-watch-anchor.js' => '9f36c42d',
|
||||
'rsrc/js/core/behavior-workflow.js' => '0a3f3021',
|
||||
'rsrc/js/core/phtize.js' => 'd254d646',
|
||||
'rsrc/js/phui/behavior-phui-dropdown-menu.js' => '54733475',
|
||||
'rsrc/js/phui/behavior-phui-dropdown-menu.js' => '1aa4c968',
|
||||
'rsrc/js/phui/behavior-phui-file-upload.js' => 'b003d4fb',
|
||||
'rsrc/js/phui/behavior-phui-object-box-tabs.js' => '2bfa2836',
|
||||
'rsrc/js/phui/behavior-phui-profile-menu.js' => '12884df9',
|
||||
'rsrc/js/phui/behavior-phui-submenu.js' => 'a6f7a73b',
|
||||
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
|
||||
'rsrc/js/phuix/PHUIXActionView.js' => '8cf6d262',
|
||||
'rsrc/js/phuix/PHUIXAutocomplete.js' => '9196fb06',
|
||||
'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'bd4c8dca',
|
||||
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '82e270da',
|
||||
'rsrc/js/phuix/PHUIXFormControl.js' => 'e15869a8',
|
||||
'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b',
|
||||
),
|
||||
|
@ -669,11 +670,12 @@ return array(
|
|||
'javelin-behavior-phabricator-watch-anchor' => '9f36c42d',
|
||||
'javelin-behavior-pholio-mock-edit' => 'bee502c8',
|
||||
'javelin-behavior-pholio-mock-view' => 'fbe497e7',
|
||||
'javelin-behavior-phui-dropdown-menu' => '54733475',
|
||||
'javelin-behavior-phui-dropdown-menu' => '1aa4c968',
|
||||
'javelin-behavior-phui-file-upload' => 'b003d4fb',
|
||||
'javelin-behavior-phui-hovercards' => 'bcaccd64',
|
||||
'javelin-behavior-phui-object-box-tabs' => '2bfa2836',
|
||||
'javelin-behavior-phui-profile-menu' => '12884df9',
|
||||
'javelin-behavior-phui-submenu' => 'a6f7a73b',
|
||||
'javelin-behavior-policy-control' => 'd0c516d5',
|
||||
'javelin-behavior-policy-rule-editor' => '5e9f347c',
|
||||
'javelin-behavior-project-boards' => '14a1faae',
|
||||
|
@ -822,7 +824,7 @@ return array(
|
|||
'phui-badge-view-css' => '3baef8db',
|
||||
'phui-big-info-view-css' => 'bd903741',
|
||||
'phui-box-css' => '5c8387cf',
|
||||
'phui-button-css' => 'a64a8de6',
|
||||
'phui-button-css' => 'e266e0bc',
|
||||
'phui-calendar-css' => 'ccabe893',
|
||||
'phui-calendar-day-css' => 'd1cf6f93',
|
||||
'phui-calendar-list-css' => '56e6381a',
|
||||
|
@ -870,7 +872,7 @@ return array(
|
|||
'phuix-action-list-view' => 'b5c256b8',
|
||||
'phuix-action-view' => '8cf6d262',
|
||||
'phuix-autocomplete' => '9196fb06',
|
||||
'phuix-dropdown-menu' => 'bd4c8dca',
|
||||
'phuix-dropdown-menu' => '82e270da',
|
||||
'phuix-form-control-view' => 'e15869a8',
|
||||
'phuix-icon-view' => 'bff6884b',
|
||||
'policy-css' => '957ea14c',
|
||||
|
@ -1024,6 +1026,12 @@ return array(
|
|||
'javelin-workflow',
|
||||
'javelin-workboard-controller',
|
||||
),
|
||||
'1aa4c968' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
'phuix-dropdown-menu',
|
||||
),
|
||||
'1ad0a787' => array(
|
||||
'javelin-install',
|
||||
'javelin-reactor',
|
||||
|
@ -1275,12 +1283,6 @@ return array(
|
|||
'javelin-leader',
|
||||
'javelin-json',
|
||||
),
|
||||
54733475 => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
'phuix-dropdown-menu',
|
||||
),
|
||||
'54b612ba' => array(
|
||||
'javelin-color',
|
||||
'javelin-install',
|
||||
|
@ -1529,6 +1531,13 @@ return array(
|
|||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
),
|
||||
'82e270da' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
),
|
||||
'834a1173' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-scrollbar',
|
||||
|
@ -1693,6 +1702,11 @@ return array(
|
|||
'javelin-uri',
|
||||
'phabricator-notification',
|
||||
),
|
||||
'a6f7a73b' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
),
|
||||
'a80d0378' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
|
@ -1846,13 +1860,6 @@ return array(
|
|||
'javelin-vector',
|
||||
'phui-hovercard',
|
||||
),
|
||||
'bd4c8dca' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
'javelin-dom',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
),
|
||||
'bdaf4d04' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
|
|
|
@ -474,8 +474,11 @@ abstract class PhabricatorController extends AphrontController {
|
|||
public function newCurtainView($object) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$action_id = celerity_generate_unique_node_id();
|
||||
|
||||
$action_list = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
->setViewer($viewer)
|
||||
->setID($action_id);
|
||||
|
||||
// NOTE: Applications (objects of class PhabricatorApplication) can't
|
||||
// currently be set here, although they don't need any of the extensions
|
||||
|
|
|
@ -166,15 +166,6 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Merge Duplicates In'))
|
||||
->setHref("/search/attach/{$phid}/TASK/merge/")
|
||||
->setWorkflow(true)
|
||||
->setIcon('fa-compress')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
|
||||
$edit_config = $edit_engine->loadDefaultEditConfiguration();
|
||||
$can_create = (bool)$edit_config;
|
||||
|
||||
|
@ -195,23 +186,36 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
$edit_uri = $this->getApplicationURI($edit_uri);
|
||||
}
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Create Subtask'))
|
||||
->setHref($edit_uri)
|
||||
->setIcon('fa-level-down')
|
||||
->setDisabled(!$can_create)
|
||||
->setWorkflow(!$can_create));
|
||||
$task_submenu = array();
|
||||
|
||||
$task_submenu[] = id(new PhabricatorActionView())
|
||||
->setName(pht('Create Subtask'))
|
||||
->setHref($edit_uri)
|
||||
->setIcon('fa-level-down')
|
||||
->setDisabled(!$can_create)
|
||||
->setWorkflow(!$can_create);
|
||||
|
||||
$task_submenu[] = id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Blocking Tasks'))
|
||||
->setHref("/search/attach/{$phid}/TASK/blocks/")
|
||||
->setWorkflow(true)
|
||||
->setIcon('fa-link')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true);
|
||||
|
||||
$task_submenu[] = id(new PhabricatorActionView())
|
||||
->setName(pht('Merge Duplicates In'))
|
||||
->setHref("/search/attach/{$phid}/TASK/merge/")
|
||||
->setWorkflow(true)
|
||||
->setIcon('fa-compress')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Blocking Tasks'))
|
||||
->setHref("/search/attach/{$phid}/TASK/blocks/")
|
||||
->setWorkflow(true)
|
||||
->setIcon('fa-link')
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
|
||||
->setName(pht('Edit Related Tasks...'))
|
||||
->setIcon('fa-anchor')
|
||||
->setSubmenu($task_submenu));
|
||||
|
||||
$owner_phid = $task->getOwnerPHID();
|
||||
$author_phid = $task->getAuthorPHID();
|
||||
|
|
|
@ -21,6 +21,10 @@ final class PhabricatorActionListView extends AphrontView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getID() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
|
@ -44,13 +48,20 @@ final class PhabricatorActionListView extends AphrontView {
|
|||
|
||||
require_celerity_resource('phabricator-action-list-view-css');
|
||||
|
||||
$items = array();
|
||||
foreach ($actions as $action) {
|
||||
foreach ($action->getItems() as $item) {
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return phutil_tag(
|
||||
'ul',
|
||||
array(
|
||||
'class' => 'phabricator-action-list-view',
|
||||
'id' => $this->id,
|
||||
),
|
||||
$actions);
|
||||
$items);
|
||||
}
|
||||
|
||||
public function getDropdownMenuMetadata() {
|
||||
|
|
|
@ -14,6 +14,10 @@ final class PhabricatorActionView extends AphrontView {
|
|||
private $metadata;
|
||||
private $selected;
|
||||
private $openInNewWindow;
|
||||
private $submenu = array();
|
||||
private $hidden;
|
||||
private $depth;
|
||||
private $id;
|
||||
|
||||
public function setSelected($selected) {
|
||||
$this->selected = $selected;
|
||||
|
@ -95,7 +99,60 @@ final class PhabricatorActionView extends AphrontView {
|
|||
return $this->openInNewWindow;
|
||||
}
|
||||
|
||||
public function getID() {
|
||||
if (!$this->id) {
|
||||
$this->id = celerity_generate_unique_node_id();
|
||||
}
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setSubmenu(array $submenu) {
|
||||
$this->submenu = $submenu;
|
||||
|
||||
if (!$this->getHref()) {
|
||||
$this->setHref('#');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getItems($depth = 0) {
|
||||
$items = array();
|
||||
|
||||
$items[] = $this;
|
||||
foreach ($this->submenu as $action) {
|
||||
foreach ($action->getItems($depth + 1) as $item) {
|
||||
$item
|
||||
->setHidden(true)
|
||||
->setDepth($depth + 1);
|
||||
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function setHidden($hidden) {
|
||||
$this->hidden = $hidden;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getHidden() {
|
||||
return $this->hidden;
|
||||
}
|
||||
|
||||
public function setDepth($depth) {
|
||||
$this->depth = $depth;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDepth() {
|
||||
return $this->depth;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$caret_id = celerity_generate_unique_node_id();
|
||||
|
||||
$icon = null;
|
||||
if ($this->icon) {
|
||||
|
@ -155,6 +212,18 @@ final class PhabricatorActionView extends AphrontView {
|
|||
$target = null;
|
||||
}
|
||||
|
||||
if ($this->submenu) {
|
||||
$caret = javelin_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'caret-right',
|
||||
'id' => $caret_id,
|
||||
),
|
||||
'');
|
||||
} else {
|
||||
$caret = null;
|
||||
}
|
||||
|
||||
$item = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
|
@ -164,7 +233,7 @@ final class PhabricatorActionView extends AphrontView {
|
|||
'sigil' => $sigils,
|
||||
'meta' => $this->metadata,
|
||||
),
|
||||
array($icon, $this->name));
|
||||
array($icon, $this->name, $caret));
|
||||
}
|
||||
} else {
|
||||
$item = phutil_tag(
|
||||
|
@ -190,10 +259,47 @@ final class PhabricatorActionView extends AphrontView {
|
|||
$classes[] = 'phabricator-action-view-selected';
|
||||
}
|
||||
|
||||
return phutil_tag(
|
||||
if ($this->submenu) {
|
||||
$classes[] = 'phabricator-action-view-submenu';
|
||||
}
|
||||
|
||||
$style = array();
|
||||
|
||||
if ($this->hidden) {
|
||||
$style[] = 'display: none;';
|
||||
}
|
||||
|
||||
if ($this->depth) {
|
||||
$indent = ($this->depth * 16);
|
||||
$style[] = "margin-left: {$indent}px;";
|
||||
}
|
||||
|
||||
$sigil = null;
|
||||
$meta = null;
|
||||
|
||||
if ($this->submenu) {
|
||||
Javelin::initBehavior('phui-submenu');
|
||||
$sigil = 'phui-submenu';
|
||||
|
||||
$item_ids = array();
|
||||
foreach ($this->submenu as $subitem) {
|
||||
$item_ids[] = $subitem->getID();
|
||||
}
|
||||
|
||||
$meta = array(
|
||||
'itemIDs' => $item_ids,
|
||||
'caretID' => $caret_id,
|
||||
);
|
||||
}
|
||||
|
||||
return javelin_tag(
|
||||
'li',
|
||||
array(
|
||||
'id' => $this->getID(),
|
||||
'class' => implode(' ', $classes),
|
||||
'style' => implode(' ', $style),
|
||||
'sigil' => $sigil,
|
||||
'meta' => $meta,
|
||||
),
|
||||
$item);
|
||||
}
|
||||
|
|
|
@ -110,6 +110,18 @@ final class PHUIButtonView extends AphrontTagView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setDropdownMenuID($id) {
|
||||
Javelin::initBehavior('phui-dropdown-menu');
|
||||
|
||||
$this->addSigil('phui-dropdown-menu');
|
||||
$this->setMetadata(
|
||||
array(
|
||||
'menuID' => $id,
|
||||
));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getTagAttributes() {
|
||||
|
||||
require_celerity_resource('phui-button-css');
|
||||
|
|
|
@ -24,6 +24,7 @@ final class PHUIHeaderView extends AphrontTagView {
|
|||
private $badges = array();
|
||||
private $href;
|
||||
private $actionList;
|
||||
private $actionListID;
|
||||
|
||||
public function setHeader($header) {
|
||||
$this->header = $header;
|
||||
|
@ -90,6 +91,11 @@ final class PHUIHeaderView extends AphrontTagView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setActionListID($action_list_id) {
|
||||
$this->actionListID = $action_list_id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPolicyObject(PhabricatorPolicyInterface $object) {
|
||||
$this->policyObject = $object;
|
||||
return $this;
|
||||
|
@ -189,14 +195,20 @@ final class PHUIHeaderView extends AphrontTagView {
|
|||
|
||||
protected function getTagContent() {
|
||||
|
||||
if ($this->actionList) {
|
||||
if ($this->actionList || $this->actionListID) {
|
||||
$action_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('Actions'))
|
||||
->setHref('#')
|
||||
->setIcon('fa-bars')
|
||||
->addClass('phui-mobile-menu')
|
||||
->setDropdownMenu($this->actionList);
|
||||
->addClass('phui-mobile-menu');
|
||||
|
||||
if ($this->actionList) {
|
||||
$action_button->setDropdownMenu($this->actionList);
|
||||
} else if ($this->actionListID) {
|
||||
$action_button->setDropdownMenuID($this->actionListID);
|
||||
}
|
||||
|
||||
$this->addActionLink($action_button);
|
||||
}
|
||||
|
||||
|
|
|
@ -327,9 +327,7 @@ final class PHUITimelineEventView extends AphrontView {
|
|||
'sigil' => $sigil,
|
||||
'aria-haspopup' => 'true',
|
||||
'aria-expanded' => 'false',
|
||||
'meta' => array(
|
||||
'items' => hsprintf('%s', $action_list),
|
||||
),
|
||||
'meta' => $action_list->getDropdownMenuMetadata(),
|
||||
),
|
||||
array(
|
||||
$aural,
|
||||
|
|
|
@ -114,7 +114,7 @@ final class PHUITwoColumnView extends AphrontTagView {
|
|||
$curtain = $this->getCurtain();
|
||||
if ($curtain) {
|
||||
$action_list = $curtain->getActionList();
|
||||
$this->header->setActionList($action_list);
|
||||
$this->header->setActionListID($action_list->getID());
|
||||
}
|
||||
|
||||
$header = phutil_tag_div(
|
||||
|
|
|
@ -264,6 +264,42 @@ a.policy-control .caret {
|
|||
border-top-color: #000;
|
||||
}
|
||||
|
||||
.phabricator-action-view-submenu .caret-right {
|
||||
float: right;
|
||||
margin-top: 4px;
|
||||
margin-right: 6px;
|
||||
border-left-color: {$lightgreytext};
|
||||
}
|
||||
|
||||
.phabricator-action-view-submenu .caret {
|
||||
float: right;
|
||||
margin-top: 5px;
|
||||
margin-right: 4px;
|
||||
border-top: 7px solid {$lightgreytext};
|
||||
}
|
||||
|
||||
.phabricator-action-view-submenu.phui-submenu-open {
|
||||
background: {$greybackground};
|
||||
}
|
||||
|
||||
.phui-submenu-animate {
|
||||
animation: phui-submenu-summon 0.25s;
|
||||
}
|
||||
|
||||
@keyframes phui-submenu-summon {
|
||||
0% {
|
||||
color: {$lightgreytext};
|
||||
margin-left: 0;
|
||||
transform: rotate(12deg);
|
||||
}
|
||||
60% {
|
||||
margin-left: 24px;
|
||||
transform: rotate(-5deg);
|
||||
margin-top: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Icons */
|
||||
.button.has-icon {
|
||||
position: relative;
|
||||
|
|
|
@ -16,17 +16,42 @@ JX.behavior('phui-dropdown-menu', function() {
|
|||
|
||||
e.kill();
|
||||
|
||||
var list = JX.$H(data.items).getFragment().firstChild;
|
||||
var list;
|
||||
var placeholder;
|
||||
if (data.items) {
|
||||
list = JX.$H(data.items).getFragment().firstChild;
|
||||
} else {
|
||||
list = JX.$(data.menuID);
|
||||
placeholder = JX.$N('span');
|
||||
}
|
||||
|
||||
var icon = e.getNode('phui-dropdown-menu');
|
||||
data.menu = new JX.PHUIXDropdownMenu(icon);
|
||||
data.menu.setContent(list);
|
||||
|
||||
data.menu.listen('open', function() {
|
||||
if (placeholder) {
|
||||
JX.DOM.replace(list, placeholder);
|
||||
}
|
||||
data.menu.setContent(list);
|
||||
});
|
||||
|
||||
data.menu.listen('close', function() {
|
||||
if (placeholder) {
|
||||
JX.DOM.replace(placeholder, list);
|
||||
}
|
||||
});
|
||||
|
||||
data.menu.open();
|
||||
|
||||
JX.DOM.listen(list, 'click', 'tag:a', function(e) {
|
||||
if (!e.isNormalClick()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (JX.Stratcom.pass()) {
|
||||
return;
|
||||
}
|
||||
|
||||
data.menu.close();
|
||||
});
|
||||
});
|
||||
|
|
44
webroot/rsrc/js/phui/behavior-phui-submenu.js
Normal file
44
webroot/rsrc/js/phui/behavior-phui-submenu.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* @provides javelin-behavior-phui-submenu
|
||||
* @requires javelin-behavior
|
||||
* javelin-stratcom
|
||||
* javelin-dom
|
||||
*/
|
||||
|
||||
JX.behavior('phui-submenu', function() {
|
||||
|
||||
JX.Stratcom.listen('click', 'phui-submenu', function(e) {
|
||||
if (!e.isNormalClick()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var node = e.getNode('phui-submenu');
|
||||
var data = e.getNodeData('phui-submenu');
|
||||
|
||||
e.kill();
|
||||
|
||||
data.open = !data.open;
|
||||
|
||||
for (var ii = 0; ii < data.itemIDs.length; ii++) {
|
||||
var id = data.itemIDs[ii];
|
||||
var item = JX.$(id);
|
||||
if (data.open) {
|
||||
JX.DOM.show(item);
|
||||
} else {
|
||||
JX.DOM.hide(item);
|
||||
}
|
||||
|
||||
// Add a class so we can animate zany effects.
|
||||
JX.DOM.alterClass(item, 'phui-submenu-animate', data.open);
|
||||
}
|
||||
|
||||
JX.DOM.alterClass(node, 'phui-submenu-open', data.open);
|
||||
|
||||
// Toggle the caret from ">" to "V" when opening the menu, and back again
|
||||
// when closing it.
|
||||
var caret = JX.$(data.caretID);
|
||||
JX.DOM.alterClass(caret, 'caret', data.open);
|
||||
JX.DOM.alterClass(caret, 'caret-right', !data.open);
|
||||
});
|
||||
|
||||
});
|
|
@ -42,7 +42,7 @@ JX.install('PHUIXDropdownMenu', {
|
|||
JX.Stratcom.listen('keydown', null, JX.bind(this, this._onkey));
|
||||
},
|
||||
|
||||
events: ['open'],
|
||||
events: ['open', 'close'],
|
||||
|
||||
properties: {
|
||||
width: null,
|
||||
|
@ -83,6 +83,8 @@ JX.install('PHUIXDropdownMenu', {
|
|||
this._open = false;
|
||||
this._hide();
|
||||
|
||||
this.invoke('close');
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in a new issue