1
0
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:
pavlyna 2020-03-11 17:20:30 +02:00 committed by GitHub
parent f86f5ca065
commit 16ff44d056
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 14 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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()