mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-01-19 06:18:16 +01:00
3536 cover beforeinput behavior on edge legacy browser (#3537)
* 3536 support flat functionality + beforeinput in Edge * 3536 support flat functionality + beforeinput in Edge * 3536 remove support for flat functionality * 3536 added description of regexp Co-authored-by: Pavlyna Bevz <pavlynabevz@pbevz-mbp.local>
This commit is contained in:
parent
f86f5ca065
commit
16ff44d056
@ -13,7 +13,7 @@ import scrollIntoView from 'scroll-into-view-if-needed'
|
|||||||
|
|
||||||
import Children from './children'
|
import Children from './children'
|
||||||
import Hotkeys from '../utils/hotkeys'
|
import Hotkeys from '../utils/hotkeys'
|
||||||
import { IS_FIREFOX, IS_SAFARI } from '../utils/environment'
|
import { IS_FIREFOX, IS_SAFARI, IS_EDGE_LEGACY } from '../utils/environment'
|
||||||
import { ReactEditor } from '..'
|
import { ReactEditor } from '..'
|
||||||
import { ReadOnlyContext } from '../hooks/use-read-only'
|
import { ReadOnlyContext } from '../hooks/use-read-only'
|
||||||
import { useSlate } from '../hooks/use-slate'
|
import { useSlate } from '../hooks/use-slate'
|
||||||
@ -37,6 +37,9 @@ import {
|
|||||||
PLACEHOLDER_SYMBOL,
|
PLACEHOLDER_SYMBOL,
|
||||||
} from '../utils/weak-maps'
|
} from '../utils/weak-maps'
|
||||||
|
|
||||||
|
// COMPAT: Firefox/Edge Legacy don't support the `beforeinput` event
|
||||||
|
const HAS_BEFORE_INPUT_SUPPORT = !(IS_FIREFOX || IS_EDGE_LEGACY)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `RenderElementProps` are passed to the `renderElement` handler.
|
* `RenderElementProps` are passed to the `renderElement` handler.
|
||||||
*/
|
*/
|
||||||
@ -422,11 +425,17 @@ export const Editable = (props: EditableProps) => {
|
|||||||
data-gramm={false}
|
data-gramm={false}
|
||||||
role={readOnly ? undefined : 'textbox'}
|
role={readOnly ? undefined : 'textbox'}
|
||||||
{...attributes}
|
{...attributes}
|
||||||
// COMPAT: Firefox doesn't support the `beforeinput` event, so we'd
|
// COMPAT: Certain browsers don't support the `beforeinput` event, so we'd
|
||||||
// have to use hacks to make these replacement-based features work.
|
// have to use hacks to make these replacement-based features work.
|
||||||
spellCheck={IS_FIREFOX ? undefined : attributes.spellCheck}
|
spellCheck={
|
||||||
autoCorrect={IS_FIREFOX ? undefined : attributes.autoCorrect}
|
!HAS_BEFORE_INPUT_SUPPORT ? undefined : attributes.spellCheck
|
||||||
autoCapitalize={IS_FIREFOX ? undefined : attributes.autoCapitalize}
|
}
|
||||||
|
autoCorrect={
|
||||||
|
!HAS_BEFORE_INPUT_SUPPORT ? undefined : attributes.autoCorrect
|
||||||
|
}
|
||||||
|
autoCapitalize={
|
||||||
|
!HAS_BEFORE_INPUT_SUPPORT ? undefined : attributes.autoCapitalize
|
||||||
|
}
|
||||||
data-slate-editor
|
data-slate-editor
|
||||||
data-slate-node="value"
|
data-slate-node="value"
|
||||||
contentEditable={readOnly ? undefined : true}
|
contentEditable={readOnly ? undefined : true}
|
||||||
@ -444,11 +453,11 @@ export const Editable = (props: EditableProps) => {
|
|||||||
}}
|
}}
|
||||||
onBeforeInput={useCallback(
|
onBeforeInput={useCallback(
|
||||||
(event: React.FormEvent<HTMLDivElement>) => {
|
(event: React.FormEvent<HTMLDivElement>) => {
|
||||||
// COMPAT: Firefox doesn't support the `beforeinput` event, so we
|
// COMPAT: Certain browsers don't support the `beforeinput` event, so we
|
||||||
// fall back to React's leaky polyfill instead just for it. It
|
// fall back to React's leaky polyfill instead just for it. It
|
||||||
// only works for the `insertText` input type.
|
// only works for the `insertText` input type.
|
||||||
if (
|
if (
|
||||||
IS_FIREFOX &&
|
!HAS_BEFORE_INPUT_SUPPORT &&
|
||||||
!readOnly &&
|
!readOnly &&
|
||||||
!isEventHandled(event, attributes.onBeforeInput) &&
|
!isEventHandled(event, attributes.onBeforeInput) &&
|
||||||
hasEditableTarget(editor, event.target)
|
hasEditableTarget(editor, event.target)
|
||||||
@ -644,12 +653,12 @@ export const Editable = (props: EditableProps) => {
|
|||||||
!readOnly &&
|
!readOnly &&
|
||||||
!isEventHandled(event, attributes.onDrop)
|
!isEventHandled(event, attributes.onDrop)
|
||||||
) {
|
) {
|
||||||
// COMPAT: Firefox doesn't fire `beforeinput` events at all, and
|
// COMPAT: Certain browsers don't fire `beforeinput` events at all, and
|
||||||
// Chromium browsers don't properly fire them for files being
|
// Chromium browsers don't properly fire them for files being
|
||||||
// dropped into a `contenteditable`. (2019/11/26)
|
// dropped into a `contenteditable`. (2019/11/26)
|
||||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=1028668
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1028668
|
||||||
if (
|
if (
|
||||||
IS_FIREFOX ||
|
!HAS_BEFORE_INPUT_SUPPORT ||
|
||||||
(!IS_SAFARI && event.dataTransfer.files.length > 0)
|
(!IS_SAFARI && event.dataTransfer.files.length > 0)
|
||||||
) {
|
) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
@ -793,10 +802,10 @@ export const Editable = (props: EditableProps) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// COMPAT: Firefox doesn't support the `beforeinput` event, so we
|
// COMPAT: Certain browsers don't support the `beforeinput` event, so we
|
||||||
// fall back to guessing at the input intention for hotkeys.
|
// fall back to guessing at the input intention for hotkeys.
|
||||||
// COMPAT: In iOS, some of these hotkeys are handled in the
|
// COMPAT: In iOS, some of these hotkeys are handled in the
|
||||||
if (IS_FIREFOX) {
|
if (!HAS_BEFORE_INPUT_SUPPORT) {
|
||||||
// We don't have a core behavior for these, but they change the
|
// We don't have a core behavior for these, but they change the
|
||||||
// DOM if we don't prevent them, so we have to.
|
// DOM if we don't prevent them, so we have to.
|
||||||
if (
|
if (
|
||||||
@ -892,13 +901,14 @@ export const Editable = (props: EditableProps) => {
|
|||||||
)}
|
)}
|
||||||
onPaste={useCallback(
|
onPaste={useCallback(
|
||||||
(event: React.ClipboardEvent<HTMLDivElement>) => {
|
(event: React.ClipboardEvent<HTMLDivElement>) => {
|
||||||
// COMPAT: Firefox doesn't support the `beforeinput` event, so we
|
// COMPAT: Certain browsers don't support the `beforeinput` event, so we
|
||||||
// fall back to React's `onPaste` here instead.
|
// fall back to React's `onPaste` here instead.
|
||||||
// COMPAT: Firefox, Chrome and Safari are not emitting `beforeinput` events
|
// COMPAT: Firefox, Chrome and Safari are not emitting `beforeinput` events
|
||||||
// when "paste without formatting" option is used.
|
// when "paste without formatting" option is used.
|
||||||
// This unfortunately needs to be handled with paste events instead.
|
// This unfortunately needs to be handled with paste events instead.
|
||||||
if (
|
if (
|
||||||
(IS_FIREFOX || isPlainTextOnlyPaste(event.nativeEvent)) &&
|
(!HAS_BEFORE_INPUT_SUPPORT ||
|
||||||
|
isPlainTextOnlyPaste(event.nativeEvent)) &&
|
||||||
!readOnly &&
|
!readOnly &&
|
||||||
hasEditableTarget(editor, event.target) &&
|
hasEditableTarget(editor, event.target) &&
|
||||||
!isEventHandled(event, attributes.onPaste)
|
!isEventHandled(event, attributes.onPaste)
|
||||||
|
@ -14,3 +14,8 @@ export const IS_FIREFOX =
|
|||||||
export const IS_SAFARI =
|
export const IS_SAFARI =
|
||||||
typeof navigator !== 'undefined' &&
|
typeof navigator !== 'undefined' &&
|
||||||
/Version\/[\d\.]+.*Safari/.test(navigator.userAgent)
|
/Version\/[\d\.]+.*Safari/.test(navigator.userAgent)
|
||||||
|
|
||||||
|
// "modern" Edge was released at 79.x
|
||||||
|
export const IS_EDGE_LEGACY =
|
||||||
|
typeof navigator !== 'undefined' &&
|
||||||
|
/Edge?\/(?:[0-6][0-9]|[0-7][0-8])/i.test(navigator.userAgent)
|
||||||
|
@ -58,7 +58,6 @@ export const deserialize = el => {
|
|||||||
) {
|
) {
|
||||||
parent = el.childNodes[0]
|
parent = el.childNodes[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
const children = Array.from(parent.childNodes)
|
const children = Array.from(parent.childNodes)
|
||||||
.map(deserialize)
|
.map(deserialize)
|
||||||
.flat()
|
.flat()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user