public static function Breakpoint::isValidMediaQuery

Checks if a mediaQuery is valid.

Return value

bool Returns TRUE if the media query is valid.

Throws

\Drupal\breakpoint\InvalidBreakpointMediaQueryException

Overrides BreakpointInterface::isValidMediaQuery

See also

http://www.w3.org/TR/css3-mediaqueries/

http://www.w3.org/Style/CSS/Test/MediaQueries/20120229/reports/implement...

https://github.com/adobe/webkit/blob/master/Source/WebCore/css/

2 calls to Breakpoint::isValidMediaQuery()
BreakpointMediaQueryTest::testInvalidMediaQueries in drupal/core/modules/breakpoint/tests/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php
Test invalid media queries.
BreakpointMediaQueryTest::testValidMediaQueries in drupal/core/modules/breakpoint/tests/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php
Test valid media queries.

File

drupal/core/modules/breakpoint/lib/Drupal/breakpoint/Plugin/Core/Entity/Breakpoint.php, line 182
Definition of Drupal\breakpoint\Plugin\Core\Entity\Breakpoint.

Class

Breakpoint
Defines the Breakpoint entity.

Namespace

Drupal\breakpoint\Plugin\Core\Entity

Code

public static function isValidMediaQuery($media_query) {

  // Array describing all known media features and the expected value type or
  // an array containing the allowed values.
  $media_features = array(
    'width' => 'length',
    'min-width' => 'length',
    'max-width' => 'length',
    'height' => 'length',
    'min-height' => 'length',
    'max-height' => 'length',
    'device-width' => 'length',
    'min-device-width' => 'length',
    'max-device-width' => 'length',
    'device-height' => 'length',
    'min-device-height' => 'length',
    'max-device-height' => 'length',
    'orientation' => array(
      'portrait',
      'landscape',
    ),
    'aspect-ratio' => 'ratio',
    'min-aspect-ratio' => 'ratio',
    'max-aspect-ratio' => 'ratio',
    'device-aspect-ratio' => 'ratio',
    'min-device-aspect-ratio' => 'ratio',
    'max-device-aspect-ratio' => 'ratio',
    'color' => 'integer',
    'min-color' => 'integer',
    'max-color' => 'integer',
    'color-index' => 'integer',
    'min-color-index' => 'integer',
    'max-color-index' => 'integer',
    'monochrome' => 'integer',
    'min-monochrome' => 'integer',
    'max-monochrome' => 'integer',
    'resolution' => 'resolution',
    'min-resolution' => 'resolution',
    'max-resolution' => 'resolution',
    'scan' => array(
      'progressive',
      'interlace',
    ),
    'grid' => 'integer',
  );
  if ($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);

    // 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.');
            }
          }
          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 (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.');
                    }
                  }
                  else {
                    throw new InvalidBreakpointMediaQueryException('Invalid unit detected.');
                  }
                  break;
              }
            }
          }
        }
        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;
        }
        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.');
          }
        }
      }
    }
    return TRUE;
  }
  throw new InvalidBreakpointMediaQueryException('Media query is empty.');
}