Skip to content

Commit 66e2965

Browse files
authored
release: fixes
- fixes experimental blocks interactivity state management
2 parents d55eab2 + b7640e8 commit 66e2965

3 files changed

Lines changed: 102 additions & 7 deletions

File tree

inc/plugins/class-atomic-wind-blocks.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -751,9 +751,12 @@ public function render_state_attrs( $block_content, $block ) {
751751

752752
$has_state = false;
753753

754-
$show_if = isset( $block['attrs']['showIf'] ) ? $block['attrs']['showIf'] : '';
755-
$hide_if = isset( $block['attrs']['hideIf'] ) ? $block['attrs']['hideIf'] : '';
756-
$trigger = isset( $block['attrs']['stateTrigger'] ) ? $block['attrs']['stateTrigger'] : '';
754+
$show_if = isset( $block['attrs']['showIf'] ) ? $block['attrs']['showIf'] : '';
755+
$hide_if = isset( $block['attrs']['hideIf'] ) ? $block['attrs']['hideIf'] : '';
756+
$trigger = isset( $block['attrs']['stateTrigger'] ) ? $block['attrs']['stateTrigger'] : '';
757+
$state_action = isset( $block['attrs']['stateAction'] ) ? $block['attrs']['stateAction'] : 'toggle';
758+
$state_value = isset( $block['attrs']['stateValue'] ) ? $block['attrs']['stateValue'] : '';
759+
$state_default = ! empty( $block['attrs']['stateDefault'] );
757760

758761
if ( $show_if || $hide_if || $trigger ) {
759762
$has_state = true;
@@ -772,12 +775,24 @@ public function render_state_attrs( $block_content, $block ) {
772775
if ( $hide_if ) {
773776
$attrs .= ' data-hide-if="' . esc_attr( $hide_if ) . '"';
774777
}
778+
if ( $trigger ) {
779+
$attrs .= ' data-state-trigger="' . esc_attr( $trigger ) . '"';
780+
$attrs .= ' data-state-action="' . esc_attr( $state_action ) . '"';
775781

776-
if ( ! $attrs || false !== strpos( $block_content, 'data-show-if' ) || false !== strpos( $block_content, 'data-hide-if' ) ) {
782+
if ( 'set' === $state_action && $state_value ) {
783+
$attrs .= ' data-state-value="' . esc_attr( $state_value ) . '"';
784+
}
785+
786+
if ( $state_default ) {
787+
$attrs .= ' data-state-default';
788+
}
789+
}
790+
791+
if ( ! $attrs || false !== strpos( $block_content, 'data-show-if' ) || false !== strpos( $block_content, 'data-hide-if' ) || false !== strpos( $block_content, 'data-state-trigger' ) ) {
777792
return $block_content;
778793
}
779794

780-
return preg_replace( '/^(<[a-zA-Z][a-zA-Z0-9]*)\b/', '$1' . $attrs, $block_content, 1 );
795+
return preg_replace( '/^(\s*<[a-zA-Z][a-zA-Z0-9]*)\b/', '$1' . $attrs, $block_content, 1 );
781796
}
782797

783798
/**

src/atomic-wind/states/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ addFilter(
216216
'blocks.getSaveContent.extraProps',
217217
'atomic-wind/state-save-props',
218218
( extraProps, blockType, attributes ) => {
219-
if ( blockType.category !== 'otter-blocks' ) {
219+
if ( blockType.category !== 'atomic-wind' ) {
220220
return extraProps;
221221
}
222222

tests/test-atomic-wind-blocks.php

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,92 @@ public function test_state_injects_both_show_and_hide() {
243243
$this->assertStringContainsString( 'data-hide-if="disabled"', $result );
244244
}
245245

246-
public function test_state_trigger_only_does_not_inject_visibility_attrs() {
246+
public function test_state_trigger_injects_trigger_attrs_not_visibility() {
247247
$block = $this->make_block( 'atomic-wind/text', array( 'stateTrigger' => 'tabs' ) );
248248
$content = '<p class="wp-block">Trigger</p>';
249249

250250
$result = $this->instance->render_state_attrs( $content, $block );
251251

252+
$this->assertStringContainsString( 'data-state-trigger="tabs"', $result );
253+
$this->assertStringContainsString( 'data-state-action="toggle"', $result );
254+
$this->assertStringNotContainsString( 'data-show-if', $result );
255+
$this->assertStringNotContainsString( 'data-hide-if', $result );
256+
}
257+
258+
public function test_state_trigger_set_action_injects_value() {
259+
$block = $this->make_block( 'atomic-wind/link', array(
260+
'stateTrigger' => 'season',
261+
'stateAction' => 'set',
262+
'stateValue' => 'spring',
263+
) );
264+
$content = '<a class="wp-block">Spring</a>';
265+
266+
$result = $this->instance->render_state_attrs( $content, $block );
267+
268+
$this->assertStringContainsString( 'data-state-trigger="season"', $result );
269+
$this->assertStringContainsString( 'data-state-action="set"', $result );
270+
$this->assertStringContainsString( 'data-state-value="spring"', $result );
271+
}
272+
273+
public function test_state_trigger_toggle_omits_value() {
274+
$block = $this->make_block( 'atomic-wind/text', array(
275+
'stateTrigger' => 'panel',
276+
'stateAction' => 'toggle',
277+
) );
278+
$content = '<p class="wp-block">Toggle</p>';
279+
280+
$result = $this->instance->render_state_attrs( $content, $block );
281+
282+
$this->assertStringContainsString( 'data-state-action="toggle"', $result );
283+
$this->assertStringNotContainsString( 'data-state-value', $result );
284+
}
285+
286+
public function test_state_trigger_default_attr() {
287+
$block = $this->make_block( 'atomic-wind/link', array(
288+
'stateTrigger' => 'season',
289+
'stateAction' => 'set',
290+
'stateValue' => 'all',
291+
'stateDefault' => true,
292+
) );
293+
$content = '<a class="wp-block">All</a>';
294+
295+
$result = $this->instance->render_state_attrs( $content, $block );
296+
297+
$this->assertStringContainsString( 'data-state-default', $result );
298+
}
299+
300+
public function test_state_handles_leading_whitespace() {
301+
$block = $this->make_block( 'atomic-wind/box', array( 'showIf' => 'active' ) );
302+
$content = "\n<div class=\"wp-block\">Content</div>";
303+
304+
$result = $this->instance->render_state_attrs( $content, $block );
305+
306+
$this->assertStringContainsString( 'data-show-if="active"', $result );
307+
}
308+
309+
public function test_state_trigger_value_escapes_xss() {
310+
$block = $this->make_block( 'atomic-wind/link', array(
311+
'stateTrigger' => 'x',
312+
'stateAction' => 'set',
313+
'stateValue' => '"><script>alert(1)</script>',
314+
) );
315+
$content = '<a class="wp-block">Link</a>';
316+
317+
$result = $this->instance->render_state_attrs( $content, $block );
318+
319+
$this->assertStringNotContainsString( '<script>', $result );
320+
}
321+
322+
public function test_state_skips_trigger_when_already_present() {
323+
$block = $this->make_block( 'atomic-wind/link', array(
324+
'stateTrigger' => 'tabs',
325+
'stateAction' => 'set',
326+
'stateValue' => 'one',
327+
) );
328+
$content = '<a data-state-trigger="tabs" data-state-action="set" data-state-value="one" class="wp-block">Tab</a>';
329+
330+
$result = $this->instance->render_state_attrs( $content, $block );
331+
252332
$this->assertSame( $content, $result );
253333
}
254334

0 commit comments

Comments
 (0)