1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-18 13:11:17 +02:00

fix onBlur logic to prevent unfocus on window unfocus

This commit is contained in:
Ian Storm Taylor
2017-10-30 11:48:13 -07:00
parent d1ee4dba57
commit ce2b06af14

View File

@@ -27,6 +27,7 @@ const debug = Debug('slate:before')
*/ */
function BeforePlugin() { function BeforePlugin() {
let activeElement = null
let compositionCount = 0 let compositionCount = 0
let isComposing = false let isComposing = false
let isCopying = false let isCopying = false
@@ -69,28 +70,34 @@ function BeforePlugin() {
if (editor.props.readOnly) return true if (editor.props.readOnly) return true
const { value } = change const { value } = change
const focusTarget = event.relatedTarget const { relatedTarget, target } = event
const window = getWindow(target)
// focusTarget may be null when window itself being blurred // COMPAT: If the current `activeElement` is still the previous one, this is
// (eg. when changing tabs), or when user clicks on elements // due to the window being blurred when the tab itself becomes unfocused, so
// without`tabindex` attribute. // we want to abort early to allow to editor to stay focused when the tab
if (focusTarget) { // becomes focused again.
if (activeElement == window.document.activeElement) return true
// COMPAT: The `relatedTarget` can be null when the new focus target is not
// a "focusable" element (eg. a `<div>` without `tabindex` set).
if (relatedTarget) {
const el = findDOMNode(editor) const el = findDOMNode(editor)
// The event should be ignored if the focus returns to the editor from an
// embedded editable element (eg. an input element inside a void node).
if (focusTarget == el) return true
// when the focus moved from the editor to a void node spacer... // COMPAT: The event should be ignored if the focus is returning to the
if (focusTarget.hasAttribute('data-slate-spacer')) return true // editor from an embedded editable element (eg. an <input> element inside
// a void node).
if (relatedTarget == el) return true
// or to an editable element inside the editor but not into a void node // COMPAT: The event should be ignored if the focus is moving from the
// (eg. a list item of the check list example). // editor to inside a void node's spacer element.
if ( if (relatedTarget.hasAttribute('data-slate-spacer')) return true
el.contains(focusTarget) &&
!findNode(focusTarget, value).isVoid // COMPAT: The event should be ignored if the focus is moving to a non-
) { // editable section of an element that isn't a void node (eg. a list item
return true // of the check list example).
} const node = findNode(relatedTarget, value)
if (el.contains(relatedTarget) && node && !node.isVoid) return true
} }
debug('onBlur', { event }) debug('onBlur', { event })
@@ -323,6 +330,10 @@ function BeforePlugin() {
const el = findDOMNode(editor) const el = findDOMNode(editor)
// Save the new `activeElement`.
const window = getWindow(event.target)
activeElement = window.document.activeElement
// COMPAT: If the editor has nested editable elements, the focus can go to // COMPAT: If the editor has nested editable elements, the focus can go to
// those elements. In Firefox, this must be prevented because it results in // those elements. In Firefox, this must be prevented because it results in
// issues with keyboard navigation. (2017/03/30) // issues with keyboard navigation. (2017/03/30)
@@ -407,6 +418,10 @@ function BeforePlugin() {
if (isComposing) return true if (isComposing) return true
if (editor.props.readOnly) return true if (editor.props.readOnly) return true
// Save the new `activeElement`.
const window = getWindow(event.target)
activeElement = window.document.activeElement
debug('onSelect', { event }) debug('onSelect', { event })
} }