@wordpress/block-editor
Version:
368 lines (305 loc) • 14.4 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.COLOR_SUPPORT_KEY = void 0;
exports.ColorEdit = ColorEdit;
exports.addEditProps = addEditProps;
exports.addSaveProps = addSaveProps;
exports.addTransforms = addTransforms;
exports.withColorPaletteStyles = void 0;
var _element = require("@wordpress/element");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _classnames = _interopRequireDefault(require("classnames"));
var _hooks = require("@wordpress/hooks");
var _blocks = require("@wordpress/blocks");
var _compose = require("@wordpress/compose");
var _colors = require("../components/colors");
var _gradients = require("../components/gradients");
var _utils = require("./utils");
var _useSetting = _interopRequireDefault(require("../components/use-setting"));
var _inspectorControls = _interopRequireDefault(require("../components/inspector-controls"));
var _colorPanel = _interopRequireWildcard(require("../components/global-styles/color-panel"));
var _contrastChecker = _interopRequireDefault(require("./contrast-checker"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const COLOR_SUPPORT_KEY = 'color';
exports.COLOR_SUPPORT_KEY = COLOR_SUPPORT_KEY;
const hasColorSupport = blockType => {
const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY);
return colorSupport && (colorSupport.link === true || colorSupport.gradient === true || colorSupport.background !== false || colorSupport.text !== false);
};
const hasLinkColorSupport = blockType => {
if (_element.Platform.OS !== 'web') {
return false;
}
const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY);
return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.link;
};
const hasGradientSupport = blockType => {
const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY);
return colorSupport !== null && typeof colorSupport === 'object' && !!colorSupport.gradients;
};
const hasBackgroundColorSupport = blockType => {
const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY);
return colorSupport && colorSupport.background !== false;
};
const hasTextColorSupport = blockType => {
const colorSupport = (0, _blocks.getBlockSupport)(blockType, COLOR_SUPPORT_KEY);
return colorSupport && colorSupport.text !== false;
};
/**
* Filters registered block settings, extending attributes to include
* `backgroundColor` and `textColor` attribute.
*
* @param {Object} settings Original block settings.
*
* @return {Object} Filtered block settings.
*/
function addAttributes(settings) {
if (!hasColorSupport(settings)) {
return settings;
} // Allow blocks to specify their own attribute definition with default values if needed.
if (!settings.attributes.backgroundColor) {
Object.assign(settings.attributes, {
backgroundColor: {
type: 'string'
}
});
}
if (!settings.attributes.textColor) {
Object.assign(settings.attributes, {
textColor: {
type: 'string'
}
});
}
if (hasGradientSupport(settings) && !settings.attributes.gradient) {
Object.assign(settings.attributes, {
gradient: {
type: 'string'
}
});
}
return settings;
}
/**
* Override props assigned to save component to inject colors classnames.
*
* @param {Object} props Additional props applied to save element.
* @param {Object} blockType Block type.
* @param {Object} attributes Block attributes.
*
* @return {Object} Filtered props applied to save element.
*/
function addSaveProps(props, blockType, attributes) {
if (!hasColorSupport(blockType) || (0, _utils.shouldSkipSerialization)(blockType, COLOR_SUPPORT_KEY)) {
return props;
}
const hasGradient = hasGradientSupport(blockType); // I'd have preferred to avoid the "style" attribute usage here
const {
backgroundColor,
textColor,
gradient,
style
} = attributes;
const shouldSerialize = feature => !(0, _utils.shouldSkipSerialization)(blockType, COLOR_SUPPORT_KEY, feature); // Primary color classes must come before the `has-text-color`,
// `has-background` and `has-link-color` classes to maintain backwards
// compatibility and avoid block invalidations.
const textClass = shouldSerialize('text') ? (0, _colors.getColorClassName)('color', textColor) : undefined;
const gradientClass = shouldSerialize('gradients') ? (0, _gradients.__experimentalGetGradientClass)(gradient) : undefined;
const backgroundClass = shouldSerialize('background') ? (0, _colors.getColorClassName)('background-color', backgroundColor) : undefined;
const serializeHasBackground = shouldSerialize('background') || shouldSerialize('gradients');
const hasBackground = backgroundColor || style?.color?.background || hasGradient && (gradient || style?.color?.gradient);
const newClassName = (0, _classnames.default)(props.className, textClass, gradientClass, {
// Don't apply the background class if there's a custom gradient.
[backgroundClass]: (!hasGradient || !style?.color?.gradient) && !!backgroundClass,
'has-text-color': shouldSerialize('text') && (textColor || style?.color?.text),
'has-background': serializeHasBackground && hasBackground,
'has-link-color': shouldSerialize('link') && style?.elements?.link?.color
});
props.className = newClassName ? newClassName : undefined;
return props;
}
/**
* Filters registered block settings to extend the block edit wrapper
* to apply the desired styles and classnames properly.
*
* @param {Object} settings Original block settings.
*
* @return {Object} Filtered block settings.
*/
function addEditProps(settings) {
if (!hasColorSupport(settings) || (0, _utils.shouldSkipSerialization)(settings, COLOR_SUPPORT_KEY)) {
return settings;
}
const existingGetEditWrapperProps = settings.getEditWrapperProps;
settings.getEditWrapperProps = attributes => {
let props = {};
if (existingGetEditWrapperProps) {
props = existingGetEditWrapperProps(attributes);
}
return addSaveProps(props, settings, attributes);
};
return settings;
}
function styleToAttributes(style) {
const textColorValue = style?.color?.text;
const textColorSlug = textColorValue?.startsWith('var:preset|color|') ? textColorValue.substring('var:preset|color|'.length) : undefined;
const backgroundColorValue = style?.color?.background;
const backgroundColorSlug = backgroundColorValue?.startsWith('var:preset|color|') ? backgroundColorValue.substring('var:preset|color|'.length) : undefined;
const gradientValue = style?.color?.gradient;
const gradientSlug = gradientValue?.startsWith('var:preset|gradient|') ? gradientValue.substring('var:preset|gradient|'.length) : undefined;
const updatedStyle = { ...style
};
updatedStyle.color = { ...updatedStyle.color,
text: textColorSlug ? undefined : textColorValue,
background: backgroundColorSlug ? undefined : backgroundColorValue,
gradient: gradientSlug ? undefined : gradientValue
};
return {
style: (0, _utils.cleanEmptyObject)(updatedStyle),
textColor: textColorSlug,
backgroundColor: backgroundColorSlug,
gradient: gradientSlug
};
}
function attributesToStyle(attributes) {
return { ...attributes.style,
color: { ...attributes.style?.color,
text: attributes.textColor ? 'var:preset|color|' + attributes.textColor : attributes.style?.color?.text,
background: attributes.backgroundColor ? 'var:preset|color|' + attributes.backgroundColor : attributes.style?.color?.background,
gradient: attributes.gradient ? 'var:preset|gradient|' + attributes.gradient : attributes.style?.color?.gradient
}
};
}
function ColorInspectorControl({
children,
resetAllFilter
}) {
const attributesResetAllFilter = (0, _element.useCallback)(attributes => {
const existingStyle = attributesToStyle(attributes);
const updatedStyle = resetAllFilter(existingStyle);
return { ...attributes,
...styleToAttributes(updatedStyle)
};
}, [resetAllFilter]);
return (0, _element.createElement)(_inspectorControls.default, {
group: "color",
resetAllFilter: attributesResetAllFilter
}, children);
}
function ColorEdit(props) {
const {
clientId,
name,
attributes,
setAttributes
} = props;
const settings = (0, _utils.useBlockSettings)(name);
const isEnabled = (0, _colorPanel.useHasColorPanel)(settings);
const value = (0, _element.useMemo)(() => {
return attributesToStyle({
style: attributes.style,
textColor: attributes.textColor,
backgroundColor: attributes.backgroundColor,
gradient: attributes.gradient
});
}, [attributes.style, attributes.textColor, attributes.backgroundColor, attributes.gradient]);
const onChange = newStyle => {
setAttributes(styleToAttributes(newStyle));
};
if (!isEnabled) {
return null;
}
const defaultControls = (0, _blocks.getBlockSupport)(props.name, [COLOR_SUPPORT_KEY, '__experimentalDefaultControls']);
const enableContrastChecking = _element.Platform.OS === 'web' && !value?.color?.gradient && (settings?.color?.text || settings?.color?.link) && // Contrast checking is enabled by default.
// Deactivating it requires `enableContrastChecker` to have
// an explicit value of `false`.
false !== (0, _blocks.getBlockSupport)(props.name, [COLOR_SUPPORT_KEY, 'enableContrastChecker']);
return (0, _element.createElement)(_colorPanel.default, {
as: ColorInspectorControl,
panelId: clientId,
settings: settings,
value: value,
onChange: onChange,
defaultControls: defaultControls,
enableContrastChecker: false !== (0, _blocks.getBlockSupport)(props.name, [COLOR_SUPPORT_KEY, 'enableContrastChecker'])
}, enableContrastChecking && (0, _element.createElement)(_contrastChecker.default, {
clientId: clientId
}));
}
/**
* This adds inline styles for color palette colors.
* Ideally, this is not needed and themes should load their palettes on the editor.
*
* @param {Function} BlockListBlock Original component.
*
* @return {Function} Wrapped component.
*/
const withColorPaletteStyles = (0, _compose.createHigherOrderComponent)(BlockListBlock => props => {
const {
name,
attributes
} = props;
const {
backgroundColor,
textColor
} = attributes;
const userPalette = (0, _useSetting.default)('color.palette.custom');
const themePalette = (0, _useSetting.default)('color.palette.theme');
const defaultPalette = (0, _useSetting.default)('color.palette.default');
const colors = (0, _element.useMemo)(() => [...(userPalette || []), ...(themePalette || []), ...(defaultPalette || [])], [userPalette, themePalette, defaultPalette]);
if (!hasColorSupport(name) || (0, _utils.shouldSkipSerialization)(name, COLOR_SUPPORT_KEY)) {
return (0, _element.createElement)(BlockListBlock, props);
}
const extraStyles = {};
if (textColor && !(0, _utils.shouldSkipSerialization)(name, COLOR_SUPPORT_KEY, 'text')) {
extraStyles.color = (0, _colors.getColorObjectByAttributeValues)(colors, textColor)?.color;
}
if (backgroundColor && !(0, _utils.shouldSkipSerialization)(name, COLOR_SUPPORT_KEY, 'background')) {
extraStyles.backgroundColor = (0, _colors.getColorObjectByAttributeValues)(colors, backgroundColor)?.color;
}
let wrapperProps = props.wrapperProps;
wrapperProps = { ...props.wrapperProps,
style: { ...extraStyles,
...props.wrapperProps?.style
}
};
return (0, _element.createElement)(BlockListBlock, (0, _extends2.default)({}, props, {
wrapperProps: wrapperProps
}));
}, 'withColorPaletteStyles');
exports.withColorPaletteStyles = withColorPaletteStyles;
const MIGRATION_PATHS = {
linkColor: [['style', 'elements', 'link', 'color', 'text']],
textColor: [['textColor'], ['style', 'color', 'text']],
backgroundColor: [['backgroundColor'], ['style', 'color', 'background']],
gradient: [['gradient'], ['style', 'color', 'gradient']]
};
function addTransforms(result, source, index, results) {
const destinationBlockType = result.name;
const activeSupports = {
linkColor: hasLinkColorSupport(destinationBlockType),
textColor: hasTextColorSupport(destinationBlockType),
backgroundColor: hasBackgroundColorSupport(destinationBlockType),
gradient: hasGradientSupport(destinationBlockType)
};
return (0, _utils.transformStyles)(activeSupports, MIGRATION_PATHS, result, source, index, results);
}
(0, _hooks.addFilter)('blocks.registerBlockType', 'core/color/addAttribute', addAttributes);
(0, _hooks.addFilter)('blocks.getSaveContent.extraProps', 'core/color/addSaveProps', addSaveProps);
(0, _hooks.addFilter)('blocks.registerBlockType', 'core/color/addEditProps', addEditProps);
(0, _hooks.addFilter)('editor.BlockListBlock', 'core/color/with-color-palette-styles', withColorPaletteStyles);
(0, _hooks.addFilter)('blocks.switchToBlockType.transformedBlock', 'core/color/addTransforms', addTransforms);
//# sourceMappingURL=color.js.map