summaryrefslogtreecommitdiffstats
path: root/core/modules/breakpoint/src
diff options
context:
space:
mode:
Diffstat (limited to 'core/modules/breakpoint/src')
-rw-r--r--core/modules/breakpoint/src/Breakpoint.php62
-rw-r--r--core/modules/breakpoint/src/BreakpointGroupInterface.php70
-rw-r--r--core/modules/breakpoint/src/BreakpointInterface.php60
-rw-r--r--core/modules/breakpoint/src/BreakpointManager.php274
-rw-r--r--core/modules/breakpoint/src/BreakpointManagerInterface.php46
-rw-r--r--core/modules/breakpoint/src/Entity/Breakpoint.php308
-rw-r--r--core/modules/breakpoint/src/Entity/BreakpointGroup.php234
-rw-r--r--core/modules/breakpoint/src/InvalidBreakpointException.php13
-rw-r--r--core/modules/breakpoint/src/InvalidBreakpointMediaQueryException.php15
-rw-r--r--core/modules/breakpoint/src/InvalidBreakpointNameException.php15
-rw-r--r--core/modules/breakpoint/src/InvalidBreakpointSourceException.php15
-rw-r--r--core/modules/breakpoint/src/InvalidBreakpointSourceTypeException.php15
-rw-r--r--core/modules/breakpoint/src/Tests/BreakpointAPITest.php88
-rw-r--r--core/modules/breakpoint/src/Tests/BreakpointCRUDTest.php50
-rw-r--r--core/modules/breakpoint/src/Tests/BreakpointDiscoveryTest.php207
-rw-r--r--core/modules/breakpoint/src/Tests/BreakpointGroupAPITest.php75
-rw-r--r--core/modules/breakpoint/src/Tests/BreakpointGroupCRUDTest.php54
-rw-r--r--core/modules/breakpoint/src/Tests/BreakpointGroupTestBase.php64
-rw-r--r--core/modules/breakpoint/src/Tests/BreakpointTestBase.php51
-rw-r--r--core/modules/breakpoint/src/Tests/BreakpointThemeTest.php74
20 files changed, 629 insertions, 1161 deletions
diff --git a/core/modules/breakpoint/src/Breakpoint.php b/core/modules/breakpoint/src/Breakpoint.php
new file mode 100644
index 0000000..e75edc1
--- /dev/null
+++ b/core/modules/breakpoint/src/Breakpoint.php
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\breakpoint\Breakpoint.
+ */
+
+namespace Drupal\breakpoint;
+
+use Drupal\Core\Plugin\PluginBase;
+
+/**
+ * Default object used for breakpoint plugins.
+ *
+ * @see \Drupal\breakpoint\BreakpointManager
+ * @see plugin_api
+ */
+class Breakpoint extends PluginBase implements BreakpointInterface {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLabel() {
+ return $this->t($this->pluginDefinition['label'], array(), array('context' => 'breakpoint'));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getWeight() {
+ return (int) $this->pluginDefinition['weight'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMediaQuery() {
+ return $this->pluginDefinition['mediaQuery'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMultipliers() {
+ return $this->pluginDefinition['multipliers'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getProvider() {
+ return $this->pluginDefinition['provider'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getGroup() {
+ return $this->pluginDefinition['group'];
+ }
+
+}
diff --git a/core/modules/breakpoint/src/BreakpointGroupInterface.php b/core/modules/breakpoint/src/BreakpointGroupInterface.php
deleted file mode 100644
index ae4f2e9..0000000
--- a/core/modules/breakpoint/src/BreakpointGroupInterface.php
+++ /dev/null
@@ -1,70 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\breakpoint\Entity\BreakpointGroupInterface.
- */
-
-namespace Drupal\breakpoint;
-
-use Drupal\Core\Config\Entity\ConfigEntityInterface;
-
-/**
- * Provides an interface defining a breakpoint group entity.
- */
-interface BreakpointGroupInterface extends ConfigEntityInterface {
-
- /**
- * Checks if the breakpoint group is valid.
- *
- * @throws \Drupal\breakpoint\InvalidBreakpointSourceTypeException
- * @throws \Drupal\breakpoint\InvalidBreakpointSourceException
- *
- * @return bool
- * Returns TRUE if the breakpoint group is valid.
- */
- public function isValid();
-
- /**
- * Adds a breakpoint using a name and a media query.
- *
- * @param string $name
- * The name of the breakpoint.
- * @param string $media_query
- * Media query.
- */
- public function addBreakpointFromMediaQuery($name, $media_query);
-
- /**
- * Adds one or more breakpoints to this group.
- *
- * The breakpoint name is either the machine_name or the ID of a breakpoint.
- *
- * @param array $breakpoints
- * Array containing breakpoint objects
- *
- * @return \Drupal\breakpoint\Entity\BreakpointGroup
- * The breakpoint group object.
- */
- public function addBreakpoints($breakpoints);
-
- /**
- * Gets the array of breakpoints for the breakpoint group.
- *
- * @return \Drupal\breakpoint\Entity\BreakpointInterface[]
- * The array of breakpoints for the breakpoint group.
- */
- public function getBreakpoints();
-
- /**
- * Gets a breakpoint from the breakpoint group by ID.
- *
- * @param string $id
- * The breakpoint ID to get.
- *
- * @return \Drupal\breakpoint\Entity\BreakpointInterface|boolean
- * The breakpoint or FALSE if not in the Breakpoint group.
- */
- public function getBreakpointById($id);
-
-}
diff --git a/core/modules/breakpoint/src/BreakpointInterface.php b/core/modules/breakpoint/src/BreakpointInterface.php
index cf62bcd..a39d350 100644
--- a/core/modules/breakpoint/src/BreakpointInterface.php
+++ b/core/modules/breakpoint/src/BreakpointInterface.php
@@ -2,42 +2,62 @@
/**
* @file
- * Contains \Drupal\breakpoint\Entity\BreakpointInterface.
+ * Contains \Drupal\breakpoint\BreakpointInterface.
*/
namespace Drupal\breakpoint;
-use Drupal\Core\Config\Entity\ConfigEntityInterface;
-
/**
- * Provides an interface defining a breakpoint entity.
+ * Interface for Breakpoint plugins.
*/
-interface BreakpointInterface extends ConfigEntityInterface {
+interface BreakpointInterface {
/**
- * Checks if the breakpoint is valid.
+ * Returns the translated label.
*
- * @throws \Drupal\breakpoint\InvalidBreakpointSourceTypeException
- * @throws \Drupal\breakpoint\InvalidBreakpointSourceException
- * @throws \Drupal\breakpoint\InvalidBreakpointNameException
- * @throws \Drupal\breakpoint\InvalidBreakpointMediaQueryException
+ * @return string
+ * The translated label.
+ */
+ public function getLabel();
+
+ /**
+ * Returns the weight.
+ *
+ * @return int
+ * The weight.
+ */
+ public function getWeight();
+
+ /**
+ * Returns the media query.
*
- * @see isValidMediaQuery()
+ * @return string
+ * The media query.
*/
- public function isValid();
+ public function getMediaQuery();
/**
- * Checks if a mediaQuery is valid.
+ * Returns the multipliers.
*
- * @throws \Drupal\breakpoint\InvalidBreakpointMediaQueryException
+ * @return array
+ * The multipliers.
+ */
+ public function getMultipliers();
+
+ /**
+ * Returns the provider.
*
- * @return bool
- * Returns TRUE if the media query is valid.
+ * @return string
+ * The provider.
+ */
+ public function getProvider();
+
+ /**
+ * Returns the breakpoint group.
*
- * @see http://www.w3.org/TR/css3-mediaqueries/
- * @see http://www.w3.org/Style/CSS/Test/MediaQueries/20120229/reports/implement-report.html
- * @see https://github.com/adobe/webkit/blob/master/Source/WebCore/css/
+ * @return string
+ * The breakpoint group.
*/
- public static function isValidMediaQuery($media_query);
+ public function getGroup();
}
diff --git a/core/modules/breakpoint/src/BreakpointManager.php b/core/modules/breakpoint/src/BreakpointManager.php
new file mode 100644
index 0000000..757f2cf
--- /dev/null
+++ b/core/modules/breakpoint/src/BreakpointManager.php
@@ -0,0 +1,274 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\breakpoint\BreakpointManager.
+ */
+
+namespace Drupal\breakpoint;
+
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Extension\ThemeHandlerInterface;
+use Drupal\Core\Plugin\DefaultPluginManager;
+use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
+use Drupal\Core\Plugin\Discovery\YamlDiscovery;
+use Drupal\Core\Plugin\Factory\ContainerFactory;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\StringTranslation\TranslationInterface;
+
+/**
+ * Defines a breakpoint plugin manager to deal with breakpoints.
+ *
+ * Extension can define breakpoints in a EXTENSION_NAME.breakpoints.yml file
+ * contained in the extension's base directory. Each breakpoint has the
+ * following structure:
+ * @code
+ * MACHINE_NAME:
+ * label: STRING
+ * mediaQuery: STRING
+ * weight: INTEGER
+ * multipliers:
+ * - STRING
+ * @endcode
+ * For example:
+ * @code
+ * bartik.mobile:
+ * label: mobile
+ * mediaQuery: '(min-width: 0px)'
+ * weight: 0
+ * multipliers:
+ * - 1x
+ * - 2x
+ * @endcode
+ * Optionally a breakpoint can provide a group key. By default an extensions
+ * breakpoints will be placed in a group labelled with the extension name.
+ *
+ * @see \Drupal\breakpoint\Breakpoint
+ * @see \Drupal\breakpoint\BreakpointInterface
+ * @see plugin_api
+ */
+class BreakpointManager extends DefaultPluginManager implements BreakpointManagerInterface {
+ use StringTranslationTrait;
+
+ /**
+ * {@inheritdoc}
+ */
+ protected $defaults = array(
+ // Human readable label for breakpoint.
+ 'label' => '',
+ // The media query for the breakpoint.
+ 'mediaQuery' => '',
+ // Weight used for ordering breakpoints.
+ 'weight' => 0,
+ // Breakpoint multipliers.
+ 'multipliers' => array(),
+ // The breakpoint group.
+ 'group' => '',
+ // Default class for breakpoint implementations.
+ 'class' => 'Drupal\breakpoint\Breakpoint',
+ // The plugin id. Set by the plugin system based on the top-level YAML key.
+ 'id' => '',
+ );
+
+ /**
+ * The theme handler.
+ *
+ * @var \Drupal\Core\Extension\ThemeHandlerInterface
+ */
+ protected $themeHandler;
+
+ /**
+ * Static cache of breakpoints keyed by group.
+ *
+ * @var array
+ */
+ protected $breakpointsByGroup;
+
+ /**
+ * The plugin instances.
+ *
+ * @var array
+ */
+ protected $instances = array();
+
+ /**
+ * Constructs a new BreakpointManager instance.
+ *
+ * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+ * The module handler.
+ * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
+ * The theme handler.
+ * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+ * The cache backend.
+ * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
+ * The string translation service.
+ */
+ public function __construct(ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, CacheBackendInterface $cache_backend, TranslationInterface $string_translation) {
+ $this->discovery = new YamlDiscovery('breakpoints', $module_handler->getModuleDirectories() + $theme_handler->getThemeDirectories());
+ $this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
+ $this->factory = new ContainerFactory($this);
+ $this->moduleHandler = $module_handler;
+ $this->themeHandler = $theme_handler;
+ $this->setStringTranslation($string_translation);
+ $this->alterInfo('breakpoints');
+ $this->setCacheBackend($cache_backend, 'breakpoints', array('breakpoints' => TRUE));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function processDefinition(&$definition, $plugin_id) {
+ parent::processDefinition($definition, $plugin_id);
+ // Allow custom groups and therefore more than one group per extension.
+ if (empty($definition['group'])) {
+ $definition['group'] = $definition['provider'];
+ }
+ // Ensure a 1x multiplier exists.
+ if (!in_array('1x', $definition['multipliers'])) {
+ $definition['multipliers'][] = '1x';
+ }
+ // Ensure that multipliers are sorted correctly.
+ sort($definition['multipliers']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function findDefinitions() {
+ $definitions = $this->discovery->getDefinitions();
+ foreach ($definitions as $plugin_id => &$definition) {
+ $this->processDefinition($definition, $plugin_id);
+ }
+ if ($this->alterHook) {
+ $this->moduleHandler->alter($this->alterHook, $definitions);
+ }
+ // If this plugin was provided by a module that does not exist, remove the
+ // plugin definition.
+ foreach ($definitions as $plugin_id => $plugin_definition) {
+ // If the plugin definition is an object, attempt to convert it to an
+ // array, if that is not possible, skip further processing.
+ if (is_object($plugin_definition) && !($plugin_definition = (array) $plugin_definition)) {
+ continue;
+ }
+ // Allow themes to provide breakpoints.
+ if (isset($plugin_definition['provider']) && !in_array($plugin_definition['provider'], array('core', 'component')) && !$this->moduleHandler->moduleExists($plugin_definition['provider']) && !$this->themeHandler->themeExists($plugin_definition['provider'])) {
+ unset($definitions[$plugin_id]);
+ }
+ }
+ return $definitions;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBreakpointsByGroup($group) {
+ if (!isset($this->breakpointsByGroup[$group])) {
+ if ($cache = $this->cacheBackend->get($this->cacheKey . ':' . $group)) {
+ $this->breakpointsByGroup[$group] = $cache->data;
+ }
+ else {
+ $breakpoints = array();
+ foreach ($this->getDefinitions() as $plugin_id => $plugin_definition) {
+ if ($plugin_definition['group'] == $group) {
+ $breakpoints[$plugin_id] = $plugin_definition;
+ }
+ }
+ uasort($breakpoints, array('Drupal\Component\Utility\SortArray', 'sortByWeightElement'));
+ $this->cacheBackend->set($this->cacheKey . ':' . $group, $breakpoints, Cache::PERMANENT, array('breakpoints' => TRUE));
+ $this->breakpointsByGroup[$group] = $breakpoints;
+ }
+ }
+ $instances = array();
+ foreach ($this->breakpointsByGroup[$group] as $plugin_id => $definition) {
+ if (!isset($this->instances[$plugin_id])) {
+ $this->instances[$plugin_id] = $this->createInstance($plugin_id);
+ }
+ $instances[$plugin_id] = $this->instances[$plugin_id];
+ }
+ return $instances;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getGroups() {
+ // Use a double colon so as to not clash with the cache for each group.
+ if ($cache = $this->cacheBackend->get($this->cacheKey . '::groups')) {
+ $groups = $cache->data;
+ }
+ else {
+ $groups = array();
+ foreach ($this->getDefinitions() as $plugin_definition) {
+ if (!isset($groups[$plugin_definition['group']])) {
+ $groups[$plugin_definition['group']] = $plugin_definition['group'];
+ }
+ }
+ $this->cacheBackend->set($this->cacheKey . '::groups', $groups, Cache::PERMANENT, array('breakpoints' => TRUE));
+ }
+ // Get the labels. This is not cacheable due to translation.
+ $group_labels = array();
+ foreach ($groups as $group) {
+ $group_labels[$group] = $this->getGroupLabel($group);
+ }
+ asort($group_labels);
+ return $group_labels;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getGroupProviders($group) {
+ $providers = array();
+ $breakpoints = $this->getBreakpointsByGroup($group);
+ foreach ($breakpoints as $breakpoint) {
+ $provider = $breakpoint->getProvider();
+ $extension = FALSE;
+ if ($this->moduleHandler->moduleExists($provider)) {
+ $extension = $this->moduleHandler->getModule($provider);
+ }
+ elseif ($this->themeHandler->themeExists($provider)) {
+ $extension = $this->themeHandler->getTheme($provider);
+ }
+ if ($extension) {
+ $providers[$extension->getName()] = $extension->getType();
+ }
+ }
+ return $providers;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clearCachedDefinitions() {
+ parent::clearCachedDefinitions();
+ $this->breakpointsByGroup = NULL;
+ $this->instances = array();
+ }
+
+ /**
+ * Gets the label for a breakpoint group.
+ *
+ * @param string $group
+ * The breakpoint group.
+ *
+ * @return string
+ * The label.
+ */
+ protected function getGroupLabel($group) {
+ // Extension names are not translatable.
+ if ($this->moduleHandler->moduleExists($group)) {
+ $label = $this->moduleHandler->getName($group);
+ }
+ elseif ($this->themeHandler->themeExists($group)) {
+ $label = $this->themeHandler->getName($group);
+ }
+ else {
+ // Custom group label that should be translatable.
+ $label = $this->t($group, array(), array('context' => 'breakpoint'));
+ }
+ return $label;
+ }
+
+}
diff --git a/core/modules/breakpoint/src/BreakpointManagerInterface.php b/core/modules/breakpoint/src/BreakpointManagerInterface.php
new file mode 100644
index 0000000..357b7a8
--- /dev/null
+++ b/core/modules/breakpoint/src/BreakpointManagerInterface.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\breakpoint\BreakpointManagerInterface.
+ */
+
+namespace Drupal\breakpoint;
+
+/**
+ * Defines an interface for breakpoint managers.
+ */
+interface BreakpointManagerInterface {
+
+ /**
+ * Gets breakpoints for the specified group.
+ *
+ * @param string $group
+ * The breakpoint group to retrieve.
+ *
+ * @return \Drupal\breakpoint\BreakpointInterface[]
+ * Array of breakpoint plugins keyed by machine name.
+ */
+ public function getBreakpointsByGroup($group);
+
+ /**
+ * Gets all the existing breakpoint groups.
+ *
+ * @return array
+ * Array of breakpoint group labels. Keyed by group name.
+ */
+ public function getGroups();
+
+ /**
+ * Gets all the providers for the specified breakpoint group.
+ *
+ * @param string $group
+ * The breakpoint group to retrieve.
+ *
+ * @return array
+ * An array keyed by provider name with values of provider type (module or
+ * theme).
+ */
+ public function getGroupProviders($group);
+
+}
diff --git a/core/modules/breakpoint/src/Entity/Breakpoint.php b/core/modules/breakpoint/src/Entity/Breakpoint.php
deleted file mode 100644
index 714e44e..0000000
--- a/core/modules/breakpoint/src/Entity/Breakpoint.php
+++ /dev/null
@@ -1,308 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\Entity\Breakpoint.
- */
-
-namespace Drupal\breakpoint\Entity;
-
-use Drupal\Core\Config\Entity\ConfigEntityBase;
-use Drupal\breakpoint\BreakpointInterface;
-use Drupal\breakpoint\InvalidBreakpointException;
-use Drupal\breakpoint\InvalidBreakpointNameException;
-use Drupal\breakpoint\InvalidBreakpointSourceException;
-use Drupal\breakpoint\InvalidBreakpointSourceTypeException;
-use Drupal\breakpoint\InvalidBreakpointMediaQueryException;
-use Drupal\Core\Entity\EntityStorageInterface;
-
-/**
- * Defines the Breakpoint entity.
- *
- * @ConfigEntityType(
- * id = "breakpoint",
- * label = @Translation("Breakpoint"),
- * entity_keys = {
- * "id" = "id",
- * "label" = "label"
- * }
- * )
- */
-class Breakpoint extends ConfigEntityBase implements BreakpointInterface {
-
- /**
- * Denotes that a breakpoint or breakpoint group is defined by a theme.
- */
- const SOURCE_TYPE_THEME = 'theme';
-
- /**
- * Denotes that a breakpoint or breakpoint group is defined by a module.
- */
- const SOURCE_TYPE_MODULE = 'module';
-
- /**
- * Denotes that a breakpoint or breakpoint group is defined by the user.
- */
- const SOURCE_TYPE_USER_DEFINED = 'custom';
-
- /**
- * The breakpoint ID (config name).
- *
- * @var string
- */
- public $id;
-
- /**
- * The breakpoint name (machine name) as specified by theme or module.
- *
- * @var string
- */
- public $name;
-
- /**
- * The breakpoint label.
- *
- * @var string
- */
- public $label;
-
- /**
- * The breakpoint media query.
- *
- * @var string
- */
- public $mediaQuery = '';
-
- /**
- * The breakpoint source.
- *
- * @var string
- */
- public $source = 'user';
-
- /**
- * The breakpoint source type.
- *
- * @var string
- * Allowed values:
- * Breakpoint::SOURCE_TYPE_THEME
- * Breakpoint::SOURCE_TYPE_MODULE
- * Breakpoint::SOURCE_TYPE_USER_DEFINED
- */
- public $sourceType = Breakpoint::SOURCE_TYPE_USER_DEFINED;
-
- /**
- * The breakpoint weight.
- *
- * @var weight
- */
- public $weight = 0;
-
- /**
- * The breakpoint multipliers.
- *
- * @var multipliers
- */
- public $multipliers = array();
-
- /**
- * {@inheritdoc}
- *
- * @throws \Drupal\breakpoint\InvalidBreakpointNameException
- * Exception thrown if $values['name'] is empty.
- */
- public function __construct(array $values, $entity_type = 'breakpoint') {
- // Check required properties.
- if (empty($values['name'])) {
- throw new InvalidBreakpointNameException('Attempt to create an unnamed breakpoint.');
- }
- parent::__construct($values, $entity_type);
- }
-
- /**
- * {@inheritdoc}
- */
- public function id() {
- // If no ID is specified, build one from the properties that uniquely define
- // this breakpoint.
- if (!isset($this->id)) {
- $this->id = $this->sourceType . '.' . $this->source . '.' . $this->name;
- }
- return $this->id;
- }
-
- /**
- * Overrides Drupal\config\ConfigEntityBase::save().
- */
- public function save() {
- // Check if everything is valid.
- if (!$this->isValid()) {
- throw new InvalidBreakpointException('Invalid data detected.');
- }
-
- // Set the label if none is set.
- if (empty($this->label)) {
- $this->label = $this->name;
- }
-
- // Remove unused multipliers.
- $this->multipliers = array_filter($this->multipliers);
-
- // Always add '1x' multiplier, use array_key_exists since the value might
- // be NULL.
- if (!array_key_exists('1x', $this->multipliers)) {
- $this->multipliers = array('1x' => '1x') + $this->multipliers;
- }
- return parent::save();
- }
-
- /**
- * {@inheritdoc}
- */
- public function isValid() {
- // Check for illegal values in breakpoint source type.
- if (!in_array($this->sourceType, array(
- Breakpoint::SOURCE_TYPE_USER_DEFINED,
- Breakpoint::SOURCE_TYPE_MODULE,
- Breakpoint::SOURCE_TYPE_THEME)
- )) {
- throw new InvalidBreakpointSourceTypeException(format_string('Invalid source type @source_type', array(
- '@source_type' => $this->sourceType,
- )));
- }
- // Check for illegal characters in breakpoint source.
- if (preg_match('/[^0-9a-z_]+/', $this->source)) {
- throw new InvalidBreakpointSourceException(format_string("Invalid value '@source' for breakpoint source property. Breakpoint source property can only contain lowercase alphanumeric characters and underscores.", array('@source' => $this->source)));
- }
- // Check for illegal characters in breakpoint names.
- 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)));
- }
- return $this::isValidMediaQuery($this->mediaQuery);
- }
-
- /**
- * {@inheritdoc}
- */
- 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.');
- }
- }
- // 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 (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;
- }
- }
- }
- }
-
- // 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 (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.');
- }
- }
- }
- }
- return TRUE;
- }
- throw new InvalidBreakpointMediaQueryException('Media query is empty.');
- }
-
- /**
- * {@inheritdoc}
- */
- public function calculateDependencies() {
- parent::calculateDependencies();
- $this->dependencies = array();
- if ($this->sourceType == static::SOURCE_TYPE_MODULE) {
- $this->addDependency('module', $this->source);
- }
- elseif ($this->sourceType == static::SOURCE_TYPE_THEME) {
- $this->addDependency('theme', $this->source);
- }
- return $this->dependencies;
- }
-
-}
diff --git a/core/modules/breakpoint/src/Entity/BreakpointGroup.php b/core/modules/breakpoint/src/Entity/BreakpointGroup.php
deleted file mode 100644
index 0b585e2..0000000
--- a/core/modules/breakpoint/src/Entity/BreakpointGroup.php
+++ /dev/null
@@ -1,234 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\Entity\BreakpointGroup.
- */
-
-namespace Drupal\breakpoint\Entity;
-
-use Drupal\breakpoint\InvalidBreakpointNameException;
-use Drupal\Core\Config\Entity\ConfigEntityBase;
-use Drupal\breakpoint\BreakpointGroupInterface;
-use Drupal\breakpoint\InvalidBreakpointSourceException;
-use Drupal\breakpoint\InvalidBreakpointSourceTypeException;
-use Drupal\Core\Entity\EntityStorageInterface;
-
-/**
- * Defines the BreakpointGroup entity.
- *
- * @ConfigEntityType(
- * id = "breakpoint_group",
- * label = @Translation("Breakpoint group"),
- * entity_keys = {
- * "id" = "id",
- * "label" = "label"
- * }
- * )
- */
-class BreakpointGroup extends ConfigEntityBase implements BreakpointGroupInterface {
-
- /**
- * The breakpoint group ID.
- *
- * @var string
- */
- public $id;
-
- /**
- * The breakpoint group machine name.
- *
- * @var string
- */
- public $name;
-
- /**
- * The breakpoint group label.
- *
- * @var string
- */
- public $label;
-
- /**
- * The breakpoint group breakpoint IDs.
- *
- * @var array
- * Array containing all breakpoints IDs of this group.
- *
- * @see \Drupal\breakpoint\Entity\Breakpoint
- */
- protected $breakpoint_ids = array();
-
- /**
- * The breakpoint group breakpoints.
- *
- * @var array
- * Array containing all breakpoints objects of this group.
- *
- * @see \Drupal\breakpoint\Entity\Breakpoint
- */
- protected $breakpoints = array();
-
- /**
- * The breakpoint group source: theme or module name. Use 'user' for
- * user-created groups.
- *
- * @var string
- */
- public $source = 'user';
-
- /**
- * The breakpoint group source type.
- *
- * @var string
- * Allowed values:
- * Breakpoint::SOURCE_TYPE_THEME
- * Breakpoint::SOURCE_TYPE_MODULE
- * Breakpoint::SOURCE_TYPE_USER_DEFINED
- *
- * @see \Drupal\breakpoint\Entity\Breakpoint
- */
- public $sourceType = Breakpoint::SOURCE_TYPE_USER_DEFINED;
-
- /**
- * {@inheritdoc}
- *
- * @throws \Drupal\breakpoint\InvalidBreakpointNameException
- * Exception thrown if $values['name'] is empty.
- */
- public function __construct(array $values, $entity_type = 'breakpoint_group') {
- // Check required properties.
- if (empty($values['name'])) {
- throw new InvalidBreakpointNameException('Attempt to create an unnamed breakpoint group.');
- }
- parent::__construct($values, $entity_type);
- }
-
- /**
- * Overrides Drupal\Core\Entity\Entity::save().
- */
- public function save() {
- // Check if everything is valid.
- if (!$this->isValid()) {
- throw new InvalidBreakpointException('Invalid data detected.');
- }
- parent::save();
- }
-
- /**
- * {@inheritdoc}
- */
- public function id() {
- // If no ID is specified, build one from the properties that uniquely define
- // this breakpoint group.
- if (!isset($this->id)) {
- $this->id = $this->sourceType . '.' . $this->source . '.' . $this->name;
- }
- return $this->id;
- }
-
- /**
- * {@inheritdoc}
- */
- public function isValid() {
- // Check for illegal values in breakpoint group source type.
- if (!in_array($this->sourceType, array(
- Breakpoint::SOURCE_TYPE_USER_DEFINED,
- Breakpoint::SOURCE_TYPE_MODULE,
- Breakpoint::SOURCE_TYPE_THEME)
- )) {
- throw new InvalidBreakpointSourceTypeException(format_string('Invalid source type @source_type', array(
- '@source_type' => $this->sourceType,
- )));
- }
- // Check for illegal characters in breakpoint group source.
- if (preg_match('/[^a-z_]+/', $this->source) || empty($this->source)) {
- throw new InvalidBreakpointSourceException(format_string("Invalid value '@source' for breakpoint group source property. Breakpoint group source property can only contain lowercase letters and underscores.", array('@source' => $this->source)));
- }
- // Check for illegal characters in breakpoint group name.
- if (preg_match('/[^a-z0-9_]+/', $this->name || empty($this->name))) {
- throw new InvalidBreakpointNameException(format_string("Invalid value '@name' for breakpoint group name property. Breakpoint group name property can only contain lowercase letters, numbers and underscores.", array('@name' => $this->name)));
- }
- return TRUE;
- }
-
- /**
- * {@inheritdoc}
- */
- public function addBreakpointFromMediaQuery($name, $media_query) {
- // Use the existing breakpoint if it exists.
- $breakpoint = Breakpoint::load($this->sourceType . '.' . $this->name . '.' . $name);
- if (!$breakpoint) {
- // Build a new breakpoint.
- $breakpoint = entity_create('breakpoint', array(
- 'name' => $name,
- 'label' => $name,
- 'mediaQuery' => $media_query,
- 'source' => $this->name,
- 'sourceType' => $this->sourceType,
- 'weight' => count($this->breakpoint_ids),
- ));
- $breakpoint->save();
- }
- return $this->addBreakpoints(array($breakpoint));
- }
-
- /**
- * {@inheritdoc}
- */
- public function addBreakpoints($breakpoints) {
- foreach ($breakpoints as $breakpoint) {
- // Add breakpoint to group.
- $this->breakpoints[$breakpoint->id()] = $breakpoint;
- $this->breakpoint_ids[] = $breakpoint->id();
- }
- return $this;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getBreakpoints() {
- if (empty($this->breakpoints)) {
- foreach ($this->breakpoint_ids as $breakpoint_id) {
- $breakpoint = Breakpoint::load($breakpoint_id);
- if ($breakpoint) {
- $this->breakpoints[$breakpoint_id] = $breakpoint;
- }
- }
- }
- return $this->breakpoints;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getBreakpointById($id) {
- $breakpoints = $this->getBreakpoints();
- if (isset($breakpoints[$id])) {
- return $breakpoints[$id];
- }
- return FALSE;
- }
-
- /**
- * {@inheritdoc}
- */
- public function calculateDependencies() {
- parent::calculateDependencies();
-
- $this->dependencies = array();
- if ($this->sourceType == Breakpoint::SOURCE_TYPE_MODULE) {
- $this->addDependency('module', $this->source);
- }
- elseif ($this->sourceType == Breakpoint::SOURCE_TYPE_THEME) {
- $this->addDependency('theme', $this->source);
- }
- $breakpoints = $this->getBreakpoints();
- foreach ($breakpoints as $breakpoint) {
- $this->addDependency('entity', $breakpoint->getConfigDependencyName());
- }
- return $this->dependencies;
- }
-
-}
diff --git a/core/modules/breakpoint/src/InvalidBreakpointException.php b/core/modules/breakpoint/src/InvalidBreakpointException.php
deleted file mode 100644
index 6889fa2..0000000
--- a/core/modules/breakpoint/src/InvalidBreakpointException.php
+++ /dev/null
@@ -1,13 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\InvalidBreakpointException.
- */
-
-namespace Drupal\breakpoint;
-
-/**
- * Base exception for breakpoint exception.
- */
-class InvalidBreakpointException extends \RuntimeException {}
diff --git a/core/modules/breakpoint/src/InvalidBreakpointMediaQueryException.php b/core/modules/breakpoint/src/InvalidBreakpointMediaQueryException.php
deleted file mode 100644
index 3999965..0000000
--- a/core/modules/breakpoint/src/InvalidBreakpointMediaQueryException.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\InvalidBreakpointMediaQueryException.
- */
-
-namespace Drupal\breakpoint;
-
-use Drupal\breakpoint\InvalidBreakpointException;
-
-/**
- * Exception thrown if an illegal media query is detected.
- */
-class InvalidBreakpointMediaQueryException extends InvalidBreakpointException {}
diff --git a/core/modules/breakpoint/src/InvalidBreakpointNameException.php b/core/modules/breakpoint/src/InvalidBreakpointNameException.php
deleted file mode 100644
index 1121465..0000000
--- a/core/modules/breakpoint/src/InvalidBreakpointNameException.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\InvalidBreakpointNameException.
- */
-
-namespace Drupal\breakpoint;
-
-use Drupal\breakpoint\InvalidBreakpointException;
-
-/**
- * Exception thrown if an invalid name is detected.
- */
-class InvalidBreakpointNameException extends InvalidBreakpointException {}
diff --git a/core/modules/breakpoint/src/InvalidBreakpointSourceException.php b/core/modules/breakpoint/src/InvalidBreakpointSourceException.php
deleted file mode 100644
index 3ad5556..0000000
--- a/core/modules/breakpoint/src/InvalidBreakpointSourceException.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\InvalidBreakpointSourceException.
- */
-
-namespace Drupal\breakpoint;
-
-use Drupal\breakpoint\InvalidBreakpointException;
-
-/**
- * Exception thrown if an invalid source is detected.
- */
-class InvalidBreakpointSourceException extends InvalidBreakpointException {}
diff --git a/core/modules/breakpoint/src/InvalidBreakpointSourceTypeException.php b/core/modules/breakpoint/src/InvalidBreakpointSourceTypeException.php
deleted file mode 100644
index d9e2483..0000000
--- a/core/modules/breakpoint/src/InvalidBreakpointSourceTypeException.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\breakpoint\InvalidBreakpointSourceTypeException.
- */
-
-namespace Drupal\breakpoint;
-
-use Drupal\breakpoint\InvalidBreakpointException;
-
-/**
- * Exception thrown if an invalid source_type is detected.
- */
-class InvalidBreakpointSourceTypeException extends InvalidBreakpointException {}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointAPITest.php b/core/modules/breakpoint/src/Tests/BreakpointAPITest.php
deleted file mode 100644
index abfb430..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointAPITest.php
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointAPITest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Tests\BreakpointsTestBase;
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\breakpoint\InvalidBreakpointNameException;
-use Drupal\breakpoint\InvalidBreakpointSourceException;
-use Drupal\breakpoint\InvalidBreakpointSourceTypeException;
-use Drupal\Component\Utility\Unicode;
-
-/**
- * Tests general API functions of the breakpoint module.
- *
- * @group breakpoint
- */
-class BreakpointAPITest extends BreakpointTestBase {
-
- /**
- * Test Breakpoint::buildConfigName().
- */
- public function testConfigName() {
- // Try an invalid sourceType.
- $label = $this->randomMachineName();
- $breakpoint = entity_create('breakpoint', array(
- 'label' => $label,
- 'name' => Unicode::strtolower($label),
- 'source' => 'custom_module',
- 'sourceType' => 'oops',
- ));
-
- $exception = FALSE;
- try {
- $breakpoint->save();
- }
- catch (InvalidBreakpointSourceTypeException $e) {
- $exception = TRUE;
- }
- $this->assertTrue($exception, 'breakpoint_config_name: An exception is thrown when an invalid sourceType is entered.');
-
- // Try an invalid source.
- $breakpoint = $breakpoint->createDuplicate();
- $breakpoint->sourceType = Breakpoint::SOURCE_TYPE_USER_DEFINED;
- $breakpoint->source = 'custom*_module source';
-
- $exception = FALSE;
- try {
- $breakpoint->save();
- }
- catch (InvalidBreakpointSourceException $e) {
- $exception = TRUE;
- }
- $this->assertTrue($exception, 'breakpoint_config_name: An exception is thrown when an invalid source is entered.');
-
- // Try an invalid name (make sure there is at least once capital letter).
- $breakpoint = $breakpoint->createDuplicate();
- $breakpoint->source = 'custom_module';
- $breakpoint->name = drupal_ucfirst($this->randomMachineName());
-
- $exception = FALSE;
- try {
- $breakpoint->save();
- }
- catch (InvalidBreakpointNameException $e) {
- $exception = TRUE;
- }
- $this->assertTrue($exception, 'breakpoint_config_name: An exception is thrown when an invalid name is entered.');
-
- // Try a valid breakpoint.
- $breakpoint = $breakpoint->createDuplicate();
- $breakpoint->name = drupal_strtolower($this->randomMachineName());
- $breakpoint->mediaQuery = 'all';
-
- $exception = FALSE;
- try {
- $breakpoint->save();
- }
- catch (\Exception $e) {
- $exception = TRUE;
- }
- $this->assertFalse($exception, 'breakpoint_config_name: No exception is thrown when a valid breakpoint is passed.');
- $this->assertEqual($breakpoint->id(), Breakpoint::SOURCE_TYPE_USER_DEFINED . '.custom_module.' . $breakpoint->name, 'breakpoint_config_name: A id is set when a valid breakpoint is passed.');
- }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointCRUDTest.php b/core/modules/breakpoint/src/Tests/BreakpointCRUDTest.php
deleted file mode 100644
index 5b46d3d..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointCRUDTest.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointCRUDTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Tests\BreakpointTestBase;
-use Drupal\breakpoint\Entity\Breakpoint;
-
-/**
- * Tests creation, loading, updating, deleting of breakpoints.
- *
- * @group breakpoint
- */
-class BreakpointCRUDTest extends BreakpointTestBase {
-
- /**
- * Test CRUD operations for breakpoints.
- */
- public function testBreakpointCRUD() {
- // Add a breakpoint with minimum data only.
- $label = $this->randomMachineName();
- $breakpoint = entity_create('breakpoint', array(
- 'label' => $label,
- 'mediaQuery' => '(min-width: 600px)',
- 'name' => drupal_strtolower($label),
- ));
- $breakpoint->save();
-
- $this->verifyBreakpoint($breakpoint);
-
- // Test BreakPoint::loadMultiple().
- $all_breakpoints = Breakpoint::loadMultiple();
- $config_name = $breakpoint->id();
- $this->assertTrue(isset($all_breakpoints[$config_name]), 'New breakpoint is present when loading all breakpoints.');
- $this->verifyBreakpoint($breakpoint, $all_breakpoints[$config_name]);
-
- // Update the breakpoint.
- $breakpoint->weight = 1;
- $breakpoint->multipliers['2x'] = '2x';
- $breakpoint->save();
- $this->verifyBreakpoint($breakpoint);
-
- // Delete the breakpoint.
- $breakpoint->delete();
- $this->assertNull(Breakpoint::load($config_name), 'Loading a deleted breakpoint returns null.', 'Breakpoints API');
- }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointDiscoveryTest.php b/core/modules/breakpoint/src/Tests/BreakpointDiscoveryTest.php
new file mode 100644
index 0000000..515359b
--- /dev/null
+++ b/core/modules/breakpoint/src/Tests/BreakpointDiscoveryTest.php
@@ -0,0 +1,207 @@
+<?php
+/**
+ * @file
+ * Definition of Drupal\breakpoint\Tests\BreakpointDiscoveryTest.
+ */
+
+namespace Drupal\breakpoint\Tests;
+
+use Drupal\simpletest\KernelTestBase;
+
+/**
+ * Tests discovery of breakpoints provided by themes and modules.
+ *
+ * @group breakpoint
+ */
+class BreakpointDiscoveryTest extends KernelTestBase {
+
+ /**
+ * Modules to enable.
+ *
+ * @var array
+ */
+ public static $modules = array('breakpoint', 'breakpoint_module_test');
+
+ protected function setUp() {
+ parent::setUp();
+ \Drupal::service('theme_handler')->enable(array('breakpoint_theme_test'));
+ }
+
+ /**
+ * Test the breakpoint group created for a theme.
+ */
+ public function testThemeBreakpoints() {
+ // Verify the breakpoint group for breakpoint_theme_test was created.
+ $expected_breakpoints = array(
+ 'breakpoint_theme_test.mobile' => array(
+ 'label' => 'mobile',
+ 'mediaQuery' => '(min-width: 0px)',
+ 'weight' => 0,
+ 'multipliers' => array(
+ '1x',
+ ),
+ 'provider' => 'breakpoint_theme_test',
+ 'id' => 'breakpoint_theme_test.mobile',
+ 'group' => 'breakpoint_theme_test',
+ 'class' => 'Drupal\\breakpoint\\Breakpoint',
+ ),
+ 'breakpoint_theme_test.narrow' => array(
+ 'label' => 'narrow',
+ 'mediaQuery' => '(min-width: 560px)',
+ 'weight' => 1,
+ 'multipliers' => array(
+ '1x',
+ ),
+ 'provider' => 'breakpoint_theme_test',
+ 'id' => 'breakpoint_theme_test.narrow',
+ 'group' => 'breakpoint_theme_test',
+ 'class' => 'Drupal\\breakpoint\\Breakpoint',
+ ),
+ 'breakpoint_theme_test.wide' => array(
+ 'label' => 'wide',
+ 'mediaQuery' => '(min-width: 851px)',
+ 'weight' => 2,
+ 'multipliers' => array(
+ '1x',
+ ),
+ 'provider' => 'breakpoint_theme_test',
+ 'id' => 'breakpoint_theme_test.wide',
+ 'group' => 'breakpoint_theme_test',
+ 'class' => 'Drupal\\breakpoint\\Breakpoint',
+ ),
+ 'breakpoint_theme_test.tv' => array(
+ 'label' => 'tv',
+ 'mediaQuery' => 'only screen and (min-width: 3456px)',
+ 'weight' => 3,
+ 'multipliers' => array(
+ '1x',
+ ),
+ 'provider' => 'breakpoint_theme_test',
+ 'id' => 'breakpoint_theme_test.tv',
+ 'group' => 'breakpoint_theme_test',
+ 'class' => 'Drupal\\breakpoint\\Breakpoint',
+ ),
+ );
+
+ $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup('breakpoint_theme_test');
+ foreach ($expected_breakpoints as $id => $expected_breakpoint) {
+ $this->assertEqual($expected_breakpoint, $breakpoints[$id]->getPluginDefinition());
+ }
+
+ // Test that the order is as expected.
+ $this->assertIdentical(array_keys($expected_breakpoints), array_keys($breakpoints));
+ }
+
+ /**
+ * Test the custom breakpoint group provided by a theme and a module.
+ */
+ public function testCustomBreakpointGroups () {
+ // Verify the breakpoint group for breakpoint_theme_test.group2 was created.
+ $expected_breakpoints = array(
+ 'breakpoint_theme_test.group2.narrow' => array(
+ 'label' => 'narrow',
+ 'mediaQuery' => '(min-width: 560px)',
+ 'weight' => 1,
+ 'multipliers' => array(
+ '1x',
+ '2x',
+ ),
+ 'provider' => 'breakpoint_theme_test',
+ 'id' => 'breakpoint_theme_test.group2.narrow',
+ 'group' => 'breakpoint_theme_test.group2',
+ 'class' => 'Drupal\\breakpoint\\Breakpoint',
+ ),
+ 'breakpoint_theme_test.group2.wide' => array(
+ 'label' => 'wide',
+ 'mediaQuery' => '(min-width: 851px)',
+ 'weight' => 2,
+ 'multipliers' => array(
+ '1x',
+ '2x',
+ ),
+ 'provider' => 'breakpoint_theme_test',
+ 'id' => 'breakpoint_theme_test.group2.wide',
+ 'group' => 'breakpoint_theme_test.group2',
+ 'class' => 'Drupal\\breakpoint\\Breakpoint',
+ ),
+ 'breakpoint_module_test.breakpoint_theme_test.group2.tv' => array(
+ 'label' => 'tv',
+ 'mediaQuery' => '(min-width: 6000px)',
+ 'weight' => 3,
+ 'multipliers' => array(
+ '1x',
+ ),
+ 'provider' => 'breakpoint_module_test',
+ 'id' => 'breakpoint_module_test.breakpoint_theme_test.group2.tv',
+ 'group' => 'breakpoint_theme_test.group2',
+ 'class' => 'Drupal\\breakpoint\\Breakpoint',
+ ),
+ );
+
+ $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup('breakpoint_theme_test.group2');
+ foreach ($expected_breakpoints as $id => $expected_breakpoint) {
+ $this->assertEqual($expected_breakpoint, $breakpoints[$id]->getPluginDefinition());
+ }
+ }
+
+ /**
+ * Test the breakpoint group created for a module.
+ */
+ public function testModuleBreakpoints() {
+ $expected_breakpoints = array(
+ 'breakpoint_module_test.mobile' => array(
+ 'label' => 'mobile',
+ 'mediaQuery' => '(min-width: 0px)',
+ 'weight' => 0,
+ 'multipliers' => array(
+ '1x',
+ ),
+ 'provider' => 'breakpoint_module_test',
+ 'id' => 'breakpoint_module_test.mobile',
+ 'group' => 'breakpoint_module_test',
+ 'class' => 'Drupal\\breakpoint\\Breakpoint',
+ ),
+ 'breakpoint_module_test.standard' => array(
+ 'label' => 'standard',
+ 'mediaQuery' => '(min-width: 560px)',
+ 'weight' => 1,
+ 'multipliers' => array(
+ '1x',
+ '2x',
+ ),
+ 'provider' => 'breakpoint_module_test',
+ 'id' => 'breakpoint_module_test.standard',
+ 'group' => 'breakpoint_module_test',
+ 'class' => 'Drupal\\breakpoint\\Breakpoint',
+ ),
+ );
+
+ $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup('breakpoint_module_test');
+ foreach ($expected_breakpoints as $id => $expected_breakpoint) {
+ $this->assertEqual($expected_breakpoint, $breakpoints[$id]->getPluginDefinition());
+ }
+ }
+
+ /**
+ * Test the collection of breakpoint groups.
+ */
+ public function testBreakpointGroups() {
+ $expected = array(
+ 'bartik' => 'Bartik',
+ 'breakpoint_module_test' => 'Breakpoint test module',
+ 'breakpoint_theme_test' => 'Breakpoint test theme',
+ 'breakpoint_theme_test.group2' => 'breakpoint_theme_test.group2',
+ );
+ $breakpoint_groups = \Drupal::service('breakpoint.manager')->getGroups();
+ // Ensure the order is as expected. Should be sorted by label.
+ $this->assertIdentical($expected, $breakpoint_groups);
+
+ $expected = array(
+ 'breakpoint_theme_test' => 'theme',
+ 'breakpoint_module_test' => 'module',
+ );
+ $breakpoint_group_providers = \Drupal::service('breakpoint.manager')->getGroupProviders('breakpoint_theme_test.group2');
+ $this->assertEqual($expected, $breakpoint_group_providers);
+ }
+
+}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointGroupAPITest.php b/core/modules/breakpoint/src/Tests/BreakpointGroupAPITest.php
deleted file mode 100644
index f8a0191..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointGroupAPITest.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointGroupAPITest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Tests\BreakpointsTestBase;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\breakpoint\InvalidBreakpointNameException;
-use Drupal\breakpoint\InvalidBreakpointSourceException;
-use Drupal\breakpoint\InvalidBreakpointSourceTypeException;
-use Drupal\Component\Utility\Unicode;
-
-/**
- * Tests general API functions of the breakpoint module.
- *
- * @group breakpoint
- */
-class BreakpointGroupAPITest extends BreakpointGroupTestBase {
-
- /**
- * Test Breakpoint::buildConfigName().
- */
- public function testConfigName() {
- // Try an invalid sourceType.
- $label = $this->randomMachineName();
- $breakpoint_group = entity_create('breakpoint_group', array(
- 'label' => $label,
- 'name' => drupal_strtolower($label),
- 'source' => 'custom_module',
- 'sourceType' => 'oops',
- ));
-
- $exception = FALSE;
- try {
- $breakpoint_group->save();
- }
- catch (InvalidBreakpointSourceTypeException $e) {
- $exception = TRUE;
- }
- $this->assertTrue($exception, 'An exception is thrown when an invalid sourceType is entered.');
-
- // Try an invalid source.
- $breakpoint_group = $breakpoint_group->createDuplicate();
- $breakpoint_group->name = '';
- $breakpoint_group->sourceType = Breakpoint::SOURCE_TYPE_USER_DEFINED;
- $breakpoint_group->source = 'custom*_module source';
-
- $exception = FALSE;
- try {
- $breakpoint_group->save();
- }
- catch (InvalidBreakpointSourceException $e) {
- $exception = TRUE;
- }
- $this->assertTrue($exception, 'An exception is thrown when an invalid source is entered.');
-
- // Try a valid breakpoint_group.
- $breakpoint_group = $breakpoint_group->createDuplicate();
- $breakpoint_group->name = 'test';
- $breakpoint_group->source = 'custom_module_source';
-
- $exception = FALSE;
- try {
- $breakpoint_group->save();
- }
- catch (\Exception $e) {
- $exception = TRUE;
- }
- $this->assertFalse($exception, 'No exception is thrown when a valid data is passed.');
- }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointGroupCRUDTest.php b/core/modules/breakpoint/src/Tests/BreakpointGroupCRUDTest.php
deleted file mode 100644
index aa949de..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointGroupCRUDTest.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointGroupCRUDTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Tests\BreakpointGroupTestBase;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-use Drupal\breakpoint\Entity\Breakpoint;
-
-/**
- * Tests creation, loading, updating, deleting of breakpoint groups.
- *
- * @group breakpoint
- */
-class BreakpointGroupCRUDTest extends BreakpointGroupTestBase {
-
- /**
- * Test CRUD operations for breakpoint groups.
- */
- public function testBreakpointGroupCRUD() {
- // Add breakpoints.
- $breakpoints = array();
- for ($i = 0; $i <= 3; $i++) {
- $width = ($i + 1) * 200;
- $breakpoint = entity_create('breakpoint', array(
- 'name' => drupal_strtolower($this->randomMachineName()),
- 'weight' => $i,
- 'mediaQuery' => "(min-width: {$width}px)",
- ));
- $breakpoint->save();
- $breakpoints[$breakpoint->id()] = $breakpoint;
- }
- // Add a breakpoint group with minimum data only.
- $label = $this->randomMachineName();
-
- $group = entity_create('breakpoint_group', array(
- 'label' => $label,
- 'name' => drupal_strtolower($label),
- ));
- $group->save();
- $this->verifyBreakpointGroup($group);
-
- // Update the breakpoint group.
- $group->addBreakpoints($breakpoints)->save();
- $this->verifyBreakpointGroup($group);
-
- // Delete the breakpoint group.
- $group->delete();
- $this->assertFalse(entity_load('breakpoint_group', $group->id()), 'breakpoint_group_load: Loading a deleted breakpoint group returns false.', 'Breakpoints API');
- }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointGroupTestBase.php b/core/modules/breakpoint/src/Tests/BreakpointGroupTestBase.php
deleted file mode 100644
index 8dd8868..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointGroupTestBase.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointGroupTestBase.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\simpletest\WebTestBase;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-
-/**
- * Base class for Breakpoint group tests.
- */
-abstract class BreakpointGroupTestBase extends WebTestBase {
-
- /**
- * Modules to enable.
- *
- * @var array
- */
- public static $modules = array('breakpoint');
-
- protected function setUp() {
- parent::setUp();
- }
-
- /**
- * Verify that a breakpoint is properly stored.
- */
- public function verifyBreakpointGroup(BreakpointGroup $group, BreakpointGroup $compare_set = NULL) {
- $properties = array(
- 'label',
- 'id',
- 'name',
- 'sourceType',
- );
-
- // Verify breakpoint_group_load().
- $compare_set = is_null($compare_set) ? entity_load('breakpoint_group', $group->id()) : $compare_set;
-
- foreach ($properties as $property) {
- $t_args = array(
- '%group' => $group->label(),
- '%property' => $property,
- );
- if (is_array($compare_set->{$property})) {
- $this->assertEqual(array_keys($compare_set->{$property}), array_keys($group->{$property}), format_string('breakpoint_group_load: Proper %property for breakpoint group %group.', $t_args), 'Breakpoint API');
- }
- else {
- $t_args = array(
- '%group' => $group->label(),
- '%property' => $property,
- '%property1' => $compare_set->{$property},
- '%property2' => $group->{$property},
- );
- $this->assertEqual($compare_set->{$property}, $group->{$property}, format_string('breakpoint_group_load: Proper %property: %property1 == %property2 for breakpoint group %group.', $t_args), 'Breakpoint API');
- }
- }
-
- // Ensure that the breakpoint group has the expected breakpoints.
- $this->assertEqual(array_keys($compare_set->getBreakpoints()), array_keys($group->getBreakpoints()));
- }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointTestBase.php b/core/modules/breakpoint/src/Tests/BreakpointTestBase.php
deleted file mode 100644
index c820689..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointTestBase.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointTestBase.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\simpletest\WebTestBase;
-use Drupal\breakpoint\Entity\Breakpoint;
-
-/**
- * Base class for Breakpoint tests.
- */
-abstract class BreakpointTestBase extends WebTestBase {
-
- /**
- * Modules to enable.
- *
- * @var array
- */
- public static $modules = array('breakpoint');
-
- protected function setUp() {
- parent::setUp();
- }
-
- /**
- * Verify that a breakpoint is properly stored.
- */
- public function verifyBreakpoint(Breakpoint $breakpoint, Breakpoint $compare_breakpoint = NULL) {
- $properties = array(
- 'label',
- 'mediaQuery',
- 'source',
- 'sourceType',
- 'weight',
- 'multipliers',
- );
-
- // Verify Breakpoint::load().
- $compare_breakpoint = is_null($compare_breakpoint) ? Breakpoint::load($breakpoint->id()) : $compare_breakpoint;
- foreach ($properties as $property) {
- $t_args = array(
- '%breakpoint' => $breakpoint->label(),
- '%property' => $property,
- );
- $this->assertEqual($compare_breakpoint->{$property}, $breakpoint->{$property}, format_string('Proper %property for breakpoint %breakpoint.', $t_args), 'Breakpoint API');
- }
- }
-}
diff --git a/core/modules/breakpoint/src/Tests/BreakpointThemeTest.php b/core/modules/breakpoint/src/Tests/BreakpointThemeTest.php
deleted file mode 100644
index 233ae72..0000000
--- a/core/modules/breakpoint/src/Tests/BreakpointThemeTest.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointsThemeTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Tests\BreakpointGroupTestBase;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-use Drupal\breakpoint\Entity\Breakpoint;
-
-/**
- * Thoroughly test the breakpoints provided by a theme.
- *
- * @group breakpoint
- */
-class BreakpointThemeTest extends BreakpointGroupTestBase {
-
- protected function setUp() {
- parent::setUp();
- theme_enable(array('breakpoint_test_theme'));
- }
-
- /**
- * Test the breakpoints provided by a theme.
- */
- public function testThemeBreakpoints() {
- // Verify the breakpoint group for breakpoint_test_theme was created.
- $breakpoint_group_obj = entity_create('breakpoint_group', array(
- 'label' => 'Breakpoint test theme',
- 'name' => 'breakpoint_test_theme',
- 'source' => 'breakpoint_test_theme',
- 'sourceType' => Breakpoint::SOURCE_TYPE_THEME,
- 'id' => Breakpoint::SOURCE_TYPE_THEME . '.breakpoint_test_theme.breakpoint_test_theme',
- ));
- $breakpoint_group_obj->addBreakpoints(entity_load_multiple('breakpoint',
- array(
- 'theme.breakpoint_test_theme.mobile',
- 'theme.breakpoint_test_theme.narrow',
- 'theme.breakpoint_test_theme.wide',
- 'theme.breakpoint_test_theme.tv',
- )
- ));
-
- // Verify we can load this breakpoint defined by the theme.
- $this->verifyBreakpointGroup($breakpoint_group_obj);
- }
-
- /**
- * Test the breakpoints defined by the custom group.
- */
- public function testThemeBreakpointGroup() {
- // Verify the breakpoint group 'test' was created by breakpoint_test_theme.
- $breakpoint_group_obj = entity_create('breakpoint_group', array(
- 'label' => 'Test Theme',
- 'name' => 'test',
- 'sourceType' => Breakpoint::SOURCE_TYPE_THEME,
- 'source' => 'breakpoint_test_theme',
- 'id' => Breakpoint::SOURCE_TYPE_THEME . '.breakpoint_test_theme.test',
- ));
- $breakpoint_group_obj->addBreakpoints(entity_load_multiple('breakpoint',
- array(
- 'theme.breakpoint_test_theme.mobile',
- 'theme.breakpoint_test_theme.narrow',
- 'theme.breakpoint_test_theme.wide',
- )
- ));
-
- // Verify we can load this breakpoint defined by the theme.
- $this->verifyBreakpointGroup($breakpoint_group_obj);
- }
-
-}