From 9b98573327522d63b626447114f8559d2b68ffa8 Mon Sep 17 00:00:00 2001 From: picklesrus Date: Wed, 8 Mar 2017 14:27:53 -0800 Subject: [PATCH] =?UTF-8?q?Cross=20browser=20friendly=20fix=20for=20#904.?= =?UTF-8?q?=20=20This=20calls=20blur=20and=20focus=20from=20=E2=80=A6=20(#?= =?UTF-8?q?972)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Cross browser friendly fix for #904. This calls blur and focus from workspace.markFocused and removes the event listener on focus events. markFocused is called from all of our mouse down handlers, which triggers the focus event leading to an infinite loop of focus. As far as I can tell, there are no uses of the focus handler that actually did anything for us. --- core/inject.js | 1 - core/workspace_svg.js | 25 +++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/core/inject.js b/core/inject.js index 72a3c1a37..2255c84bc 100644 --- a/core/inject.js +++ b/core/inject.js @@ -66,7 +66,6 @@ Blockly.inject = function(container, opt_options) { workspaceDragSurface); Blockly.init_(workspace); workspace.markFocused(); - Blockly.bindEventWithChecks_(svg, 'focus', workspace, workspace.markFocused); Blockly.svgResize(workspace); return workspace; }; diff --git a/core/workspace_svg.js b/core/workspace_svg.js index c3dc66972..74282ab65 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -685,7 +685,7 @@ Blockly.WorkspaceSvg.prototype.setupDragSurface = function() { // This can happen if the user starts a drag, mouses up outside of the // document where the mouseup listener is registered (e.g. outside of an - // iframe) and then moves the mouse back in the workspace. On mobile and ff, + // iframe) and then moves the mouse back in the workspace. On mobile and ff, // we get the mouseup outside the frame. On chrome and safari desktop we do // not. if (this.isDragSurfaceActive_) { @@ -1369,8 +1369,29 @@ Blockly.WorkspaceSvg.prototype.markFocused = function() { Blockly.mainWorkspace = this; // We call e.preventDefault in many event handlers which means we // need to explicitly grab focus (e.g from a textarea) because - // the browser will not do it for us. + // the browser will not do it for us. How to do this is browser dependant. + this.setBrowserFocus(); + } +}; + +/** + * Set the workspace to have focus in the browser. + * @private + */ +Blockly.WorkspaceSvg.prototype.setBrowserFocus = function() { + // Blur whatever was focused since explcitly grabbing focus below does not + // work in Edge. + if (document.activeElement) { + document.activeElement.blur(); + } + try { + // Focus the workspace SVG - this is for Chrome and Firefox. this.getParentSvg().focus(); + } 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 + // instead. This doesn't work in Chrome. + this.getParentSvg().parentNode.focus(); } };