diff --git a/core/core.libraries.yml b/core/core.libraries.yml index a56f674..e0031ba 100644 --- a/core/core.libraries.yml +++ b/core/core.libraries.yml @@ -678,9 +678,7 @@ normalize: picturefill: remote: https://github.com/scottjehl/picturefill - # @todo Contribute upstream and/or replace with upstream version. - # @see https://drupal.org/node/1775530 - version: VERSION + version: 2.0.0 js: assets/vendor/picturefill/picturefill.js: { weight: -10 } dependencies: diff --git a/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/Breakpoint.php b/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/Breakpoint.php index 2298106..aa137bd 100644 --- a/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/Breakpoint.php +++ b/core/modules/breakpoint/lib/Drupal/breakpoint/Entity/Breakpoint.php @@ -178,17 +178,17 @@ public function isValid() { if (preg_match('/[^0-9a-z_\-]/', $this->name)) { throw new InvalidBreakpointNameException(format_string("Invalid value '@name' for breakpoint name property. Breakpoint name property can only contain lowercase alphanumeric characters, underscores (_), and hyphens (-).", array('@name' => $this->name))); } - // Skip the empty media query provided by the breakpoint module. - if ($this->id != 'module.breakpoint._none') { - return $this::isValidMediaQuery($this->mediaQuery); - } - return TRUE; + return static::isValidMediaQuery($this->mediaQuery); } /** * {@inheritdoc} */ public static function isValidMediaQuery($media_query) { + // Allow empty media queries. + if (empty($media_query)) { + return TRUE; + } // Array describing all known media features and the expected value type or // an array containing the allowed values. $media_features = array( @@ -206,92 +206,89 @@ public static function isValidMediaQuery($media_query) { 'scan' => array('progressive', 'interlace'), 'grid' => 'integer', ); - if ($media_query) { - // Strip new lines and trim. - $media_query = str_replace(array("\r", "\n"), ' ', trim($media_query)); + // Strip new lines and trim. + $media_query = str_replace(array("\r", "\n"), ' ', trim($media_query)); - // Remove comments /* ... */. - $media_query = preg_replace('/\/\*[\s\S]*?\*\//', '', $media_query); + // Remove comments /* ... */. + $media_query = preg_replace('/\/\*[\s\S]*?\*\//', '', $media_query); - // Check media list. - $parts = explode(',', $media_query); - foreach ($parts as $part) { - // Split on ' and ' - $query_parts = explode(' and ', trim($part)); - $media_type_found = FALSE; - foreach ($query_parts as $query_part) { - $matches = array(); - // Try to match: '(media_feature: value)' and variants. - if (preg_match('/^\(([\w\-]+)(:\s?([\w\-\.]+))?\)/', trim($query_part), $matches)) { - // Single expression like '(color)'. - if (isset($matches[1]) && !isset($matches[2])) { - if (!array_key_exists($matches[1], $media_features)) { - throw new InvalidBreakpointMediaQueryException('Invalid media feature detected.'); - } + // Check media list. + $parts = explode(',', $media_query); + foreach ($parts as $part) { + // Split on ' and ' + $query_parts = explode(' and ', trim($part)); + $media_type_found = FALSE; + foreach ($query_parts as $query_part) { + $matches = array(); + // Try to match: '(media_feature: value)' and variants. + if (preg_match('/^\(([\w\-]+)(:\s?([\w\-\.]+))?\)/', trim($query_part), $matches)) { + // Single expression like '(color)'. + if (isset($matches[1]) && !isset($matches[2])) { + if (!array_key_exists($matches[1], $media_features)) { + throw new InvalidBreakpointMediaQueryException('Invalid media feature detected.'); } - // Full expression like '(min-width: 20em)'. - elseif (isset($matches[3]) && !isset($matches[4])) { - $value = trim($matches[3]); - if (!array_key_exists($matches[1], $media_features)) { - // We need to allow vendor prefixed media features and make sure - // we are future proof, so only check allowed characters. - if (!preg_match('/^[a-zA-Z0-9\:\-\\ ]+$/i', trim($matches[1]))) { - throw new InvalidBreakpointMediaQueryException('Invalid media query detected.'); - } + } + // Full expression like '(min-width: 20em)'. + elseif (isset($matches[3]) && !isset($matches[4])) { + $value = trim($matches[3]); + if (!array_key_exists($matches[1], $media_features)) { + // We need to allow vendor prefixed media features and make sure + // we are future proof, so only check allowed characters. + if (!preg_match('/^[a-zA-Z0-9\:\-\\ ]+$/i', trim($matches[1]))) { + throw new InvalidBreakpointMediaQueryException('Invalid media query detected.'); } - elseif (is_array($media_features[$matches[1]])) { - // Check if value is allowed. - if (!array_key_exists($value, $media_features[$matches[1]])) { - throw new InvalidBreakpointMediaQueryException('Value is not allowed.'); - } + } + elseif (is_array($media_features[$matches[1]])) { + // Check if value is allowed. + if (!array_key_exists($value, $media_features[$matches[1]])) { + throw new InvalidBreakpointMediaQueryException('Value is not allowed.'); } - elseif (isset ($media_features[$matches[1]])) { - switch ($media_features[$matches[1]]) { - case 'length': - $length_matches = array(); - // Check for a valid number and an allowed unit. - if (preg_match('/^(\-)?(\d+(?:\.\d+)?)?((?:|em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|dpi|dpcm))$/i', trim($value), $length_matches)) { - // Only -0 is allowed. - if ($length_matches[1] === '-' && $length_matches[2] !== '0') { - throw new InvalidBreakpointMediaQueryException('Invalid length detected.'); - } - // If there's a unit, a number is needed as well. - if ($length_matches[2] === '' && $length_matches[3] !== '') { - throw new InvalidBreakpointMediaQueryException('Unit found, value is missing.'); - } + } + elseif (isset ($media_features[$matches[1]])) { + switch ($media_features[$matches[1]]) { + case 'length': + $length_matches = array(); + // Check for a valid number and an allowed unit. + if (preg_match('/^(\-)?(\d+(?:\.\d+)?)?((?:|em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|dpi|dpcm))$/i', trim($value), $length_matches)) { + // Only -0 is allowed. + if ($length_matches[1] === '-' && $length_matches[2] !== '0') { + throw new InvalidBreakpointMediaQueryException('Invalid length detected.'); } - else { - throw new InvalidBreakpointMediaQueryException('Invalid unit detected.'); + // If there's a unit, a number is needed as well. + if ($length_matches[2] === '' && $length_matches[3] !== '') { + throw new InvalidBreakpointMediaQueryException('Unit found, value is missing.'); } - break; - } + } + else { + throw new InvalidBreakpointMediaQueryException('Invalid unit detected.'); + } + break; } } } + } - // Check for screen, only screen, not screen and variants. - elseif (preg_match('/^((?:only|not)?\s?)([\w\-]+)$/i', trim($query_part), $matches)) { - if ($media_type_found) { - throw new InvalidBreakpointMediaQueryException('Only one media type is allowed.'); - } - $media_type_found = TRUE; + // Check for screen, only screen, not screen and variants. + elseif (preg_match('/^((?:only|not)?\s?)([\w\-]+)$/i', trim($query_part), $matches)) { + if ($media_type_found) { + throw new InvalidBreakpointMediaQueryException('Only one media type is allowed.'); } - // Check for (scan), (only scan), (not scan) and variants. - elseif (preg_match('/^((?:only|not)\s?)\(([\w\-]+)\)$/i', trim($query_part), $matches)) { + $media_type_found = TRUE; + } + // Check for (scan), (only scan), (not scan) and variants. + elseif (preg_match('/^((?:only|not)\s?)\(([\w\-]+)\)$/i', trim($query_part), $matches)) { + throw new InvalidBreakpointMediaQueryException('Invalid media query detected.'); + } + else { + // We need to allow vendor prefixed media fetures and make sure we + // are future proof, so only check allowed characters. + if (!preg_match('/^[a-zA-Z0-9\-\\ ]+$/i', trim($query_part), $matches)) { throw new InvalidBreakpointMediaQueryException('Invalid media query detected.'); } - else { - // We need to allow vendor prefixed media fetures and make sure we - // are future proof, so only check allowed characters. - if (!preg_match('/^[a-zA-Z0-9\-\\ ]+$/i', trim($query_part), $matches)) { - throw new InvalidBreakpointMediaQueryException('Invalid media query detected.'); - } - } } } - return TRUE; } - throw new InvalidBreakpointMediaQueryException('Media query is empty.'); + return TRUE; } /** diff --git a/core/modules/breakpoint/tests/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php b/core/modules/breakpoint/tests/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php index 1186619..ddd862f 100644 --- a/core/modules/breakpoint/tests/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php +++ b/core/modules/breakpoint/tests/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php @@ -62,6 +62,8 @@ public function testValidMediaQueries() { 'screen and (-webkit-min-device-pixel-ratio: 7)', 'screen and (min-orientation: landscape)', 'screen and (max-orientation: landscape)', + // Empty media queries are allowed. + '', ); foreach ($media_queries as $media_query) { @@ -74,7 +76,6 @@ public function testValidMediaQueries() { */ public function testInvalidMediaQueries() { $media_queries = array( - '', 'not (orientation)', 'only (orientation)', 'all and not all', diff --git a/core/modules/responsive_image/lib/Drupal/responsive_image/ResponsiveImageMappingForm.php b/core/modules/responsive_image/lib/Drupal/responsive_image/ResponsiveImageMappingForm.php index 10163de..2908d6f 100644 --- a/core/modules/responsive_image/lib/Drupal/responsive_image/ResponsiveImageMappingForm.php +++ b/core/modules/responsive_image/lib/Drupal/responsive_image/ResponsiveImageMappingForm.php @@ -85,11 +85,11 @@ public function form(array $form, array &$form_state) { '#title' => t('Type'), '#type' => 'radios', '#options' => array( - '' => t('Do not use this breakpoint'), + '_none' => t('Do not use this breakpoint'), 'image_style' => t('Use image styles'), 'sizes' => t('Use the sizes attribute'), ), - '#default_value' => isset($mapping_definition['mapping_type']) ? $mapping_definition['mapping_type'] : '', + '#default_value' => isset($mapping_definition['mapping_type']) ? $mapping_definition['mapping_type'] : '_none', ); $form['mappings'][$breakpoint_id][$multiplier]['image_style'] = array( '#type' => 'select', diff --git a/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageAdminUITest.php b/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageAdminUITest.php index 19b62cf..f3e1b07 100644 --- a/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageAdminUITest.php +++ b/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageAdminUITest.php @@ -164,7 +164,7 @@ public function testResponsiveImageAdmin() { $this->assertFieldByName('mappings[custom.user.small][1x][image_style]', 'thumbnail'); $this->assertFieldByName('mappings[custom.user.small][1x][mapping_type]', 'image_style'); $this->assertFieldByName('mappings[custom.user.small][2x][image_style]', ''); - $this->assertFieldByName('mappings[custom.user.small][2x][mapping_type]', ''); + $this->assertFieldByName('mappings[custom.user.small][2x][mapping_type]', '_none'); $this->assertFieldByName('mappings[custom.user.medium][1x][image_style]', ''); $this->assertFieldByName('mappings[custom.user.medium][1x][mapping_type]', 'sizes'); $this->assertFieldByName('mappings[custom.user.medium][1x][sizes]', '(min-width: 700px) 700px, 100vw'); @@ -172,11 +172,11 @@ public function testResponsiveImageAdmin() { $this->assertFieldChecked('edit-mappings-customusermedium-1x-sizes-image-styles-medium'); $this->assertNoFieldChecked('edit-mappings-customusermedium-1x-sizes-image-styles-thumbnail'); $this->assertFieldByName('mappings[custom.user.medium][2x][image_style]', ''); - $this->assertFieldByName('mappings[custom.user.medium][2x][mapping_type]', ''); + $this->assertFieldByName('mappings[custom.user.medium][2x][mapping_type]', '_none'); $this->assertFieldByName('mappings[custom.user.large][1x][image_style]', 'large'); $this->assertFieldByName('mappings[custom.user.large][1x][mapping_type]', 'image_style'); $this->assertFieldByName('mappings[custom.user.large][2x][image_style]', ''); - $this->assertFieldByName('mappings[custom.user.large][2x][mapping_type]', ''); + $this->assertFieldByName('mappings[custom.user.large][2x][mapping_type]', '_none'); // Delete the mapping. $this->drupalGet('admin/config/media/responsive-image-mapping/mapping_one/delete'); diff --git a/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageFieldDisplayTest.php index f2a44dd..eae51dc 100644 --- a/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageFieldDisplayTest.php +++ b/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageFieldDisplayTest.php @@ -81,6 +81,19 @@ public function setUp() { $breakpoint->save(); $breakpoint_group->addBreakpoints(array($breakpoint)); } + // Empty breakpoint + $breakpoint = entity_create('breakpoint', array( + 'name' => 'none', + 'mediaQuery' => '', + 'source' => 'user', + 'sourceType' => Breakpoint::SOURCE_TYPE_USER_DEFINED, + 'multipliers' => array( + '1.5x' => 0, + '2x' => '2x', + ), + )); + $breakpoint->save(); + $breakpoint_group->addBreakpoints(array($breakpoint)); $breakpoint_group->save(); // Add responsive image mapping. @@ -112,6 +125,16 @@ public function setUp() { 'sizes' => '', 'sizes_image_styles' => array(), ); + $mappings['custom.user.none']['1x'] = array( + 'mapping_type' => 'sizes', + 'image_style' => '', + 'sizes' => '(min-width: 500px) 500px, 100vw', + 'sizes_image_styles' => array( + 'large' => 'large', + 'medium' => 'medium', + 'thumbnail' => 'thumbnail', + ), + ); $responsive_image_mapping->setMappings($mappings); $responsive_image_mapping->save(); } @@ -212,10 +235,15 @@ public function _testResponsiveImageFieldFormatters($scheme) { $this->assertRaw('/styles/large/'); $this->assertRaw('media="(min-width: 200px)"'); $this->assertRaw('media="(min-width: 400px)"'); - $this->assertRaw('media="(min-width: 600px)"'); $this->assertRaw('sizes="(min-width: 700px) 700px, 100vw"'); + $this->assertPattern('/media="\(min-width: 400px\)".+?sizes="\(min-width: 700px\) 700px, 100vw"/'); + $this->assertRaw('media="(min-width: 600px)"'); + // Make sure the empty breakpoint mapping doesn't have a media attribute. + $this->assertNoPattern('/media="[^"]*".+?sizes="\(min-width: 500px\) 500px, 100vw"/'); + $this->assertRaw('sizes="(min-width: 500px) 500px, 100vw"'); // Check for the MIME-type. $this->assertRaw('type="image/png"'); + $cache_tags = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Tags')); $this->assertTrue(in_array('responsive_image_mapping:mapping_one', $cache_tags)); $this->assertTrue(in_array('image_style:thumbnail', $cache_tags)); @@ -236,7 +264,7 @@ public function _testResponsiveImageFieldFormatters($scheme) { ), ); $default_output = drupal_render($fallback_image); - $this->assertRaw($default_output/*, 'Image style thumbnail formatter displaying correctly on full node view.'*/); + $this->assertRaw($default_output, 'Image style thumbnail formatter displaying correctly on full node view.'); if ($scheme == 'private') { // Log out and try to access the file. diff --git a/core/modules/breakpoint/config/install/breakpoint.breakpoint.module.breakpoint._none.yml b/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.none.yml similarity index 57% rename from core/modules/breakpoint/config/install/breakpoint.breakpoint.module.breakpoint._none.yml rename to core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.none.yml index 13d876c..37cd2cc 100644 --- a/core/modules/breakpoint/config/install/breakpoint.breakpoint.module.breakpoint._none.yml +++ b/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.none.yml @@ -1,9 +1,9 @@ -id: module.breakpoint._none -name: _none +id: theme.bartik.none +name: none label: None (empty media query) mediaQuery: '' -source: breakpoint -sourceType: module +source: bartik +sourceType: theme weight: 99 multipliers: 1x: 1x diff --git a/core/themes/bartik/config/install/breakpoint.breakpoint_group.theme.bartik.bartik.yml b/core/themes/bartik/config/install/breakpoint.breakpoint_group.theme.bartik.bartik.yml index 09212eb..ae73fc8 100644 --- a/core/themes/bartik/config/install/breakpoint.breakpoint_group.theme.bartik.bartik.yml +++ b/core/themes/bartik/config/install/breakpoint.breakpoint_group.theme.bartik.bartik.yml @@ -5,7 +5,7 @@ breakpoint_ids: - theme.bartik.mobile - theme.bartik.narrow - theme.bartik.wide - - module.breakpoint._none + - theme.bartik.none source: bartik sourceType: theme status: true