-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
utils.js
110 lines (102 loc) · 3.08 KB
/
utils.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
101
102
103
104
105
106
107
108
109
110
/**
* External dependencies
*/
import { pickBy, isEmpty, mapValues, get, setWith, clone, every } from 'lodash';
/**
* WordPress dependencies
*/
import { getBlockSupport } from '@wordpress/blocks';
const identity = ( x ) => x;
/**
* Removed falsy values from nested object.
*
* @param {*} object
* @return {*} Object cleaned from falsy values
*/
export const cleanEmptyObject = ( object ) => {
if (
object === null ||
typeof object !== 'object' ||
Array.isArray( object )
) {
return object;
}
const cleanedNestedObjects = pickBy(
mapValues( object, cleanEmptyObject ),
identity
);
return isEmpty( cleanedNestedObjects ) ? undefined : cleanedNestedObjects;
};
export function immutableSet( object, path, value ) {
return setWith( object ? clone( object ) : {}, path, value, clone );
}
export function transformStyles(
activeSupports,
migrationPaths,
result,
source,
index,
results
) {
// If there are no active supports return early.
if ( every( activeSupports, ( isActive ) => ! isActive ) ) {
return result;
}
// If the condition verifies we are probably in the presence of a wrapping transform
// e.g: nesting paragraphs in a group or columns and in that case the styles should not be transformed.
if ( results.length === 1 && result.innerBlocks.length === source.length ) {
return result;
}
// For cases where we have a transform from one block to multiple blocks
// or multiple blocks to one block we apply the styles of the first source block
// to the result(s).
let referenceBlockAttributes = source[ 0 ]?.attributes;
// If we are in presence of transform between more than one block in the source
// that has more than one block in the result
// we apply the styles on source N to the result N,
// if source N does not exists we do nothing.
if ( results.length > 1 && source.length > 1 ) {
if ( source[ index ] ) {
referenceBlockAttributes = source[ index ]?.attributes;
} else {
return result;
}
}
let returnBlock = result;
Object.entries( activeSupports ).forEach( ( [ support, isActive ] ) => {
if ( isActive ) {
migrationPaths[ support ].forEach( ( path ) => {
const styleValue = get( referenceBlockAttributes, path );
if ( styleValue ) {
returnBlock = {
...returnBlock,
attributes: immutableSet(
returnBlock.attributes,
path,
styleValue
),
};
}
} );
}
} );
return returnBlock;
}
/**
* Check whether serialization of specific block support feature or set should
* be skipped.
*
* @param {string|Object} blockType Block name or block type object.
* @param {string} featureSet Name of block support feature set.
* @param {string} feature Name of the individual feature to check.
*
* @return {boolean} Whether serialization should occur.
*/
export function shouldSkipSerialization( blockType, featureSet, feature ) {
const support = getBlockSupport( blockType, featureSet );
const skipSerialization = support?.__experimentalSkipSerialization;
if ( Array.isArray( skipSerialization ) ) {
return skipSerialization.includes( feature );
}
return skipSerialization;
}