Commit dbb32f2e authored by alexpott's avatar alexpott

Issue #2260061 by Jelle_S, attiks, Wim Leers, mdrummond, mgifford, holist:...

Issue #2260061 by Jelle_S, attiks, Wim Leers, mdrummond, mgifford, holist: Responsive image module does not support sizes/picture polyfill 2.2
parent 45268c11
/*jshint loopfunc: true, browser: true, curly: true, eqeqeq: true, expr: true, forin: true, latedef: true, newcap: true, noarg: true, trailing: true, undef: true, unused: true */
/*! Picturefill - Author: Scott Jehl, 2012 | License: MIT/GPLv2 */
(function (w) {
// Enable strict mode.
"use strict";
// Test if `<picture>` is supported natively, if so, exit.
if (!!(w.document.createElement('picture') && w.document.createElement('source') && w.HTMLPictureElement)) {
return;
}
w.picturefill = function () {
// Copy attributes from the source to the destination.
function _copyAttributes(src, tar) {
if (src.getAttribute('width') && src.getAttribute('height')) {
tar.width = src.getAttribute('width');
tar.height = src.getAttribute('height');
}
}
// Get all picture tags.
var ps = w.document.getElementsByTagName('picture');
// Loop the pictures.
for (var i = 0, il = ps.length; i < il; i++) {
var sources = ps[i].getElementsByTagName('source');
var picImg = null;
var matches = [];
// If no sources are found, they're likely erased from the DOM.
// Try finding them inside comments.
if (!sources.length) {
var picText = ps[i].innerHTML;
var frag = w.document.createElement('div');
// For IE9, convert the source elements to divs.
var srcs = picText.replace(/(<)source([^>]+>)/gmi, '$1div$2').match(/<div[^>]+>/gmi);
frag.innerHTML = srcs.join('');
sources = frag.getElementsByTagName('div');
}
// See which sources match.
for (var j = 0, jl = sources.length; j < jl; j++) {
var media = sources[j].getAttribute('media');
// If there's no media specified or the media query matches, add it.
if (!media || (w.matchMedia && w.matchMedia(media).matches)) {
matches.push(sources[j]);
}
}
if (matches.length) {
// Grab the most appropriate (last) match.
var match = matches.pop();
var srcset = match.getAttribute('srcset');
// Find any existing img element in the picture element.
picImg = ps[i].getElementsByTagName('img')[0];
// Add a new img element if one doesn't exists.
if (!picImg) {
picImg = w.document.createElement('img');
picImg.alt = ps[i].getAttribute('alt');
ps[i].appendChild(picImg);
}
// Source element uses a srcset.
if (srcset) {
var screenRes = w.devicePixelRatio || 1;
// Split comma-separated `srcset` sources into an array.
sources = srcset.split(', ');
// Loop through each source/resolution in srcset.
for (var res = sources.length, r = res - 1; r >= 0; r--) {
// Remove any leading whitespace, then split on spaces.
var source = sources[ r ].replace(/^\s*/, '').replace(/\s*$/, '').split(' ');
// Parse out the resolution for each source in `srcset`.
var resMatch = parseFloat(source[1], 10);
if (screenRes >= resMatch) {
if (picImg.getAttribute('src') !== source[0]) {
var newImg = document.createElement('img');
newImg.src = source[0];
// When the image is loaded, set a width equal to that of the
// original’s intrinsic width divided by the screen resolution.
newImg.onload = function () {
// Clone the original image into memory so the width is
// unaffected by page styles.
var w = this.cloneNode(true).width;
if (w > 0) {
this.width = (w / resMatch);
}
};
// Copy width and height from the source tag to the img element.
_copyAttributes(match, newImg);
picImg.parentNode.replaceChild(newImg, picImg);
}
// We’ve matched, so bail out of the loop here.
break;
}
}
} else {
// No srcset used, so just use the 'src' value.
picImg.src = match.getAttribute('src');
// Copy width and height from the source tag to the img element.
_copyAttributes(match, picImg);
}
}
}
};
// Run on resize and domready (w.load as a fallback)
if (w.addEventListener) {
w.addEventListener('resize', w.picturefill, false);
w.addEventListener('DOMContentLoaded', function () {
w.picturefill();
// Run once only.
w.removeEventListener('load', w.picturefill, false);
}, false);
w.addEventListener('load', w.picturefill, false);
}
else if (w.attachEvent) {
w.attachEvent('onload', w.picturefill);
}
})(this);
/*! Picturefill - v2.2.1 - 2015-02-03
* http://scottjehl.github.io/picturefill
* Copyright (c) 2015 https://github.com/scottjehl/picturefill/blob/master/Authors.txt; Licensed MIT */
window.matchMedia||(window.matchMedia=function(){"use strict";var a=window.styleMedia||window.media;if(!a){var b=document.createElement("style"),c=document.getElementsByTagName("script")[0],d=null;b.type="text/css",b.id="matchmediajs-test",c.parentNode.insertBefore(b,c),d="getComputedStyle"in window&&window.getComputedStyle(b,null)||b.currentStyle,a={matchMedium:function(a){var c="@media "+a+"{ #matchmediajs-test { width: 1px; } }";return b.styleSheet?b.styleSheet.cssText=c:b.textContent=c,"1px"===d.width}}}return function(b){return{matches:a.matchMedium(b||"all"),media:b||"all"}}}()),function(a,b,c){"use strict";function d(a){var b,c,d,e,g,h=a||{};b=h.elements||f.getAllElements();for(var i=0,j=b.length;j>i;i++)if(c=b[i],d=c.parentNode,e=void 0,g=void 0,"IMG"===c.nodeName.toUpperCase()&&(c[f.ns]||(c[f.ns]={}),h.reevaluate||!c[f.ns].evaluated)){if("PICTURE"===d.nodeName.toUpperCase()){if(f.removeVideoShim(d),e=f.getMatch(c,d),e===!1)continue}else e=void 0;("PICTURE"===d.nodeName.toUpperCase()||c.srcset&&!f.srcsetSupported||!f.sizesSupported&&c.srcset&&c.srcset.indexOf("w")>-1)&&f.dodgeSrcset(c),e?(g=f.processSourceSet(e),f.applyBestCandidate(g,c)):(g=f.processSourceSet(c),(void 0===c.srcset||c[f.ns].srcset)&&f.applyBestCandidate(g,c)),c[f.ns].evaluated=!0}}function e(){function c(){var b;a._picturefillWorking||(a._picturefillWorking=!0,a.clearTimeout(b),b=a.setTimeout(function(){d({reevaluate:!0}),a._picturefillWorking=!1},60))}d();var e=setInterval(function(){return d(),/^loaded|^i|^c/.test(b.readyState)?void clearInterval(e):void 0},250);a.addEventListener?a.addEventListener("resize",c,!1):a.attachEvent&&a.attachEvent("onresize",c)}if(a.HTMLPictureElement)return void(a.picturefill=function(){});b.createElement("picture");var f={};f.ns="picturefill",function(){f.srcsetSupported="srcset"in c,f.sizesSupported="sizes"in c}(),f.trim=function(a){return a.trim?a.trim():a.replace(/^\s+|\s+$/g,"")},f.endsWith=function(a,b){return a.endsWith?a.endsWith(b):-1!==a.indexOf(b,a.length-b.length)},f.restrictsMixedContent=function(){return"https:"===a.location.protocol},f.matchesMedia=function(b){return a.matchMedia&&a.matchMedia(b).matches},f.getDpr=function(){return a.devicePixelRatio||1},f.getWidthFromLength=function(a){a=a&&a.indexOf("%")>-1==!1&&(parseFloat(a)>0||a.indexOf("calc(")>-1)?a:"100vw",a=a.replace("vw","%"),f.lengthEl||(f.lengthEl=b.createElement("div"),f.lengthEl.style.cssText="border:0;display:block;font-size:1em;left:0;margin:0;padding:0;position:absolute;visibility:hidden"),f.lengthEl.style.width=a,b.body.appendChild(f.lengthEl),f.lengthEl.className="helper-from-picturefill-js",f.lengthEl.offsetWidth<=0&&(f.lengthEl.style.width=b.documentElement.offsetWidth+"px");var c=f.lengthEl.offsetWidth;return b.body.removeChild(f.lengthEl),c},f.types={},f.types["image/jpeg"]=!0,f.types["image/gif"]=!0,f.types["image/png"]=!0,f.types["image/svg+xml"]=b.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1"),f.types["image/webp"]=function(){var a="image/webp";c.onerror=function(){f.types[a]=!1,d()},c.onload=function(){f.types[a]=1===c.width,d()},c.src="data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA="},f.verifyTypeSupport=function(a){var b=a.getAttribute("type");return null===b||""===b?!0:"function"==typeof f.types[b]?(f.types[b](),"pending"):f.types[b]},f.parseSize=function(a){var b=/(\([^)]+\))?\s*(.+)/g.exec(a);return{media:b&&b[1],length:b&&b[2]}},f.findWidthFromSourceSize=function(a){for(var b,c=f.trim(a).split(/\s*,\s*/),d=0,e=c.length;e>d;d++){var g=c[d],h=f.parseSize(g),i=h.length,j=h.media;if(i&&(!j||f.matchesMedia(j))){b=i;break}}return f.getWidthFromLength(b)},f.parseSrcset=function(a){for(var b=[];""!==a;){a=a.replace(/^\s+/g,"");var c,d=a.search(/\s/g),e=null;if(-1!==d){c=a.slice(0,d);var f=c.slice(-1);if((","===f||""===c)&&(c=c.replace(/,+$/,""),e=""),a=a.slice(d+1),null===e){var g=a.indexOf(",");-1!==g?(e=a.slice(0,g),a=a.slice(g+1)):(e=a,a="")}}else c=a,a="";(c||e)&&b.push({url:c,descriptor:e})}return b},f.parseDescriptor=function(a,b){var c,d=b||"100vw",e=a&&a.replace(/(^\s+|\s+$)/g,""),g=f.findWidthFromSourceSize(d);if(e)for(var h=e.split(" "),i=h.length-1;i>=0;i--){var j=h[i],k=j&&j.slice(j.length-1);if("h"!==k&&"w"!==k||f.sizesSupported){if("x"===k){var l=j&&parseFloat(j,10);c=l&&!isNaN(l)?l:1}}else c=parseFloat(parseInt(j,10)/g)}return c||1},f.getCandidatesFromSourceSet=function(a,b){for(var c=f.parseSrcset(a),d=[],e=0,g=c.length;g>e;e++){var h=c[e];d.push({url:h.url,resolution:f.parseDescriptor(h.descriptor,b)})}return d},f.dodgeSrcset=function(a){a.srcset&&(a[f.ns].srcset=a.srcset,a.removeAttribute("srcset"))},f.processSourceSet=function(a){var b=a.getAttribute("srcset"),c=a.getAttribute("sizes"),d=[];return"IMG"===a.nodeName.toUpperCase()&&a[f.ns]&&a[f.ns].srcset&&(b=a[f.ns].srcset),b&&(d=f.getCandidatesFromSourceSet(b,c)),d},f.applyBestCandidate=function(a,b){var c,d,e;a.sort(f.ascendingSort),d=a.length,e=a[d-1];for(var g=0;d>g;g++)if(c=a[g],c.resolution>=f.getDpr()){e=c;break}if(e&&!f.endsWith(b.src,e.url))if(f.restrictsMixedContent()&&"http:"===e.url.substr(0,"http:".length).toLowerCase())void 0!==typeof console&&console.warn("Blocked mixed content image "+e.url);else{b.src=e.url,b.currentSrc=b.src;var h=b.style||{},i="webkitBackfaceVisibility"in h,j=h.zoom;i&&(h.zoom=".999",i=b.offsetWidth,h.zoom=j)}},f.ascendingSort=function(a,b){return a.resolution-b.resolution},f.removeVideoShim=function(a){var b=a.getElementsByTagName("video");if(b.length){for(var c=b[0],d=c.getElementsByTagName("source");d.length;)a.insertBefore(d[0],c);c.parentNode.removeChild(c)}},f.getAllElements=function(){for(var a=[],c=b.getElementsByTagName("img"),d=0,e=c.length;e>d;d++){var g=c[d];("PICTURE"===g.parentNode.nodeName.toUpperCase()||null!==g.getAttribute("srcset")||g[f.ns]&&null!==g[f.ns].srcset)&&a.push(g)}return a},f.getMatch=function(a,b){for(var c,d=b.childNodes,e=0,g=d.length;g>e;e++){var h=d[e];if(1===h.nodeType){if(h===a)return c;if("SOURCE"===h.nodeName.toUpperCase()){null!==h.getAttribute("src")&&void 0!==typeof console&&console.warn("The `src` attribute is invalid on `picture` `source` element; instead, use `srcset`.");var i=h.getAttribute("media");if(h.getAttribute("srcset")&&(!i||f.matchesMedia(i))){var j=f.verifyTypeSupport(h);if(j===!0){c=h;break}if("pending"===j)return!1}}}}return c},e(),d._=f,"object"==typeof module&&"object"==typeof module.exports?module.exports=d:"function"==typeof define&&define.amd?define(function(){return d}):"object"==typeof a&&(a.picturefill=d)}(window,window.document,new window.Image);
......@@ -834,15 +834,13 @@ normalize:
picturefill:
remote: https://github.com/scottjehl/picturefill
# @todo Contribute upstream and/or replace with upstream version.
# @see https://drupal.org/node/1775530
version: VERSION
version: 2.2.1
license:
name: MIT
url: https://github.com/scottjehl/picturefill/blob/master/LICENSE
url: https://github.com/scottjehl/picturefill/blob/2.2/LICENSE
gpl-compatible: true
js:
assets/vendor/picturefill/picturefill.js: { weight: -10 }
assets/vendor/picturefill/picturefill.min.js: { weight: -10, minified: true }
dependencies:
- core/matchmedia
......
......@@ -33,54 +33,54 @@ protected function setUp() {
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.tv' => array(
'label' => 'tv',
'mediaQuery' => 'only screen and (min-width: 1220px)',
'weight' => 0,
'multipliers' => array(
'1x',
),
'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',
'provider' => 'breakpoint_theme_test',
'id' => 'breakpoint_theme_test.tv',
'group' => 'breakpoint_theme_test',
'class' => 'Drupal\\breakpoint\\Breakpoint',
),
'breakpoint_theme_test.wide' => array(
'label' => 'wide',
'mediaQuery' => '(min-width: 851px)',
'weight' => 1,
'multipliers' => array(
'1x',
),
'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',
'provider' => 'breakpoint_theme_test',
'id' => 'breakpoint_theme_test.wide',
'group' => 'breakpoint_theme_test',
'class' => 'Drupal\\breakpoint\\Breakpoint',
),
'breakpoint_theme_test.narrow' => array(
'label' => 'narrow',
'mediaQuery' => '(min-width: 560px)',
'weight' => 2,
'multipliers' => array(
'1x',
),
'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',
'provider' => 'breakpoint_theme_test',
'id' => 'breakpoint_theme_test.narrow',
'group' => 'breakpoint_theme_test',
'class' => 'Drupal\\breakpoint\\Breakpoint',
),
'breakpoint_theme_test.mobile' => array(
'label' => 'mobile',
'mediaQuery' => '(min-width: 0px)',
'weight' => 3,
'multipliers' => array(
'1x',
),
'provider' => 'breakpoint_theme_test',
'id' => 'breakpoint_theme_test.mobile',
'group' => 'breakpoint_theme_test',
'class' => 'Drupal\\breakpoint\\Breakpoint',
),
);
$breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup('breakpoint_theme_test');
......@@ -101,7 +101,7 @@ public function testCustomBreakpointGroups () {
'breakpoint_theme_test.group2.narrow' => array(
'label' => 'narrow',
'mediaQuery' => '(min-width: 560px)',
'weight' => 1,
'weight' => 2,
'multipliers' => array(
'1x',
'2x',
......@@ -114,7 +114,7 @@ public function testCustomBreakpointGroups () {
'breakpoint_theme_test.group2.wide' => array(
'label' => 'wide',
'mediaQuery' => '(min-width: 851px)',
'weight' => 2,
'weight' => 1,
'multipliers' => array(
'1x',
'2x',
......@@ -127,7 +127,7 @@ public function testCustomBreakpointGroups () {
'breakpoint_module_test.breakpoint_theme_test.group2.tv' => array(
'label' => 'tv',
'mediaQuery' => '(min-width: 6000px)',
'weight' => 3,
'weight' => 0,
'multipliers' => array(
'1x',
),
......@@ -152,7 +152,7 @@ public function testModuleBreakpoints() {
'breakpoint_module_test.mobile' => array(
'label' => 'mobile',
'mediaQuery' => '(min-width: 0px)',
'weight' => 0,
'weight' => 1,
'multipliers' => array(
'1x',
),
......@@ -164,7 +164,7 @@ public function testModuleBreakpoints() {
'breakpoint_module_test.standard' => array(
'label' => 'standard',
'mediaQuery' => '(min-width: 560px)',
'weight' => 1,
'weight' => 0,
'multipliers' => array(
'1x',
'2x',
......
breakpoint_module_test.mobile:
label: mobile
mediaQuery: '(min-width: 0px)'
weight: 0
weight: 1
# 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
weight: 0
# Don't include a 1x multiplier this will be enforced by default.
multipliers:
- 2x
......@@ -15,7 +15,7 @@ breakpoint_module_test.standard:
breakpoint_module_test.breakpoint_theme_test.group2.tv:
label: tv
mediaQuery: '(min-width: 6000px)'
weight: 3
weight: 0
multipliers:
- 1x
group: breakpoint_theme_test.group2
......@@ -87,9 +87,9 @@ public function testGetWeight() {
* @covers ::getMediaQuery
*/
public function testGetMediaQuery() {
$this->pluginDefinition['mediaQuery'] = 'only screen and (min-width: 3456px)';
$this->pluginDefinition['mediaQuery'] = 'only screen and (min-width: 1220px)';
$this->setupBreakpoint();
$this->assertEquals('only screen and (min-width: 3456px)', $this->breakpoint->getMediaQuery());
$this->assertEquals('only screen and (min-width: 1220px)', $this->breakpoint->getMediaQuery());
}
/**
......
breakpoint_theme_test.mobile:
label: mobile
mediaQuery: '(min-width: 0px)'
weight: 0
weight: 3
multipliers:
- 1x
breakpoint_theme_test.narrow:
label: narrow
mediaQuery: '(min-width: 560px)'
weight: 1
weight: 2
multipliers:
- 1x
# Out of order breakpoint to test sorting.
breakpoint_theme_test.tv:
label: tv
mediaQuery: 'only screen and (min-width: 3456px)'
weight: 3
mediaQuery: 'only screen and (min-width: 1220px)'
weight: 0
multipliers:
- 1x
breakpoint_theme_test.wide:
label: wide
mediaQuery: '(min-width: 851px)'
weight: 2
weight: 1
multipliers:
- 1x
breakpoint_theme_test.group2.narrow:
label: narrow
mediaQuery: '(min-width: 560px)'
weight: 1
weight: 2
multipliers:
- 1x
- 2x
......@@ -34,7 +34,7 @@ breakpoint_theme_test.group2.narrow:
breakpoint_theme_test.group2.wide:
label: wide
mediaQuery: '(min-width: 851px)'
weight: 2
weight: 1
multipliers:
- 1x
- 2x
......
......@@ -363,13 +363,13 @@ public function doResponsiveImageListTest() {
$edit['label'] = $this->randomMachineName();
$edit['id'] = strtolower($edit['label']);
$this->drupalPostForm('admin/config/media/responsive-image-mapping/add', $edit, t('Save'));
$this->assertRaw(t('Responsive image mapping %label saved.', array('%label' => $edit['label'])));
$this->drupalPostForm('admin/config/media/responsive-image-style/add', $edit, t('Save'));
$this->assertRaw(t('Responsive image style %label saved.', array('%label' => $edit['label'])));
// Get the responsive image mapping listing.
$this->drupalGet('admin/config/media/responsive-image-mapping');
// Get the responsive image style listing.
$this->drupalGet('admin/config/media/responsive-image-style');
$translate_link = 'admin/config/media/responsive-image-mapping/' . $edit['id'] . '/translate';
$translate_link = 'admin/config/media/responsive-image-style/' . $edit['id'] . '/translate';
// Test if the link to translate the style is on the page.
$this->assertLinkByHref($translate_link);
......
# Schema for the configuration files of the Responsive Image module.
responsive_image.mappings.*:
responsive_image.styles.*:
type: config_entity
label: 'Responsive image mapping'
label: 'Responsive image style'
mapping:
id:
type: string
......@@ -10,33 +10,57 @@ responsive_image.mappings.*:
label:
type: label
label: 'Label'
mappings:
image_style_mappings:
type: sequence
label: 'Mappings'
label: 'Image style mappings'
sequence:
- type: mapping
label: 'Mapping'
label: 'Image style mapping'
mapping:
# Image mapping type. Either 'sizes' (using the 'sizes' attribute)
# or 'image_style' (using a single image style to map to this
# breakpoint).
image_mapping_type:
type: string
label: 'Responsive image mapping type'
image_mapping:
type: responsive_image.image_mapping_type.[%parent.image_mapping_type]
breakpoint_id:
type: string
label: 'Breakpoint ID'
multiplier:
type: string
label: 'Multiplier'
image_style:
type: string
label: 'Image style'
breakpointGroup:
breakpoint_group:
type: string
label: 'Breakpoint group'
responsive_image.image_mapping_type.image_style:
type: string
label: 'Image style'
responsive_image.image_mapping_type.sizes:
type: mapping
mapping:
# The value for the sizes attribute as described in the spec:
# http://www.w3.org/html/wg/drafts/html/master/embedded-content.html#attr-img-sizes
sizes:
type: string
label: 'Sizes attribute'
sizes_image_styles:
type: sequence
label: 'Image styles to be used when using the ''sizes'' attribute'
sequence:
- type: string
label: 'Image style'
field.formatter.settings.responsive_image:
type: mapping
label: 'Responsive image list format settings'
mapping:
responsive_image_mapping:
responsive_image_style:
type: string
label: 'Responsive image mapping'
label: 'Responsive image style'
fallback_image_style:
type: string
label: 'Fallback image style'
......
......@@ -7,4 +7,4 @@ core: 8.x
dependencies:
- breakpoint
- image
configure: entity.responsive_image_mapping.collection
configure: entity.responsive_image_style.collection
responsive_image.mapping_page_add:
route_name: responsive_image.mapping_page_add
title: 'Add responsive image mapping'
responsive_image.style_page_add:
route_name: responsive_image.style_page_add
title: 'Add responsive image style'
appears_on:
- entity.responsive_image_mapping.collection
- entity.responsive_image_style.collection
entity.responsive_image_mapping.collection:
title: 'Responsive image mappings'
description: 'Manage responsive image mappings'
entity.responsive_image_style.collection:
title: 'Responsive image styles'
description: 'Manage responsive image styles'
weight: 10
route_name: entity.responsive_image_mapping.collection
route_name: entity.responsive_image_style.collection
parent: system.admin_config_media
entity.responsive_image_mapping.edit_form:
entity.responsive_image_style.edit_form:
title: Edit
route_name: entity.responsive_image_mapping.edit_form
base_route: entity.responsive_image_mapping.edit_form
route_name: entity.responsive_image_style.edit_form
base_route: entity.responsive_image_style.edit_form
weight: -10
entity.responsive_image_mapping.collection:
path: '/admin/config/media/responsive-image-mapping'
entity.responsive_image_style.collection:
path: '/admin/config/media/responsive-image-style'
defaults:
_entity_list: 'responsive_image_mapping'
_title: 'Responsive image mappings'
_entity_list: 'responsive_image_style'
_title: 'Responsive image styles'
requirements:
_permission: 'administer responsive images'
responsive_image.mapping_page_add:
path: '/admin/config/media/responsive-image-mapping/add'
responsive_image.style_page_add:
path: '/admin/config/media/responsive-image-style/add'
defaults:
_entity_form: 'responsive_image_mapping.add'
_title: 'Add responsive image mapping'
_entity_form: 'responsive_image_style.add'
_title: 'Add responsive image style'
requirements:
_permission: 'administer responsive images'
entity.responsive_image_mapping.edit_form:
path: '/admin/config/media/responsive-image-mapping/{responsive_image_mapping}'
entity.responsive_image_style.edit_form:
path: '/admin/config/media/responsive-image-style/{responsive_image_style}'
defaults:
_entity_form: 'responsive_image_mapping.edit'
_title: 'Edit responsive image mapping'
_entity_form: 'responsive_image_style.edit'
_title: 'Edit responsive image style'
requirements:
_permission: 'administer responsive images'
entity.responsive_image_mapping.duplicate_form:
path: '/admin/config/media/responsive-image-mapping/{responsive_image_mapping}/duplicate'
entity.responsive_image_style.duplicate_form:
path: '/admin/config/media/responsive-image-style/{responsive_image_style}/duplicate'
defaults:
_entity_form: 'responsive_image_mapping.duplicate'
_title: 'Duplicate responsive image mapping'
_entity_form: 'responsive_image_style.duplicate'
_title: 'Duplicate responsive image style'
requirements:
_permission: 'administer responsive images'
responsive_image.mapping_action_confirm:
path: '/admin/config/media/responsive-image-mapping/{responsive_image_mapping}/delete'
entity.responsive_image_style.delete_form:
path: '/admin/config/media/responsive-image-style/{responsive_image_style}/delete'
defaults:
_entity_form: 'responsive_image_mapping.delete'
_entity_form: 'responsive_image_style.delete'
_title: 'Delete'
requirements:
_permission: 'administer responsive images'
......@@ -2,44 +2,45 @@
/**
* @file
* Contains \Drupal\responsive_image\Entity\ResponsiveImageMapping.
* Contains \Drupal\responsive_image\Entity\ResponsiveImageStyle.
*/
namespace Drupal\responsive_image\Entity;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\responsive_image\ResponsiveImageMappingInterface;
use Drupal\responsive_image\ResponsiveImageStyleInterface;
/**
* Defines the responsive image mapping entity.
* Defines the responsive image style entity.
*
* @ConfigEntityType(
* id = "responsive_image_mapping",
* label = @Translation("Responsive image mapping"),
* id = "responsive_image_style",
* label = @Translation("Responsive image style"),
* handlers = {
* "list_builder" = "Drupal\responsive_image\ResponsiveImageMappingListBuilder",
* "list_builder" = "Drupal\responsive_image\ResponsiveImageStyleListBuilder",
* "form" = {
* "edit" = "Drupal\responsive_image\ResponsiveImageMappingForm",
* "add" = "Drupal\responsive_image\ResponsiveImageMappingForm",
* "edit" = "Drupal\responsive_image\ResponsiveImageStyleForm",
* "add" = "Drupal\responsive_image\ResponsiveImageStyleForm",
* "delete" = "Drupal\Core\Entity\EntityDeleteForm",
* "duplicate" = "Drupal\responsive_image\ResponsiveImageMappingForm"
* "duplicate" = "Drupal\responsive_image\ResponsiveImageStyleForm"
* }
* },
* list_path = "admin/config/media/responsive-image-mapping",
* list_path = "admin/config/media/responsive-image-style",
* admin_permission = "administer responsive images",
* config_prefix = "mappings",
* config_prefix = "styles",
* entity_keys = {
* "id" = "id",
* "label" = "label"
* },
* links = {
* "edit-form" = "/admin/config/media/responsive-image-mapping/{responsive_image_mapping}",
* "duplicate-form" = "/admin/config/media/responsive-image-mapping/{responsive_image_mapping}/duplicate",
* "collection" = "/admin/config/media/responsive-image-mapping",
* "edit-form" = "/admin/config/media/responsive-image-style/{responsive_image_style}",
* "duplicate-form" = "/admin/config/media/responsive-image-style/{responsive_image_style}/duplicate",
* "delete-form" = "/admin/config/media/responsive-image-style/{responsive_image_style}/delete",
* "collection" = "/admin/config/media/responsive-image-style",
* }
* )
*/
class ResponsiveImageMapping extends ConfigEntityBase implements ResponsiveImageMappingInterface {
class ResponsiveImageStyle extends ConfigEntityBase implements ResponsiveImageStyleInterface {
/**
* The responsive image ID (machine name).
......@@ -56,101 +57,105 @@ class ResponsiveImageMapping extends ConfigEntityBase implements ResponsiveImage
protected $label;
/**
* The responsive image mappings.
* The image style mappings.