mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-15 11:44:05 +02:00
fix: focus loss inside Shadow DOM in Firefox. (#5676)
This commit is contained in:
5
.changeset/clean-rats-raise.md
Normal file
5
.changeset/clean-rats-raise.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'slate-react': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Changed behaviour of ReactEditor.findDocumentOrShadowRoot. It returns shadow root or document without checking for the existence of the getSelection method.
|
@@ -36,6 +36,7 @@ import {
|
|||||||
DOMText,
|
DOMText,
|
||||||
getActiveElement,
|
getActiveElement,
|
||||||
getDefaultView,
|
getDefaultView,
|
||||||
|
getSelection,
|
||||||
isDOMElement,
|
isDOMElement,
|
||||||
isDOMNode,
|
isDOMNode,
|
||||||
isPlainTextOnlyPaste,
|
isPlainTextOnlyPaste,
|
||||||
@@ -231,7 +232,7 @@ export const Editable = (props: EditableProps) => {
|
|||||||
const root = ReactEditor.findDocumentOrShadowRoot(editor)
|
const root = ReactEditor.findDocumentOrShadowRoot(editor)
|
||||||
const { activeElement } = root
|
const { activeElement } = root
|
||||||
const el = ReactEditor.toDOMNode(editor, editor)
|
const el = ReactEditor.toDOMNode(editor, editor)
|
||||||
const domSelection = root.getSelection()
|
const domSelection = getSelection(root)
|
||||||
|
|
||||||
if (activeElement === el) {
|
if (activeElement === el) {
|
||||||
state.latestElement = activeElement
|
state.latestElement = activeElement
|
||||||
@@ -308,7 +309,7 @@ export const Editable = (props: EditableProps) => {
|
|||||||
// Make sure the DOM selection state is in sync.
|
// Make sure the DOM selection state is in sync.
|
||||||
const { selection } = editor
|
const { selection } = editor
|
||||||
const root = ReactEditor.findDocumentOrShadowRoot(editor)
|
const root = ReactEditor.findDocumentOrShadowRoot(editor)
|
||||||
const domSelection = root.getSelection()
|
const domSelection = getSelection(root)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!domSelection ||
|
!domSelection ||
|
||||||
@@ -1090,7 +1091,7 @@ export const Editable = (props: EditableProps) => {
|
|||||||
// editable element no longer has focus. Refer to:
|
// editable element no longer has focus. Refer to:
|
||||||
// https://stackoverflow.com/questions/12353247/force-contenteditable-div-to-stop-accepting-input-after-it-loses-focus-under-web
|
// https://stackoverflow.com/questions/12353247/force-contenteditable-div-to-stop-accepting-input-after-it-loses-focus-under-web
|
||||||
if (IS_WEBKIT) {
|
if (IS_WEBKIT) {
|
||||||
const domSelection = root.getSelection()
|
const domSelection = getSelection(root)
|
||||||
domSelection?.removeAllRanges()
|
domSelection?.removeAllRanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@ import {
|
|||||||
DOMSelection,
|
DOMSelection,
|
||||||
DOMStaticRange,
|
DOMStaticRange,
|
||||||
DOMText,
|
DOMText,
|
||||||
|
getSelection,
|
||||||
hasShadowRoot,
|
hasShadowRoot,
|
||||||
isDOMElement,
|
isDOMElement,
|
||||||
isDOMNode,
|
isDOMNode,
|
||||||
@@ -280,7 +281,7 @@ export const ReactEditor: ReactEditorInterface = {
|
|||||||
deselect: editor => {
|
deselect: editor => {
|
||||||
const { selection } = editor
|
const { selection } = editor
|
||||||
const root = ReactEditor.findDocumentOrShadowRoot(editor)
|
const root = ReactEditor.findDocumentOrShadowRoot(editor)
|
||||||
const domSelection = root.getSelection()
|
const domSelection = getSelection(root)
|
||||||
|
|
||||||
if (domSelection && domSelection.rangeCount > 0) {
|
if (domSelection && domSelection.rangeCount > 0) {
|
||||||
domSelection.removeAllRanges()
|
domSelection.removeAllRanges()
|
||||||
@@ -295,10 +296,7 @@ export const ReactEditor: ReactEditorInterface = {
|
|||||||
const el = ReactEditor.toDOMNode(editor, editor)
|
const el = ReactEditor.toDOMNode(editor, editor)
|
||||||
const root = el.getRootNode()
|
const root = el.getRootNode()
|
||||||
|
|
||||||
if (
|
if (root instanceof Document || root instanceof ShadowRoot) {
|
||||||
(root instanceof Document || root instanceof ShadowRoot) &&
|
|
||||||
root.getSelection != null
|
|
||||||
) {
|
|
||||||
return root
|
return root
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,7 +435,7 @@ export const ReactEditor: ReactEditorInterface = {
|
|||||||
if (root.activeElement !== el) {
|
if (root.activeElement !== el) {
|
||||||
// Ensure that the DOM selection state is set to the editor's selection
|
// Ensure that the DOM selection state is set to the editor's selection
|
||||||
if (editor.selection && root instanceof Document) {
|
if (editor.selection && root instanceof Document) {
|
||||||
const domSelection = root.getSelection()
|
const domSelection = getSelection(root)
|
||||||
const domRange = ReactEditor.toDOMRange(editor, editor.selection)
|
const domRange = ReactEditor.toDOMRange(editor, editor.selection)
|
||||||
domSelection?.removeAllRanges()
|
domSelection?.removeAllRanges()
|
||||||
domSelection?.addRange(domRange)
|
domSelection?.addRange(domRange)
|
||||||
|
@@ -274,6 +274,16 @@ export const getClipboardData = (
|
|||||||
return dataTransfer
|
return dataTransfer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the dom selection from Shadow Root if possible, otherwise from the document
|
||||||
|
*/
|
||||||
|
export const getSelection = (root: Document | ShadowRoot): Selection | null => {
|
||||||
|
if (root.getSelection != null) {
|
||||||
|
return root.getSelection()
|
||||||
|
}
|
||||||
|
return document.getSelection()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether a mutation originates from a editable element inside the editor.
|
* Check whether a mutation originates from a editable element inside the editor.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user