From 60d0b5de4253c8bad25d535da5696ed441bcf040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Richter?= Date: Tue, 19 Mar 2019 16:35:13 +0100 Subject: [PATCH 1/2] `commands` function can return a promise (#67) The app developer can provide a `commands` function that returns a promise. When the user invokes the context menu it will appear only once the promise is resolved. This allows the app developer to involve async operations when calculating the available commands. The returned promise must resolve with an array of commands. Note: the array itself must not contain any promise. The cxtmenu API remains fully compatible. The `commands` function still can return an array of commands. The README is extended. --- README.md | 2 +- src/cxtmenu.js | 88 ++++++++++++++++++++++++++++---------------------- 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index d7c83fa6..26655582 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ let defaults = { enabled: true // whether the command is selectable } */ - ], // function( ele ){ return [ /*...*/ ] }, // example function for commands + ], // function( ele ){ return [ /*...*/ ] }, // a function that returns commands or a promise of commands fillColor: 'rgba(0, 0, 0, 0.75)', // the background colour of the menu activeFillColor: 'rgba(1, 105, 217, 0.75)', // the colour used to indicate the selected command activePadding: 20, // additional size in pixels for the active command diff --git a/src/cxtmenu.js b/src/cxtmenu.js index 47f25308..89dc0dc1 100644 --- a/src/cxtmenu.js +++ b/src/cxtmenu.js @@ -372,61 +372,73 @@ let cxtmenu = function(params){ } if( typeof options.commands === 'function' ){ - commands = options.commands(target); + const res = options.commands(target); + if( res instanceof Promise ){ + res.then(_commands => { + commands = _commands; + openMenu(); + }) + } else { + commands = res; + openMenu(); + } } else { commands = options.commands; + openMenu(); } - if( !commands || commands.length === 0 ){ return; } + function openMenu(){ + if( !commands || commands.length === 0 ){ return; } - zoomEnabled = cy.userZoomingEnabled(); - cy.userZoomingEnabled( false ); + zoomEnabled = cy.userZoomingEnabled(); + cy.userZoomingEnabled( false ); - panEnabled = cy.userPanningEnabled(); - cy.userPanningEnabled( false ); + panEnabled = cy.userPanningEnabled(); + cy.userPanningEnabled( false ); - boxEnabled = cy.boxSelectionEnabled(); - cy.boxSelectionEnabled( false ); + boxEnabled = cy.boxSelectionEnabled(); + cy.boxSelectionEnabled( false ); - grabbable = target.grabbable && target.grabbable(); - if( grabbable ){ - target.ungrabify(); - } + grabbable = target.grabbable && target.grabbable(); + if( grabbable ){ + target.ungrabify(); + } - let rp, rw, rh; - if( !isCy && ele.isNode() && !ele.isParent() && !options.atMouse ){ - rp = ele.renderedPosition(); - rw = ele.renderedWidth(); - rh = ele.renderedHeight(); - } else { - rp = e.renderedPosition || e.cyRenderedPosition; - rw = 1; - rh = 1; - } + let rp, rw, rh; + if( !isCy && ele.isNode() && !ele.isParent() && !options.atMouse ){ + rp = ele.renderedPosition(); + rw = ele.renderedWidth(); + rh = ele.renderedHeight(); + } else { + rp = e.renderedPosition || e.cyRenderedPosition; + rw = 1; + rh = 1; + } - offset = getOffset(container); + offset = getOffset(container); - ctrx = rp.x; - ctry = rp.y; + ctrx = rp.x; + ctry = rp.y; - createMenuItems(); + createMenuItems(); - setStyles(parent, { - display: 'block', - left: (rp.x - r) + 'px', - top: (rp.y - r) + 'px' - }); + setStyles(parent, { + display: 'block', + left: (rp.x - r) + 'px', + top: (rp.y - r) + 'px' + }); - rs = Math.max(rw, rh)/2; - rs = Math.max(rs, options.minSpotlightRadius); - rs = Math.min(rs, options.maxSpotlightRadius); + rs = Math.max(rw, rh)/2; + rs = Math.max(rs, options.minSpotlightRadius); + rs = Math.min(rs, options.maxSpotlightRadius); - queueDrawBg(); + queueDrawBg(); - activeCommandI = undefined; + activeCommandI = undefined; - inGesture = true; - gestureStartEvent = e; + inGesture = true; + gestureStartEvent = e; + } }) .on('cxtdrag tapdrag', options.selector, dragHandler = function(e){ From 8b4fab063417d6e6aab2b02bbcff24f0de245609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Richter?= Date: Tue, 26 Mar 2019 23:42:50 +0100 Subject: [PATCH 2/2] Make promise check generic (#67) --- src/cxtmenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cxtmenu.js b/src/cxtmenu.js index 89dc0dc1..15bacb67 100644 --- a/src/cxtmenu.js +++ b/src/cxtmenu.js @@ -373,7 +373,7 @@ let cxtmenu = function(params){ if( typeof options.commands === 'function' ){ const res = options.commands(target); - if( res instanceof Promise ){ + if( res.then ){ res.then(_commands => { commands = _commands; openMenu();