| @@ -133,10 +133,24 @@ | ||
| 133 | 133 | 'verticalAlignment', |
| 134 | 134 | 'isStackedOnMobile', |
| 135 | 135 | // media-text's image side is an attribute, not child order. |
| 136 | 136 | 'mediaPosition', |
| 137 | + // Without a size field the model writes picture size into style.css. | |
| 138 | + 'mediaWidth', | |
| 139 | + 'minHeight', | |
| 140 | + 'minHeightUnit', | |
| 141 | + // One field per colour; the patcher routes a slug or a hex into WP's pair. | |
| 142 | + 'overlayColor', | |
| 143 | + 'dimRatio', | |
| 144 | + 'iconColor', | |
| 145 | + 'iconBackgroundColor', | |
| 146 | + // The icon follows the network; a new url alone keeps the old icon. | |
| 147 | + 'service', | |
| 137 | 148 | ]; |
| 138 | 149 | |
| 150 | +// core/navigation paints from colour attributes but declares no supports.color. | |
| 151 | +const ATTRIBUTE_COLOR_TYPES = new Set(['core/navigation']); | |
| 152 | + | |
| 139 | 153 | const simpleAttrSchema = (definition) => { |
| 140 | 154 | if (!definition) return null; |
| 141 | 155 | const schema = {}; |
| 142 | 156 | if (definition.type) schema.type = definition.type; |
| @@ -147,8 +161,9 @@ | ||
| 147 | 161 | export const buildBlockSchema = (blockType) => { |
| 148 | 162 | if (!blockType) return null; |
| 149 | 163 | const attributes = blockType.attributes ?? {}; |
| 150 | 164 | const supports = blockType.supports ?? {}; |
| 165 | + const attrColor = ATTRIBUTE_COLOR_TYPES.has(blockType.name); | |
| 151 | 166 | const typography = supports.typography; |
| 152 | 167 | |
| 153 | 168 | const simple = Object.fromEntries( |
| 154 | 169 | SIMPLE_ATTRIBUTES.map((name) => [name, simpleAttrSchema(attributes[name])]), |
| @@ -156,8 +171,12 @@ | ||
| 156 | 171 | |
| 157 | 172 | const properties = prune({ |
| 158 | 173 | ...simple, |
| 159 | 174 | align: attributes.align ? alignSchema(supports.align) : null, |
| 175 | + // Quote and pullquote align text with an attribute, not a typography support. | |
| 176 | + textAlign: attributes.textAlign | |
| 177 | + ? { type: 'string', enum: ['left', 'center', 'right'] } | |
| 178 | + : null, | |
| 160 | 179 | layout: attributes.layout ? layoutSchema(supports) : null, |
| 161 | 180 | // Model-facing name; block-patch maps it back to the real home. |
| 162 | 181 | text: |
| 163 | 182 | RICH_TEXT_ATTRIBUTES.some((name) => attributes[name]) || |
| @@ -165,13 +184,17 @@ | ||
| 165 | 184 | ? str |
| 166 | 185 | : null, |
| 167 | 186 | url: attributes.url ? str : null, |
| 168 | 187 | backgroundColor: |
| 169 | - attributes.backgroundColor && colorChannel(supports.color, 'background') | |
| 188 | + attributes.backgroundColor && | |
| 189 | + (attrColor || colorChannel(supports.color, 'background')) | |
| 170 | 190 | ? str |
| 171 | 191 | : null, |
| 172 | 192 | textColor: |
| 173 | - attributes.textColor && colorChannel(supports.color, 'text') ? str : null, | |
| 193 | + attributes.textColor && | |
| 194 | + (attrColor || colorChannel(supports.color, 'text')) | |
| 195 | + ? str | |
| 196 | + : null, | |
| 174 | 197 | // Gradients omitted: the theme's preset slugs are too opaque for the model |
| 175 | 198 | // to pick reliably, so gradients go through style.css instead. |
| 176 | 199 | fontSize: attributes.fontSize && feat(typography, 'fontSize') ? str : null, |
| 177 | 200 | fontFamily: |