From 40bdfac017c3b2eadcc5a3aea1d8eee4f1664eea Mon Sep 17 00:00:00 2001 From: alschmiedt Date: Mon, 11 Nov 2019 16:44:58 -0800 Subject: [PATCH] Fix setting focus for workspace (#3425) * Fix setting focus for workspace --- core/components/menu/menu.js | 2 +- core/field_colour.js | 4 ++-- core/field_textinput.js | 19 ++++++++++++++++++- core/gesture.js | 6 ++++-- core/inject.js | 12 +++++------- core/workspace_svg.js | 4 ++-- 6 files changed, 32 insertions(+), 15 deletions(-) diff --git a/core/components/menu/menu.js b/core/components/menu/menu.js index 4386f47ac..6bad647d7 100644 --- a/core/components/menu/menu.js +++ b/core/components/menu/menu.js @@ -73,7 +73,7 @@ Blockly.Menu.prototype.createDom = function() { Blockly.Menu.prototype.focus = function() { var el = this.getElement(); if (el) { - el.focus(); + el.focus({preventScroll:true}); Blockly.utils.dom.addClass(el, 'focused'); } }; diff --git a/core/field_colour.js b/core/field_colour.js index 6878977e6..095f29c72 100644 --- a/core/field_colour.js +++ b/core/field_colour.js @@ -334,7 +334,7 @@ Blockly.FieldColour.prototype.showEditor_ = function() { this, this.dropdownDispose_.bind(this)); // Focus so we can start receiving keyboard events. - this.picker_.focus(); + this.picker_.focus({preventScroll:true}); }; /** @@ -487,7 +487,7 @@ Blockly.FieldColour.prototype.onMouseMove_ = function(e) { * @private */ Blockly.FieldColour.prototype.onMouseEnter_ = function() { - this.picker_.focus(); + this.picker_.focus({preventScroll:true}); }; /** diff --git a/core/field_textinput.js b/core/field_textinput.js index 853ec1187..ff39d69a9 100644 --- a/core/field_textinput.js +++ b/core/field_textinput.js @@ -269,7 +269,7 @@ Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) { this.isBeingEdited_ = true; if (!quietInput) { - this.htmlInput_.focus(); + this.htmlInput_.focus({preventScroll:true}); this.htmlInput_.select(); } }; @@ -349,6 +349,10 @@ Blockly.FieldTextInput.prototype.bindInputEvents_ = function(htmlInput) { this.onKeyInputWrapper_ = Blockly.bindEventWithChecks_( htmlInput, 'input', this, this.onHtmlInputChange_); + + this.onBlurInputWrapper_ = + Blockly.bindEventWithChecks_( + htmlInput, 'blur', this, this.onHtmlInputBlur_); }; /** @@ -362,6 +366,9 @@ Blockly.FieldTextInput.prototype.unbindInputEvents_ = function() { if (this.onKeyInputWrapper_) { Blockly.unbindEvent_(this.onKeyInputWrapper_); } + if (this.onBlurInputWrapper_) { + Blockly.unbindEvent_(this.onBlurInputWrapper_); + } }; /** @@ -406,6 +413,16 @@ Blockly.FieldTextInput.prototype.onHtmlInputChange_ = function(_e) { } }; +/** + * Handle blur for the editor. + * @param {!Event} _e Focus event. + * @protected + */ +Blockly.FieldTextInput.prototype.onHtmlInputBlur_ = function(_e) { + Blockly.WidgetDiv.hide(); + Blockly.DropDownDiv.hideWithoutAnimation(); +}; + /** * Set the html input value and the field's internal value. The difference * between this and ``setValue`` is that this also updates the html input diff --git a/core/gesture.js b/core/gesture.js index 758aad0e8..536f665fc 100644 --- a/core/gesture.js +++ b/core/gesture.js @@ -483,12 +483,14 @@ Blockly.Gesture.prototype.doStart = function(e) { // dragged, the block was moved, the parent workspace zoomed, etc. this.startWorkspace_.resize(); } - this.startWorkspace_.markFocused(); - this.mostRecentEvent_ = e; // Hide chaff also hides the flyout, so don't do it if the click is in a // flyout. Blockly.hideChaff(!!this.flyout_); + + this.startWorkspace_.markFocused(); + this.mostRecentEvent_ = e; + Blockly.Tooltip.block(); if (this.targetBlock_) { diff --git a/core/inject.js b/core/inject.js index 587aca07b..3bec1b7f5 100644 --- a/core/inject.js +++ b/core/inject.js @@ -78,18 +78,16 @@ Blockly.inject = function(container, opt_options) { Blockly.user.keyMap.setKeyMap(options.keyMap); Blockly.init_(workspace); + + // Keep focus on the first workspace so entering keyboard navigation looks correct. Blockly.mainWorkspace = workspace; Blockly.svgResize(workspace); - subContainer.addEventListener('focus', function() { + subContainer.addEventListener('focusin', function() { Blockly.mainWorkspace = workspace; }); - subContainer.addEventListener('blur', function() { - Blockly.mainWorkspace = null; - }); - return workspace; }; @@ -127,7 +125,8 @@ Blockly.createDom_ = function(container, options) { 'xmlns:html': Blockly.utils.dom.HTML_NS, 'xmlns:xlink': Blockly.utils.dom.XLINK_NS, 'version': '1.1', - 'class': 'blocklySvg' + 'class': 'blocklySvg', + 'tabindex': '0' }, container); /* @@ -183,7 +182,6 @@ Blockly.createMainWorkspace_ = function(svg, options, blockDragSurface, // A null translation will also apply the correct initial scale. mainWorkspace.translate(0, 0); - Blockly.mainWorkspace = mainWorkspace; if (!options.readOnly && !mainWorkspace.isMovable()) { // Helper function for the workspaceChanged callback. diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 01909a3d0..da6eacaf4 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -1874,7 +1874,7 @@ Blockly.WorkspaceSvg.prototype.setBrowserFocus = function() { } try { // Focus the workspace SVG - this is for Chrome and Firefox. - this.getParentSvg().focus(); + this.getParentSvg().focus({preventScroll:true}); } catch (e) { // IE and Edge do not support focus on SVG elements. When that fails // above, get the injectionDiv (the workspace's parent) and focus that @@ -1886,7 +1886,7 @@ Blockly.WorkspaceSvg.prototype.setBrowserFocus = function() { } catch (e) { // setActive support was discontinued in Edge so when that fails, call // focus instead. - this.getParentSvg().parentNode.focus(); + this.getParentSvg().parentNode.focus({preventScroll:true}); } } };