180 lines
3.9 KiB
JavaScript
180 lines
3.9 KiB
JavaScript
|
import { merge } from 'lodash';
|
||
|
|
||
|
import { applyFilters } from '@wordpress/hooks';
|
||
|
|
||
|
import conditionCheck from '../control-condition-check';
|
||
|
import { maybeDecode } from '../encode-decode';
|
||
|
|
||
|
const { controls: registeredControls } = window.VPGutenbergVariables;
|
||
|
|
||
|
/**
|
||
|
* Prepare styles from params
|
||
|
* Params example:
|
||
|
array(
|
||
|
'element' => '$ .inner-selector',
|
||
|
'property' => 'height',
|
||
|
'mask' => '$px',
|
||
|
)
|
||
|
*
|
||
|
* @param {string} selector CSS selector.
|
||
|
* @param {Mixed} value Property value.
|
||
|
* @param {Array} params Output params.
|
||
|
*
|
||
|
* @return {string}
|
||
|
*/
|
||
|
export function prepareStylesFromParams(selector, value, params) {
|
||
|
if (
|
||
|
!selector ||
|
||
|
typeof value === 'undefined' ||
|
||
|
value === '' ||
|
||
|
value === null ||
|
||
|
typeof params.property === 'undefined'
|
||
|
) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Value mask.
|
||
|
if (typeof params.mask !== 'undefined') {
|
||
|
value = params.mask.replace('$', value);
|
||
|
}
|
||
|
|
||
|
// Custom selector mask.
|
||
|
if (typeof params.element !== 'undefined' && /\$/g.test(params.element)) {
|
||
|
selector = params.element.replace('$', selector);
|
||
|
} else {
|
||
|
selector +=
|
||
|
typeof params.element !== 'undefined' ? ` ${params.element}` : '';
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
[selector]: {
|
||
|
[params.property]: value,
|
||
|
},
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if these control has dynamic CSS.
|
||
|
*
|
||
|
* @param {string} controlName control name.
|
||
|
*
|
||
|
* @return {boolean}
|
||
|
*/
|
||
|
export function hasDynamicCSS(controlName) {
|
||
|
return (
|
||
|
typeof registeredControls[controlName] !== 'undefined' &&
|
||
|
typeof registeredControls[controlName].style !== 'undefined' &&
|
||
|
registeredControls[controlName].style.length
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get dynamic CSS from options.
|
||
|
*
|
||
|
* @param {Array} options block options.
|
||
|
*
|
||
|
* @return {string}
|
||
|
*/
|
||
|
export default function getDynamicCSS(options) {
|
||
|
let result = '';
|
||
|
let selector = '';
|
||
|
|
||
|
if (typeof options.block_id !== 'undefined' && options.block_id) {
|
||
|
selector = options.block_id;
|
||
|
} else if (typeof options.id !== 'undefined' && options.id) {
|
||
|
selector = options.id;
|
||
|
}
|
||
|
if (!selector) {
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
selector = `.vp-id-${selector}`;
|
||
|
let controlStylesObject = {};
|
||
|
|
||
|
// Controls styles.
|
||
|
Object.keys(registeredControls).forEach((k) => {
|
||
|
const control = registeredControls[k];
|
||
|
let allow = typeof control.style !== 'undefined' && control.style;
|
||
|
|
||
|
// Check condition.
|
||
|
if (
|
||
|
allow &&
|
||
|
typeof control.condition !== 'undefined' &&
|
||
|
control.condition.length
|
||
|
) {
|
||
|
allow = conditionCheck(control.condition, options);
|
||
|
}
|
||
|
|
||
|
// Prepare styles.
|
||
|
if (allow) {
|
||
|
control.style.forEach((data) => {
|
||
|
let val = options[control.name];
|
||
|
val = applyFilters(
|
||
|
'vpf.editor.controls-dynamic-css-value',
|
||
|
val,
|
||
|
options,
|
||
|
control,
|
||
|
selector,
|
||
|
data
|
||
|
);
|
||
|
|
||
|
// Prepare Aspect Ratio control value.
|
||
|
if (control.type && control.type === 'aspect_ratio' && val) {
|
||
|
const ratioArray = val.split(':');
|
||
|
|
||
|
if (ratioArray[0] && ratioArray[1]) {
|
||
|
val = `${100 * (ratioArray[1] / ratioArray[0])}%`;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let stylesObject = prepareStylesFromParams(selector, val, data);
|
||
|
stylesObject = applyFilters(
|
||
|
'vpf.editor.controls-dynamic-css-styles-object',
|
||
|
stylesObject,
|
||
|
selector,
|
||
|
val,
|
||
|
data,
|
||
|
options,
|
||
|
control
|
||
|
);
|
||
|
|
||
|
if (stylesObject) {
|
||
|
controlStylesObject = merge(
|
||
|
controlStylesObject,
|
||
|
stylesObject
|
||
|
);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Prepare CSS of controls.
|
||
|
Object.keys(controlStylesObject).forEach((sel) => {
|
||
|
result += `${sel} {\n`;
|
||
|
|
||
|
Object.keys(controlStylesObject[sel]).forEach((prop) => {
|
||
|
result += ` ${prop}: ${controlStylesObject[sel][prop]};\n`;
|
||
|
});
|
||
|
|
||
|
result += `}\n`;
|
||
|
});
|
||
|
|
||
|
// Custom CSS.
|
||
|
if (typeof options.custom_css !== 'undefined' && options.custom_css) {
|
||
|
let customCss = options.custom_css;
|
||
|
|
||
|
// Decode.
|
||
|
customCss = maybeDecode(customCss);
|
||
|
|
||
|
// replace 'selector' to actual css selector.
|
||
|
customCss = customCss.replace(/selector/g, selector);
|
||
|
|
||
|
// a little security fix.
|
||
|
customCss = customCss.replace(/<\//g, '</');
|
||
|
|
||
|
result += customCss;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|