summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/lib/Drupal/Core/Extension/ModuleHandler.php7
-rw-r--r--core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php11
-rw-r--r--core/lib/Drupal/Core/Extension/ThemeHandler.php30
-rw-r--r--core/lib/Drupal/Core/Extension/ThemeHandlerInterface.php35
-rw-r--r--core/modules/breakpoint/breakpoint.module33
-rw-r--r--core/modules/breakpoint/breakpoint.services.yml6
-rw-r--r--core/modules/breakpoint/config/schema/breakpoint.schema.yml58
-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
-rw-r--r--core/modules/breakpoint/tests/modules/breakpoint_module_test/breakpoint_module_test.breakpoints.yml21
-rw-r--r--core/modules/breakpoint/tests/modules/breakpoint_module_test/breakpoint_module_test.info.yml6
-rw-r--r--core/modules/breakpoint/tests/src/BreakpointConfigEntityUnitTest.php123
-rw-r--r--core/modules/breakpoint/tests/src/BreakpointGroupConfigEntityUnitTest.php158
-rw-r--r--core/modules/breakpoint/tests/src/BreakpointMediaQueryTest.php117
-rw-r--r--core/modules/breakpoint/tests/src/BreakpointTest.php122
-rw-r--r--core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.mobile.yml11
-rw-r--r--core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.narrow.yml11
-rw-r--r--core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.tv.yml11
-rw-r--r--core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.wide.yml11
-rw-r--r--core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.breakpoint_test_theme.yml12
-rw-r--r--core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.test.yml11
-rw-r--r--core/modules/breakpoint/tests/themes/breakpoint_theme_test/breakpoint_theme_test.breakpoints.yml41
-rw-r--r--core/modules/breakpoint/tests/themes/breakpoint_theme_test/breakpoint_theme_test.info.yml (renamed from core/modules/breakpoint/tests/themes/breakpoint_test_theme/breakpoint_test_theme.info.yml)0
-rw-r--r--core/modules/responsive_image/config/schema/responsive_image.schema.yml23
-rw-r--r--core/modules/responsive_image/responsive_image.module28
-rw-r--r--core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php167
-rw-r--r--core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php52
-rw-r--r--core/modules/responsive_image/src/ResponsiveImageMappingForm.php73
-rw-r--r--core/modules/responsive_image/src/ResponsiveImageMappingInterface.php68
-rw-r--r--core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php76
-rw-r--r--core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php53
-rw-r--r--core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.breakpoints.yml21
-rw-r--r--core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.info.yml6
-rw-r--r--core/modules/responsive_image/tests/src/ResponsiveImageMappingConfigEntityUnitTest.php198
-rw-r--r--core/modules/responsive_image/tests/src/ResponsiveImageMappingEntityTest.php124
-rw-r--r--core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.narrow.yml11
-rw-r--r--core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.standard.yml11
-rw-r--r--core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.wide.yml11
-rw-r--r--core/modules/toolbar/config/install/breakpoint.breakpoint_group.module.toolbar.toolbar.yml11
-rw-r--r--core/modules/toolbar/js/toolbar.js12
-rw-r--r--core/modules/toolbar/toolbar.breakpoints.yml18
-rw-r--r--core/modules/toolbar/toolbar.module19
-rw-r--r--core/themes/bartik/bartik.breakpoints.yml18
-rw-r--r--core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.mobile.yml11
-rw-r--r--core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.narrow.yml11
-rw-r--r--core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.wide.yml11
-rw-r--r--core/themes/bartik/config/install/breakpoint.breakpoint_group.theme.bartik.bartik.yml11
-rw-r--r--core/themes/seven/config/install/seven.breakpoints.yml2
-rw-r--r--core/themes/seven/seven.breakpoints.yml12
-rw-r--r--core/themes/stark/config/install/stark.breakpoints.yml3
-rw-r--r--core/themes/stark/stark.breakpoints.yml18
69 files changed, 1461 insertions, 2243 deletions
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index eac7318..cb65449 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -1068,4 +1068,11 @@ class ModuleHandler implements ModuleHandlerInterface {
return $dirs;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getName($module) {
+ $module_data = system_rebuild_module_data();
+ return $module_data[$module]->info['name'];
+ }
}
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
index 97250aa..48b5760 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandlerInterface.php
@@ -346,4 +346,15 @@ interface ModuleHandlerInterface {
*/
public function getModuleDirectories();
+ /**
+ * Gets the human readable name of a given module.
+ *
+ * @param string $module
+ * The machine name of the module which title should be shown.
+ *
+ * @return string
+ * Returns the human readable name of the module.
+ */
+ public function getName($theme);
+
}
diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php
index c529bad..d9ef77e 100644
--- a/core/lib/Drupal/Core/Extension/ThemeHandler.php
+++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php
@@ -682,4 +682,34 @@ class ThemeHandler implements ThemeHandlerInterface {
return system_list('theme');
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getThemeDirectories() {
+ $dirs = array();
+ foreach ($this->listInfo() as $name => $theme) {
+ $dirs[$name] = DRUPAL_ROOT . '/' . $theme->getPath();
+ }
+ return $dirs;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function themeExists($theme) {
+ $themes = $this->listInfo();
+ return isset($themes[$theme]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTheme($name) {
+ $themes = $this->listInfo();
+ if (isset($themes[$name])) {
+ return $themes[$name];
+ }
+ throw new \InvalidArgumentException(sprintf('The theme %s does not exist.', $name));
+ }
+
}
diff --git a/core/lib/Drupal/Core/Extension/ThemeHandlerInterface.php b/core/lib/Drupal/Core/Extension/ThemeHandlerInterface.php
index 96b636c..74f9ad2 100644
--- a/core/lib/Drupal/Core/Extension/ThemeHandlerInterface.php
+++ b/core/lib/Drupal/Core/Extension/ThemeHandlerInterface.php
@@ -139,4 +139,39 @@ interface ThemeHandlerInterface {
*/
public function getDefault();
+ /**
+ * Returns an array of directories for all enabled themes.
+ *
+ * Useful for tasks such as finding a file that exists in all theme
+ * directories.
+ *
+ * @return array
+ */
+ public function getThemeDirectories();
+
+ /**
+ * Determines whether a given theme is enabled.
+ *
+ * @param string $theme
+ * The name of the theme (without the .theme extension).
+ *
+ * @return bool
+ * TRUE if the theme is both installed and enabled.
+ */
+ public function themeExists($theme);
+
+ /**
+ * Returns a theme extension object from the currently active theme list.
+ *
+ * @param string $name
+ * The name of the theme to return.
+ *
+ * @return \Drupal\Core\Extension\Extension
+ * An extension object.
+ *
+ * @throws \InvalidArgumentException
+ * Thrown when the requested theme does not exist.
+ */
+ public function getTheme($name);
+
}
diff --git a/core/modules/breakpoint/breakpoint.module b/core/modules/breakpoint/breakpoint.module
index 6f69efc..35187b1 100644
--- a/core/modules/breakpoint/breakpoint.module
+++ b/core/modules/breakpoint/breakpoint.module
@@ -5,9 +5,6 @@
* Manage breakpoints and breakpoint groups for responsive designs.
*/
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-use Drupal\Core\Config\Entity\ConfigEntityStorage;
use Drupal\Core\Routing\RouteMatchInterface;
/**
@@ -40,33 +37,15 @@ function breakpoint_help($route_name, RouteMatchInterface $route_match) {
}
/**
- * Load all breakpoint groups as select options.
- *
- * @return array
- * An array containing breakpoint group labels indexed by their ids.
+ * Implements hook_themes_enabled()
*/
-function breakpoint_group_select_options() {
- $options = array();
- $breakpoint_groups = BreakpointGroup::loadMultiple();
- foreach ($breakpoint_groups as $breakpoint_group) {
- $options[$breakpoint_group->id()] = $breakpoint_group->label();
- }
- asort($options);
- return $options;
+function breakpoint_themes_enabled($theme_list) {
+ \Drupal::service('breakpoint.manager')->clearCachedDefinitions();
}
/**
- * Load all breakpoints as select options.
- *
- * @return array
- * An array containing breakpoints indexed by their ids.
+ * Implements hook_themes_disabled()
*/
-function breakpoint_select_options() {
- $options = array();
- $breakpoints = Breakpoint::loadMultiple();
- foreach ($breakpoints as $breakpoint) {
- $options[$breakpoint->id()] = $breakpoint->label() . ' (' . $breakpoint->source . ' - ' . $breakpoint->sourceType . ') [' . $breakpoint->mediaQuery . ']';
- }
- asort($options);
- return $options;
+function breakpoint_themes_disabled($theme_list) {
+ \Drupal::service('breakpoint.manager')->clearCachedDefinitions();
}
diff --git a/core/modules/breakpoint/breakpoint.services.yml b/core/modules/breakpoint/breakpoint.services.yml
new file mode 100644
index 0000000..a1e86ec
--- /dev/null
+++ b/core/modules/breakpoint/breakpoint.services.yml
@@ -0,0 +1,6 @@
+services:
+ breakpoint.manager:
+ class: Drupal\breakpoint\BreakpointManager
+ arguments: ['@module_handler', '@theme_handler', '@cache.discovery', '@string_translation']
+ tags:
+ - { name: plugin_manager_cache_clear }
diff --git a/core/modules/breakpoint/config/schema/breakpoint.schema.yml b/core/modules/breakpoint/config/schema/breakpoint.schema.yml
deleted file mode 100644
index c44ef4c..0000000
--- a/core/modules/breakpoint/config/schema/breakpoint.schema.yml
+++ /dev/null
@@ -1,58 +0,0 @@
-# Schema for the configuration files of the Breakpoint module.
-breakpoint.breakpoint.*.*.*:
- type: config_entity
- label: 'Defines the Breakpoint entity'
- mapping:
- id:
- type: string
- label: 'ID'
- label:
- type: label
- label: 'Label'
- name:
- type: string
- label: 'Machine name'
- mediaQuery:
- type: string
- label: 'Media query'
- source:
- type: string
- label: 'Source'
- sourceType:
- type: string
- label: 'Source type'
- weight:
- type: integer
- label: 'Weight'
- multipliers:
- type: sequence
- label: 'Multipliers'
- sequence:
- - type: string
- label: 'Multiplier'
-
-breakpoint.breakpoint_group.*.*.*:
- type: config_entity
- label: 'Breakpoint group settings'
- mapping:
- id:
- type: string
- label: 'ID'
- label:
- type: label
- label: 'Label'
- name:
- type: string
- label: 'Machine name'
- breakpoint_ids:
- type: sequence
- label: 'Breakpoints'
- sequence:
- - type: string
- label: 'Breakpoint name'
- source:
- type: string
- label: 'Group source: theme or module name'
- sourceType:
- type: string
- label: 'Group source type'
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);
- }
-
-}
diff --git a/core/modules/breakpoint/tests/modules/breakpoint_module_test/breakpoint_module_test.breakpoints.yml b/core/modules/breakpoint/tests/modules/breakpoint_module_test/breakpoint_module_test.breakpoints.yml
new file mode 100644
index 0000000..0c24709
--- /dev/null
+++ b/core/modules/breakpoint/tests/modules/breakpoint_module_test/breakpoint_module_test.breakpoints.yml
@@ -0,0 +1,21 @@
+breakpoint_module_test.mobile:
+ label: mobile
+ mediaQuery: '(min-width: 0px)'
+ weight: 0
+ # Don't include multipliers. A 1x multiplier this will be enforced by default.
+breakpoint_module_test.standard:
+ label: standard
+ mediaQuery: '(min-width: 560px)'
+ weight: 1
+ # Don't include a 1x multiplier this will be enforced by default.
+ multipliers:
+ - 2x
+# Test providing a breakpoint for group matching the group provided by
+# breakpoint_test_theme.
+breakpoint_module_test.breakpoint_theme_test.group2.tv:
+ label: tv
+ mediaQuery: '(min-width: 6000px)'
+ weight: 3
+ multipliers:
+ - 1x
+ group: breakpoint_theme_test.group2
diff --git a/core/modules/breakpoint/tests/modules/breakpoint_module_test/breakpoint_module_test.info.yml b/core/modules/breakpoint/tests/modules/breakpoint_module_test/breakpoint_module_test.info.yml
new file mode 100644
index 0000000..5acc9cd
--- /dev/null
+++ b/core/modules/breakpoint/tests/modules/breakpoint_module_test/breakpoint_module_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Breakpoint test module'
+type: module
+description: 'Test module for breakpoint.'
+version: VERSION
+core: 8.x
+
diff --git a/core/modules/breakpoint/tests/src/BreakpointConfigEntityUnitTest.php b/core/modules/breakpoint/tests/src/BreakpointConfigEntityUnitTest.php
deleted file mode 100644
index 3b10801..0000000
--- a/core/modules/breakpoint/tests/src/BreakpointConfigEntityUnitTest.php
+++ /dev/null
@@ -1,123 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\breakpoint\Tests\BreakpointConfigEntityUnitTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\breakpoint\Entity\Breakpoint
- * @group breakpoint
- */
-class BreakpointConfigEntityUnitTest extends UnitTestCase {
-
- /**
- * The entity under test.
- *
- * @var \Drupal\breakpoint\Entity\Breakpoint|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $entity;
-
- /**
- * The entity type used for testing.
- *
- * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $entityType;
-
- /**
- * The entity manager used for testing.
- *
- * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $entityManager;
-
- /**
- * The ID of the type of the entity under test.
- *
- * @var string
- */
- protected $entityTypeId;
-
- /**
- * The UUID generator used for testing.
- *
- * @var \Drupal\Component\Uuid\UuidInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $uuid;
-
- /**
- * {@inheritdoc}
- */
- protected function setUp() {
- $this->entityTypeId = $this->randomMachineName();
-
- $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
- $this->entityType->expects($this->any())
- ->method('getProvider')
- ->will($this->returnValue('breakpoint'));
-
- $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
- $this->entityManager->expects($this->any())
- ->method('getDefinition')
- ->with($this->entityTypeId)
- ->will($this->returnValue($this->entityType));
-
- $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
-
- $container = new ContainerBuilder();
- $container->set('entity.manager', $this->entityManager);
- $container->set('uuid', $this->uuid);
- \Drupal::setContainer($container);
- }
-
- /**
- * @covers ::calculateDependencies
- */
- public function testCalculateDependenciesModule() {
- $values = array(
- 'name' => 'test',
- 'source' => 'test_module',
- 'sourceType' => Breakpoint::SOURCE_TYPE_MODULE,
- );
- $entity = new Breakpoint($values, $this->entityTypeId);
-
- $dependencies = $entity->calculateDependencies();
- $this->assertArrayNotHasKey('theme', $dependencies);
- $this->assertContains('test_module', $dependencies['module']);
- }
-
- /**
- * @covers ::calculateDependencies
- */
- public function testCalculateDependenciesTheme() {
- $values = array(
- 'name' => 'test',
- 'source' => 'test_theme',
- 'sourceType' => Breakpoint::SOURCE_TYPE_THEME,
- );
- $entity = new Breakpoint($values, $this->entityTypeId);
-
- $dependencies = $entity->calculateDependencies();
- $this->assertArrayNotHasKey('module', $dependencies);
- $this->assertContains('test_theme', $dependencies['theme']);
- }
-
- /**
- * @expectedException \Drupal\breakpoint\InvalidBreakpointNameException
- */
- public function testNameException () {
- new Breakpoint(array(
- 'label' => $this->randomMachineName(),
- 'source' => 'custom_module',
- 'sourceType' => 'oops',
- ));
- }
-
-}
diff --git a/core/modules/breakpoint/tests/src/BreakpointGroupConfigEntityUnitTest.php b/core/modules/breakpoint/tests/src/BreakpointGroupConfigEntityUnitTest.php
deleted file mode 100644
index 61ad1ac..0000000
--- a/core/modules/breakpoint/tests/src/BreakpointGroupConfigEntityUnitTest.php
+++ /dev/null
@@ -1,158 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\breakpoint\Tests\BreakpointGroupConfigEntityUnitTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\breakpoint\Entity\BreakpointGroup;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\breakpoint\Entity\BreakpointGroup
- * @group breakpoint
- */
-class BreakpointGroupConfigEntityUnitTest extends UnitTestCase {
-
- /**
- * The entity under test.
- *
- * @var \Drupal\breakpoint\Entity\BreakpointGroup|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $entity;
-
- /**
- * The entity type used for testing.
- *
- * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $entityType;
-
- /**
- * The entity manager used for testing.
- *
- * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $entityManager;
-
- /**
- * The ID of the type of the entity under test.
- *
- * @var string
- */
- protected $entityTypeId;
-
- /**
- * The UUID generator used for testing.
- *
- * @var \Drupal\Component\Uuid\UuidInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $uuid;
-
- /**
- * {@inheritdoc}
- */
- protected function setUp() {
- $this->entityTypeId = $this->randomMachineName();
-
- $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
- $this->entityType->expects($this->any())
- ->method('getProvider')
- ->will($this->returnValue('breakpoint'));
-
- $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
- $this->entityManager->expects($this->any())
- ->method('getDefinition')
- ->with($this->entityTypeId)
- ->will($this->returnValue($this->entityType));
-
- $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
-
- $container = new ContainerBuilder();
- $container->set('entity.manager', $this->entityManager);
- $container->set('uuid', $this->uuid);
- \Drupal::setContainer($container);
- }
-
- /**
- * Sets up the entity to test.
- */
- public function setUpEntity($values) {
- // Mocking the entity under test because the class contains calls to
- // procedural code.
- $this->entity = $this->getMockBuilder('\Drupal\breakpoint\Entity\BreakpointGroup')
- ->setConstructorArgs(array($values, $this->entityTypeId))
- ->setMethods(array('getBreakpoints'))
- ->getMock();
- }
-
- /**
- * @covers ::calculateDependencies
- */
- public function testCalculateDependenciesModule() {
- $this->setUpEntity(
- array(
- 'name' => 'test',
- 'source' => 'test_module',
- 'sourceType' => Breakpoint::SOURCE_TYPE_MODULE,
- )
- );
- $breakpoint = $this->getMock('\Drupal\breakpoint\BreakpointInterface');
- $breakpoint->expects($this->once())
- ->method('getConfigDependencyName')
- ->will($this->returnValue('breakpoint.breakpoint.test'));
-
- $this->entity->expects($this->once())
- ->method('getBreakpoints')
- ->will($this->returnValue(array($breakpoint)));
-
- $dependencies = $this->entity->calculateDependencies();
- $this->assertArrayNotHasKey('theme', $dependencies);
- $this->assertContains('test_module', $dependencies['module']);
- $this->assertContains('breakpoint.breakpoint.test', $dependencies['entity']);
- }
-
- /**
- * @covers ::calculateDependencies
- */
- public function testCalculateDependenciesTheme() {
- $this->setUpEntity(
- array(
- 'name' => 'test',
- 'source' => 'test_theme',
- 'sourceType' => Breakpoint::SOURCE_TYPE_THEME,
- )
- );
-
- $breakpoint = $this->getMockBuilder('\Drupal\breakpoint\Entity\Breakpoint')
- ->disableOriginalConstructor()->getMock();
- $breakpoint->expects($this->once())
- ->method('getConfigDependencyName')
- ->will($this->returnValue('breakpoint.breakpoint.test'));
-
- $this->entity->expects($this->once())
- ->method('getBreakpoints')
- ->will($this->returnValue(array($breakpoint)));
-
- $dependencies = $this->entity->calculateDependencies();
- $this->assertArrayNotHasKey('module', $dependencies);
- $this->assertContains('test_theme', $dependencies['theme']);
- $this->assertContains('breakpoint.breakpoint.test', $dependencies['entity']);
- }
-
- /**
- * @expectedException \Drupal\breakpoint\InvalidBreakpointNameException
- */
- public function testNameException () {
- new BreakpointGroup(array(
- 'label' => $this->randomMachineName(),
- 'source' => 'custom_module',
- 'sourceType' => 'oops',
- ));
- }
-
-}
diff --git a/core/modules/breakpoint/tests/src/BreakpointMediaQueryTest.php b/core/modules/breakpoint/tests/src/BreakpointMediaQueryTest.php
deleted file mode 100644
index c8ab81d..0000000
--- a/core/modules/breakpoint/tests/src/BreakpointMediaQueryTest.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-/**
- * @file
- * Definition of Drupal\breakpoint\Tests\BreakpointMediaQueryTest.
- */
-
-namespace Drupal\breakpoint\Tests;
-
-use Drupal\Tests\UnitTestCase;
-use Drupal\breakpoint\Entity\Breakpoint;
-use Drupal\breakpoint\InvalidBreakpointMediaQueryException;
-
-/**
- * Tests validation of media queries.
- *
- * @group breakpoint
- */
-class BreakpointMediaQueryTest extends UnitTestCase {
-
- /**
- * Test valid media queries.
- */
- public function testValidMediaQueries() {
- $media_queries = array(
- // Bartik breakpoints.
- '(min-width: 0px)',
- 'all and (min-width: 560px) and (max-width:850px)',
- 'all and (min-width: 851px)',
- // Seven breakpoints.
- '(min-width: 0em)',
- 'screen and (min-width: 40em)',
- // Stark breakpoints.
- '(min-width: 0px)',
- 'all and (min-width: 480px) and (max-width: 959px)',
- 'all and (min-width: 960px)',
- // Other media queries.
- '(orientation)',
- 'all and (orientation)',
- 'not all and (orientation)',
- 'only all and (orientation)',
- 'screen and (width)',
- 'screen and (width: 0)',
- 'screen and (width: 0px)',
- 'screen and (width: 0em)',
- 'screen and (min-width: -0)',
- 'screen and (max-width: 0)',
- 'screen and (max-width: 0.3)',
- 'screen and (min-width)',
- // Multiline and comments.
- 'screen and /* this is a comment */ (min-width)',
- "screen\nand /* this is a comment */ (min-width)",
- "screen\n\nand /* this is\n a comment */ (min-width)",
- // Unrecognized features are allowed.
- 'screen and (-webkit-min-device-pixel-ratio: 7)',
- 'screen and (min-orientation: landscape)',
- 'screen and (max-orientation: landscape)',
- );
-
- foreach ($media_queries as $media_query) {
- $this->assertTrue(Breakpoint::isValidMediaQuery($media_query), $media_query . ' is valid.');
- }
- }
-
- /**
- * Test invalid media queries.
- */
- public function testInvalidMediaQueries() {
- $media_queries = array(
- '',
- 'not (orientation)',
- 'only (orientation)',
- 'all and not all',
- 'screen and (width: 0xx)',
- 'screen and (width: -8xx)',
- 'screen and (width: -xx)',
- 'screen and (width: xx)',
- 'screen and (width: px)',
- 'screen and (width: -8px)',
- 'screen and (width: -0.8px)',
- 'screen and (height: 0xx)',
- 'screen and (height: -8xx)',
- 'screen and (height: -xx)',
- 'screen and (height: xx)',
- 'screen and (height: px)',
- 'screen and (height: -8px)',
- 'screen and (height: -0.8px)',
- 'screen and (device-width: 0xx)',
- 'screen and (device-width: -8xx)',
- 'screen and (device-width: -xx)',
- 'screen and (device-width: xx)',
- 'screen and (device-width: px)',
- 'screen and (device-width: -8px)',
- 'screen and (device-width: -0.8px)',
- 'screen and (device-height: 0xx)',
- 'screen and (device-height: -8xx)',
- 'screen and (device-height: -xx)',
- 'screen and (device-height: xx)',
- 'screen and (device-height: px)',
- 'screen and (device-height: -8px)',
- 'screen and (device-height: -0.8px)',
- 'screen and (min-orientation)',
- 'screen and (max-orientation)',
- 'screen and (orientation: bogus)',
- '(orientation: bogus)',
- 'screen and (ori"entation: bogus)',
- );
-
- foreach ($media_queries as $media_query) {
- try {
- $this->assertFalse(Breakpoint::isValidMediaQuery($media_query), $media_query . ' is not valid.');
- }
- catch (InvalidBreakpointMediaQueryException $e) {
- $this->assertTrue(TRUE, sprintf('%s is not valid.', $media_query));
- }
- }
- }
-}
diff --git a/core/modules/breakpoint/tests/src/BreakpointTest.php b/core/modules/breakpoint/tests/src/BreakpointTest.php
new file mode 100644
index 0000000..a2b62ea
--- /dev/null
+++ b/core/modules/breakpoint/tests/src/BreakpointTest.php
@@ -0,0 +1,122 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\breakpoint\Tests\BreakpointTest.
+ */
+
+namespace Drupal\breakpoint\Tests;
+
+use Drupal\breakpoint\Breakpoint;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\breakpoint\Breakpoint
+ * @group Breakpoint
+ */
+class BreakpointTest extends UnitTestCase {
+
+ /**
+ * The used plugin ID.
+ *
+ * @var string
+ */
+ protected $pluginId = 'breakpoint';
+
+ /**
+ * The used plugin definition.
+ *
+ * @var array
+ */
+ protected $pluginDefinition = array(
+ 'id' => 'breakpoint',
+ );
+
+ /**
+ * The breakpoint under test.
+ *
+ * @var \Drupal\breakpoint\Breakpoint
+ */
+ protected $breakpoint;
+
+ /**
+ * The mocked translator.
+ *
+ * @var \Drupal\Core\StringTranslation\TranslationInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $stringTranslation;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $this->stringTranslation = $this->getMock('Drupal\Core\StringTranslation\TranslationInterface');
+ }
+
+ /**
+ * Sets up the breakpoint defaults.
+ */
+ protected function setupBreakpoint() {
+ $this->breakpoint = new Breakpoint(array(), $this->pluginId, $this->pluginDefinition);
+ $this->breakpoint->setStringTranslation($this->stringTranslation);
+ }
+
+ /**
+ * @covers ::getLabel
+ */
+ public function testGetLabel() {
+ $this->pluginDefinition['label'] = 'Test label';
+ $this->stringTranslation->expects($this->once())
+ ->method('translate')
+ ->with($this->pluginDefinition['label'], array(), array('context' => 'breakpoint'))
+ ->will($this->returnValue('Test label translated'));
+ $this->setupBreakpoint();
+ $this->assertEquals('Test label translated', $this->breakpoint->getLabel());
+ }
+
+ /**
+ * @covers ::getWeight
+ */
+ public function testGetWeight() {
+ $this->pluginDefinition['weight'] = '4';
+ $this->setupBreakpoint();
+ // Assert that the type returned in an integer.
+ $this->assertSame(4, $this->breakpoint->getWeight());
+ }
+
+ /**
+ * @covers ::getMediaQuery
+ */
+ public function testGetMediaQuery() {
+ $this->pluginDefinition['mediaQuery'] = 'only screen and (min-width: 3456px)';
+ $this->setupBreakpoint();
+ $this->assertEquals('only screen and (min-width: 3456px)', $this->breakpoint->getMediaQuery());
+ }
+
+ /**
+ * @covers ::getMultipliers
+ */
+ public function testGetMultipliers() {
+ $this->pluginDefinition['multipliers'] = array('1x', '2x');
+ $this->setupBreakpoint();
+ $this->assertSame(array('1x', '2x'), $this->breakpoint->getMultipliers());
+ }
+
+ /**
+ * @covers ::getProvider
+ */
+ public function testGetProvider() {
+ $this->pluginDefinition['provider'] = 'Breakpoint';
+ $this->setupBreakpoint();
+ $this->assertEquals('Breakpoint', $this->breakpoint->getProvider());
+ }
+
+ /**
+ * @covers ::getGroup
+ */
+ public function testGetGroup() {
+ $this->pluginDefinition['group'] = 'Breakpoint';
+ $this->setupBreakpoint();
+ $this->assertEquals('Breakpoint', $this->breakpoint->getGroup());
+ }
+
+}
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.mobile.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.mobile.yml
deleted file mode 100644
index 8e5e3c4..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.mobile.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.breakpoint_test_theme.mobile
-name: mobile
-label: mobile
-mediaQuery: '(min-width: 0px)'
-source: breakpoint_test_theme
-sourceType: theme
-weight: 0
-multipliers:
- 1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.narrow.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.narrow.yml
deleted file mode 100644
index a34b582..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.narrow.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.breakpoint_test_theme.narrow
-name: narrow
-label: narrow
-mediaQuery: '(min-width: 560px)'
-source: breakpoint_test_theme
-sourceType: theme
-weight: 1
-multipliers:
- 1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.tv.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.tv.yml
deleted file mode 100644
index d594ff4..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.tv.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.breakpoint_test_theme.tv
-name: tv
-label: tv
-mediaQuery: 'only screen and (min-width: 3456px)'
-source: breakpoint_test_theme
-sourceType: theme
-weight: 3
-multipliers:
- 1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.wide.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.wide.yml
deleted file mode 100644
index 34e5f4f..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint.theme.breakpoint_test_theme.wide.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.breakpoint_test_theme.wide
-name: wide
-label: wide
-mediaQuery: '(min-width: 851px)'
-source: breakpoint_test_theme
-sourceType: theme
-weight: 2
-multipliers:
- 1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.breakpoint_test_theme.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.breakpoint_test_theme.yml
deleted file mode 100644
index c335fb0..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.breakpoint_test_theme.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-id: theme.breakpoint_test_theme.breakpoint_test_theme
-name: breakpoint_test_theme
-label: 'Breakpoint test theme'
-breakpoint_ids:
- - theme.breakpoint_test_theme.mobile
- - theme.breakpoint_test_theme.narrow
- - theme.breakpoint_test_theme.wide
- - theme.breakpoint_test_theme.tv
-source: breakpoint_test_theme
-sourceType: theme
-status: true
-langcode: en
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.test.yml b/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.test.yml
deleted file mode 100644
index e074998..0000000
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/config/install/breakpoint.breakpoint_group.theme.breakpoint_test_theme.test.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.breakpoint_test_theme.test
-name: test
-label: 'Test Theme'
-breakpoint_ids:
- - theme.breakpoint_test_theme.mobile
- - theme.breakpoint_test_theme.narrow
- - theme.breakpoint_test_theme.wide
-source: breakpoint_test_theme
-sourceType: theme
-status: true
-langcode: en
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_theme_test/breakpoint_theme_test.breakpoints.yml b/core/modules/breakpoint/tests/themes/breakpoint_theme_test/breakpoint_theme_test.breakpoints.yml
new file mode 100644
index 0000000..6d34ec7
--- /dev/null
+++ b/core/modules/breakpoint/tests/themes/breakpoint_theme_test/breakpoint_theme_test.breakpoints.yml
@@ -0,0 +1,41 @@
+breakpoint_theme_test.mobile:
+ label: mobile
+ mediaQuery: '(min-width: 0px)'
+ weight: 0
+ multipliers:
+ - 1x
+breakpoint_theme_test.narrow:
+ label: narrow
+ mediaQuery: '(min-width: 560px)'
+ weight: 1
+ multipliers:
+ - 1x
+# Out of order breakpoint to test sorting.
+breakpoint_theme_test.tv:
+ label: tv
+ mediaQuery: 'only screen and (min-width: 3456px)'
+ weight: 3
+ multipliers:
+ - 1x
+breakpoint_theme_test.wide:
+ label: wide
+ mediaQuery: '(min-width: 851px)'
+ weight: 2
+ multipliers:
+ - 1x
+breakpoint_theme_test.group2.narrow:
+ label: narrow
+ mediaQuery: '(min-width: 560px)'
+ weight: 1
+ multipliers:
+ - 1x
+ - 2x
+ group: breakpoint_theme_test.group2
+breakpoint_theme_test.group2.wide:
+ label: wide
+ mediaQuery: '(min-width: 851px)'
+ weight: 2
+ multipliers:
+ - 1x
+ - 2x
+ group: breakpoint_theme_test.group2
diff --git a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/breakpoint_test_theme.info.yml b/core/modules/breakpoint/tests/themes/breakpoint_theme_test/breakpoint_theme_test.info.yml
index 779f997..779f997 100644
--- a/core/modules/breakpoint/tests/themes/breakpoint_test_theme/breakpoint_test_theme.info.yml
+++ b/core/modules/breakpoint/tests/themes/breakpoint_theme_test/breakpoint_theme_test.info.yml
diff --git a/core/modules/responsive_image/config/schema/responsive_image.schema.yml b/core/modules/responsive_image/config/schema/responsive_image.schema.yml
index 4cdb149..aac9add 100644
--- a/core/modules/responsive_image/config/schema/responsive_image.schema.yml
+++ b/core/modules/responsive_image/config/schema/responsive_image.schema.yml
@@ -17,17 +17,18 @@ responsive_image.mappings.*:
type: sequence
label: 'Mappings'
sequence:
- - type: sequence
- label: 'Source type'
- sequence:
- - type: sequence
- label: 'Source'
- sequence:
- - type: sequence
- label: 'Machine name'
- sequence:
- - type: string
- label: 'Image style'
+ - type: mapping
+ label: 'Mapping'
+ mapping:
+ breakpoint_id:
+ type: string
+ label: 'Breakpoint ID'
+ multiplier:
+ type: string
+ label: 'Multiplier'
+ image_style:
+ type: string
+ label: 'Image style'
breakpointGroup:
type: string
label: 'Breakpoint group'
diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module
index 63f25e6..d8985c9 100644
--- a/core/modules/responsive_image/responsive_image.module
+++ b/core/modules/responsive_image/responsive_image.module
@@ -5,7 +5,6 @@
* Responsive image display formatter for image fields.
*/
-use Drupal\breakpoint\Entity\Breakpoint;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Routing\RouteMatchInterface;
use \Drupal\Core\Template\Attribute;
@@ -90,7 +89,7 @@ function responsive_image_theme() {
'alt' => '',
'title' => NULL,
'attributes' => array(),
- 'breakpoints' => array(),
+ 'mapping_id' => array(),
),
),
'responsive_image_formatter' => array(
@@ -98,7 +97,7 @@ function responsive_image_theme() {
'item' => NULL,
'path' => NULL,
'image_style' => NULL,
- 'breakpoints' => array(),
+ 'mapping_id' => array(),
),
),
'responsive_image_source' => array(
@@ -120,13 +119,13 @@ function responsive_image_theme() {
* - item: An ImageItem object.
* - image_style: An optional image style.
* - path: An optional array containing the link 'path' and link 'options'.
- * - breakpoints: An array containing breakpoints.
+ * - mapping_id: The ID of the responsive image mapping.
*
* @ingroup themeable
*/
function theme_responsive_image_formatter($variables) {
$item = $variables['item'];
- if (!isset($variables['breakpoints']) || empty($variables['breakpoints'])) {
+ if (!isset($variables['mapping_id']) || empty($variables['mapping_id'])) {
$image_formatter = array(
'#theme' => 'image_formatter',
'#item' => $item,
@@ -141,7 +140,7 @@ function theme_responsive_image_formatter($variables) {
'#width' => $item->width,
'#height' => $item->height,
'#style_name' => $variables['image_style'],
- '#breakpoints' => $variables['breakpoints'],
+ '#mapping_id' => $variables['mapping_id'],
);
if (isset($item->uri)) {
$responsive_image['#uri'] = $item->uri;
@@ -178,7 +177,7 @@ function theme_responsive_image_formatter($variables) {
* - title: The title text is displayed when the image is hovered in some
* popular browsers.
* - style_name: The name of the style to be used as a fallback image.
- * - breakpoints: An array containing breakpoints.
+ * - mapping_id: The ID of the responsive image mapping.
*
* @ingroup themeable
*/
@@ -202,11 +201,12 @@ function theme_responsive_image($variables) {
'src' => _responsive_image_image_style_url($variables['style_name'], $variables['uri']),
'dimensions' => responsive_image_get_image_dimensions($variables),
);
-
+ $responsive_image_mapping = entity_load('responsive_image_mapping', $variables['mapping_id']);
// All breakpoints and multipliers.
- foreach ($variables['breakpoints'] as $breakpoint_name => $multipliers) {
- $breakpoint = Breakpoint::load($breakpoint_name);
- if ($breakpoint) {
+ $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup($responsive_image_mapping->getBreakpointGroup());
+ foreach ($responsive_image_mapping->getKeyedMappings() as $breakpoint_id => $multipliers) {
+ if (isset($breakpoints[$breakpoint_id])) {
+ $breakpoint = $breakpoints[$breakpoint_id];
$new_sources = array();
foreach ($multipliers as $multiplier => $image_style) {
$new_source = $variables;
@@ -220,7 +220,7 @@ function theme_responsive_image($variables) {
$sources[] = array(
'src' => _responsive_image_image_style_url($new_sources[0]['style_name'], $new_sources[0]['uri']),
'dimensions' => responsive_image_get_image_dimensions($new_sources[0]),
- 'media' => $breakpoint->mediaQuery,
+ 'media' => $breakpoint->getMediaQuery(),
);
}
else {
@@ -232,7 +232,7 @@ function theme_responsive_image($variables) {
$sources[] = array(
'srcset' => implode(', ', $srcset),
'dimensions' => responsive_image_get_image_dimensions($new_sources[0]),
- 'media' => $breakpoint->mediaQuery,
+ 'media' => $breakpoint->getMediaQuery(),
);
}
}
@@ -266,7 +266,7 @@ function theme_responsive_image($variables) {
/**
* Returns HTML for a source tag.
*
- * @param type $variables
+ * @param array $variables
* An associative array containing:
* - media: The media query to use.
* - srcset: The srcset containing the the path of the image file or a full
diff --git a/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php b/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php
index ffa63af..3e8440e 100644
--- a/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php
+++ b/core/modules/responsive_image/src/Entity/ResponsiveImageMapping.php
@@ -7,7 +7,6 @@
namespace Drupal\responsive_image\Entity;
-use Drupal\Component\Utility\String;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\responsive_image\ResponsiveImageMappingInterface;
@@ -46,174 +45,140 @@ class ResponsiveImageMapping extends ConfigEntityBase implements ResponsiveImage
*
* @var string
*/
- public $id;
+ protected $id;
/**
* The responsive image label.
*
* @var string
*/
- public $label;
+ protected $label;
/**
* The responsive image mappings.
*
+ * Each responsive mapping array contains the following keys:
+ * - breakpoint_id
+ * - multiplier
+ * - image_style
+ *
* @var array
*/
protected $mappings = array();
/**
- * The responsive image breakpoint group.
- *
- * @var Drupal\breakpoint\Entity\BreakpointGroup
+ * @var array
*/
- protected $breakpointGroup = '';
+ protected $keyedMappings;
/**
- * Overrides Drupal\config\ConfigEntityBase::__construct().
+ * The responsive image breakpoint group.
+ *
+ * @var string
*/
- public function __construct(array $values, $entity_type) {
- parent::__construct($values, $entity_type);
- $this->loadBreakpointGroup();
- $this->loadAllMappings();
- }
+ protected $breakpointGroup = '';
/**
* {@inheritdoc}
*/
- public function calculateDependencies() {
- parent::calculateDependencies();
- if (isset($this->breakpointGroup)) {
- // @todo Implement toArray() so we do not have reload the
- // entity since this property is changed in
- // \Drupal\responsive_image\Entity\ResponsiveImageMapping::save().
- $breakpoint_group = \Drupal::entityManager()->getStorage('breakpoint_group')->load($this->breakpointGroup);
- $this->addDependency('entity', $breakpoint_group->getConfigDependencyName());
- }
- return $this->dependencies;
+ public function __construct(array $values, $entity_type_id = 'responsive_image_mapping') {
+ parent::__construct($values, $entity_type_id);
}
/**
- * Overrides Drupal\Core\Entity::save().
+ * {@inheritdoc}
*/
- public function save() {
- // Only save the keys, but return the full objects.
- $breakpoint_group = $this->getBreakpointGroup();
- if ($breakpoint_group && is_object($breakpoint_group)) {
- $this->setBreakpointGroup($breakpoint_group->id());
- }
-
- // Split the breakpoint ids into their different parts, as dots as
- // identifiers are not possible.
- $loaded_mappings = $this->mappings;
- $this->mappings = array();
- foreach ($loaded_mappings as $breakpoint_id => $mapping) {
- list($source_type, $source, $name) = explode('.', $breakpoint_id);
- $this->mappings[$source_type][$source][$name] = $mapping;
+ public function addMapping($breakpoint_id, $multiplier, $image_style) {
+ foreach ($this->mappings as &$mapping) {
+ if ($mapping['breakpoint_id'] === $breakpoint_id && $mapping['multiplier'] === $multiplier) {
+ $mapping['image_style'] = $image_style;
+ return $this;
+ }
}
-
- parent::save();
- $this->loadBreakpointGroup();
- $this->loadAllMappings();
+ $this->mappings[] = array(
+ 'breakpoint_id' => $breakpoint_id,
+ 'multiplier' => $multiplier,
+ 'image_style' => $image_style,
+ );
+ $this->keyedMappings = NULL;
+ return $this;
}
/**
- * Implements \Drupal\Core\Entity\EntityInterface::createDuplicate().
+ * {@inheritdoc}
*/
- public function createDuplicate() {
- return entity_create('responsive_image_mapping', array(
- 'id' => '',
- 'label' => t('Clone of !label', array('!label' => String::checkPlain($this->label()))),
- 'mappings' => $this->getMappings(),
- ));
+ public function hasMappings() {
+ return !empty($this->mappings);
}
/**
- * Loads the breakpoint group.
+ * {@inheritdoc}
*/
- protected function loadBreakpointGroup() {
- if ($this->getBreakpointGroup()) {
- $breakpoint_group = entity_load('breakpoint_group', $this->getBreakpointGroup());
- $this->setBreakpointGroup($breakpoint_group);
+ public function getKeyedMappings() {
+ if (!$this->keyedMappings) {
+ $this->keyedMappings = array();
+ foreach($this->mappings as $mapping) {
+ $this->keyedMappings[$mapping['breakpoint_id']][$mapping['multiplier']] = $mapping['image_style'];
+ }
}
+ return $this->keyedMappings;
}
/**
- * Loads all mappings and removes non-existing ones.
+ * {@inheritdoc}
*/
- protected function loadAllMappings() {
- $loaded_mappings = $this->getMappings();
- $all_mappings = array();
- if ($breakpoint_group = $this->getBreakpointGroup()) {
- foreach ($breakpoint_group->getBreakpoints() as $breakpoint_id => $breakpoint) {
- // Get the components of the breakpoint ID to match the format of the
- // configuration file.
- list($source_type, $source, $name) = explode('.', $breakpoint_id);
-
- // Get the mapping for the default multiplier.
- $all_mappings[$breakpoint_id]['1x'] = '';
- if (isset($loaded_mappings[$source_type][$source][$name]['1x'])) {
- $all_mappings[$breakpoint_id]['1x'] = $loaded_mappings[$source_type][$source][$name]['1x'];
- }
-
- // Get the mapping for the other multipliers.
- if (isset($breakpoint->multipliers) && !empty($breakpoint->multipliers)) {
- foreach ($breakpoint->multipliers as $multiplier => $status) {
- if ($status) {
- $all_mappings[$breakpoint_id][$multiplier] = '';
- if (isset($loaded_mappings[$source_type][$source][$name][$multiplier])) {
- $all_mappings[$breakpoint_id][$multiplier] = $loaded_mappings[$source_type][$source][$name][$multiplier];
- }
- }
- }
- }
- }
+ public function getImageStyle($breakpoint_id, $multiplier) {
+ $map = $this->getKeyedMappings();
+ if (isset($map[$breakpoint_id][$multiplier])) {
+ return $map[$breakpoint_id][$multiplier];
}
- $this->setMappings($all_mappings);
}
/**
* {@inheritdoc}
*/
- public function hasMappings() {
- $mapping_found = FALSE;
- foreach ($this->getMappings() as $multipliers) {
- $filtered_array = array_filter($multipliers);
- if (!empty($filtered_array)) {
- $mapping_found = TRUE;
- break;
- }
- }
- return $mapping_found;
+ public function getMappings() {
+ return $this->get('mappings');
}
/**
* {@inheritdoc}
*/
- public function setMappings(array $mappings) {
- $this->set('mappings', $mappings);
+ public function setBreakpointGroup($breakpoint_group) {
+ // If the breakpoint group is changed then the mappings are invalid.
+ if ($breakpoint_group !== $this->breakpointGroup) {
+ $this->removeMappings();
+ }
+ $this->set('breakpointGroup', $breakpoint_group);
return $this;
}
/**
* {@inheritdoc}
*/
- public function getMappings() {
- return $this->get('mappings');
+ public function getBreakpointGroup() {
+ return $this->get('breakpointGroup');
}
/**
* {@inheritdoc}
*/
- public function setBreakpointGroup($breakpoint_group) {
- $this->set('breakpointGroup', $breakpoint_group);
+ public function removeMappings() {
+ $this->mappings = array();
+ $this->keyedMappings = NULL;
return $this;
}
/**
* {@inheritdoc}
*/
- public function getBreakpointGroup() {
- return $this->get('breakpointGroup');
+ public function calculateDependencies() {
+ parent::calculateDependencies();
+ $providers = \Drupal::service('breakpoint.manager')->getGroupProviders($this->breakpointGroup);
+ foreach ($providers as $provider => $type) {
+ $this->addDependency($type, $provider);
+ }
+ return $this->dependencies;
}
+
}
diff --git a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php
index 24a80d4..68aa58b 100644
--- a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php
+++ b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php
@@ -132,59 +132,35 @@ class ResponsiveImageFormatter extends ImageFormatterBase {
$link_file = TRUE;
}
- $breakpoint_styles = array();
$fallback_image_style = '';
- $responsive_image_mapping = entity_load('responsive_image_mapping', $this->getSetting('responsive_image_mapping'));
- if ($responsive_image_mapping) {
- foreach ($responsive_image_mapping->getMappings() as $breakpoint_name => $multipliers) {
- // Make sure there are multipliers.
- if (!empty($multipliers)) {
- // Make sure that the breakpoint exists and is enabled.
- // @todo add the following when breakpoint->status is added again:
- // $responsive_image_mapping->breakpointGroup->breakpoints[$breakpoint_name]->status
- $breakpoint = $responsive_image_mapping->getBreakpointGroup()->getBreakpointById($breakpoint_name);
- if ($breakpoint) {
- // Determine the enabled multipliers.
- $multipliers = array_intersect_key($multipliers, $breakpoint->multipliers);
- foreach ($multipliers as $multiplier => $image_style) {
- // Make sure the multiplier still exists.
- if (!empty($image_style)) {
- // First mapping found is used as fallback.
- if (empty($fallback_image_style)) {
- $fallback_image_style = $image_style;
- }
- if (!isset($breakpoint_styles[$breakpoint_name])) {
- $breakpoint_styles[$breakpoint_name] = array();
- }
- $breakpoint_styles[$breakpoint_name][$multiplier] = $image_style;
- }
- }
- }
- }
- }
- }
-
// Check if the user defined a custom fallback image style.
if ($this->getSetting('fallback_image_style')) {
$fallback_image_style = $this->getSetting('fallback_image_style');
}
// Collect cache tags to be added for each item in the field.
+ $responsive_image_mapping = entity_load('responsive_image_mapping', $this->getSetting('responsive_image_mapping'));
+ $image_styles_to_load = array();
+ if ($fallback_image_style) {
+ $image_styles_to_load[] = $fallback_image_style;
+ }
$all_cache_tags = array();
if ($responsive_image_mapping) {
$all_cache_tags[] = $responsive_image_mapping->getCacheTag();
- foreach ($breakpoint_styles as $breakpoint_name => $style_per_multiplier) {
- foreach ($style_per_multiplier as $multiplier => $image_style_name) {
- $image_style = entity_load('image_style', $image_style_name);
- $all_cache_tags[] = $image_style->getCacheTag();
+ foreach ($responsive_image_mapping->getMappings() as $mapping) {
+ // First mapping found is used as fallback.
+ if (empty($fallback_image_style)) {
+ $fallback_image_style = $mapping['image_style'];
}
+ $image_styles_to_load[] = $mapping['image_style'];
}
}
- if ($fallback_image_style) {
- $image_style = entity_load('image_style', $fallback_image_style);
+ $image_styles = entity_load_multiple('image_style', $image_styles_to_load);
+ foreach ($image_styles as $image_style) {
$all_cache_tags[] = $image_style->getCacheTag();
}
+
$cache_tags = NestedArray::mergeDeepArray($all_cache_tags);
foreach ($items as $delta => $item) {
@@ -203,7 +179,7 @@ class ResponsiveImageFormatter extends ImageFormatterBase {
),
'#item' => $item,
'#image_style' => $fallback_image_style,
- '#breakpoints' => $breakpoint_styles,
+ '#mapping_id' => $responsive_image_mapping ? $responsive_image_mapping->id() : '',
'#path' => isset($uri) ? $uri : '',
'#cache' => array(
'tags' => $cache_tags,
diff --git a/core/modules/responsive_image/src/ResponsiveImageMappingForm.php b/core/modules/responsive_image/src/ResponsiveImageMappingForm.php
index d1510dd..b3780f0 100644
--- a/core/modules/responsive_image/src/ResponsiveImageMappingForm.php
+++ b/core/modules/responsive_image/src/ResponsiveImageMappingForm.php
@@ -7,9 +7,10 @@
namespace Drupal\responsive_image;
-use Drupal\Component\Utility\String;
+use Drupal\breakpoint\BreakpointManagerInterface;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Form controller for the responsive image edit/add forms.
@@ -17,14 +18,38 @@ use Drupal\Core\Form\FormStateInterface;
class ResponsiveImageMappingForm extends EntityForm {
/**
+ * The breakpoint manager.
+ *
+ * @var \Drupal\breakpoint\BreakpointManagerInterface
+ */
+ protected $breakpointManager;
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ return new static(
+ $container->get('breakpoint.manager')
+ );
+ }
+
+ /**
+ * Constructs the responsive image mapping form.
+ *
+ * @param \Drupal\breakpoint\BreakpointManagerInterface $breakpoint_manager
+ * The breakpoint manager.
+ */
+ public function __construct(BreakpointManagerInterface $breakpoint_manager) {
+ $this->breakpointManager = $breakpoint_manager;
+ }
+
+ /**
* Overrides Drupal\Core\Entity\EntityForm::form().
*
* @param array $form
* A nested array form elements comprising the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
- * @param \Drupal\responsive_image\ResponsiveImageMappingInterface $responsive_image_mapping
- * The entity being edited.
*
* @return array
* The array containing the complete form.
@@ -67,23 +92,23 @@ class ResponsiveImageMappingForm extends EntityForm {
$form['breakpointGroup'] = array(
'#type' => 'select',
'#title' => $this->t('Breakpoint group'),
- '#default_value' => ($responsive_image_mapping->getBreakpointGroup() != '') ? $responsive_image_mapping->getBreakpointGroup()->id() : '',
- '#options' => breakpoint_group_select_options(),
+ '#default_value' => $responsive_image_mapping->getBreakpointGroup(),
+ '#options' => $this->breakpointManager->getGroups(),
'#required' => TRUE,
'#description' => $description,
);
$image_styles = image_style_options(TRUE);
$image_styles[RESPONSIVE_IMAGE_EMPTY_IMAGE] = $this->t('- empty image -');
- foreach ($responsive_image_mapping->getMappings() as $breakpoint_id => $mapping) {
- foreach ($mapping as $multiplier => $image_style) {
- $breakpoint = $responsive_image_mapping->getBreakpointGroup()->getBreakpointById($breakpoint_id);
- $label = $multiplier . ' ' . $breakpoint->name . ' [' . $breakpoint->mediaQuery . ']';
- $form['mappings'][$breakpoint_id][$multiplier] = array(
+ $breakpoints = $this->breakpointManager->getBreakpointsByGroup($responsive_image_mapping->getBreakpointGroup());
+ foreach ($breakpoints as $breakpoint_id => $breakpoint) {
+ foreach ($breakpoint->getMultipliers() as $multiplier) {
+ $label = $multiplier . ' ' . $breakpoint->getLabel() . ' [' . $breakpoint->getMediaQuery() . ']';
+ $form['keyed_mappings'][$breakpoint_id][$multiplier] = array(
'#type' => 'select',
- '#title' => String::checkPlain($label),
+ '#title' => $label,
'#options' => $image_styles,
- '#default_value' => $image_style,
+ '#default_value' => $responsive_image_mapping->getImageStyle($breakpoint_id, $multiplier),
'#description' => $this->t('Select an image style for this breakpoint.'),
);
}
@@ -98,21 +123,12 @@ class ResponsiveImageMappingForm extends EntityForm {
* {@inheritdoc}
*/
public function validate(array $form, FormStateInterface $form_state) {
- /** @var \Drupal\responsive_image\ResponsiveImageMappingInterface $responsive_image_mapping */
- $responsive_image_mapping = $this->entity;
-
// Only validate on edit.
- if ($form_state->hasValue('mappings')) {
- $responsive_image_mapping->setMappings($form_state->getValue('mappings'));
-
+ if ($form_state->hasValue('keyed_mappings')) {
// Check if another breakpoint group is selected.
if ($form_state->getValue('breakpointGroup') != $form_state->getCompleteForm()['breakpointGroup']['#default_value']) {
- // Remove the mappings.
- $form_state->unsetValue('mappings');
- }
- // Make sure at least one mapping is defined.
- elseif (!$responsive_image_mapping->isNew() && !$responsive_image_mapping->hasMappings()) {
- $form_state->setErrorByName('mappings', $this->t('Please select at least one mapping.'));
+ // Remove the mappings since the breakpoint ID has changed.
+ $form_state->unsetValue('keyed_mappings');
}
}
}
@@ -123,6 +139,15 @@ class ResponsiveImageMappingForm extends EntityForm {
public function save(array $form, FormStateInterface $form_state) {
/** @var \Drupal\responsive_image\ResponsiveImageMappingInterface $responsive_image_mapping */
$responsive_image_mapping = $this->entity;
+ // Remove all the existing mappings and replace with submitted values.
+ $responsive_image_mapping->removeMappings();
+ if ($form_state->hasValue('keyed_mappings')) {
+ foreach ($form_state->getValue('keyed_mappings') as $breakpoint_id => $multipliers) {
+ foreach ($multipliers as $multiplier => $image_style) {
+ $responsive_image_mapping->addMapping($breakpoint_id, $multiplier, $image_style);
+ }
+ }
+ }
$responsive_image_mapping->save();
$this->logger('responsive_image')->notice('Responsive image mapping @label saved.', array('@label' => $responsive_image_mapping->label()));
diff --git a/core/modules/responsive_image/src/ResponsiveImageMappingInterface.php b/core/modules/responsive_image/src/ResponsiveImageMappingInterface.php
index bb8b535..fd9b28b 100644
--- a/core/modules/responsive_image/src/ResponsiveImageMappingInterface.php
+++ b/core/modules/responsive_image/src/ResponsiveImageMappingInterface.php
@@ -18,47 +18,81 @@ interface ResponsiveImageMappingInterface extends ConfigEntityInterface {
* Checks if there is at least one mapping defined.
*
* return bool
- * Whether the entity has any responsive_image mappings.
+ * Whether the entity has any responsive image mappings.
*/
public function hasMappings();
/**
- * Sets the mappings for the responsive_image mapping.
+ * Returns the mappings of breakpoint ID and multiplier to image style.
*
- * The array is keyed by the Breakpoint Group Id and then then by each
- * Breakpoints multipliers within the Breakpoint Group.
- *
- * @param array[] $mappings
- * The mappings the responsive_image mapping will be set with.
- *
- * @return $this
+ * @return array[]
+ * The responsive image mappings. Keyed by breakpoint ID then multiplier.
+ * The value is the image style ID.
*/
- public function setMappings(array $mappings);
+ public function getKeyedMappings();
/**
- * Returns the mappings for the responsive_image mapping.
+ * Returns the mappings for the responsive image mapping.
*
* @return array[]
- * The responsive_imagemappings.
+ * An array responsive image mappings. Each responsive mapping array
+ * contains the following keys:
+ * - breakpoint_id
+ * - multiplier
+ * - image_style
*/
public function getMappings();
/**
* Sets the breakpoint group for the responsive_image mapping.
*
- * @param \Drupal\breakpoint\Entity\BreakpointGroup $breakpoint_group
- * The responsive_image mappings breakpoint group.
+ * @param string $breakpoint_group
+ * The responsive image mapping breakpoint group.
*
* @return $this
*/
public function setBreakpointGroup($breakpoint_group);
/**
- * Returns the breakpoint group for the responsive_image mapping.
+ * Returns the breakpoint group for the responsive image mapping.
*
- * @return \Drupal\breakpoint\Entity\BreakpointGroup
- * The responsive_image mappings breakpoint group.
+ * @return string
+ * The breakpoint group.
*/
public function getBreakpointGroup();
+ /**
+ * Gets the image style ID for a breakpoint ID and multiplier.
+ *
+ * @param string $breakpoint_id
+ * The breakpoint ID.
+ * @param string $multiplier
+ * The multiplier.
+ *
+ * @return string|null
+ * The image style ID. Null if the mapping does not exist.
+ */
+ public function getImageStyle($breakpoint_id, $multiplier);
+
+ /**
+ * Adds a mapping to the responsive image configuration entity.
+ *
+ * @param string $breakpoint_id
+ * The breakpoint ID.
+ * @param string $multiplier
+ * The multiplier.
+ * @param string $image_style
+ * The image style ID.
+ *
+ * @return $this
+ */
+ public function addMapping($breakpoint_id, $multiplier, $image_style);
+
+ /**
+ * Removes all mappings from the responsive image configuration entity.
+ *
+ * @return $this
+ */
+ public function removeMappings();
+
}
diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php
index 65d8094..7ddc0aa 100644
--- a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php
+++ b/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php
@@ -8,7 +8,6 @@
namespace Drupal\responsive_image\Tests;
use Drupal\simpletest\WebTestBase;
-use Drupal\breakpoint\Entity\Breakpoint;
/**
* Thoroughly test the administrative interface of the Responsive Image module.
@@ -18,18 +17,11 @@ use Drupal\breakpoint\Entity\Breakpoint;
class ResponsiveImageAdminUITest extends WebTestBase {
/**
- * The breakpoint group for testing.
- *
- * @var \Drupal\breakpoint\Entity\BreakpointGroupInterface
- */
- protected $breakpointGroup;
-
- /**
* Modules to enable.
*
* @var array
*/
- public static $modules = array('responsive_image');
+ public static $modules = array('responsive_image', 'responsive_image_test_module');
/**
* Drupal\simpletest\WebTestBase\setUp().
@@ -43,32 +35,6 @@ class ResponsiveImageAdminUITest extends WebTestBase {
));
$this->drupalLogin($this->admin_user);
-
- // Add breakpoint_group and breakpoints.
- $this->breakpointGroup = entity_create('breakpoint_group', array(
- 'name' => 'atestset',
- 'label' => 'A test set',
- 'sourceType' => Breakpoint::SOURCE_TYPE_USER_DEFINED,
- ));
-
- $breakpoint_names = array('small', 'medium', 'large');
- for ($i = 0; $i < 3; $i++) {
- $width = ($i + 1) * 200;
- $breakpoint = entity_create('breakpoint', array(
- 'name' => $breakpoint_names[$i],
- 'mediaQuery' => "(min-width: {$width}px)",
- 'source' => 'user',
- 'sourceType' => Breakpoint::SOURCE_TYPE_USER_DEFINED,
- 'multipliers' => array(
- '1.5x' => 0,
- '2x' => '2x',
- ),
- ));
- $breakpoint->save();
- $this->breakpointGroup->addBreakpoints(array($breakpoint));
- }
- $this->breakpointGroup->save();
-
}
/**
@@ -81,13 +47,13 @@ class ResponsiveImageAdminUITest extends WebTestBase {
// Add a new responsive image mapping, our breakpoint set should be selected.
$this->drupalGet('admin/config/media/responsive-image-mapping/add');
- $this->assertFieldByName('breakpointGroup', $this->breakpointGroup->id());
+ $this->assertFieldByName('breakpointGroup', 'responsive_image_test_module');
// Create a new group.
$edit = array(
'label' => 'Mapping One',
'id' => 'mapping_one',
- 'breakpointGroup' => $this->breakpointGroup->id(),
+ 'breakpointGroup' => 'responsive_image_test_module',
);
$this->drupalPostForm('admin/config/media/responsive-image-mapping/add', $edit, t('Save'));
@@ -101,32 +67,32 @@ class ResponsiveImageAdminUITest extends WebTestBase {
// Edit the group.
$this->drupalGet('admin/config/media/responsive-image-mapping/mapping_one');
$this->assertFieldByName('label', 'Mapping One');
- $this->assertFieldByName('breakpointGroup', $this->breakpointGroup->id());
+ $this->assertFieldByName('breakpointGroup', 'responsive_image_test_module');
- // Check if the dropdows are present for the mappings.
- $this->assertFieldByName('mappings[custom.user.small][1x]', '');
- $this->assertFieldByName('mappings[custom.user.small][2x]', '');
- $this->assertFieldByName('mappings[custom.user.medium][1x]', '');
- $this->assertFieldByName('mappings[custom.user.medium][2x]', '');
- $this->assertFieldByName('mappings[custom.user.large][1x]', '');
- $this->assertFieldByName('mappings[custom.user.large][2x]', '');
+ // Check if the dropdowns are present for the mappings.
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.mobile][1x]', '');
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.mobile][2x]', '');
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.narrow][1x]', '');
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.narrow][2x]', '');
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.wide][1x]', '');
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.wide][2x]', '');
// Save mappings for 1x variant only.
$edit = array(
'label' => 'Mapping One',
- 'breakpointGroup' => $this->breakpointGroup->id(),
- 'mappings[custom.user.small][1x]' => 'thumbnail',
- 'mappings[custom.user.medium][1x]' => 'medium',
- 'mappings[custom.user.large][1x]' => 'large',
+ 'breakpointGroup' => 'responsive_image_test_module',
+ 'keyed_mappings[responsive_image_test_module.mobile][1x]' => 'thumbnail',
+ 'keyed_mappings[responsive_image_test_module.narrow][1x]' => 'medium',
+ 'keyed_mappings[responsive_image_test_module.wide][1x]' => 'large',
);
$this->drupalPostForm('admin/config/media/responsive-image-mapping/mapping_one', $edit, t('Save'));
$this->drupalGet('admin/config/media/responsive-image-mapping/mapping_one');
- $this->assertFieldByName('mappings[custom.user.small][1x]', 'thumbnail');
- $this->assertFieldByName('mappings[custom.user.small][2x]', '');
- $this->assertFieldByName('mappings[custom.user.medium][1x]', 'medium');
- $this->assertFieldByName('mappings[custom.user.medium][2x]', '');
- $this->assertFieldByName('mappings[custom.user.large][1x]', 'large');
- $this->assertFieldByName('mappings[custom.user.large][2x]', '');
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.mobile][1x]', 'thumbnail');
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.mobile][2x]', '');
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.narrow][1x]', 'medium');
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.narrow][2x]', '');
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.wide][1x]', 'large');
+ $this->assertFieldByName('keyed_mappings[responsive_image_test_module.wide][2x]', '');
// Delete the mapping.
$this->drupalGet('admin/config/media/responsive-image-mapping/mapping_one/delete');
diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
index c534a8e..ffe6af3 100644
--- a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
+++ b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
@@ -7,7 +7,6 @@
namespace Drupal\responsive_image\Tests;
-use Drupal\breakpoint\Entity\Breakpoint;
use Drupal\image\Tests\ImageFieldTestBase;
/**
@@ -24,7 +23,7 @@ class ResponsiveImageFieldDisplayTest extends ImageFieldTestBase {
*
* @var array
*/
- public static $modules = array('field_ui', 'responsive_image');
+ public static $modules = array('field_ui', 'responsive_image', 'responsive_image_test_module');
/**
* Drupal\simpletest\WebTestBase\setUp().
@@ -47,45 +46,17 @@ class ResponsiveImageFieldDisplayTest extends ImageFieldTestBase {
'administer image styles'
));
$this->drupalLogin($this->admin_user);
-
- // Add breakpoint_group and breakpoints.
- $breakpoint_group = entity_create('breakpoint_group', array(
- 'name' => 'atestset',
- 'label' => 'A test set',
- 'sourceType' => Breakpoint::SOURCE_TYPE_USER_DEFINED,
- ));
-
- $breakpoint_names = array('small', 'medium', 'large');
- for ($i = 0; $i < 3; $i++) {
- $width = ($i + 1) * 200;
- $breakpoint = entity_create('breakpoint', array(
- 'name' => $breakpoint_names[$i],
- 'mediaQuery' => "(min-width: {$width}px)",
- '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.
$responsive_image_mapping = entity_create('responsive_image_mapping', array(
'id' => 'mapping_one',
'label' => 'Mapping One',
- 'breakpointGroup' => $breakpoint_group->id(),
+ 'breakpointGroup' => 'responsive_image_test_module',
));
- $responsive_image_mapping->save();
- $mappings = array();
- $mappings['custom.user.small']['1x'] = 'thumbnail';
- $mappings['custom.user.medium']['1x'] = 'medium';
- $mappings['custom.user.large']['1x'] = 'large';
- $responsive_image_mapping->setMappings($mappings);
- $responsive_image_mapping->save();
+ $responsive_image_mapping
+ ->addMapping('responsive_image_test_module.mobile', '1x', 'thumbnail')
+ ->addMapping('responsive_image_test_module.narrow', '1x', 'medium')
+ ->addMapping('responsive_image_test_module.wide', '1x', 'large')
+ ->save();
}
/**
@@ -130,7 +101,9 @@ class ResponsiveImageFieldDisplayTest extends ImageFieldTestBase {
$display_options = array(
'type' => 'responsive_image',
'module' => 'responsive_image',
- 'settings' => array('image_link' => 'file'),
+ 'settings' => array(
+ 'image_link' => 'file'
+ ),
);
$display = entity_get_display('node', 'article', 'default');
$display->setComponent($field_name, $display_options)
@@ -178,9 +151,9 @@ class ResponsiveImageFieldDisplayTest extends ImageFieldTestBase {
$this->assertRaw('/styles/thumbnail/');
$this->assertRaw('/styles/medium/');
$this->assertRaw('/styles/large/');
- $this->assertRaw('media="(min-width: 200px)"');
- $this->assertRaw('media="(min-width: 400px)"');
- $this->assertRaw('media="(min-width: 600px)"');
+ $this->assertRaw('media="(min-width: 0px)"');
+ $this->assertRaw('media="(min-width: 560px)"');
+ $this->assertRaw('media="(min-width: 851px)"');
$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));
diff --git a/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.breakpoints.yml b/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.breakpoints.yml
new file mode 100644
index 0000000..247ab23
--- /dev/null
+++ b/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.breakpoints.yml
@@ -0,0 +1,21 @@
+responsive_image_test_module.mobile:
+ label: mobile
+ mediaQuery: '(min-width: 0px)'
+ weight: 0
+ multipliers:
+ - 1x
+ - 2x
+responsive_image_test_module.narrow:
+ label: narrow
+ mediaQuery: '(min-width: 560px)'
+ weight: 1
+ multipliers:
+ - 1x
+ - 2x
+responsive_image_test_module.wide:
+ label: wide
+ mediaQuery: '(min-width: 851px)'
+ weight: 2
+ multipliers:
+ - 1x
+ - 2x
diff --git a/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.info.yml b/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.info.yml
new file mode 100644
index 0000000..7610145
--- /dev/null
+++ b/core/modules/responsive_image/tests/modules/responsive_image_test_module/responsive_image_test_module.info.yml
@@ -0,0 +1,6 @@
+name: 'Responsive image test theme'
+type: module
+description: 'Test theme for responsive image.'
+version: VERSION
+core: 8.x
+
diff --git a/core/modules/responsive_image/tests/src/ResponsiveImageMappingConfigEntityUnitTest.php b/core/modules/responsive_image/tests/src/ResponsiveImageMappingConfigEntityUnitTest.php
new file mode 100644
index 0000000..7f9a921
--- /dev/null
+++ b/core/modules/responsive_image/tests/src/ResponsiveImageMappingConfigEntityUnitTest.php
@@ -0,0 +1,198 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\responsive_image\Tests\ResponsiveImageMappingConfigEntityUnitTest.
+ */
+
+namespace Drupal\responsive_image\Tests;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\responsive_image\Entity\ResponsiveImageMapping;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\responsive_image\Entity\ResponsiveImageMapping
+ * @group block
+ */
+class ResponsiveImageMappingConfigEntityUnitTest extends UnitTestCase {
+
+ /**
+ * The entity type used for testing.
+ *
+ * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $entityType;
+
+ /**
+ * The entity manager used for testing.
+ *
+ * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $entityManager;
+
+ /**
+ * The breakpoint manager used for testing.
+ *
+ * @var \Drupal\breakpoint\BreakpointManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $breakpointManager;
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
+ $this->entityType->expects($this->any())
+ ->method('getProvider')
+ ->will($this->returnValue('responsive_image'));
+
+ $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
+ $this->entityManager->expects($this->any())
+ ->method('getDefinition')
+ ->with('responsive_image_mapping')
+ ->will($this->returnValue($this->entityType));
+
+ $this->breakpointManager = $this->getMock('\Drupal\breakpoint\BreakpointManagerInterface');
+
+ $container = new ContainerBuilder();
+ $container->set('entity.manager', $this->entityManager);
+ $container->set('breakpoint.manager', $this->breakpointManager);
+ \Drupal::setContainer($container);
+ }
+
+ /**
+ * @covers ::calculateDependencies
+ */
+ public function testCalculateDependencies() {
+ $entity = new ResponsiveImageMapping(array('breakpointGroup' => 'test_group'));
+ $entity->setBreakpointGroup('test_group');
+
+ $this->breakpointManager->expects($this->any())
+ ->method('getGroupProviders')
+ ->with('test_group')
+ ->willReturn(array('bartik' => 'theme', 'toolbar' => 'module'));
+
+ $dependencies = $entity->calculateDependencies();
+ $this->assertContains('toolbar', $dependencies['module']);
+ $this->assertContains('bartik', $dependencies['theme']);
+ }
+
+ /**
+ * @covers ::addMapping
+ * @covers ::hasMapping
+ */
+ public function testHasMappings() {
+ $entity = new ResponsiveImageMapping(array());
+ $this->assertFalse($entity->hasMappings());
+ $entity->addMapping('test_breakpoint', '1x', 'test_style');
+ $this->assertTrue($entity->hasMappings());
+ }
+
+ /**
+ * @covers ::addMapping
+ * @covers ::getImageStyle
+ */
+ public function testGetImageStyle() {
+ $entity = new ResponsiveImageMapping(array(''));
+ $entity->addMapping('test_breakpoint', '1x', 'test_style');
+ $this->assertEquals('test_style', $entity->getImageStyle('test_breakpoint', '1x'));
+ $this->assertNull($entity->getImageStyle('test_unknown_breakpoint', '1x'));
+ }
+
+ /**
+ * @covers ::addMapping
+ * @covers ::getMappings
+ */
+ public function testGetKeyedMappings() {
+ $entity = new ResponsiveImageMapping(array(''));
+ $entity->addMapping('test_breakpoint', '1x', 'test_style');
+ $entity->addMapping('test_breakpoint', '2x', 'test_style2');
+ $entity->addMapping('test_breakpoint2', '1x', 'test_style3');
+
+ $expected = array(
+ 'test_breakpoint' => array(
+ '1x' => 'test_style',
+ '2x' => 'test_style2',
+ ),
+ 'test_breakpoint2' => array(
+ '1x' => 'test_style3',
+ )
+ );
+ $this->assertEquals($expected, $entity->getKeyedMappings());
+
+ // Add another mapping to ensure keyed mapping static cache is rebuilt.
+ $entity->addMapping('test_breakpoint2', '2x', 'test_style4');
+ $expected['test_breakpoint2']['2x'] = 'test_style4';
+ $this->assertEquals($expected, $entity->getKeyedMappings());
+ }
+
+ /**
+ * @covers ::addMapping
+ * @covers ::getMappings
+ */
+ public function testGetMappings() {
+ $entity = new ResponsiveImageMapping(array(''));
+ $entity->addMapping('test_breakpoint', '1x', 'test_style');
+ $entity->addMapping('test_breakpoint', '2x', 'test_style2');
+ $entity->addMapping('test_breakpoint2', '1x', 'test_style3');
+
+ $expected = array(
+ array(
+ 'breakpoint_id' => 'test_breakpoint',
+ 'multiplier' => '1x',
+ 'image_style' => 'test_style',
+ ),
+ array(
+ 'breakpoint_id' => 'test_breakpoint',
+ 'multiplier' => '2x',
+ 'image_style' => 'test_style2',
+ ),
+ array(
+ 'breakpoint_id' => 'test_breakpoint2',
+ 'multiplier' => '1x',
+ 'image_style' => 'test_style3',
+ ),
+ );
+ $this->assertEquals($expected, $entity->getMappings());
+ }
+
+ /**
+ * @covers ::addMapping
+ * @covers ::removeMappings
+ */
+ public function testRemoveMappings() {
+ $entity = new ResponsiveImageMapping(array(''));
+ $entity->addMapping('test_breakpoint', '1x', 'test_style');
+ $entity->addMapping('test_breakpoint', '2x', 'test_style2');
+ $entity->addMapping('test_breakpoint2', '1x', 'test_style3');
+
+ $this->assertTrue($entity->hasMappings());
+ $entity->removeMappings();
+ $this->assertEmpty($entity->getMappings());
+ $this->assertEmpty($entity->getKeyedMappings());
+ $this->assertFalse($entity->hasMappings());
+ }
+
+ /**
+ * @covers ::setBreakpointGroup
+ * @covers ::getBreakpointGroup
+ */
+ public function testSetBreakpointGroup() {
+ $entity = new ResponsiveImageMapping(array('breakpointGroup' => 'test_group'));
+ $entity->addMapping('test_breakpoint', '1x', 'test_style');
+ $entity->addMapping('test_breakpoint', '2x', 'test_style2');
+ $entity->addMapping('test_breakpoint2', '1x', 'test_style3');
+
+ // Ensure that setting to same group does not remove mappings.
+ $entity->setBreakpointGroup('test_group');
+ $this->assertTrue($entity->hasMappings());
+ $this->assertEquals('test_group', $entity->getBreakpointGroup());
+
+ // Ensure that changing the group removes mappings.
+ $entity->setBreakpointGroup('test_group2');
+ $this->assertEquals('test_group2', $entity->getBreakpointGroup());
+ $this->assertFalse($entity->hasMappings());
+ }
+
+}
diff --git a/core/modules/responsive_image/tests/src/ResponsiveImageMappingEntityTest.php b/core/modules/responsive_image/tests/src/ResponsiveImageMappingEntityTest.php
deleted file mode 100644
index 78303f6..0000000
--- a/core/modules/responsive_image/tests/src/ResponsiveImageMappingEntityTest.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\responsive_image\Tests\ResponsiveImageMappingEntityTest.
- */
-
-namespace Drupal\responsive_image\Tests;
-
-use Drupal\responsive_image\Entity\ResponsiveImageMapping;
-use Drupal\Tests\UnitTestCase;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
-
-/**
- * @coversDefaultClass \Drupal\responsive_image\Entity\ResponsiveImageMapping
- * @group responsive_image
- */
-class ResponsiveImageMappingEntityTest extends UnitTestCase {
-
- /**
- * The entity type used for testing.
- *
- * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $entityType;
-
- /**
- * The entity manager used for testing.
- *
- * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $entityManager;
-
- /**
- * The ID of the type of the entity under test.
- *
- * @var string
- */
- protected $entityTypeId;
-
- /**
- * The UUID generator used for testing.
- *
- * @var \Drupal\Component\Uuid\UuidInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $uuid;
-
- /**
- * The ID of the breakpoint group used for testing.
- *
- * @var string
- */
- protected $breakpointGroupId;
-
- /**
- * The breakpoint group used for testing.
- *
- * @var \Drupal\breakpoint\Entity\BreakpointGroup|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $breakpointGroup;
-
- /**
- * The breakpoint group storage used for testing.
- *
- * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface|\PHPUnit_Framework_MockObject_MockObject
- */
- protected $breakpointGroupStorage;
-
- /**
- * {@inheritdoc}
- */
- protected function setUp() {
- $this->entityTypeId = $this->randomMachineName();
- $this->provider = $this->randomMachineName();
- $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
- $this->entityType->expects($this->any())
- ->method('getProvider')
- ->will($this->returnValue($this->provider));
-
- $this->entityManager = $this->getMock('\Drupal\Core\Entity\EntityManagerInterface');
- $this->entityManager->expects($this->any())
- ->method('getDefinition')
- ->with($this->entityTypeId)
- ->will($this->returnValue($this->entityType));
-
- $this->uuid = $this->getMock('\Drupal\Component\Uuid\UuidInterface');
-
- $this->breakpointGroupId = $this->randomMachineName(9);
- $this->breakpointGroup = $this->getMock('Drupal\breakpoint\Entity\BreakpointGroup', array(), array(array('name' => 'test', 'id' => $this->breakpointGroupId)));
-
- $this->breakpointGroupStorage = $this->getMock('\Drupal\Core\Config\Entity\ConfigEntityStorageInterface');
- $this->breakpointGroupStorage
- ->expects($this->any())
- ->method('load')
- ->with($this->breakpointGroupId)
- ->will($this->returnValue($this->breakpointGroup));
-
- $this->entityManager->expects($this->any())
- ->method('getStorage')
- ->will($this->returnValue($this->breakpointGroupStorage));
-
- $container = new ContainerBuilder();
- $container->set('entity.manager', $this->entityManager);
- $container->set('uuid', $this->uuid);
- \Drupal::setContainer($container);
- }
-
- /**
- * @covers ::calculateDependencies
- */
- public function testCalculateDependencies() {
- $responsive_image_mapping = new ResponsiveImageMapping(array(), $this->entityTypeId);
- // Set the breakpoint group after creating the entity to avoid the calls
- // in the constructor.
- $responsive_image_mapping->setBreakpointGroup($this->breakpointGroupId);
- $this->breakpointGroup->expects($this->once())
- ->method('getConfigDependencyName')
- ->will($this->returnValue('breakpoint.breakpoint_group.' . $this->breakpointGroupId));
-
- $dependencies = $responsive_image_mapping->calculateDependencies();
- $this->assertContains('breakpoint.breakpoint_group.' . $this->breakpointGroupId, $dependencies['entity']);
- }
-
-}
diff --git a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.narrow.yml b/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.narrow.yml
deleted file mode 100644
index 5fae446..0000000
--- a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.narrow.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: module.toolbar.narrow
-name: narrow
-label: narrow
-mediaQuery: 'only screen and (min-width: 16.5em)'
-source: toolbar
-sourceType: module
-weight: 0
-multipliers:
- 1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.standard.yml b/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.standard.yml
deleted file mode 100644
index feda076..0000000
--- a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.standard.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: module.toolbar.standard
-name: standard
-label: standard
-mediaQuery: 'only screen and (min-width: 38.125em)'
-source: toolbar
-sourceType: module
-weight: 1
-multipliers:
- 1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.wide.yml b/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.wide.yml
deleted file mode 100644
index 554b286..0000000
--- a/core/modules/toolbar/config/install/breakpoint.breakpoint.module.toolbar.wide.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: module.toolbar.wide
-name: wide
-label: wide
-mediaQuery: 'only screen and (min-width: 61em)'
-source: toolbar
-sourceType: module
-weight: 2
-multipliers:
- 1x: 1x
-status: true
-langcode: en
diff --git a/core/modules/toolbar/config/install/breakpoint.breakpoint_group.module.toolbar.toolbar.yml b/core/modules/toolbar/config/install/breakpoint.breakpoint_group.module.toolbar.toolbar.yml
deleted file mode 100644
index 148cd20..0000000
--- a/core/modules/toolbar/config/install/breakpoint.breakpoint_group.module.toolbar.toolbar.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: module.toolbar.toolbar
-name: toolbar
-label: toolbar
-breakpoint_ids:
- - module.toolbar.narrow
- - module.toolbar.standard
- - module.toolbar.wide
-source: toolbar
-sourceType: module
-status: true
-langcode: en
diff --git a/core/modules/toolbar/js/toolbar.js b/core/modules/toolbar/js/toolbar.js
index 909708d..b99e0c7 100644
--- a/core/modules/toolbar/js/toolbar.js
+++ b/core/modules/toolbar/js/toolbar.js
@@ -11,9 +11,9 @@
var options = $.extend(
{
breakpoints: {
- 'module.toolbar.narrow': '',
- 'module.toolbar.standard': '',
- 'module.toolbar.wide': ''
+ 'toolbar.narrow': '',
+ 'toolbar.standard': '',
+ 'toolbar.wide': ''
}
},
drupalSettings.toolbar,
@@ -156,7 +156,7 @@
*/
mediaQueryChangeHandler: function (model, label, mql) {
switch (label) {
- case 'module.toolbar.narrow':
+ case 'toolbar.narrow':
model.set({
'isOriented': mql.matches,
'isTrayToggleVisible': false
@@ -168,12 +168,12 @@
model.set({'orientation': 'vertical'}, {validate: true});
}
break;
- case 'module.toolbar.standard':
+ case 'toolbar.standard':
model.set({
'isFixed': mql.matches
});
break;
- case 'module.toolbar.wide':
+ case 'toolbar.wide':
model.set({
'orientation': ((mql.matches) ? 'horizontal' : 'vertical')
}, {validate: true});
diff --git a/core/modules/toolbar/toolbar.breakpoints.yml b/core/modules/toolbar/toolbar.breakpoints.yml
new file mode 100644
index 0000000..a68784a
--- /dev/null
+++ b/core/modules/toolbar/toolbar.breakpoints.yml
@@ -0,0 +1,18 @@
+toolbar.narrow:
+ label: narrow
+ mediaQuery: 'only screen and (min-width: 16.5em)'
+ weight: 0
+ multipliers:
+ - 1x
+toolbar.standard:
+ label: standard
+ mediaQuery: 'only screen and (min-width: 38.125em)'
+ weight: 1
+ multipliers:
+ - 1x
+toolbar.wide:
+ label: wide
+ mediaQuery: 'only screen and (min-width: 61em)'
+ weight: 2
+ multipliers:
+ - 1x
diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module
index 34d36c1..788378c 100644
--- a/core/modules/toolbar/toolbar.module
+++ b/core/modules/toolbar/toolbar.module
@@ -175,18 +175,19 @@ function toolbar_pre_render($element) {
// Get the configured breakpoints to switch from vertical to horizontal
// toolbar presentation.
- $breakpoints = entity_load('breakpoint_group', 'module.toolbar.toolbar');
+ $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup('toolbar');
if (!empty($breakpoints)) {
- $media_queries = array();
- $media_queries['toolbar']['breakpoints'] = array_map(
- function ($object) {
- return $object->mediaQuery;
- },
- $breakpoints->getBreakpoints()
- );
+ $media_queries = array();
+ foreach ($breakpoints as $id => $breakpoint) {
+ $media_queries[$id] = $breakpoint->getMediaQuery();
+ }
$element['#attached']['js'][] = array(
- 'data' => $media_queries,
+ 'data' => array(
+ 'toolbar' => array(
+ 'breakpoints' => $media_queries,
+ )
+ ),
'type' => 'setting',
);
}
diff --git a/core/themes/bartik/bartik.breakpoints.yml b/core/themes/bartik/bartik.breakpoints.yml
new file mode 100644
index 0000000..17b9fc8
--- /dev/null
+++ b/core/themes/bartik/bartik.breakpoints.yml
@@ -0,0 +1,18 @@
+bartik.mobile:
+ label: mobile
+ mediaQuery: '(min-width: 0px)'
+ weight: 0
+ multipliers:
+ - 1x
+bartik.narrow:
+ label: narrow
+ mediaQuery: 'all and (min-width: 560px) and (max-width: 850px)'
+ weight: 1
+ multipliers:
+ - 1x
+bartik.wide:
+ label: wide
+ mediaQuery: 'all and (min-width: 851px)'
+ weight: 2
+ multipliers:
+ - 1x
diff --git a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.mobile.yml b/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.mobile.yml
deleted file mode 100644
index 7add4c0..0000000
--- a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.mobile.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.bartik.mobile
-name: mobile
-label: mobile
-mediaQuery: '(min-width: 0px)'
-source: bartik
-sourceType: theme
-weight: 0
-multipliers:
- 1x: 1x
-status: true
-langcode: en
diff --git a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.narrow.yml b/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.narrow.yml
deleted file mode 100644
index 0736ab6..0000000
--- a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.narrow.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.bartik.narrow
-name: narrow
-label: narrow
-mediaQuery: 'all and (min-width: 560px) and (max-width: 850px)'
-source: bartik
-sourceType: theme
-weight: 1
-multipliers:
- 1x: 1x
-status: true
-langcode: en
diff --git a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.wide.yml b/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.wide.yml
deleted file mode 100644
index d43f1ae..0000000
--- a/core/themes/bartik/config/install/breakpoint.breakpoint.theme.bartik.wide.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.bartik.wide
-name: wide
-label: wide
-mediaQuery: 'all and (min-width: 851px)'
-source: bartik
-sourceType: theme
-weight: 2
-multipliers:
- 1x: 1x
-status: true
-langcode: en
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
deleted file mode 100644
index a7d85fc..0000000
--- a/core/themes/bartik/config/install/breakpoint.breakpoint_group.theme.bartik.bartik.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-id: theme.bartik.bartik
-name: bartik
-label: Bartik
-breakpoint_ids:
- - theme.bartik.mobile
- - theme.bartik.narrow
- - theme.bartik.wide
-source: bartik
-sourceType: theme
-status: true
-langcode: en
diff --git a/core/themes/seven/config/install/seven.breakpoints.yml b/core/themes/seven/config/install/seven.breakpoints.yml
deleted file mode 100644
index 9fd82d7..0000000
--- a/core/themes/seven/config/install/seven.breakpoints.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-mobile: '(min-width: 0em)'
-wide: 'screen and (min-width: 40em)'
diff --git a/core/themes/seven/seven.breakpoints.yml b/core/themes/seven/seven.breakpoints.yml
new file mode 100644
index 0000000..1b6bd2f
--- /dev/null
+++ b/core/themes/seven/seven.breakpoints.yml
@@ -0,0 +1,12 @@
+seven.mobile:
+ label: mobile
+ mediaQuery: '(min-width: 0em)'
+ weight: 0
+ multipliers:
+ - 1x
+seven.wide:
+ label: wide
+ mediaQuery: 'screen and (min-width: 40em)'
+ weight: 1
+ multipliers:
+ - 1x
diff --git a/core/themes/stark/config/install/stark.breakpoints.yml b/core/themes/stark/config/install/stark.breakpoints.yml
deleted file mode 100644
index e2eb626..0000000
--- a/core/themes/stark/config/install/stark.breakpoints.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-mobile: '(min-width: 0px)'
-narrow: 'all and (min-width: 480px) and (max-width: 959px)'
-wide: 'all and (min-width: 960px)'
diff --git a/core/themes/stark/stark.breakpoints.yml b/core/themes/stark/stark.breakpoints.yml
new file mode 100644
index 0000000..d1cdd9b
--- /dev/null
+++ b/core/themes/stark/stark.breakpoints.yml
@@ -0,0 +1,18 @@
+stark.mobile:
+ label: mobile
+ mediaQuery: '(min-width: 0px)'
+ weight: 0
+ multipliers:
+ - 1x
+stark.narrow:
+ label: narrow
+ mediaQuery: 'all and (min-width: 480px) and (max-width: 959px)'
+ weight: 1
+ multipliers:
+ - 1x
+stark.wide:
+ label: wide
+ mediaQuery: 'all and (min-width: 960px)'
+ weight: 2
+ multipliers:
+ - 1x