Extend CSS converter
Scope: Internal — there is no public registration hook. The full documented outcome requires a PR against Elementor Core (
Converter_Registry_Factory/Expander_Registry_Factory), or a privateCss_Converterinstance not integrated into core import. Full split + disclaimer: skills-scope.md.
Implementation location
- Fork/clone elementor/elementor.
- Implement in
modules/atomic-widgets/css-converter/:converter-registry-factory.php,expander-registry-factory.phpexpanders/,converters/
- Add PHPUnit under
tests/phpunit/elementor/modules/atomic-widgets/css-converter/. - Submit PR against Core. Third-party plugins cannot wire converters into the core import pipeline.
- Skill fixture (boundary demo):
tests/phpunit/elementor/modules/atomic-widgets/css-converter/test-skill-fixture-custom-registry.php— privateCss_Convertervs empty registry.
Read first: css-converter/extension.md, pipeline.md, overview.md. Example: docs/atomic-builder/examples/internal-extend-css-converter.md.
Prerequisites
- Experiment
e_atomic_elements— RESTPOST /wp-json/elementor/v1/css-to-atomicdepends on atomic module state. - New style schema keys from extend-prop-types need both schema work and converter +
covered_properties()work here.
Checklist (Internal-first)
- Confirm need — converter maps legacy CSS longhands/shorthands → atomic
Style_SchemaPropValues; not the same as style transformers at render time. - No public discovery hook — Core factory registration or private
Css_Converterwith custom registries (not wired to core import UI). - Shorthand → longhand — subclass
Shorthand_Expander_Base; register inExpander_Registry_Factory::create()— order matters (first match wins). Input rule:['property' => string, 'value' => string|null]. Each expanded rule must includeproperty,value, anddeclaration(e.g.'border-top-width: 1px') — seeshorthand-expander-base.php/border-shorthand-expander.php. - Longhand → PropValue — subclass
Property_Converter_Base; register inConverter_Registry_Factory::real_converters(). Return PropValues via the matching prop type's::generate()(e.g.String_Prop_Type::generate()for strings, not onlySize_Prop_Type::generate()). - Update coverage constants — add property to family constant:
STRING_PROPERTIES,SIZE_PROPERTIES,UNITLESS_SIZE_PROPERTIES,OTHER_PROPERTIES, etc.;covered_properties()merges them. CI:test-css-converter-rest-api.php::test_coverage__every_style_schema_property_is_hardcoded_as_covered. - PHPUnit — under
tests/phpunit/elementor/modules/atomic-widgets/css-converter/. Fast loop:tests/phpunit/run-unit.sh tests/phpunit/.../test-*.php. - Verify —
POST /wp-json/elementor/v1/css-to-atomicwith sample CSS; full suite:composer run testwith--filteras needed.
External partial APIs (do not satisfy this skill)
- Filter
elementor/atomic-widgets/styles/schemaextends schema only — does not register converters. Without factory + coverage updates, declarations route tocustomCssor fail CI. - Private
Css_Converterin a plugin proves the pattern but does not integrate core import UI.
External workaround (not integrated into Core import)
Third-party plugins cannot register via WordPress filter. Options:
- Open a core PR adding expander/converter to factory classes.
- Instantiate custom
Css_Converterwith privately built registries for plugin-internal migration tooling. Constructor requires aConversion_Failure_Reporter— usenew Null_Failure_Reporter()for tests/tooling (css-converter.php).
Internal implementation path
- Module:
modules/atomic-widgets/css-converter/ - Side longhands (
padding-top, etc.) merge viaObject_Side_Merge_Converter/Object_Field_Merge_Converter— not always top-levelcovered_properties()entries. - Pipeline routing:
propsvscustomCssvsrejected— pipeline.md.
See also
- fundamentals/style-schema.md
- extend-prop-types — style transformers after conversion (External)