diff --git a/core/contextmenu.js b/core/contextmenu.js index c843273e3..95f4591ca 100644 --- a/core/contextmenu.js +++ b/core/contextmenu.js @@ -61,12 +61,33 @@ Blockly.ContextMenu.show = function(e, options, rtl) { Blockly.ContextMenu.hide(); return; } + var menu = Blockly.ContextMenu.populate_(options, rtl); + + goog.events.listen(menu, goog.ui.Component.EventType.ACTION, + Blockly.ContextMenu.hide); + + Blockly.ContextMenu.position_(menu, e, rtl); + // 1ms delay is required for focusing on context menus because some other + // mouse event is still waiting in the queue and clears focus. + setTimeout(function() {menu.getElement().focus();}, 1); + Blockly.ContextMenu.currentBlock = null; // May be set by Blockly.Block. +}; + +/** + * Create the context menu object and populate it with the given options. + * @param {!Array.} options Array of menu options. + * @param {boolean} rtl True if RTL, false if LTR. + * @return {!goog.ui.Menu} The menu that will be shown on right click. + * @private + */ +Blockly.ContextMenu.populate_ = function(options, rtl) { /* Here's what one option object looks like: {text: 'Make It So', enabled: true, callback: Blockly.MakeItSo} */ var menu = new goog.ui.Menu(); + menu.setAllowAutoFocus(true); menu.setRightToLeft(rtl); for (var i = 0, option; option = options[i]; i++) { var menuItem = new goog.ui.MenuItem(option.text); @@ -76,15 +97,25 @@ Blockly.ContextMenu.show = function(e, options, rtl) { if (option.enabled) { goog.events.listen(menuItem, goog.ui.Component.EventType.ACTION, option.callback); - menuItem.handleContextMenu = function(e) { + menuItem.handleContextMenu = function(/* e */) { // Right-clicking on menu option should count as a click. goog.events.dispatchEvent(this, goog.ui.Component.EventType.ACTION); }; } } - goog.events.listen(menu, goog.ui.Component.EventType.ACTION, - Blockly.ContextMenu.hide); - // Record windowSize and scrollOffset before adding menu. + return menu; +}; + +/** + * Add the menu to the page and position it correctly. + * @param {!goog.ui.Menu} menu The menu to add and position. + * @param {!Event} e Mouse event for the right click that is making the context + * menu appear. + * @param {boolean} rtl True if RTL, false if LTR. + * @private + */ +Blockly.ContextMenu.position_ = function(menu, e, rtl) { + // Record windowSize and scrollOffset before adding menu. var windowSize = goog.dom.getViewportSize(); var scrollOffset = goog.style.getViewportPageOffset(document); var div = Blockly.WidgetDiv.DIV; @@ -115,12 +146,6 @@ Blockly.ContextMenu.show = function(e, options, rtl) { } } Blockly.WidgetDiv.position(x, y, windowSize, scrollOffset, rtl); - - menu.setAllowAutoFocus(true); - // 1ms delay is required for focusing on context menus because some other - // mouse event is still waiting in the queue and clears focus. - setTimeout(function() {menuDom.focus();}, 1); - Blockly.ContextMenu.currentBlock = null; // May be set by Blockly.Block. }; /**