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:
@@ -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",
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
|
22
packages/slate-react/src/utils/where-if-supported.ts
Normal file
22
packages/slate-react/src/utils/where-if-supported.ts
Normal 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} }` +
|
||||
`}`
|
||||
)
|
||||
}
|
Reference in New Issue
Block a user