1 |
|
2 |
|
3 |
|
4 | import { __ } from '@wordpress/i18n';
|
5 | import { createBlock, getPhrasingContentSchema } from '@wordpress/blocks';
|
6 | import { RichText } from '@wordpress/block-editor';
|
7 | import { Path, Rect, SVG } from '@wordpress/components';
|
8 |
|
9 | export const name = 'core/preformatted';
|
10 |
|
11 | export 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 | };
|