-
Notifications
You must be signed in to change notification settings - Fork 740
Context menu async loading sub-menu's #431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
9ed1115
87eccfc
8432265
e85f560
aafa478
860c2aa
4464e03
f0a17f3
1cd7d07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -194,6 +194,11 @@ | |
}, | ||
// position the sub-menu | ||
positionSubmenu: function ($menu) { | ||
if ($menu === undefined) { | ||
//When user hovers over item (which has sub items) handle.focusItem will call this. | ||
//but the submenu does not exist yet if opt.items is a promise. just return, will call positionSubmenu after promise is completed. | ||
return; | ||
} | ||
if ($.ui && $.ui.position) { | ||
// .position() is provided as a jQuery UI utility | ||
// (...and it won't work on hidden elements) | ||
|
@@ -1159,6 +1164,8 @@ | |
$t.addClass('context-menu-separator ' + root.classNames.notSelectable); | ||
} else if (item.type === 'html') { | ||
$t.addClass('context-menu-html ' + root.classNames.notSelectable); | ||
} else if (item.type === 'sub') { | ||
//we don't want to execute the next else-if if it is a sub. | ||
} else if (item.type) { | ||
$label = $('<label></label>').appendTo($t); | ||
createNameNode(item).appendTo($label); | ||
|
@@ -1227,7 +1234,7 @@ | |
createNameNode(item).appendTo($t); | ||
|
||
item.appendTo = item.$node; | ||
op.create(item, root); | ||
//op.create(item, root); decide later, might be a promise. | ||
$t.data('contextMenu', item).addClass('context-menu-submenu'); | ||
item.callback = null; | ||
break; | ||
|
@@ -1249,6 +1256,17 @@ | |
break; | ||
} | ||
|
||
if (item.type === 'sub') { | ||
//if item contains items, and this is a promise, we should create it later | ||
//check if subitems is of type promise. If it is a promise we need to create it later, after promise has been resolved | ||
if ('function' === typeof item.items.then) { | ||
// probably a promise, process it, when completed it will create the sub menu's. | ||
op.processPromises(item, root, item.items); | ||
} else { | ||
// normal submenu. | ||
op.create(item, root); | ||
} | ||
} | ||
// disable key listener in <input> | ||
if (item.type && item.type !== 'sub' && item.type !== 'html' && item.type !== 'cm_seperator') { | ||
$input | ||
|
@@ -1411,6 +1429,35 @@ | |
} | ||
|
||
return $layer; | ||
}, | ||
processPromises: function (opt, root, promise) { | ||
function completedPromise(opt,root,items) { | ||
//completed promise (dev called promise.resolve) | ||
//we now have a list of items which can be used to create the rest of the context menu. | ||
if (items === undefined) { | ||
//meh, null result, dev should have checked | ||
errorPromise(undefined);//own error object | ||
} | ||
finishPromiseProcess(opt,root, items); | ||
}; | ||
function errorPromise(opt,root,errorItem) { | ||
//user called promise.reject() with an error item, if not, provide own error item. | ||
if ( typeof errorItem === 'string' || errorItem === undefined) { | ||
errorItem = { "error": { name: "No items and no error item", icon: "context-menu-icon context-menu-icon-quit" } }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this the errorItem as name if it is a string? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm. I might had a reason for that but not sure why anymore, maybe to force users to build nice error items or something. I'll update it, one second. |
||
if (window.console) { | ||
(console.error || console.log).call(console, 'When you reject a promise, provide an "items" object, equal to normal sub-menu items'); | ||
} | ||
} | ||
finishPromiseProcess(opt,root,errorItem); | ||
}; | ||
function finishPromiseProcess(opt,root,items) { | ||
opt.items = items;//override promise to items. | ||
op.create(opt, root, true);//create submenu | ||
op.update(opt, root);//correctly update position if user is already hovered over menu item | ||
root.positionSubmenu.call(opt.$node, opt.$menu); //positionSubmenu, will only do anything if user already hovered over menu item that just got new subitems. | ||
}; | ||
//wait for promise completion. .then(success, error, notify) (we don't track notify). Bind the opt and root to avoid scope problems | ||
promise.then(completedPromise.bind(this, opt, root), errorPromise.bind(this, opt, root)); | ||
} | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't the logic for creating the submenu called here but evaluated later, outside the case statement?