PluginProbe
Tableberg – Simple Gutenberg Table Block / 1.1.5
Tableberg – Simple Gutenberg Table Block v1.1.5
1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.5 1.0.4 1.0.3 1.0.2 1.0.1 trunk 0.0.2 0.2.1 0.3.2 0.3.3 0.4.1 0.5.0 0.5.1 0.5.2 0.5.3 0.5.4 0.5.5 0.5.6 0.5.7 All 42 releases
← All changes | renderer/Cell/CellRenderer.php +98 -55 1.1.01.1.5 View file →
@@ -8,8 +8,9 @@
8 8 use Tableberg\Renderer\ListEl\ListRenderer;
9 9 use Tableberg\Renderer\Text\TextRenderer;
10 10
11 11 use function apply_filters;
12 +use function Tableberg\Renderer\generate_css_string;
12 13 use function Tableberg\Renderer\getArrayOrNull;
13 14 use function Tableberg\Renderer\getStringOrNull;
14 15
15 16 class CellRenderer {
@@ -46,8 +47,65 @@
46 47 $context->cellStyleOverride,
47 48 $styleValues
48 49 );
49 50
51 + // Pro styling of a single cell goes through one filter rather than
52 + // one per property, so a new pro style needs no change here. Pro
53 + // gets the styles free resolved plus every attribute of the cell,
54 + // and returns the ones it wants rendered.
55 + //
56 + // Applied after the `styles` overrides rather than inside them: a
57 + // cell can carry a pro attribute without any `styles` at all.
58 + $proStyleValues = apply_filters(
59 + 'tableberg/cell_styles',
60 + $styleValues,
61 + $context->cellAttrs,
62 + $context
63 + );
64 + if (is_array($proStyleValues)) {
65 + // Merged, not replaced, so a filter that returns a partial set
66 + // cannot leave the renderer with missing keys.
67 + $styleValues = array_merge($styleValues, $proStyleValues);
68 + }
69 +
70 + // Table-wide Pro grid modes win over common and individual cell
71 + // borders. They render inner separators only; the separate table
72 + // border control owns the outside rectangle.
73 + if ($context->innerBorderType === 'row') {
74 + $styleValues['borderLeft'] = '';
75 + $styleValues['borderRight'] = '';
76 + if ($context->row === 0) {
77 + $styleValues['borderTop'] = '';
78 + }
79 + if ($context->row + $context->rowSpan >= $context->totalRows) {
80 + $styleValues['borderBottom'] = '';
81 + }
82 + } elseif ($context->innerBorderType === 'col') {
83 + $styleValues['borderTop'] = '';
84 + $styleValues['borderBottom'] = '';
85 + if ($context->col === 0) {
86 + $styleValues['borderLeft'] = '';
87 + }
88 + if ($context->col + $context->colSpan >= $context->totalCols) {
89 + $styleValues['borderRight'] = '';
90 + }
91 + }
92 +
93 + if ($context->isEmpty) {
94 + // An "empty cell" renders as a bare, unstyled cell on the
95 + // frontend: no content, and no background/border either, so it
96 + // is indistinguishable from a cell that was never styled.
97 + $styleValues['backgroundColor'] = '';
98 + $styleValues['borderTop'] = '';
99 + $styleValues['borderRight'] = '';
100 + $styleValues['borderBottom'] = '';
101 + $styleValues['borderLeft'] = '';
102 + $styleValues['borderTopLeftRadius'] = '';
103 + $styleValues['borderTopRightRadius'] = '';
104 + $styleValues['borderBottomRightRadius'] = '';
105 + $styleValues['borderBottomLeftRadius'] = '';
106 + }
107 +
50 108 $isStickyHeaderCell =
51 109 $context->stickyHeader &&
52 110 $context->row === 0 &&
53 111 $context->tag === 'th';
@@ -54,82 +112,82 @@
54 112
55 113 $isStickyFirstColCell =
56 114 $context->stickyFirstCol && $context->col === 0;
57 115
58 - $styleParts = ['position:relative'];
116 + $styleParts = ['position' => 'relative'];
59 117 if ($styleValues['paddingTop'] !== '') {
60 - $styleParts[] = 'padding-top:' . $styleValues['paddingTop'];
118 + $styleParts['padding-top'] = $styleValues['paddingTop'];
61 119 }
62 120 if ($styleValues['paddingRight'] !== '') {
63 - $styleParts[] = 'padding-right:' . $styleValues['paddingRight'];
121 + $styleParts['padding-right'] = $styleValues['paddingRight'];
64 122 }
65 123 if ($styleValues['paddingBottom'] !== '') {
66 - $styleParts[] = 'padding-bottom:' . $styleValues['paddingBottom'];
124 + $styleParts['padding-bottom'] = $styleValues['paddingBottom'];
67 125 }
68 126 if ($styleValues['paddingLeft'] !== '') {
69 - $styleParts[] = 'padding-left:' . $styleValues['paddingLeft'];
127 + $styleParts['padding-left'] = $styleValues['paddingLeft'];
70 128 }
71 129 if ($styleValues['verticalAlign'] !== '') {
72 - $styleParts[] = 'vertical-align:' . $styleValues['verticalAlign'];
130 + $styleParts['vertical-align'] = $styleValues['verticalAlign'];
73 131 }
74 132 if ($styleValues['backgroundColor'] !== '') {
75 - $styleParts[] = 'background-color:' . $styleValues['backgroundColor'];
133 + $styleParts['background-color'] = $styleValues['backgroundColor'];
76 134 }
77 135 if ($styleValues['borderTop'] !== '') {
78 - $styleParts[] = 'border-top:' . $styleValues['borderTop'];
136 + $styleParts['border-top'] = $styleValues['borderTop'];
79 137 }
80 138 if ($styleValues['borderRight'] !== '') {
81 - $styleParts[] = 'border-right:' . $styleValues['borderRight'];
139 + $styleParts['border-right'] = $styleValues['borderRight'];
82 140 }
83 141 if ($styleValues['borderBottom'] !== '') {
84 - $styleParts[] = 'border-bottom:' . $styleValues['borderBottom'];
142 + $styleParts['border-bottom'] = $styleValues['borderBottom'];
85 143 }
86 144 if ($styleValues['borderLeft'] !== '') {
87 - $styleParts[] = 'border-left:' . $styleValues['borderLeft'];
145 + $styleParts['border-left'] = $styleValues['borderLeft'];
88 146 }
89 147 if ($styleValues['borderTopLeftRadius'] !== '') {
90 - $styleParts[] = 'border-top-left-radius:' . $styleValues['borderTopLeftRadius'];
148 + $styleParts['border-top-left-radius'] = $styleValues['borderTopLeftRadius'];
91 149 }
92 150 if ($styleValues['borderTopRightRadius'] !== '') {
93 - $styleParts[] = 'border-top-right-radius:' . $styleValues['borderTopRightRadius'];
151 + $styleParts['border-top-right-radius'] = $styleValues['borderTopRightRadius'];
94 152 }
95 153 if ($styleValues['borderBottomRightRadius'] !== '') {
96 - $styleParts[] = 'border-bottom-right-radius:' . $styleValues['borderBottomRightRadius'];
154 + $styleParts['border-bottom-right-radius'] = $styleValues['borderBottomRightRadius'];
97 155 }
98 156 if ($styleValues['borderBottomLeftRadius'] !== '') {
99 - $styleParts[] = 'border-bottom-left-radius:' . $styleValues['borderBottomLeftRadius'];
157 + $styleParts['border-bottom-left-radius'] = $styleValues['borderBottomLeftRadius'];
100 158 }
101 159 if ($context->colSpan === 1 && $context->width !== null && $context->width !== '') {
102 - $styleParts[] = 'width:' . $context->width;
103 - $styleParts[] = 'min-width:' . $context->width;
160 + $styleParts['width'] = $context->width;
161 + $styleParts['min-width'] = $context->width;
104 162 }
105 163 if ($context->rowSpan === 1 && $context->height !== null && $context->height !== '') {
106 - $styleParts[] = 'height:' . $context->height;
107 - $styleParts[] = 'min-height:' . $context->height;
164 + $styleParts['height'] = $context->height;
165 + $styleParts['min-height'] = $context->height;
108 166 }
109 167
110 168 if ($isStickyHeaderCell) {
111 - $styleParts[] = 'position:sticky';
112 - $styleParts[] = 'top:0';
113 - $styleParts[] = $isStickyFirstColCell ? 'z-index:3' : 'z-index:2';
169 + $styleParts['position'] = 'sticky';
170 + $styleParts['top'] = '0';
171 + $styleParts['z-index'] = $isStickyFirstColCell ? '3' : '2';
114 172
115 173 if ($styleValues['backgroundColor'] === '') {
116 - $styleParts[] = 'background-color:#fff';
174 + $styleParts['background-color'] = '#fff';
117 175 }
118 176 }
119 177
120 178 if ($isStickyFirstColCell) {
121 179 if (!$isStickyHeaderCell) {
122 - $styleParts[] = 'position:sticky';
123 - $styleParts[] = 'z-index:1';
180 + $styleParts['position'] = 'sticky';
181 + $styleParts['z-index'] = '1';
124 182 }
125 - $styleParts[] = 'left:0';
183 + $styleParts['left'] = '0';
126 184
127 185 if (
128 186 !$isStickyHeaderCell &&
129 187 $styleValues['backgroundColor'] === ''
130 188 ) {
131 - $styleParts[] = 'background-color:#fff';
189 + $styleParts['background-color'] = '#fff';
132 190 }
133 191 }
134 192
135 193 $tag = $context->tag === 'th' ? 'th' : 'td';
@@ -149,9 +207,10 @@
149 207 if (!is_object($element)) {
150 208 continue;
151 209 }
152 210
153 - $name = getStringOrNull($element->name->asText()) ?? 'unknown';
211 + $elementName = $element->name->asText();
212 + $name = getStringOrNull($elementName) ?? 'unknown';
154 213 $attributes = is_array($element->attributes)
155 214 ? $element->attributes
156 215 : [];
157 216
@@ -280,9 +339,9 @@
280 339 >
281 340 ▲▼
282 341 </span>" : '';
283 342
284 - $stylesStr = implode(';', $styleParts);
343 + $stylesStr = generate_css_string($styleParts);
285 344
286 345 $attrsStr = ($tag === 'th' && $sortableType !== null) ?
287 346 "data-sortable='{$sortableType}'
288 347 role='button'
@@ -363,9 +422,10 @@
363 422 if (!is_object($element)) {
364 423 continue;
365 424 }
366 425
367 - $name = getStringOrNull($element->name->asText()) ?? 'unknown';
426 + $elementName = $element->name->asText();
427 + $name = getStringOrNull($elementName) ?? 'unknown';
368 428 $attributes = is_array($element->attributes)
369 429 ? $element->attributes
370 430 : [];
371 431
@@ -410,13 +470,8 @@
410 470 $styleValues['paddingLeft'] = $overridePadding['left']->asAttr();
411 471 }
412 472 }
413 473
414 - if (isset($cellStyleOverride['backgroundColor'])
415 - && $cellStyleOverride['backgroundColor'] instanceof StringAttr) {
416 - $styleValues['backgroundColor'] = $cellStyleOverride['backgroundColor']->asAttr();
417 - }
418 -
419 474 if (isset($cellStyleOverride['orientation'])
420 475 && $cellStyleOverride['orientation'] instanceof StringAttr) {
421 476 $orientation = $cellStyleOverride['orientation']->asAttr();
422 477 $styleValues['orientation'] = $orientation;
@@ -432,29 +487,17 @@
432 487 && $cellStyleOverride['elementGap'] instanceof StringAttr) {
433 488 $styleValues['elementGap'] = $cellStyleOverride['elementGap']->asAttr();
434 489 }
435 490
436 - if (isset($cellStyleOverride['verticalAlign'])
437 - && $cellStyleOverride['verticalAlign'] instanceof StringAttr) {
438 - $verticalAlign = $cellStyleOverride['verticalAlign']->asAttr();
439 - $styleValues['verticalAlign'] = $verticalAlign;
440 - }
491 + // A cell's own vertical alignment is a pro feature, resolved through
492 + // the `tableberg/cell_styles` filter below. Free only applies the
493 + // table-wide default, so it can't be switched on without a licence.
441 494
442 - $overrideBorder = getArrayOrNull($cellStyleOverride['border']);
443 - if (is_array($overrideBorder)) {
444 - if (isset($overrideBorder['top']) && $overrideBorder['top'] instanceof StringAttr) {
445 - $styleValues['borderTop'] = $overrideBorder['top']->asAttr();
446 - }
447 - if (isset($overrideBorder['right']) && $overrideBorder['right'] instanceof StringAttr) {
448 - $styleValues['borderRight'] = $overrideBorder['right']->asAttr();
449 - }
450 - if (isset($overrideBorder['bottom']) && $overrideBorder['bottom'] instanceof StringAttr) {
451 - $styleValues['borderBottom'] = $overrideBorder['bottom']->asAttr();
452 - }
453 - if (isset($overrideBorder['left']) && $overrideBorder['left'] instanceof StringAttr) {
454 - $styleValues['borderLeft'] = $overrideBorder['left']->asAttr();
455 - }
456 - }
495 + // Border is a pro attribute now (moved off this shared `styles`
496 + // object, same as backgroundColor before it), resolved instead
497 + // through the `tableberg/cell_styles` filter below — not here, or
498 + // it would keep rendering a lapsed/legacy border regardless of
499 + // licence status.
457 500
458 501 $overrideBorderRadius = getArrayOrNull($cellStyleOverride['borderRadius']);
459 502 if (is_array($overrideBorderRadius)) {
460 503 if (isset($overrideBorderRadius['topLeft'])