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:
@@ -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 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user