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

Improve compatibility for browsers that do not support ResizeObserver or :where selector (#5265)

* Add fallback for default styles when `:where` selector is not supported

* Add polyfill for ResizeObserver

* Add changeset
This commit is contained in:
Kyle McLean
2023-01-30 16:37:03 -07:00
committed by GitHub
parent 2ab56c32af
commit 3cf51f4d88
6 changed files with 48 additions and 7 deletions

View File

@@ -14,6 +14,7 @@
"dist/"
],
"dependencies": {
"@juggle/resize-observer": "^3.4.0",
"@types/is-hotkey": "^0.1.1",
"@types/lodash": "^4.14.149",
"direction": "^1.0.3",

View File

@@ -66,6 +66,7 @@ import {
NODE_TO_ELEMENT,
PLACEHOLDER_SYMBOL,
} from '../utils/weak-maps'
import { whereIfSupported } from '../utils/where-if-supported'
import { RestoreDOM } from './restore-dom/restore-dom'
import { useAndroidInputManager } from '../hooks/android-input-manager/use-android-input-manager'
import { useTrackUserInput } from '../hooks/use-track-user-input'
@@ -812,9 +813,8 @@ export const Editable = (props: EditableProps) => {
// Set global default styles for editors.
const defaultStylesElement = document.createElement('style')
defaultStylesElement.setAttribute('data-slate-default-styles', 'true')
defaultStylesElement.innerHTML =
// :where is used to give these rules lower specificity so user stylesheets can override them.
`:where([data-slate-editor]) {` +
const selector = '[data-slate-editor]'
const defaultStyles =
// Allow positioning relative to the editable element.
`position: relative;` +
// Prevent the default outline styles.
@@ -822,8 +822,9 @@ export const Editable = (props: EditableProps) => {
// Preserve adjacent whitespace and new lines.
`white-space: pre-wrap;` +
// Allow words to break if they are too long.
`word-wrap: break-word;` +
`}`
`word-wrap: break-word;`
defaultStylesElement.innerHTML = whereIfSupported(selector, defaultStyles)
document.head.appendChild(defaultStylesElement)
}

View File

@@ -1,5 +1,6 @@
import React, { useRef, useEffect } from 'react'
import { Element, Text } from 'slate'
import { ResizeObserver as ResizeObserverPolyfill } from '@juggle/resize-observer'
import String from './string'
import {
PLACEHOLDER_SYMBOL,
@@ -8,6 +9,7 @@ import {
} from '../utils/weak-maps'
import { RenderLeafProps, RenderPlaceholderProps } from './editable'
import { useSlateStatic } from '../hooks/use-slate-static'
import { whereIfSupported } from '../utils/where-if-supported'
/**
* Individual leaves in a text node with unique formatting.
@@ -59,12 +61,14 @@ const Leaf = (props: {
placeholderResizeObserver.current.observe(placeholderEl)
} else if (placeholderEl) {
// Create a new observer and observe the placeholder element.
const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill
placeholderResizeObserver.current = new ResizeObserver(([{ target }]) => {
const styleElement = EDITOR_TO_STYLE_ELEMENT.get(editor)
if (styleElement) {
// Make the min-height the height of the placeholder.
const minHeight = `${target.clientHeight}px`
styleElement.innerHTML = `:where([data-slate-editor-id="${editor.id}"]) { min-height: ${minHeight}; }`
const selector = `[data-slate-editor-id="${editor.id}"]`
const styles = `min-height: ${target.clientHeight}px;`
styleElement.innerHTML = whereIfSupported(selector, styles)
}
})

View File

@@ -0,0 +1,22 @@
/**
* Returns a set of rules that use the `:where` selector if it is supported,
* otherwise it falls back to the provided selector on its own.
*
* The `:where` selector is used to give a selector a lower specificity,
* allowing the rule to be overridden by a user-defined stylesheet.
*
* Older browsers do not support the `:where` selector.
* If it is not supported, the selector will be used without `:where`,
* which means that the rule will have a higher specificity and a user-defined
* stylesheet will not be able to override it easily.
*/
export function whereIfSupported(selector: string, styles: string): string {
return (
`@supports (selector(:where(${selector}))) {` +
`:where(${selector}) { ${styles} }` +
`}` +
`@supports not (selector(:where(${selector}))) {` +
`${selector} { ${styles} }` +
`}`
)
}