UNPKG

2.55 kBJavaScriptView Raw
1/**
2 * WordPress dependencies
3 */
4import { __ } from '@wordpress/i18n';
5import { createBlock, getPhrasingContentSchema } from '@wordpress/blocks';
6import { RichText } from '@wordpress/block-editor';
7import { Path, Rect, SVG } from '@wordpress/components';
8
9export const name = 'core/preformatted';
10
11export const settings = {
12 title: __( 'Preformatted' ),
13
14 description: __( 'Add text that respects your spacing and tabs, and also allows styling.' ),
15
16 icon: <SVG viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><Path d="M0,0h24v24H0V0z" fill="none" /><Path d="M20,4H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V6C22,4.9,21.1,4,20,4z M20,18H4V6h16V18z" /><Rect x="6" y="10" width="2" height="2" /><Rect x="6" y="14" width="8" height="2" /><Rect x="16" y="14" width="2" height="2" /><Rect x="10" y="10" width="8" height="2" /></SVG>,
17
18 category: 'formatting',
19
20 attributes: {
21 content: {
22 type: 'string',
23 source: 'html',
24 selector: 'pre',
25 default: '',
26 },
27 },
28
29 transforms: {
30 from: [
31 {
32 type: 'block',
33 blocks: [ 'core/code', 'core/paragraph' ],
34 transform: ( { content } ) =>
35 createBlock( 'core/preformatted', {
36 content,
37 } ),
38 },
39 {
40 type: 'raw',
41 isMatch: ( node ) => (
42 node.nodeName === 'PRE' &&
43 ! (
44 node.children.length === 1 &&
45 node.firstChild.nodeName === 'CODE'
46 )
47 ),
48 schema: {
49 pre: {
50 children: getPhrasingContentSchema(),
51 },
52 },
53 },
54 ],
55 to: [
56 {
57 type: 'block',
58 blocks: [ 'core/paragraph' ],
59 transform: ( attributes ) =>
60 createBlock( 'core/paragraph', attributes ),
61 },
62 ],
63 },
64
65 edit( { attributes, mergeBlocks, setAttributes, className } ) {
66 const { content } = attributes;
67
68 return (
69 <RichText
70 tagName="pre"
71 // Ensure line breaks are normalised to HTML.
72 value={ content.replace( /\n/g, '<br>' ) }
73 onChange={ ( nextContent ) => {
74 setAttributes( {
75 // Ensure line breaks are normalised to characters. This
76 // saves space, is easier to read, and ensures display
77 // filters work correctly.
78 content: nextContent.replace( /<br ?\/?>/g, '\n' ),
79 } );
80 } }
81 placeholder={ __( 'Write preformatted text…' ) }
82 wrapperClassName={ className }
83 onMerge={ mergeBlocks }
84 />
85 );
86 },
87
88 save( { attributes } ) {
89 const { content } = attributes;
90
91 return <RichText.Content tagName="pre" value={ content } />;
92 },
93
94 merge( attributes, attributesToMerge ) {
95 return {
96 content: attributes.content + attributesToMerge.content,
97 };
98 },
99};