diff --git a/core/modules/responsive_image/src/ResponsiveImageStyleForm.php b/core/modules/responsive_image/src/ResponsiveImageStyleForm.php index 04241fd..d97fd2a 100644 --- a/core/modules/responsive_image/src/ResponsiveImageStyleForm.php +++ b/core/modules/responsive_image/src/ResponsiveImageStyleForm.php @@ -114,22 +114,53 @@ public function form(array $form, FormStateInterface $form_state) { foreach ($breakpoint->getMultipliers() as $multiplier) { $label = $multiplier . ' ' . $breakpoint->getLabel() . ' [' . $breakpoint->getMediaQuery() . ']'; $form['keyed_styles'][$breakpoint_id][$multiplier] = array( - '#type' => 'container', + '#type' => 'details', + '#title' => $label, ); $image_style_mapping = $responsive_image_style->getImageStyleMapping($breakpoint_id, $multiplier); - // @todo The image_mapping_type is only temporarily hardcoded, until - // support for the other responsive image mapping type ('sizes') is - // added in https://www.drupal.org/node/2334387. $form['keyed_styles'][$breakpoint_id][$multiplier]['image_mapping_type'] = array( - '#type' => 'value', - '#value' => 'image_style', + '#title' => $this->t('Type'), + '#type' => 'radios', + '#options' => array( + '_none' => $this->t('Do not use this breakpoint'), + 'image_style' => $this->t('Use image styles'), + 'sizes' => $this->t('Use the sizes attribute'), + ), + '#default_value' => isset($image_style_mapping['image_mapping_type']) ? $image_style_mapping['image_mapping_type'] : '_none', ); - $form['keyed_styles'][$breakpoint_id][$multiplier]['image_mapping'] = array( + $form['keyed_styles'][$breakpoint_id][$multiplier]['image_style'] = array( '#type' => 'select', - '#title' => $label, + '#title' => $this->t('Image style'), '#options' => $image_styles, - '#default_value' => isset($image_style_mapping['image_mapping']) ? $image_style_mapping['image_mapping'] : array(), + '#default_value' => isset($image_style_mapping['image_mapping']) && is_string($image_style_mapping['image_mapping']) ? $image_style_mapping['image_mapping'] : '', '#description' => $this->t('Select an image style for this breakpoint.'), + '#states' => array( + 'visible' => array( + ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => array('value' => 'image_style'), + ), + ), + ); + $form['keyed_styles'][$breakpoint_id][$multiplier]['sizes'] = array( + '#type' => 'textfield', + '#title' => $this->t('Sizes'), + '#default_value' => isset($image_style_mapping['image_mapping']['sizes']) ? $image_style_mapping['image_mapping']['sizes'] : '', + '#description' => $this->t('Enter the value for the sizes attribute (e.g. "(min-width:700px) 700px, 100vw").'), + '#states' => array( + 'visible' => array( + ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => array('value' => 'sizes'), + ), + ), + ); + $form['keyed_styles'][$breakpoint_id][$multiplier]['sizes_image_styles'] = array( + '#title' => $this->t('Image styles'), + '#type' => 'checkboxes', + '#options' => array_diff_key($image_styles, array('' => '')), + '#default_value' => isset($image_style_mapping['image_mapping']['sizes_image_styles']) ? $image_style_mapping['image_mapping']['sizes_image_styles'] : array(), + '#states' => array( + 'visible' => array( + ':input[name="keyed_styles[' . $breakpoint_id . '][' . $multiplier . '][image_mapping_type]"]' => array('value' => 'sizes'), + ), + ), ); } } @@ -150,9 +181,6 @@ public function validate(array $form, FormStateInterface $form_state) { // Remove the image style mappings since the breakpoint ID has changed. $form_state->unsetValue('keyed_styles'); } - // @todo Filter 'sizes_image_styles' to a normal array in - // https://www.drupal.org/node/2334387. For an example see - // \Drupal\Core\Block\BlockBase::validateConfigurationForm(). } } @@ -167,7 +195,23 @@ public function save(array $form, FormStateInterface $form_state) { if ($form_state->hasValue('keyed_styles')) { foreach ($form_state->getValue('keyed_styles') as $breakpoint_id => $multipliers) { foreach ($multipliers as $multiplier => $image_style_mapping) { - $responsive_image_style->addImageStyleMapping($breakpoint_id, $multiplier, $image_style_mapping); + if ($image_style_mapping['image_mapping_type'] == 'sizes') { + $mapping = array( + 'image_mapping_type' => 'sizes', + 'image_mapping' => array( + 'sizes' => $image_style_mapping['sizes'], + 'sizes_image_styles' => array_keys(array_filter($image_style_mapping['sizes_image_styles'])), + ) + ); + $responsive_image_style->addImageStyleMapping($breakpoint_id, $multiplier, $mapping); + } + else if ($image_style_mapping['image_mapping_type'] == 'image_style') { + $mapping = array( + 'image_mapping_type' => 'image_style', + 'image_mapping' => $image_style_mapping['image_style'] + ); + $responsive_image_style->addImageStyleMapping($breakpoint_id, $multiplier, $mapping); + } } } } diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php index fae8cf8..5498e2a 100644 --- a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php +++ b/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php @@ -79,7 +79,15 @@ public function testResponsiveImageAdmin() { foreach ($cases as $case) { // Check if the radio buttons are present. - $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][image_mapping]', ''); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][image_mapping_type]', ''); + // Check if the image style dropdowns are present. + $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][image_style]', ''); + // Check if the sizes textfields are present. + $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][sizes]', ''); + // Check if the image styles checkboxes are present. + foreach (array_keys(image_style_options(FALSE)) as $image_style_name) { + $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][sizes_image_styles][' . $image_style_name . ']'); + } } // Save styles for 1x variant only. @@ -87,24 +95,35 @@ public function testResponsiveImageAdmin() { 'label' => 'Style One', 'breakpoint_group' => 'responsive_image_test_module', 'fallback_image_style' => 'thumbnail', - 'keyed_styles[responsive_image_test_module.mobile][1x][image_mapping]' => 'thumbnail', - 'keyed_styles[responsive_image_test_module.narrow][1x][image_mapping]' => 'medium', - 'keyed_styles[responsive_image_test_module.wide][1x][image_mapping]' => 'large', + 'keyed_styles[responsive_image_test_module.mobile][1x][image_mapping_type]' => 'image_style', + 'keyed_styles[responsive_image_test_module.mobile][1x][image_style]' => 'thumbnail', + 'keyed_styles[responsive_image_test_module.narrow][1x][image_mapping_type]' => 'sizes', + 'keyed_styles[responsive_image_test_module.narrow][1x][sizes]' => '(min-width: 700px) 700px, 100vw', + 'keyed_styles[responsive_image_test_module.narrow][1x][sizes_image_styles][large]' => 'large', + 'keyed_styles[responsive_image_test_module.narrow][1x][sizes_image_styles][medium]' => 'medium', + 'keyed_styles[responsive_image_test_module.wide][1x][image_mapping_type]' => 'image_style', + 'keyed_styles[responsive_image_test_module.wide][1x][image_style]' => 'large', ); $this->drupalPostForm('admin/config/media/responsive-image-style/style_one', $edit, t('Save')); $this->drupalGet('admin/config/media/responsive-image-style/style_one'); - // Check the style for multipliers 1x and 2x for the mobile breakpoint. - $this->assertFieldByName('keyed_styles[responsive_image_test_module.mobile][1x][image_mapping]', 'thumbnail'); - $this->assertFieldByName('keyed_styles[responsive_image_test_module.mobile][2x][image_mapping]', ''); - - // Check the style for multipliers 1x and 2x for the narrow breakpoint. - $this->assertFieldByName('keyed_styles[responsive_image_test_module.narrow][1x][image_mapping]', 'medium'); - $this->assertFieldByName('keyed_styles[responsive_image_test_module.narrow][2x][image_mapping]', ''); - - // Check the style for multipliers 1x and 2x for the wide breakpoint. - $this->assertFieldByName('keyed_styles[responsive_image_test_module.wide][1x][image_mapping]', 'large'); - $this->assertFieldByName('keyed_styles[responsive_image_test_module.wide][2x][image_mapping]', ''); + // Check the mapping for multipliers 1x and 2x for the mobile breakpoint. + $this->assertFieldByName('keyed_styles[responsive_image_test_module.mobile][1x][image_style]', 'thumbnail'); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.mobile][1x][image_mapping_type]', 'image_style'); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.mobile][2x][image_mapping_type]', '_none'); + + // Check the mapping for multipliers 1x and 2x for the narrow breakpoint. + $this->assertFieldByName('keyed_styles[responsive_image_test_module.narrow][1x][image_mapping_type]', 'sizes'); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.narrow][1x][sizes]', '(min-width: 700px) 700px, 100vw'); + $this->assertFieldChecked('edit-keyed-styles-responsive-image-test-modulenarrow-1x-sizes-image-styles-large'); + $this->assertFieldChecked('edit-keyed-styles-responsive-image-test-modulenarrow-1x-sizes-image-styles-medium'); + $this->assertNoFieldChecked('edit-keyed-styles-responsive-image-test-modulenarrow-1x-sizes-image-styles-thumbnail'); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.narrow][2x][image_mapping_type]', '_none'); + + // Check the mapping for multipliers 1x and 2x for the wide breakpoint. + $this->assertFieldByName('keyed_styles[responsive_image_test_module.wide][1x][image_style]', 'large'); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.wide][1x][image_mapping_type]', 'image_style'); + $this->assertFieldByName('keyed_styles[responsive_image_test_module.wide][2x][image_mapping_type]', '_none'); // Delete the style. $this->drupalGet('admin/config/media/responsive-image-style/style_one/delete');