/
githubmirror
/
gutenberg
Обзор
Документация
Войти
/
githubmirror
/
gutenberg
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
trunk
packages/block-library/src/html/modal.js
225 строк
6 KB
Marco Ciampini
ESLint: Replace strict config with bulk suppressions (#81248)
07 авг 2026, 14:34
Не верифицирован
07 авг 2026, 14:34
7f43eaf
Код
Авторство
О чём код?
import { __ } from '@wordpress/i18n'; import { useState } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { Modal, Button, Flex, Notice, privateApis as componentsPrivateApis, __experimentalVStack as VStack, __experimentalHStack as HStack, } from '@wordpress/components'; import { PlainText, store as blockEditorStore, privateApis as blockEditorPrivateApis, } from '@wordpress/block-editor'; import { fullscreen, square } from '@wordpress/icons'; import { useViewportMatch } from '@wordpress/compose'; import { unlock } from '../lock-unlock'; import Preview from './preview'; import { parseContent, serializeContent } from './utils'; const { Tabs } = unlock( componentsPrivateApis ); const { useNativeUndo } = unlock( blockEditorPrivateApis ); export default function HTMLEditModal( { onRequestClose, content, onUpdate } ) { // Parse content into separate sections and use as initial state const { html, css, js } = parseContent( content ); const [ editedHtml, setEditedHtml ] = useState( html ); const [ editedCss, setEditedCss ] = useState( css ); const [ editedJs, setEditedJs ] = useState( js ); const [ isFullscreen, setIsFullscreen ] = useState( false ); // The fields hold local state that is only committed when the dialog is // saved, so undo and redo within them must remain the browser's own. const nativeUndoRef = useNativeUndo(); const isMobileViewport = useViewportMatch( 'small', '<' ); // Check if user has permission to save scripts and get editor styles const { canUserUseUnfilteredHTML } = useSelect( ( select ) => { const settings = select( blockEditorStore ).getSettings(); return { canUserUseUnfilteredHTML: settings.__experimentalCanUserUseUnfilteredHTML, }; }, [] ); // Determine if we should show a warning about CSS/JS content being stripped const hasRestrictedContent = ! canUserUseUnfilteredHTML && ( css.trim() || js.trim() ); const handleUpdate = () => { // For users without unfiltered_html capability, strip CSS and JS content // to prevent kses from leaving broken content onUpdate( serializeContent( { html: editedHtml, css: canUserUseUnfilteredHTML ? editedCss : '', js: canUserUseUnfilteredHTML ? editedJs : '', } ) ); }; const handleUpdateAndClose = () => { handleUpdate(); onRequestClose(); }; const toggleFullscreen = () => { setIsFullscreen( ( prevState ) => ! prevState ); }; return ( <> <Modal title={ __( 'Edit HTML' ) } onRequestClose={ onRequestClose } className="block-library-html__modal" size="large" isDismissible={ false } shouldCloseOnClickOutside={ false } isFullScreen={ isFullscreen } __experimentalHideHeader > <Tabs orientation="horizontal" defaultTabId="html"> <VStack expanded> <HStack justify="space-between" className="block-library-html__modal-header" > <div> <Tabs.TabList> <Tabs.Tab tabId="html">HTML</Tabs.Tab> { canUserUseUnfilteredHTML && ( <Tabs.Tab tabId="css">CSS</Tabs.Tab> ) } { canUserUseUnfilteredHTML && ( <Tabs.Tab tabId="js"> { __( 'JavaScript' ) } </Tabs.Tab> ) } </Tabs.TabList> </div> { ! isMobileViewport && ( <div> <Button __next40pxDefaultSize icon={ isFullscreen ? square : fullscreen } label={ __( 'Enable/disable fullscreen' ) } onClick={ toggleFullscreen } variant="tertiary" /> </div> ) } </HStack> { hasRestrictedContent && ( <Notice status="warning" isDismissible={ false } className="block-library-html__modal-notice" > { __( 'This block contains CSS or JavaScript that will be removed when you save because you do not have permission to use unfiltered HTML.' ) } </Notice> ) } <Flex direction={ isMobileViewport ? 'column' : 'row' } className="block-library-html__modal-tabs" align="stretch" gap={ 8 } > <div ref={ nativeUndoRef } className="block-library-html__modal-content" > <Tabs.TabPanel tabId="html" focusable={ false } className="block-library-html__modal-tab" > <PlainText value={ editedHtml } onChange={ setEditedHtml } placeholder={ __( 'Write HTML…' ) } aria-label={ __( 'HTML' ) } className="block-library-html__modal-editor" async /> </Tabs.TabPanel> { canUserUseUnfilteredHTML && ( <Tabs.TabPanel tabId="css" focusable={ false } className="block-library-html__modal-tab" > <PlainText value={ editedCss } onChange={ setEditedCss } placeholder={ __( 'Write CSS…' ) } aria-label={ __( 'CSS' ) } className="block-library-html__modal-editor" async /> </Tabs.TabPanel> ) } { canUserUseUnfilteredHTML && ( <Tabs.TabPanel tabId="js" focusable={ false } className="block-library-html__modal-tab" > <PlainText value={ editedJs } onChange={ setEditedJs } placeholder={ __( 'Write JavaScript…' ) } aria-label={ __( 'JavaScript' ) } className="block-library-html__modal-editor" async /> </Tabs.TabPanel> ) } </div> <div className="block-library-html__preview"> <Preview content={ serializeContent( { html: editedHtml, css: editedCss, js: editedJs, } ) } /> </div> </Flex> <HStack alignment="center" justify="flex-end" spacing={ 4 } className="block-library-html__modal-footer" > <Button __next40pxDefaultSize variant="tertiary" onClick={ onRequestClose } > { __( 'Cancel' ) } </Button> <Button __next40pxDefaultSize variant="primary" onClick={ handleUpdateAndClose } > { __( 'Update' ) } </Button> </HStack> </VStack> </Tabs> </Modal> </> ); }