-
Notifications
You must be signed in to change notification settings - Fork 4k
/
anchor.js
100 lines (89 loc) · 2.73 KB
/
anchor.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* External dependencies
*/
import { assign } from 'lodash';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import { hasBlockSupport } from '../api';
import InspectorControls from '../inspector-controls';
/**
* Regular expression matching invalid anchor characters for replacement.
*
* @type {RegExp}
*/
const ANCHOR_REGEX = /[\s#]/g;
/**
* Filters registered block settings, extending attributes with anchor using ID
* of the first node
*
* @param {Object} settings Original block settings
* @return {Object} Filtered block settings
*/
export function addAttribute( settings ) {
if ( hasBlockSupport( settings, 'anchor' ) ) {
// Use Lodash's assign to gracefully handle if attributes are undefined
settings.attributes = assign( settings.attributes, {
anchor: {
type: 'string',
source: 'attribute',
attribute: 'id',
selector: '*',
},
} );
}
return settings;
}
/**
* Override the default edit UI to include a new block inspector control for
* assigning the anchor ID, if block supports anchor
*
* @param {Element} element Original edit element
* @param {Object} props Props passed to BlockEdit
* @return {Element} Filtered edit element
*/
export function addInspectorControl( element, props ) {
if ( hasBlockSupport( props.name, 'anchor' ) && props.focus ) {
element = [
element,
<InspectorControls key="inspector-anchor">
<InspectorControls.TextControl
label={ __( 'HTML Anchor' ) }
help={ __( 'Anchors lets you link directly to a section on a page.' ) }
value={ props.attributes.anchor || '' }
onChange={ ( nextValue ) => {
nextValue = nextValue.replace( ANCHOR_REGEX, '-' );
props.setAttributes( {
anchor: nextValue,
} );
} } />
</InspectorControls>,
];
}
return element;
}
/**
* Override props assigned to save component to inject anchor ID, if block
* supports anchor. This is only applied if the block's save result is an
* element and not a markup string.
*
* @param {Object} extraProps Additional props applied to save element
* @param {Object} blockType Block type
* @param {Object} attributes Current block attributes
* @return {Object} Filtered props applied to save element
*/
export function addSaveProps( extraProps, blockType, attributes ) {
if ( hasBlockSupport( blockType, 'anchor' ) ) {
extraProps.id = attributes.anchor;
}
return extraProps;
}
export default function anchor( { addFilter } ) {
addFilter( 'registerBlockType', 'core\anchor-attribute', addAttribute );
addFilter( 'BlockEdit', 'core\anchor-inspector-control', addInspectorControl );
addFilter( 'getSaveContent.extraProps', 'core\anchor-save-props', addSaveProps );
}