From 7e7a4a09e7215e5ef374bc4ef3debf15c1e8a676 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Mon, 21 Aug 2023 11:25:54 +0200 Subject: [PATCH 01/12] [gitflow-maven-plugin] Update for next development version 1.13.3-2.22.6-SNAPSHOT --- bundles/core/pom.xml | 4 ++-- examples/bundles/examples-core/pom.xml | 6 +++--- examples/content-packages/examples-libs/pom.xml | 6 +++--- examples/content-packages/examples-sample-content/pom.xml | 4 ++-- examples/content-packages/examples/pom.xml | 6 +++--- examples/pom.xml | 4 ++-- parent/pom.xml | 4 ++-- pom.xml | 4 ++-- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/bundles/core/pom.xml b/bundles/core/pom.xml index b61560c..c40103d 100644 --- a/bundles/core/pom.xml +++ b/bundles/core/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT ../../parent/pom.xml io.wcm io.wcm.wcm.core.components - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT jar WCM Core Components diff --git a/examples/bundles/examples-core/pom.xml b/examples/bundles/examples-core/pom.xml index 044c290..e08eff1 100644 --- a/examples/bundles/examples-core/pom.xml +++ b/examples/bundles/examples-core/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-core - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT jar WCM Core Components Examples Core @@ -44,7 +44,7 @@ io.wcm io.wcm.wcm.core.components - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT compile diff --git a/examples/content-packages/examples-libs/pom.xml b/examples/content-packages/examples-libs/pom.xml index 72c32f9..6297664 100644 --- a/examples/content-packages/examples-libs/pom.xml +++ b/examples/content-packages/examples-libs/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-libs - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT content-package WCM Core Components Examples wcm.io Libraries @@ -42,7 +42,7 @@ io.wcm io.wcm.wcm.core.components - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT compile diff --git a/examples/content-packages/examples-sample-content/pom.xml b/examples/content-packages/examples-sample-content/pom.xml index 1ce9df1..550286e 100644 --- a/examples/content-packages/examples-sample-content/pom.xml +++ b/examples/content-packages/examples-sample-content/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-sample-content - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT content-package WCM Core Components Examples Content diff --git a/examples/content-packages/examples/pom.xml b/examples/content-packages/examples/pom.xml index 81d3a8e..ac7ec97 100644 --- a/examples/content-packages/examples/pom.xml +++ b/examples/content-packages/examples/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT content-package WCM Core Components Examples @@ -42,7 +42,7 @@ io.wcm.samples io.wcm.wcm.core.components.examples-core - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT compile diff --git a/examples/pom.xml b/examples/pom.xml index 1157cb5..486b444 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT ../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples.root - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT pom diff --git a/parent/pom.xml b/parent/pom.xml index f02ccfb..48ca58b 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -31,7 +31,7 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT pom WCM Core Components @@ -54,7 +54,7 @@ http://localhost:4503 - 2023-08-21T09:23:27Z + 2023-08-21T09:25:52Z diff --git a/pom.xml b/pom.xml index 031a5a6..8bf9170 100644 --- a/pom.xml +++ b/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT parent/pom.xml io.wcm io.wcm.wcm.core.components.root - 1.13.2-2.22.6 + 1.13.3-2.22.6-SNAPSHOT pom ${site.url}/${site.url.module.prefix}/ From 311c39a7c33fd01b7bce6f07bb7445f57e2e16bf Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Thu, 31 Aug 2023 12:28:30 +0200 Subject: [PATCH 02/12] update dependency --- examples/content-packages/examples-libs/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/content-packages/examples-libs/pom.xml b/examples/content-packages/examples-libs/pom.xml index 6297664..c6d56fe 100644 --- a/examples/content-packages/examples-libs/pom.xml +++ b/examples/content-packages/examples-libs/pom.xml @@ -188,7 +188,7 @@ io.wcm io.wcm.wcm.ui.granite - 1.9.12 + 1.9.14 From 234813281227714df94aa0e6624a72a7531f53ab Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Mon, 4 Sep 2023 15:01:12 +0200 Subject: [PATCH 03/12] Image v3 (#13) --- bundles/core/pom.xml | 4 +- .../impl/models/v2/ImageV2Impl.java | 285 ++------- .../impl/models/v3/ImageV3Impl.java | 372 ++++++++++++ .../util/ComponentFeatureImageResolver.java | 23 +- .../app-root/components/image/v2/README.md | 2 +- .../app-root/components/image/v3/README.md | 25 + .../app-root/components/image/v3/image.json | 196 +++++++ .../components/image/v3/image/image.html | 34 ++ .../impl/models/v2/ImageV2ImplTest.java | 40 +- .../impl/models/v3/ImageV3ImplTest.java | 548 ++++++++++++++++++ .../wcmio/v1/ResponsiveImageV1ImplTest.java | 1 - changes.xml | 6 + examples/bundles/examples-core/pom.xml | 6 +- .../content-packages/examples-libs/pom.xml | 6 +- .../library/core-content/image/.content.xml | 61 +- .../examples-sample-content/pom.xml | 4 +- examples/content-packages/examples/pom.xml | 6 +- examples/pom.xml | 4 +- parent/pom.xml | 26 +- pom.xml | 4 +- src/site/markdown/components.md | 3 +- 21 files changed, 1344 insertions(+), 312 deletions(-) create mode 100644 bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java create mode 100644 bundles/core/src/main/webapp/app-root/components/image/v3/README.md create mode 100644 bundles/core/src/main/webapp/app-root/components/image/v3/image.json create mode 100644 bundles/core/src/main/webapp/app-root/components/image/v3/image/image.html create mode 100644 bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3ImplTest.java diff --git a/bundles/core/pom.xml b/bundles/core/pom.xml index c40103d..ab80cde 100644 --- a/bundles/core/pom.xml +++ b/bundles/core/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT ../../parent/pom.xml io.wcm io.wcm.wcm.core.components - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT jar WCM Core Components diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2Impl.java index 4055cd2..c8f1c37 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2Impl.java @@ -19,53 +19,29 @@ */ package io.wcm.wcm.core.components.impl.models.v2; -import static com.day.cq.commons.ImageResource.PN_ALT; -import static com.day.cq.commons.jcr.JcrConstants.JCR_TITLE; - import java.util.Arrays; -import java.util.Collections; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; -import javax.annotation.PostConstruct; - import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.sling.api.SlingHttpServletRequest; -import org.apache.sling.api.resource.ValueMap; import org.apache.sling.models.annotations.Exporter; import org.apache.sling.models.annotations.Model; -import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy; -import org.apache.sling.models.annotations.injectorspecific.Self; -import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import com.adobe.cq.export.json.ComponentExporter; import com.adobe.cq.export.json.ExporterConstants; import com.adobe.cq.wcm.core.components.models.Image; import com.adobe.cq.wcm.core.components.models.ImageArea; -import com.adobe.cq.wcm.core.components.models.datalayer.ImageData; -import com.adobe.cq.wcm.core.components.models.datalayer.builder.AssetDataBuilder; -import com.adobe.cq.wcm.core.components.models.datalayer.builder.DataLayerBuilder; -import com.day.cq.wcm.api.designer.Style; -import com.fasterxml.jackson.annotation.JsonIgnore; import io.wcm.handler.link.Link; -import io.wcm.handler.link.LinkHandler; -import io.wcm.handler.media.Asset; import io.wcm.handler.media.Media; -import io.wcm.handler.media.MediaHandler; -import io.wcm.handler.media.Rendition; -import io.wcm.handler.url.UrlHandler; -import io.wcm.sling.models.annotations.AemObject; -import io.wcm.wcm.core.components.impl.models.helpers.AbstractComponentImpl; import io.wcm.wcm.core.components.impl.models.helpers.ImageAreaV1Impl; +import io.wcm.wcm.core.components.impl.models.v3.ImageV3Impl; import io.wcm.wcm.core.components.impl.servlets.ImageWidthProxyServlet; import io.wcm.wcm.core.components.impl.util.HandlerUnwrapper; import io.wcm.wcm.core.components.models.mixin.LinkMixin; -import io.wcm.wcm.core.components.models.mixin.MediaMixin; /** * wcm.io-based enhancements for {@link Image}: @@ -84,222 +60,36 @@ @Exporter( name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) -public class ImageV2Impl extends AbstractComponentImpl implements Image, MediaMixin, LinkMixin { +public class ImageV2Impl extends ImageV3Impl implements LinkMixin { /** * Resource type */ public static final String RESOURCE_TYPE = "wcm-io/wcm/core/components/image/v2/image"; - private static final String WIDTH_PLACEHOLDER = "{.width}"; - - @AemObject - private Style currentStyle; - @Self - private LinkHandler linkHandler; - @Self - private MediaHandler mediaHandler; - @Self - private UrlHandler urlHandler; - - @ValueMapValue(name = PN_ALT, injectionStrategy = InjectionStrategy.OPTIONAL) - private @Nullable String alt; - @ValueMapValue(name = JCR_TITLE, injectionStrategy = InjectionStrategy.OPTIONAL) - private @Nullable String title; - - @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL) - private @Nullable String imageCrop; - @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL) - private @Nullable String imageRotate; - - private Link link; - private Media media; - private String uuid; - private String fileReference; - private boolean displayPopupTitle; - private boolean enableLazyLoading; - private int lazyThreshold; - private boolean isDecorative; - private List areas; - - private List widths = Collections.emptyList(); - private long noScriptWidth; - private String srcPattern; - - @PostConstruct - private void activate() { - ValueMap properties = resource.getValueMap(); - // read basic properties - displayPopupTitle = properties.get(PN_DISPLAY_POPUP_TITLE, currentStyle.get(PN_DISPLAY_POPUP_TITLE, true)); - enableLazyLoading = !currentStyle.get(PN_DESIGN_LAZY_LOADING_ENABLED, true); - lazyThreshold = currentStyle.get(PN_DESIGN_LAZY_THRESHOLD, 0); - isDecorative = properties.get(PN_IS_DECORATIVE, currentStyle.get(PN_IS_DECORATIVE, false)); - boolean altFromAsset = properties.get(PN_ALT_VALUE_FROM_DAM, currentStyle.get(PN_ALT_VALUE_FROM_DAM, true)); - - // resolve media and properties from DAM asset - media = HandlerUnwrapper.get(mediaHandler, resource) + @Override + protected Media buildMedia(boolean altFromAsset, boolean imageFromPageImage) { + return HandlerUnwrapper.get(mediaHandler, resource) // disable dynamic media support as it is not compatible with the "src-pattern" concept .dynamicMediaDisabled(true) .decorative(isDecorative) .forceAltValueFromAsset(altFromAsset) .build(); - if (media.isValid() && !media.getRendition().isImage()) { - // no image asset selected (cannot be rendered) - set to invalid - media = mediaHandler.invalid(); - } - if (media.isValid()) { - initPropertiesFromDamAsset(properties); - widths = buildRenditionWidths(media.getRendition()); - noScriptWidth = getNoScriptWidth(); - srcPattern = buildSrcPattern(media.getUrl()); - areas = ImageAreaV1Impl.convertMap(media.getMap()); - } - - // resolve link - decorative images have no link and no alt text by definition - if (isDecorative) { - link = linkHandler.invalid(); - } - else { - link = HandlerUnwrapper.get(linkHandler, resource).build(); - } - } - - /** - * Checks if the resolved media is a DAM asset, and initializes properties from it. - * @param properties Resource properties - */ - private void initPropertiesFromDamAsset(ValueMap properties) { - Asset asset = media.getAsset(); - if (asset != null) { - com.day.cq.dam.api.Asset damAsset = asset.adaptTo(com.day.cq.dam.api.Asset.class); - if (damAsset != null) { - boolean titleFromAsset = properties.get(PN_TITLE_VALUE_FROM_DAM, currentStyle.get(PN_TITLE_VALUE_FROM_DAM, true)); - boolean uuidDisabled = currentStyle.get(PN_UUID_DISABLED, false); - - fileReference = damAsset.getPath(); - alt = asset.getAltText(); - - if (!uuidDisabled) { - uuid = damAsset.getID(); - } - - if (titleFromAsset) { - String assetTitle = asset.getTitle(); - if (StringUtils.isNotEmpty(assetTitle)) { - title = assetTitle; - } - } - } - } - } - - @Override - @NotNull - public Link getLinkObject() { - return link; - } - - @Override - @NotNull - public Media getMediaObject() { - return media; - } - - @Override - public String getSrc() { - if (noScriptWidth > 0) { - return StringUtils.replace(srcPattern, WIDTH_PLACEHOLDER, "." + noScriptWidth); - } - else { - return media.getUrl(); - } - } - - @Override - public String getAlt() { - return alt; - } - - @Override - public String getTitle() { - return title; - } - - @Override - public String getUuid() { - return uuid; - } - - /** - * @deprecated Deprecated in API - */ - @Override - @Deprecated - public String getLink() { - return link.getUrl(); - } - - @Override - public boolean displayPopupTitle() { - return displayPopupTitle; } @Override - public String getFileReference() { - return fileReference; - } - - @Override - public boolean isLazyEnabled() { - return enableLazyLoading; - } - - @Override - public int getLazyThreshold() { - return lazyThreshold; - } - - @Override - public String getSrcUriTemplate() { - return srcPattern; - } - - @Override - public int @NotNull [] getWidths() { - return widths.stream() - .mapToInt(Long::intValue) - .toArray(); - } - - @Override - public List getAreas() { - return areas; - } - - @Override - public boolean isDecorative() { - return isDecorative; + protected List buildAreas() { + return ImageAreaV1Impl.convertMap(media.getMap()); } - /** - * @deprecated Deprecated in API - */ - @Override - @Deprecated - public String getJson() { - // not required for image v2 - return null; - } - - /** * Validates the configured list of widths, removes those that are bigger than the original rendition, * and returns them sorted by size. - * @param rendition Primary rendition * @return Widths */ - private List buildRenditionWidths(Rendition rendition) { - long maxWidth = rendition.getWidth(); + @Override + protected List buildRenditionWidths() { + long maxWidth = media.getRendition().getWidth(); String[] configuredWidths = currentStyle.get(PN_DESIGN_ALLOWED_RENDITION_WIDTHS, new String[0]); return Arrays.stream(configuredWidths) .map(NumberUtils::toLong) @@ -308,23 +98,13 @@ private List buildRenditionWidths(Rendition rendition) { .collect(Collectors.toList()); } - /** - * Picks a "medium" widths from the set of available widths. - * @return Picked width - */ - private long getNoScriptWidth() { - if (widths.isEmpty()) { - return 0; - } - return widths.get((int)Math.round(widths.size() / 2d - 0.5d)); - } - /** * Build image url pattern based in ImageWidthServlet for dynamic rendition selection. - * @param mediaUrl Media Url * @return Url pattern */ - private String buildSrcPattern(String mediaUrl) { + @Override + protected String buildSrcPattern() { + String mediaUrl = media.getUrl(); String extension = StringUtils.substringAfterLast(mediaUrl, "."); String fileName = StringUtils.substringAfterLast(mediaUrl, "/"); @@ -349,23 +129,32 @@ private String buildSrcPattern(String mediaUrl) { "." + ImageWidthProxyServlet.SELECTOR + WIDTH_PLACEHOLDER + "."); } - // --- data layer --- + @Override + @NotNull + public Link getLinkObject() { + return link.getLinkObject(); + } @Override - @JsonIgnore - @SuppressWarnings("null") - public @NotNull ImageData getComponentData() { - return DataLayerBuilder.extending(super.getComponentData()).asImageComponent() - .withTitle(this::getTitle) - .withLinkUrl(this::getLink) - .withAssetData(() -> Optional.of(media) - .filter(Media::isValid) - .map(Media::getAsset) - .map(asset -> asset.adaptTo(com.day.cq.dam.api.Asset.class)) - .map(DataLayerBuilder::forAsset) - .map(AssetDataBuilder::build) - .orElse(null)) - .build(); + public String getSrc() { + long noScriptWidth = getNoScriptWidth(); + if (noScriptWidth > 0) { + return StringUtils.replace(srcPattern, WIDTH_PLACEHOLDER, "." + noScriptWidth); + } + else { + return media.getUrl(); + } + } + + /** + * Picks a "medium" widths from the set of available widths. + * @return Picked width + */ + private long getNoScriptWidth() { + if (widths.isEmpty()) { + return 0; + } + return widths.get((int)Math.round(widths.size() / 2d - 0.5d)); } } diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java new file mode 100644 index 0000000..b9069af --- /dev/null +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java @@ -0,0 +1,372 @@ +/* + * #%L + * wcm.io + * %% + * Copyright (C) 2023 wcm.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package io.wcm.wcm.core.components.impl.models.v3; + +import static com.day.cq.commons.ImageResource.PN_ALT; +import static com.day.cq.commons.jcr.JcrConstants.JCR_TITLE; +import static io.wcm.handler.media.MediaNameConstants.PROP_CSS_CLASS; +import static io.wcm.handler.media.MediaNameConstants.URI_TEMPLATE_PLACEHOLDER_WIDTH; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.StringUtils; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.ValueMap; +import org.apache.sling.models.annotations.Exporter; +import org.apache.sling.models.annotations.Model; +import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy; +import org.apache.sling.models.annotations.injectorspecific.Self; +import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.adobe.cq.export.json.ComponentExporter; +import com.adobe.cq.export.json.ExporterConstants; +import com.adobe.cq.wcm.core.components.models.Image; +import com.adobe.cq.wcm.core.components.models.ImageArea; +import com.adobe.cq.wcm.core.components.models.datalayer.ImageData; +import com.adobe.cq.wcm.core.components.models.datalayer.builder.AssetDataBuilder; +import com.adobe.cq.wcm.core.components.models.datalayer.builder.DataLayerBuilder; +import com.day.cq.wcm.api.designer.Style; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import io.wcm.handler.link.LinkHandler; +import io.wcm.handler.media.Asset; +import io.wcm.handler.media.Media; +import io.wcm.handler.media.MediaHandler; +import io.wcm.handler.media.Rendition; +import io.wcm.handler.media.UriTemplate; +import io.wcm.handler.media.UriTemplateType; +import io.wcm.handler.media.format.Ratio; +import io.wcm.handler.url.UrlHandler; +import io.wcm.sling.models.annotations.AemObject; +import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.impl.models.helpers.AbstractComponentImpl; +import io.wcm.wcm.core.components.impl.models.helpers.ImageAreaV2Impl; +import io.wcm.wcm.core.components.impl.util.ComponentFeatureImageResolver; +import io.wcm.wcm.core.components.impl.util.HandlerUnwrapper; +import io.wcm.wcm.core.components.models.mixin.MediaMixin; + +/** + * wcm.io-based enhancements for {@link Image}: + *
    + *
  • Build image using Media handler
  • + *
  • Build link using Link handler
  • + *
+ */ +@Model(adaptables = SlingHttpServletRequest.class, + adapters = { Image.class, ComponentExporter.class }, + resourceType = ImageV3Impl.RESOURCE_TYPE) +@Exporter( + name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, + extensions = ExporterConstants.SLING_MODEL_EXTENSION) +public class ImageV3Impl extends AbstractComponentImpl implements Image, MediaMixin { + + /** + * Resource type + */ + static final String RESOURCE_TYPE = "wcm-io/wcm/core/components/image/v3/image"; + + /** + * Width placeholder for URI template + */ + public static final String WIDTH_PLACEHOLDER = "{.width}"; + + @AemObject + protected Style currentStyle; + @Self + protected LinkHandler linkHandler; + @Self + protected MediaHandler mediaHandler; + @Self + protected UrlHandler urlHandler; + + @ValueMapValue(name = PN_ALT, injectionStrategy = InjectionStrategy.OPTIONAL) + protected @Nullable String alt; + @ValueMapValue(name = JCR_TITLE, injectionStrategy = InjectionStrategy.OPTIONAL) + protected @Nullable String title; + + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL) + protected @Nullable String imageCrop; + @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL) + protected @Nullable String imageRotate; + + protected LinkWrapper link; + protected Media media; + protected String uuid; + protected String fileReference; + protected boolean displayPopupTitle; + protected boolean enableLazyLoading; + protected int lazyThreshold; + protected boolean isDecorative; + protected List areas; + + protected List widths = Collections.emptyList(); + protected String srcPattern; + + @PostConstruct + private void activate() { + ValueMap properties = resource.getValueMap(); + + // read basic properties + displayPopupTitle = properties.get(PN_DISPLAY_POPUP_TITLE, currentStyle.get(PN_DISPLAY_POPUP_TITLE, true)); + enableLazyLoading = !currentStyle.get(PN_DESIGN_LAZY_LOADING_ENABLED, true); + lazyThreshold = currentStyle.get(PN_DESIGN_LAZY_THRESHOLD, 0); + isDecorative = properties.get(PN_IS_DECORATIVE, currentStyle.get(PN_IS_DECORATIVE, false)); + boolean altFromAsset = properties.get(PN_ALT_VALUE_FROM_DAM, currentStyle.get(PN_ALT_VALUE_FROM_DAM, true)); + boolean imageFromPageImage = properties.get(PN_IMAGE_FROM_PAGE_IMAGE, true); + + // resolve link - decorative images have no link and no alt text by definition + if (isDecorative) { + link = new LinkWrapper(linkHandler.invalid()); + } + else { + link = new LinkWrapper(HandlerUnwrapper.get(linkHandler, resource).build()); + } + + // resolve media and properties from DAM asset + media = buildMedia(altFromAsset, imageFromPageImage); + + if (media.isValid() && !media.getRendition().isImage()) { + // no image asset selected (cannot be rendered) - set to invalid + media = mediaHandler.invalid(); + } + if (media.isValid()) { + initPropertiesFromDamAsset(properties); + widths = buildRenditionWidths(); + srcPattern = buildSrcPattern(); + areas = buildAreas(); + } + + } + + protected Media buildMedia(boolean altFromAsset, boolean imageFromPageImage) { + ComponentFeatureImageResolver imageResolver = new ComponentFeatureImageResolver(resource, getCurrentPage(), currentStyle, mediaHandler) + .targetPage(getCurrentPage()) + .altValueFromDam(altFromAsset) + .imageFromPageImage(imageFromPageImage) + .mediaHandlerProperty(PROP_CSS_CLASS, "cmp-image__image") + .mediaHandlerProperty("itemprop", "contentUrl"); + String imageTitle = title; + if (displayPopupTitle && imageTitle != null) { + imageResolver.mediaHandlerProperty("title", imageTitle); + } + return imageResolver.buildMedia(); + } + + protected List buildAreas() { + return ImageAreaV2Impl.convertMap(media.getMap()); + } + + /** + * Checks if the resolved media is a DAM asset, and initializes properties from it. + * @param properties Resource properties + */ + private void initPropertiesFromDamAsset(ValueMap properties) { + Asset asset = media.getAsset(); + if (asset != null) { + com.day.cq.dam.api.Asset damAsset = asset.adaptTo(com.day.cq.dam.api.Asset.class); + if (damAsset != null) { + boolean titleFromAsset = properties.get(PN_TITLE_VALUE_FROM_DAM, currentStyle.get(PN_TITLE_VALUE_FROM_DAM, true)); + boolean uuidDisabled = currentStyle.get(PN_UUID_DISABLED, false); + + fileReference = damAsset.getPath(); + alt = asset.getAltText(); + + if (!uuidDisabled) { + uuid = damAsset.getID(); + } + + if (titleFromAsset) { + String assetTitle = asset.getTitle(); + if (StringUtils.isNotEmpty(assetTitle)) { + title = assetTitle; + } + } + } + } + } + + /** + * Build lists of rendition widths based on the resolved media renditions + * (those that share the same ratio as the primary rendition) + * @return Widths + */ + protected List buildRenditionWidths() { + double primaryRatio = media.getRendition().getRatio(); + return media.getRenditions().stream() + .filter(rendition -> Ratio.matches(rendition.getRatio(), primaryRatio)) + .map(Rendition::getWidth) + .distinct() + .sorted() + .collect(Collectors.toList()); + } + + /** + * Build image url pattern via Media Handler URI template. + * @return Url pattern + */ + protected String buildSrcPattern() { + Rendition rendition = media.getRendition(); + if (!rendition.isImage() || rendition.isVectorImage()) { + return null; + } + UriTemplate uriTempalte = rendition.getUriTemplate(UriTemplateType.SCALE_WIDTH); + return StringUtils.replace(uriTempalte.getUriTemplate(), URI_TEMPLATE_PLACEHOLDER_WIDTH, WIDTH_PLACEHOLDER); + } + + @Override + @NotNull + public Media getMediaObject() { + return media; + } + + @Override + public String getSrc() { + return media.getUrl(); + } + + @Override + public String getAlt() { + return alt; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public String getUuid() { + return uuid; + } + + @Override + public com.adobe.cq.wcm.core.components.commons.link.Link getImageLink() { + return link.orNull(); + } + + /** + * @deprecated Deprecated in API + */ + @Override + @Deprecated(forRemoval = true) + public String getLink() { + return link.getURL(); + } + + @Override + public boolean displayPopupTitle() { + return displayPopupTitle; + } + + @Override + public String getFileReference() { + return fileReference; + } + + @Override + public boolean isLazyEnabled() { + return enableLazyLoading; + } + + @Override + public int getLazyThreshold() { + return lazyThreshold; + } + + @Override + public String getSrcUriTemplate() { + return srcPattern; + } + + @Override + public int @NotNull [] getWidths() { + return widths.stream() + .mapToInt(Long::intValue) + .toArray(); + } + + @Override + public List getAreas() { + return areas; + } + + @Override + public boolean isDecorative() { + return isDecorative; + } + + @Override + public String getWidth() { + return null; + } + + @Override + public String getHeight() { + return null; + } + + @Override + public @Nullable String getSizes() { + return null; + } + + @Override + public String getSrcset() { + return null; + } + + @Override + public String getSmartCropRendition() { + return null; + } + + @Override + public boolean isDmImage() { + return false; + } + + + // --- data layer --- + + @Override + @JsonIgnore + @SuppressWarnings("null") + public @NotNull ImageData getComponentData() { + return DataLayerBuilder.extending(super.getComponentData()).asImageComponent() + .withTitle(this::getTitle) + .withLinkUrl(() -> this.link.getLinkObject().getUrl()) + .withAssetData(() -> Optional.of(media) + .filter(Media::isValid) + .map(Media::getAsset) + .map(asset -> asset.adaptTo(com.day.cq.dam.api.Asset.class)) + .map(DataLayerBuilder::forAsset) + .map(AssetDataBuilder::build) + .orElse(null)) + .build(); + } + +} diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/util/ComponentFeatureImageResolver.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/util/ComponentFeatureImageResolver.java index 477a170..9ed91ce 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/util/ComponentFeatureImageResolver.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/util/ComponentFeatureImageResolver.java @@ -55,9 +55,9 @@ public class ComponentFeatureImageResolver { private final MediaHandler mediaHandler; private final Map mediaHandlerProperties = new HashMap<>(); - private final boolean imageFromPageImage; + private boolean imageFromPageImage; private final boolean altValueFromPageImage; - private final boolean altValueFromDam; + private boolean altValueFromDam; private final boolean isDecorative; private final String componentAltText; @@ -105,6 +105,24 @@ public ComponentFeatureImageResolver mediaHandlerProperty(@NotNull String key, @ return this; } + /** + * @param value Image from page image + * @return self + */ + public ComponentFeatureImageResolver imageFromPageImage(boolean value) { + this.imageFromPageImage = value; + return this; + } + + /** + * @param value Alt Value from DAM + * @return self + */ + public ComponentFeatureImageResolver altValueFromDam(boolean value) { + this.altValueFromDam = value; + return this; + } + /** * Build media after resolving feature images and alt. texts. * @return Media @@ -167,6 +185,7 @@ else if (!(altValueFromPageImage || altValueFromDam)) { // otherwise rely to default media handler behavior builder.altText(componentAltText); } + builder.forceAltValueFromAsset(altValueFromDam); // apply custom media handling properties mediaHandlerProperties.entrySet().forEach(entry -> builder.property(entry.getKey(), entry.getValue())); diff --git a/bundles/core/src/main/webapp/app-root/components/image/v2/README.md b/bundles/core/src/main/webapp/app-root/components/image/v2/README.md index 20e7b61..fe28556 100644 --- a/bundles/core/src/main/webapp/app-root/components/image/v2/README.md +++ b/bundles/core/src/main/webapp/app-root/components/image/v2/README.md @@ -1,4 +1,4 @@ -Image (v2) - deprecated +Image (v2) ==== Image component written in HTL that renders an adaptive image. diff --git a/bundles/core/src/main/webapp/app-root/components/image/v3/README.md b/bundles/core/src/main/webapp/app-root/components/image/v3/README.md new file mode 100644 index 0000000..dbc64c0 --- /dev/null +++ b/bundles/core/src/main/webapp/app-root/components/image/v3/README.md @@ -0,0 +1,25 @@ +Image (v3) +==== +Image component written in HTL that renders an adaptive image. + +Extends the [Image AEM Sites Core Component][extends-component] + +## Resource Type +``` +wcm-io/wcm/core/components/image/v3/image +``` + +## Enhanced Features + +* Inherits all features from its [super component][extends-component] +* Uses [wcm.io Media Handler][wcmio-handler-media] for processing the image +* Allows to select media format(s) and auto-cropping in the content policy +* Automatically customizes the in-place image editor cropping ratios to the selected/the applications media formats +* Uses the enhanced Media Handler File Upload dialog widget with path field and media format validation +* Uses [wcm.io Link Handler][wcmio-handler-link] for processing the image link +* Uses the Link Handler dialog widget for defining link type and link target + + +[extends-component]: https://github.com/adobe/aem-core-wcm-components/tree/master/content/src/content/jcr_root/apps/core/wcm/components/image/v3/image +[wcmio-handler-media]: https://wcm.io/handler/media/ +[wcmio-handler-link]: https://wcm.io/handler/link/ diff --git a/bundles/core/src/main/webapp/app-root/components/image/v3/image.json b/bundles/core/src/main/webapp/app-root/components/image/v3/image.json new file mode 100644 index 0000000..174824b --- /dev/null +++ b/bundles/core/src/main/webapp/app-root/components/image/v3/image.json @@ -0,0 +1,196 @@ +{ + "jcr:primaryType": "cq:Component", + "jcr:title": "wcm.io Image (v3)", + "componentGroup": ".wcmio-core-wcm", + "sling:resourceSuperType": "core/wcm/components/image/v3/image", + + /* Fallback mode for Link Handler to support existing content that used a single property name */ + "wcmio:linkTargetUrlFallbackProperty": "linkURL", + + "cq:editConfig": { + "jcr:primaryType": "cq:EditConfig", + "cq:inherit": true, + /* + * Overwrite inplace edit config to: + * - Disable cropping on inline toolbar as it does not support predefined ratios + * - Remove default ratios as they are fetched from assigned media formats + * - Remove image/webp support + */ + "cq:inplaceEditing": { + "jcr:primaryType": "cq:InplaceEditingConfig", + "editorType": "image", + "active": true, + "configPath": "inplaceEditingConfig", + "inplaceEditingConfig": { + "jcr:primaryType": "nt:unstructured", + "plugins": { + "crop": { + "features": "*", + "supportedMimeTypes": ["image/jpeg", "image/png", "image/tiff"] + }, + "flip": { + "features": "-", + "supportedMimeTypes": ["image/jpeg", "image/png", "image/tiff"] + }, + "map": { + "features": "*", + "supportedMimeTypes": ["image/jpeg", "image/png", "image/tiff", "image/svg+xml"] + }, + "rotate": { + "features": "*", + "supportedMimeTypes": ["image/jpeg", "image/png", "image/tiff"] + }, + "zoom": { + "features": "*", + "supportedMimeTypes": ["image/jpeg", "image/png", "image/tiff", "image/svg+xml"] + } + }, + "ui": { + "inline": { + "toolbar": ["rotate#right", "history#undo", "history#redo", "fullscreen#fullscreen", "control#close", "control#finish"], + "replacementToolbars": { + "crop": ["crop#identifier", "crop#unlaunch", "crop#confirm"] + } + }, + "fullscreen": { + "toolbar": { + "left": ["crop#launchwithratio", "rotate#right", "map#launch", "flip#horizontal", "flip#vertical", "zoom#reset100", "zoom#popupslider"], + "right": ["history#undo", "history#redo", "fullscreen#fullscreenexit"] + }, + "replacementToolbars": { + "crop": { + "left": ["crop#identifier"], + "right": ["crop#unlaunch", "crop#confirm"] + }, + "map": { + "left": ["map#rectangle", "map#circle", "map#polygon"], + "right": ["map#unlaunch", "map#confirm"] + } + } + } + } + } + } + }, + + "cq:dialog": { + "jcr:primaryType": "nt:unstructured", + "extraClientlibs": ["io.wcm.wcm.core.components.image.v2.editor"], + "content": { + "items": { + "tabs": { + "items": { + + "asset": { + "items": { + "columns": { + "items": { + "column": { + "items": { + + /* Does not work with media handler */ + "pageImageThumbnail": { + "sling:hideResource": true + }, + + /* Use wcm.io Media Handler FileUpload */ + "file": { + "sling:resourceType": "wcm-io/handler/media/components/granite/form/fileupload", + "allowUpload": "${not empty cqDesign.allowUpload ? cqDesign.allowUpload : true}" + }, + + /* Supported differently with media handler */ + "dynamicmediaGroup": { + "sling:hideResource": true + } + + } + } + } + } + } + }, + + "metadata": { + "items": { + "columns": { + "items": { + "column": { + "items": { + "link": { + /* hide link pagefield and replace it with wcm.io Link dialog */ + "sling:hideResource": true + } + } + } + } + } + } + }, + + /* wcm.io Link Handler Tab */ + "link": { + "sling:resourceType": "granite/ui/components/coral/foundation/include", + "path": "wcm-io/handler/link/components/global/include/linkRefNoTitleTab" + } + + } + } + } + } + }, + + "cq:design_dialog": { + "jcr:primaryType": "nt:unstructured", + "content": { + "items": { + "tabs": { + "items": { + + "properties": { + "items": { + "content": { + "items": { + + "enableDmFeatures": { + /* Dynamic Media gets active automatically with media handler */ + "sling:hideResource": true + }, + + /* Supported differently with media handler */ + "enableAssetDelivery": { + "sling:hideResource": true + }, + "resizeWidth": { + "sling:hideResource": true + }, + "heading": { + "sling:hideResource": true + }, + "responsiveGroup": { + "sling:hideResource": true + }, + + /* Media format definition */ + "mediaFormatSelection": { + "sling:resourceType": "granite/ui/components/coral/foundation/include", + "path": "wcm-io/handler/media/components/global/include/mediaFormatSelection", + "sling:orderBefore": "enableLazyLoading" + }, + + "jpegQuality": { + /* JPEG quality is configured via media handler configuration */ + "sling:hideResource": true + } + } + } + } + } + + } + } + } + } + } + +} diff --git a/bundles/core/src/main/webapp/app-root/components/image/v3/image/image.html b/bundles/core/src/main/webapp/app-root/components/image/v3/image/image.html new file mode 100644 index 0000000..5fc8d75 --- /dev/null +++ b/bundles/core/src/main/webapp/app-root/components/image/v3/image/image.html @@ -0,0 +1,34 @@ + + + diff --git a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2ImplTest.java b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2ImplTest.java index f38570d..f28b49e 100644 --- a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2ImplTest.java +++ b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2ImplTest.java @@ -102,7 +102,7 @@ void setUp() { @Test @SuppressWarnings("deprecation") void testNoImage() { - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE)); Image underTest = AdaptTo.notNull(context.request(), Image.class); @@ -132,7 +132,7 @@ void testNoImage() { @Test void testInvalidAssetReference() { - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, "/content/dam/invalid")); @@ -145,7 +145,7 @@ void testInvalidAssetReference() { @Test @SuppressWarnings("deprecation") void testWithAssetImage() { - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath(), JCR_TITLE, "Resource Title", @@ -174,7 +174,7 @@ void testWithAssetImage() { @Test @SuppressWarnings("deprecation") void testWithUploadedImage() { - Resource imageResource = context.create().resource(page.getContentResource().getPath() + "/image", + Resource imageResource = context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, NN_MEDIA_INLINE_STANDARD + "Name", "file1.png"); context.load().binaryFile("/files/test.png", imageResource.getPath() + "/" + NN_MEDIA_INLINE_STANDARD, ContentType.PNG); @@ -201,11 +201,11 @@ void testWithUploadedImage() { } @Test - @SuppressWarnings({ "null", "deprecation" }) + @SuppressWarnings("deprecation") void testWithImageAndLink() { enableDataLayer(context, true); - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath(), PN_LINK_TITLE, ExternalLinkType.ID, @@ -233,7 +233,7 @@ void testWithImageAndLink() { @Test @SuppressWarnings("deprecation") void testWithImageAndLink_Decorative() { - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath(), PN_LINK_TITLE, ExternalLinkType.ID, @@ -257,7 +257,7 @@ void testWithImageAndLink_Decorative_ContentPolicy() { PN_IS_DECORATIVE, true, PN_DESIGN_LAZY_THRESHOLD, 10); - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath(), PN_LINK_TITLE, ExternalLinkType.ID, @@ -275,7 +275,7 @@ void testWithImageAndLink_Decorative_ContentPolicy() { @Test void testWithImage_TitleAltNotFormAsset() { - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath(), JCR_TITLE, "Resource Title", @@ -295,7 +295,7 @@ void testWithImage_TitleAltNotFormAsset_ContentPolicy() { PN_TITLE_VALUE_FROM_DAM, false, PN_ALT_VALUE_FROM_DAM, false); - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath(), JCR_TITLE, "Resource Title", @@ -311,7 +311,7 @@ void testWithImage_TitleAltNotFormAsset_ContentPolicy() { void testWithNoImageAsset() { Asset pdfAsset = context.create().asset(DAM_ROOT + "/file1.pdf", "/files/test.pdf", ContentType.PDF); - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, pdfAsset.getPath())); @@ -322,7 +322,7 @@ void testWithNoImageAsset() { @Test void testDisplayPopupTitle() { - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath(), PN_DISPLAY_POPUP_TITLE, false)); @@ -337,7 +337,7 @@ void testDisplayPopupTitle_ContentPolicy() { context.contentPolicyMapping(RESOURCE_TYPE, PN_DISPLAY_POPUP_TITLE, false); - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath())); @@ -351,7 +351,7 @@ void testLazyEnabled_ContentPolicy() { context.contentPolicyMapping(RESOURCE_TYPE, PN_DESIGN_LAZY_LOADING_ENABLED, false); // property is internally named "disabled", value is inverted - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath())); @@ -366,7 +366,7 @@ void testUUID() { ModifiableValueMap props = AdaptTo.notNull(resource, ModifiableValueMap.class); props.put(JCR_UUID, "test-uuid"); - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath())); @@ -384,7 +384,7 @@ void testUUID_Disabled() { ModifiableValueMap props = AdaptTo.notNull(resource, ModifiableValueMap.class); props.put(JCR_UUID, "test-uuid"); - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath())); @@ -398,7 +398,7 @@ void testWidths() { context.contentPolicyMapping(RESOURCE_TYPE, PN_DESIGN_ALLOWED_RENDITION_WIDTHS, new String[] { "100", "50", "200", "-123", "0", "junk" }); - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath())); @@ -414,7 +414,7 @@ void testWidths() { @Test void testAreas() { - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath(), PN_MAP, ImageAreaTestData.MAP_STRING)); @@ -430,7 +430,7 @@ void testWithImageAutoCropping_ContentPolicy() { PN_COMPONENT_MEDIA_FORMATS, new String[] { MediaFormats.SQUARE.getName() }, PN_COMPONENT_MEDIA_AUTOCROP, true); - context.currentResource(context.create().resource(page.getContentResource().getPath() + "/image", + context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath())); @@ -451,7 +451,7 @@ void testWithImageAutoCropping_ContentPolicy_WrappedResource() { PN_COMPONENT_MEDIA_FORMATS, new String[] { MediaFormats.SQUARE.getName() }, PN_COMPONENT_MEDIA_AUTOCROP, true); - Resource resource = context.create().resource(page.getContentResource().getPath() + "/image", + Resource resource = context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, DELEGATE_RESOURCE_TYPE, PN_MEDIA_REF_STANDARD, asset.getPath()); diff --git a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3ImplTest.java b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3ImplTest.java new file mode 100644 index 0000000..57522a9 --- /dev/null +++ b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3ImplTest.java @@ -0,0 +1,548 @@ +/* + * #%L + * wcm.io + * %% + * Copyright (C) 2023 wcm.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package io.wcm.wcm.core.components.impl.models.v3; + +import static com.adobe.cq.wcm.core.components.models.Image.PN_ALT_VALUE_FROM_DAM; +import static com.adobe.cq.wcm.core.components.models.Image.PN_DESIGN_LAZY_LOADING_ENABLED; +import static com.adobe.cq.wcm.core.components.models.Image.PN_DESIGN_LAZY_THRESHOLD; +import static com.adobe.cq.wcm.core.components.models.Image.PN_DISPLAY_POPUP_TITLE; +import static com.adobe.cq.wcm.core.components.models.Image.PN_IMAGE_FROM_PAGE_IMAGE; +import static com.adobe.cq.wcm.core.components.models.Image.PN_IS_DECORATIVE; +import static com.adobe.cq.wcm.core.components.models.Image.PN_MAP; +import static com.adobe.cq.wcm.core.components.models.Image.PN_TITLE_VALUE_FROM_DAM; +import static com.adobe.cq.wcm.core.components.models.Image.PN_UUID_DISABLED; +import static com.adobe.cq.wcm.core.components.models.Page.NN_PAGE_FEATURED_IMAGE; +import static com.day.cq.commons.ImageResource.PN_ALT; +import static com.day.cq.commons.jcr.JcrConstants.JCR_TITLE; +import static com.day.cq.commons.jcr.JcrConstants.JCR_UUID; +import static com.day.cq.dam.api.DamConstants.DC_DESCRIPTION; +import static com.day.cq.dam.api.DamConstants.DC_TITLE; +import static io.wcm.handler.link.LinkNameConstants.PN_LINK_EXTERNAL_REF; +import static io.wcm.handler.link.LinkNameConstants.PN_LINK_TITLE; +import static io.wcm.handler.media.MediaNameConstants.NN_COMPONENT_MEDIA_RESPONSIVEIMAGE_SIZES; +import static io.wcm.handler.media.MediaNameConstants.NN_MEDIA_INLINE_STANDARD; +import static io.wcm.handler.media.MediaNameConstants.PN_COMPONENT_MEDIA_AUTOCROP; +import static io.wcm.handler.media.MediaNameConstants.PN_COMPONENT_MEDIA_FORMATS; +import static io.wcm.handler.media.MediaNameConstants.PN_COMPONENT_MEDIA_RESPONSIVE_TYPE; +import static io.wcm.handler.media.MediaNameConstants.PN_MEDIA_REF_STANDARD; +import static io.wcm.wcm.core.components.impl.models.helpers.DataLayerTestUtils.enableDataLayer; +import static io.wcm.wcm.core.components.impl.models.v3.ImageV3Impl.RESOURCE_TYPE; +import static io.wcm.wcm.core.components.testcontext.AppAemContext.CONTENT_ROOT; +import static io.wcm.wcm.core.components.testcontext.AppAemContext.DAM_ROOT; +import static io.wcm.wcm.core.components.testcontext.TestUtils.assertInvalidLink; +import static io.wcm.wcm.core.components.testcontext.TestUtils.assertInvalidMedia; +import static io.wcm.wcm.core.components.testcontext.TestUtils.assertValidLink; +import static io.wcm.wcm.core.components.testcontext.TestUtils.assertValidMedia; +import static io.wcm.wcm.core.components.testcontext.TestUtils.loadComponentDefinition; +import static org.apache.sling.api.resource.ResourceResolver.PROPERTY_RESOURCE_TYPE; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Map; + +import org.apache.sling.api.resource.ModifiableValueMap; +import org.apache.sling.api.resource.Resource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.adobe.cq.wcm.core.components.models.Image; +import com.adobe.cq.wcm.core.components.models.datalayer.AssetData; +import com.adobe.cq.wcm.core.components.models.datalayer.ComponentData; +import com.adobe.cq.wcm.core.components.models.datalayer.ImageData; +import com.day.cq.dam.api.Asset; +import com.day.cq.wcm.api.Page; + +import io.wcm.handler.link.type.ExternalLinkType; +import io.wcm.sling.commons.adapter.AdaptTo; +import io.wcm.testing.mock.aem.junit5.AemContext; +import io.wcm.testing.mock.aem.junit5.AemContextExtension; +import io.wcm.wcm.commons.contenttype.ContentType; +import io.wcm.wcm.core.components.testcontext.AppAemContext; +import io.wcm.wcm.core.components.testcontext.ImageAreaTestData; +import io.wcm.wcm.core.components.testcontext.MediaFormats; +import io.wcm.wcm.core.components.testcontext.ResourceTypeForcingResourceWrapper; + +@ExtendWith(AemContextExtension.class) +class ImageV3ImplTest { + + private final AemContext context = AppAemContext.newAemContext(); + + private Page page; + private Asset asset; + + @BeforeEach + void setUp() { + loadComponentDefinition(context, RESOURCE_TYPE); + + page = context.create().page(CONTENT_ROOT + "/page1"); + asset = context.create().asset(DAM_ROOT + "/sample.jpg", 160, 90, ContentType.JPEG, + DC_TITLE, "Asset Title", + DC_DESCRIPTION, "Asset Description"); + // create web rendition to test auto-cropping + context.create().assetRenditionWebEnabled(asset); + } + + @Test + @SuppressWarnings("deprecation") + void testNoImage() { + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE)); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertNull(underTest.getSrc()); + assertNull(underTest.getTitle()); + assertNull(underTest.getAlt()); + assertNull(underTest.getUuid()); + assertNull(underTest.getLink()); + assertTrue(underTest.displayPopupTitle()); + assertNull(underTest.getFileReference()); + assertNull(underTest.getJson()); + assertArrayEquals(new int[0], underTest.getWidths()); + assertNull(underTest.getSrcUriTemplate()); + assertFalse(underTest.isLazyEnabled()); + assertEquals(0, underTest.getLazyThreshold()); + assertNull(underTest.getAreas()); + assertFalse(underTest.isDecorative()); + assertNotNull(underTest.getId()); + + assertInvalidMedia(underTest); + assertInvalidLink(underTest.getImageLink()); + assertNull(underTest.getData()); + + assertNull(underTest.getWidth()); + assertNull(underTest.getHeight()); + assertNull(underTest.getSizes()); + assertNull(underTest.getSrcset()); + assertNull(underTest.getSmartCropRendition()); + assertFalse(underTest.isDmImage()); + + assertEquals(RESOURCE_TYPE, underTest.getExportedType()); + } + + @Test + void testInvalidAssetReference() { + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_MEDIA_REF_STANDARD, "/content/dam/invalid")); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertInvalidMedia(underTest); + assertInvalidLink(underTest.getImageLink()); + } + + @Test + @SuppressWarnings("deprecation") + void testWithAssetImage() { + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath(), + JCR_TITLE, "Resource Title", + PN_ALT, "Resource Alt")); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + String expectedMediaUrl = DAM_ROOT + "/sample.jpg/_jcr_content/renditions/original./sample.jpg"; + + assertEquals(expectedMediaUrl, underTest.getSrc()); + assertEquals("Asset Title", underTest.getTitle()); + assertEquals("Asset Description", underTest.getAlt()); + assertEquals("", underTest.getUuid()); + assertNull(underTest.getLink()); + assertTrue(underTest.displayPopupTitle()); + assertEquals(asset.getPath(), underTest.getFileReference()); + assertArrayEquals(new int[] { 160 }, underTest.getWidths()); + assertEquals("/content/dam/sample/sample.jpg/_jcr_content/renditions/original.image_file.{.width}.0.file/sample.jpg", underTest.getSrcUriTemplate()); + assertFalse(underTest.isLazyEnabled()); + assertNull(underTest.getAreas()); + + assertValidMedia(underTest, expectedMediaUrl); + assertInvalidLink(underTest.getImageLink()); + } + + @Test + void testWithAssetImage_SVG() { + Asset svgAsset = context.create().asset(DAM_ROOT + "/sample.svg", 160, 90, ContentType.SVG); + + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, svgAsset.getPath())); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + String expectedMediaUrl = DAM_ROOT + "/sample.svg/_jcr_content/renditions/original./sample.svg"; + + assertEquals(expectedMediaUrl, underTest.getSrc()); + assertNull(underTest.getSrcUriTemplate()); + } + + @Test + @SuppressWarnings({ "deprecation", "null" }) + void testWithAssetImageFromPage() { + Page page1 = context.currentPage(context.create().page(page, "page1", null, + NN_PAGE_FEATURED_IMAGE, Map.of( + PN_MEDIA_REF_STANDARD, asset.getPath()))); + + context.currentResource(context.create().resource(page1, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + JCR_TITLE, "Resource Title", + PN_ALT, "Resource Alt")); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + String expectedMediaUrl = DAM_ROOT + "/sample.jpg/_jcr_content/renditions/original./sample.jpg"; + + assertEquals(expectedMediaUrl, underTest.getSrc()); + assertEquals("Asset Title", underTest.getTitle()); + assertEquals("Asset Description", underTest.getAlt()); + assertEquals("", underTest.getUuid()); + assertNull(underTest.getLink()); + assertTrue(underTest.displayPopupTitle()); + assertEquals(asset.getPath(), underTest.getFileReference()); + assertArrayEquals(new int[] { 160 }, underTest.getWidths()); + assertEquals("/content/dam/sample/sample.jpg/_jcr_content/renditions/original.image_file.{.width}.0.file/sample.jpg", underTest.getSrcUriTemplate()); + assertFalse(underTest.isLazyEnabled()); + assertNull(underTest.getAreas()); + + assertValidMedia(underTest, expectedMediaUrl); + assertInvalidLink(underTest.getImageLink()); + } + + @Test + @SuppressWarnings("deprecation") + void testWithUploadedImage() { + Resource imageResource = context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + NN_MEDIA_INLINE_STANDARD + "Name", "file1.png"); + context.load().binaryFile("/files/test.png", imageResource.getPath() + "/" + NN_MEDIA_INLINE_STANDARD, ContentType.PNG); + context.currentResource(imageResource); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + String expectedMediaUrl = "/content/sample/en/page1/_jcr_content/image/file./file1.png"; + + assertEquals(expectedMediaUrl, underTest.getSrc()); + assertNull(underTest.getTitle()); + assertNull(underTest.getAlt()); + assertNull(underTest.getUuid()); + assertNull(underTest.getLink()); + assertTrue(underTest.displayPopupTitle()); + assertNull(underTest.getFileReference()); + assertArrayEquals(new int[] { 160 }, underTest.getWidths()); + assertEquals("/content/sample/en/page1/_jcr_content/image/file.image_file.{.width}.0.file/file1.png", underTest.getSrcUriTemplate()); + assertFalse(underTest.isLazyEnabled()); + assertNull(underTest.getAreas()); + + assertValidMedia(underTest, expectedMediaUrl); + assertInvalidLink(underTest.getImageLink()); + } + + @Test + @SuppressWarnings("deprecation") + void testWithImageAndLink() { + enableDataLayer(context, true); + + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath(), + PN_LINK_TITLE, ExternalLinkType.ID, + PN_LINK_EXTERNAL_REF, "http://myhost")); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertEquals("Asset Title", underTest.getTitle()); + assertEquals("Asset Description", underTest.getAlt()); + assertEquals("http://myhost", underTest.getLink()); + + assertValidLink(underTest.getImageLink(), "http://myhost"); + + ComponentData data = underTest.getData(); + assertNotNull(data); + assertEquals(RESOURCE_TYPE, data.getType()); + assertEquals("Asset Title", data.getTitle()); + assertEquals("http://myhost", data.getLinkUrl()); + + AssetData assetData = ((ImageData)data).getAssetData(); + assertEquals(asset.getPath(), assetData.getUrl()); + assertEquals(asset.getMimeType(), assetData.getFormat()); + } + + @Test + @SuppressWarnings("deprecation") + void testWithImageAndLink_Decorative() { + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath(), + PN_LINK_TITLE, ExternalLinkType.ID, + PN_LINK_EXTERNAL_REF, "http://myhost", + PN_IS_DECORATIVE, true)); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertEquals("Asset Title", underTest.getTitle()); + assertEquals("", underTest.getAlt()); + assertNull(underTest.getLink()); + assertTrue(underTest.isDecorative()); + + assertInvalidLink(underTest.getImageLink()); + } + + @Test + @SuppressWarnings("deprecation") + void testWithImageAndLink_Decorative_ContentPolicy() { + context.contentPolicyMapping(RESOURCE_TYPE, + PN_IS_DECORATIVE, true, + PN_DESIGN_LAZY_THRESHOLD, 10); + + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath(), + PN_LINK_TITLE, ExternalLinkType.ID, + PN_LINK_EXTERNAL_REF, "http://myhost")); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertEquals("Asset Title", underTest.getTitle()); + assertEquals("", underTest.getAlt()); + assertNull(underTest.getLink()); + assertEquals(10, underTest.getLazyThreshold()); + + assertInvalidLink(underTest.getImageLink()); + } + + @Test + void testWithImage_TitleAltNotFormAsset() { + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath(), + JCR_TITLE, "Resource Title", + PN_ALT, "Resource Alt", + PN_TITLE_VALUE_FROM_DAM, false, + PN_ALT_VALUE_FROM_DAM, false)); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertEquals("Resource Title", underTest.getTitle()); + assertEquals("Resource Alt", underTest.getAlt()); + } + + @Test + void testWithImage_TitleAltNotFormAsset_ContentPolicy() { + context.contentPolicyMapping(RESOURCE_TYPE, + PN_TITLE_VALUE_FROM_DAM, false, + PN_ALT_VALUE_FROM_DAM, false); + + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath(), + JCR_TITLE, "Resource Title", + PN_ALT, "Resource Alt")); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertEquals("Resource Title", underTest.getTitle()); + assertEquals("Resource Alt", underTest.getAlt()); + } + + @Test + void testWithNoImageAsset() { + Asset pdfAsset = context.create().asset(DAM_ROOT + "/file1.pdf", "/files/test.pdf", ContentType.PDF); + + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, pdfAsset.getPath())); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertInvalidMedia(underTest); + } + + @Test + void testDisplayPopupTitle() { + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath(), + PN_DISPLAY_POPUP_TITLE, false)); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertFalse(underTest.displayPopupTitle()); + } + + @Test + void testDisplayPopupTitle_ContentPolicy() { + context.contentPolicyMapping(RESOURCE_TYPE, + PN_DISPLAY_POPUP_TITLE, false); + + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath())); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertFalse(underTest.displayPopupTitle()); + } + + @Test + void testLazyEnabled_ContentPolicy() { + context.contentPolicyMapping(RESOURCE_TYPE, + PN_DESIGN_LAZY_LOADING_ENABLED, false); // property is internally named "disabled", value is inverted + + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath())); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertTrue(underTest.isLazyEnabled()); + } + + @Test + void testUUID() { + Resource resource = AdaptTo.notNull(asset, Resource.class); + ModifiableValueMap props = AdaptTo.notNull(resource, ModifiableValueMap.class); + props.put(JCR_UUID, "test-uuid"); + + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath())); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertEquals("test-uuid", underTest.getUuid()); + } + + @Test + void testUUID_Disabled() { + context.contentPolicyMapping(RESOURCE_TYPE, + PN_UUID_DISABLED, true); + + Resource resource = AdaptTo.notNull(asset, Resource.class); + ModifiableValueMap props = AdaptTo.notNull(resource, ModifiableValueMap.class); + props.put(JCR_UUID, "test-uuid"); + + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath())); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertNull(underTest.getUuid()); + } + + @Test + void testWidths() { + context.contentPolicyMapping(RESOURCE_TYPE, + PN_COMPONENT_MEDIA_FORMATS, new String[] { MediaFormats.LANDSCAPE.getName() }, + PN_COMPONENT_MEDIA_RESPONSIVE_TYPE, "imageSizes", + NN_COMPONENT_MEDIA_RESPONSIVEIMAGE_SIZES, Map.of("sizes", "100vw", "widths", "100,50"), + PN_COMPONENT_MEDIA_AUTOCROP, true); + + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath())); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertEquals("/content/dam/sample/sample.jpg/_jcr_content/renditions/original./sample.jpg", underTest.getSrc()); + assertEquals(asset.getPath(), underTest.getFileReference()); + assertArrayEquals(new int[] { 50, 100, 160 }, underTest.getWidths()); + assertEquals("/content/dam/sample/sample.jpg/_jcr_content/renditions/original.image_file.{.width}.0.file/sample.jpg", underTest.getSrcUriTemplate()); + + assertValidMedia(underTest, DAM_ROOT + "/sample.jpg/_jcr_content/renditions/original./sample.jpg"); + } + + @Test + void testAreas() { + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath(), + PN_MAP, ImageAreaTestData.MAP_STRING)); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertEquals(ImageAreaTestData.getExpectedAreasV1(context), underTest.getAreas()); + } + + @Test + void testWithImageAutoCropping_ContentPolicy() { + context.contentPolicyMapping(RESOURCE_TYPE, + PN_COMPONENT_MEDIA_FORMATS, new String[] { MediaFormats.SQUARE.getName() }, + PN_COMPONENT_MEDIA_AUTOCROP, true); + + context.currentResource(context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath())); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertEquals("Asset Title", underTest.getTitle()); + assertEquals("/content/dam/sample/sample.jpg/_jcr_content/renditions/original.image_file.90.90.35,0,125,90.file/sample.jpg", underTest.getSrc()); + } + + @Test + void testWithImageAutoCropping_ContentPolicy_WrappedResource() { + // prepare dummy component that delegates to the component under test + final String DELEGATE_RESOURCE_TYPE = "myapp/components/delegate"; + context.create().resource("/apps/" + DELEGATE_RESOURCE_TYPE, + "sling:resourceSuperType", RESOURCE_TYPE); + + context.contentPolicyMapping(DELEGATE_RESOURCE_TYPE, + PN_COMPONENT_MEDIA_FORMATS, new String[] { MediaFormats.SQUARE.getName() }, + PN_COMPONENT_MEDIA_AUTOCROP, true); + + Resource resource = context.create().resource(page, "image", + PROPERTY_RESOURCE_TYPE, DELEGATE_RESOURCE_TYPE, + PN_IMAGE_FROM_PAGE_IMAGE, false, + PN_MEDIA_REF_STANDARD, asset.getPath()); + + // set context resource to wrapped resource + context.currentResource(new ResourceTypeForcingResourceWrapper(resource, RESOURCE_TYPE)); + + Image underTest = AdaptTo.notNull(context.request(), Image.class); + + assertEquals("Asset Title", underTest.getTitle()); + assertEquals("/content/dam/sample/sample.jpg/_jcr_content/renditions/original.image_file.90.90.35,0,125,90.file/sample.jpg", underTest.getSrc()); + } + +} diff --git a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/wcmio/v1/ResponsiveImageV1ImplTest.java b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/wcmio/v1/ResponsiveImageV1ImplTest.java index a9b22e1..b582615 100644 --- a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/wcmio/v1/ResponsiveImageV1ImplTest.java +++ b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/wcmio/v1/ResponsiveImageV1ImplTest.java @@ -178,7 +178,6 @@ void testWithUploadedImage() { } @Test - @SuppressWarnings("null") void testWithImageAndLink() { enableDataLayer(context, true); diff --git a/changes.xml b/changes.xml index e53f3a9..ad39c42 100644 --- a/changes.xml +++ b/changes.xml @@ -23,6 +23,12 @@ xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/plugins/maven-changes-plugin/xsd/changes-1.0.0.xsd"> + + + Add Image (v3). + + + Fix detection of teaser actions in Teaser V2. diff --git a/examples/bundles/examples-core/pom.xml b/examples/bundles/examples-core/pom.xml index e08eff1..9607467 100644 --- a/examples/bundles/examples-core/pom.xml +++ b/examples/bundles/examples-core/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-core - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT jar WCM Core Components Examples Core @@ -44,7 +44,7 @@ io.wcm io.wcm.wcm.core.components - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT compile diff --git a/examples/content-packages/examples-libs/pom.xml b/examples/content-packages/examples-libs/pom.xml index c6d56fe..92ae6a3 100644 --- a/examples/content-packages/examples-libs/pom.xml +++ b/examples/content-packages/examples-libs/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-libs - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT content-package WCM Core Components Examples wcm.io Libraries @@ -42,7 +42,7 @@ io.wcm io.wcm.wcm.core.components - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT compile diff --git a/examples/content-packages/examples-sample-content/jcr_root/content/wcmio-core-components-examples/library/core-content/image/.content.xml b/examples/content-packages/examples-sample-content/jcr_root/content/wcmio-core-components-examples/library/core-content/image/.content.xml index fe30ebe..62342e5 100644 --- a/examples/content-packages/examples-sample-content/jcr_root/content/wcmio-core-components-examples/library/core-content/image/.content.xml +++ b/examples/content-packages/examples-sample-content/jcr_root/content/wcmio-core-components-examples/library/core-content/image/.content.xml @@ -1,5 +1,5 @@ - + linkURL="https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/image/v3"/> @@ -114,10 +115,11 @@ sling:resourceType="core-components-examples/components/demo/component"> @@ -160,10 +162,11 @@ sling:resourceType="core-components-examples/components/demo/component"> @@ -207,10 +210,11 @@ sling:resourceType="core-components-examples/components/demo/component"> @@ -234,6 +238,47 @@ reference="../../component"/> + + + + + + + + + + + + io.wcm io.wcm.wcm.core.components.parent - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-sample-content - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT content-package WCM Core Components Examples Content diff --git a/examples/content-packages/examples/pom.xml b/examples/content-packages/examples/pom.xml index ac7ec97..054c5f1 100644 --- a/examples/content-packages/examples/pom.xml +++ b/examples/content-packages/examples/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT content-package WCM Core Components Examples @@ -42,7 +42,7 @@ io.wcm.samples io.wcm.wcm.core.components.examples-core - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT compile diff --git a/examples/pom.xml b/examples/pom.xml index 486b444..1bce240 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT ../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples.root - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT pom diff --git a/parent/pom.xml b/parent/pom.xml index 48ca58b..1461357 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -31,7 +31,7 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT pom WCM Core Components @@ -54,7 +54,7 @@ http://localhost:4503 - 2023-08-21T09:25:52Z + 2023-09-02T12:42:05Z @@ -118,49 +118,49 @@ io.wcm io.wcm.sling.commons - 1.4.0 + 1.6.4 io.wcm io.wcm.handler.commons - 1.4.0 + 1.5.0 io.wcm io.wcm.handler.url - 1.5.4 + 1.10.2 io.wcm io.wcm.handler.link - 1.7.4 + 1.10.2 io.wcm io.wcm.handler.media - 1.13.6 + 1.15.6 io.wcm io.wcm.handler.richtext - 1.5.0 + 1.6.4 io.wcm io.wcm.wcm.commons - 1.9.0 + 1.10.0 io.wcm io.wcm.wcm.ui.granite - 1.8.0 + 1.9.14 io.wcm io.wcm.testing.aem-mock.junit5 - 5.2.2 + 5.3.0 org.apache.sling @@ -170,7 +170,7 @@ org.apache.sling org.apache.sling.testing.caconfig-mock-plugin - 1.5.0 + 1.5.2 io.wcm @@ -196,7 +196,7 @@ org.skyscreamer jsonassert - 1.5.0 + 1.5.1 diff --git a/pom.xml b/pom.xml index 8bf9170..0ceb612 100644 --- a/pom.xml +++ b/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT parent/pom.xml io.wcm io.wcm.wcm.core.components.root - 1.13.3-2.22.6-SNAPSHOT + 1.14.0-2.22.6-SNAPSHOT pom ${site.url}/${site.url.module.prefix}/ diff --git a/src/site/markdown/components.md b/src/site/markdown/components.md index fc69bda..2ba0931 100644 --- a/src/site/markdown/components.md +++ b/src/site/markdown/components.md @@ -17,7 +17,7 @@ _Enhanced with_ MEDIA _Media Handler * [Title (v3)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/title/v3) | [v2](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/title/v2) LINK * [Text (v2)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/text/v2) RICHTEXT LINK -* [Image (v2)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/image/v2) (deprecated) MEDIA LINK +* [Image (v3)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/image/v3) | [(v2)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/image/v2) MEDIA LINK * [Button (v2)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/button/v2) | [(v1)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/button/v1) LINK * [Teaser (v2)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/teaser/v2) | [(v1)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/teaser/v1) MEDIA LINK RICHTEXT * [List (v4)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/list/v4) | [(v3)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/list/v3) | [(v2)](https://github.com/wcm-io/wcm-io-wcm-core-components/tree/develop/bundles/core/src/main/webapp/app-root/components/list/v2) LINK @@ -59,4 +59,3 @@ _Enhanced with_ MEDIA _Media Handler **Page Authoring Components** * Sharing (v1) -* Image (v3) From 9b2828e1d4cdc48cff57167c350418686163e0c2 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Mon, 4 Sep 2023 15:19:18 +0200 Subject: [PATCH 04/12] update io.wcm.parent_toplevel --- parent/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parent/pom.xml b/parent/pom.xml index 1461357..29967e1 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -25,7 +25,7 @@ io.wcm io.wcm.parent_toplevel - 2.2.0 + 2.2.2 From 7f6e265be9b997c5e2d0ad2ca40089383fc33163 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Mon, 4 Sep 2023 16:41:07 +0200 Subject: [PATCH 05/12] Core Components 2.23.2 (#14) --- build-deploy_aem65.sh | 2 +- bundles/core/pom.xml | 4 ++-- .../impl/models/v2/form/FormsHelperStubber.java | 2 +- changes.xml | 5 ++++- examples/bundles/examples-core/pom.xml | 6 +++--- examples/content-packages/examples-libs/pom.xml | 6 +++--- examples/content-packages/examples-sample-content/pom.xml | 4 ++-- examples/content-packages/examples/pom.xml | 6 +++--- examples/pom.xml | 4 ++-- parent/pom.xml | 8 ++++---- pom.xml | 4 ++-- src/site/markdown/index.md | 1 + 12 files changed, 28 insertions(+), 24 deletions(-) diff --git a/build-deploy_aem65.sh b/build-deploy_aem65.sh index b069249..0c4f88f 100644 --- a/build-deploy_aem65.sh +++ b/build-deploy_aem65.sh @@ -26,7 +26,7 @@ fi # install AEM 6.5 with service pack mvn --non-recursive wcmio-content-package:install \ --activate-profiles=${MAVEN_PROFILES} \ - -Dvault.artifact=adobe.binary.aem.65.servicepack:aem-service-pkg:zip:6.5.16.0 \ + -Dvault.artifact=adobe.binary.aem.65.servicepack:aem-service-pkg:zip:6.5.18.0 \ -Dvault.delayAfterInstallSec=30 if [ "$?" -ne "0" ]; then diff --git a/bundles/core/pom.xml b/bundles/core/pom.xml index ab80cde..582489b 100644 --- a/bundles/core/pom.xml +++ b/bundles/core/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT ../../parent/pom.xml io.wcm io.wcm.wcm.core.components - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT jar WCM Core Components diff --git a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/form/FormsHelperStubber.java b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/form/FormsHelperStubber.java index 5e9b1b0..bf3c72f 100644 --- a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/form/FormsHelperStubber.java +++ b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/form/FormsHelperStubber.java @@ -60,7 +60,7 @@ static void createStub() { // remove the static initializer block calling new on impl class. ctClass.removeConstructor(ctClass.getClassInitializer()); // load the stubbed class - ctClass.toClass(); + ctClass.toClass(com.day.cq.wcm.foundation.forms.FormsConstants.class); } catch (NotFoundException | CannotCompileException ex) { throw new RuntimeException(ex); diff --git a/changes.xml b/changes.xml index ad39c42..a405cea 100644 --- a/changes.xml +++ b/changes.xml @@ -23,10 +23,13 @@ xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/plugins/maven-changes-plugin/xsd/changes-1.0.0.xsd"> - + Add Image (v3). + + Update to AEM WCM Core Components 2.23.2. + diff --git a/examples/bundles/examples-core/pom.xml b/examples/bundles/examples-core/pom.xml index 9607467..10cfaa9 100644 --- a/examples/bundles/examples-core/pom.xml +++ b/examples/bundles/examples-core/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-core - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT jar WCM Core Components Examples Core @@ -44,7 +44,7 @@ io.wcm io.wcm.wcm.core.components - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT compile diff --git a/examples/content-packages/examples-libs/pom.xml b/examples/content-packages/examples-libs/pom.xml index 92ae6a3..de330e5 100644 --- a/examples/content-packages/examples-libs/pom.xml +++ b/examples/content-packages/examples-libs/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-libs - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT content-package WCM Core Components Examples wcm.io Libraries @@ -42,7 +42,7 @@ io.wcm io.wcm.wcm.core.components - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT compile diff --git a/examples/content-packages/examples-sample-content/pom.xml b/examples/content-packages/examples-sample-content/pom.xml index b76c7ad..6968846 100644 --- a/examples/content-packages/examples-sample-content/pom.xml +++ b/examples/content-packages/examples-sample-content/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-sample-content - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT content-package WCM Core Components Examples Content diff --git a/examples/content-packages/examples/pom.xml b/examples/content-packages/examples/pom.xml index 054c5f1..a73590f 100644 --- a/examples/content-packages/examples/pom.xml +++ b/examples/content-packages/examples/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT content-package WCM Core Components Examples @@ -42,7 +42,7 @@ io.wcm.samples io.wcm.wcm.core.components.examples-core - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT compile diff --git a/examples/pom.xml b/examples/pom.xml index 1bce240..d21b4a3 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT ../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples.root - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT pom diff --git a/parent/pom.xml b/parent/pom.xml index 29967e1..73b5e87 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -31,7 +31,7 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT pom WCM Core Components @@ -48,13 +48,13 @@ - 2.22.6 + 2.23.2 http://localhost:4502 http://localhost:4503 - 2023-09-02T12:42:05Z + 2023-09-04T13:32:18Z @@ -63,7 +63,7 @@ io.wcm.maven io.wcm.maven.aem-dependencies - 6.5.14.0000 + 6.5.17.0001 pom import diff --git a/pom.xml b/pom.xml index 0ceb612..72e7a59 100644 --- a/pom.xml +++ b/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT parent/pom.xml io.wcm io.wcm.wcm.core.components.root - 1.14.0-2.22.6-SNAPSHOT + 1.14.0-2.23.2-SNAPSHOT pom ${site.url}/${site.url.module.prefix}/ diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index 8ed44ba..cfd5eb2 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -35,6 +35,7 @@ There is currently no added wcm.io support for the Core Component AMP extensions |wcm.io WCM Core Components version | AEM Sites Core Component version | AEM version supported |-----------------------------------|----------------------------------|--------------------------------------------- +| 1.14.0-2.23.2 | 2.23.2 and up | AEM 6.5.17, AEMaaCS | 1.13.0-2.22.6 | 2.22.6 and up | AEM 6.5.14, AEMaaCS | 1.12.0-2.20.0 | 2.20.0 and up | AEM 6.5.13, AEMaaCS | 1.11.0-2.19.0 | 2.19.0 and up | AEM 6.5.7, AEMaaCS From 02d3cce89745e0d58bf02018616a00852f00c663 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Mon, 4 Sep 2023 19:43:55 +0200 Subject: [PATCH 06/12] ComponentFeatureImageResolver: Switch to image from page by default if no image reference is given in image/teaser resource. --- .../impl/models/v2/ImageV2Impl.java | 2 +- .../impl/models/v3/ImageV3Impl.java | 6 ++---- .../util/ComponentFeatureImageResolver.java | 16 +++++++++++----- .../impl/models/v3/ImageV3ImplTest.java | 19 ------------------- changes.xml | 5 ++++- 5 files changed, 18 insertions(+), 30 deletions(-) diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2Impl.java index c8f1c37..ec7693b 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ImageV2Impl.java @@ -68,7 +68,7 @@ public class ImageV2Impl extends ImageV3Impl implements LinkMixin { public static final String RESOURCE_TYPE = "wcm-io/wcm/core/components/image/v2/image"; @Override - protected Media buildMedia(boolean altFromAsset, boolean imageFromPageImage) { + protected Media buildMedia(boolean altFromAsset) { return HandlerUnwrapper.get(mediaHandler, resource) // disable dynamic media support as it is not compatible with the "src-pattern" concept .dynamicMediaDisabled(true) diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java index b9069af..51d281d 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java @@ -136,7 +136,6 @@ private void activate() { lazyThreshold = currentStyle.get(PN_DESIGN_LAZY_THRESHOLD, 0); isDecorative = properties.get(PN_IS_DECORATIVE, currentStyle.get(PN_IS_DECORATIVE, false)); boolean altFromAsset = properties.get(PN_ALT_VALUE_FROM_DAM, currentStyle.get(PN_ALT_VALUE_FROM_DAM, true)); - boolean imageFromPageImage = properties.get(PN_IMAGE_FROM_PAGE_IMAGE, true); // resolve link - decorative images have no link and no alt text by definition if (isDecorative) { @@ -147,7 +146,7 @@ private void activate() { } // resolve media and properties from DAM asset - media = buildMedia(altFromAsset, imageFromPageImage); + media = buildMedia(altFromAsset); if (media.isValid() && !media.getRendition().isImage()) { // no image asset selected (cannot be rendered) - set to invalid @@ -162,11 +161,10 @@ private void activate() { } - protected Media buildMedia(boolean altFromAsset, boolean imageFromPageImage) { + protected Media buildMedia(boolean altFromAsset) { ComponentFeatureImageResolver imageResolver = new ComponentFeatureImageResolver(resource, getCurrentPage(), currentStyle, mediaHandler) .targetPage(getCurrentPage()) .altValueFromDam(altFromAsset) - .imageFromPageImage(imageFromPageImage) .mediaHandlerProperty(PROP_CSS_CLASS, "cmp-image__image") .mediaHandlerProperty("itemprop", "contentUrl"); String imageTitle = title; diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/util/ComponentFeatureImageResolver.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/util/ComponentFeatureImageResolver.java index 9ed91ce..e1e4b63 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/util/ComponentFeatureImageResolver.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/util/ComponentFeatureImageResolver.java @@ -42,6 +42,7 @@ import io.wcm.handler.media.Media; import io.wcm.handler.media.MediaBuilder; import io.wcm.handler.media.MediaHandler; +import io.wcm.handler.media.MediaInvalidReason; /** * Resolves images and alt. texts for components either from the component resource, @@ -128,7 +129,16 @@ public ComponentFeatureImageResolver altValueFromDam(boolean value) { * @return Media */ public @NotNull Media buildMedia() { - Media media; + Media media = mediaHandler.invalid(); + + if (!imageFromPageImage) { + // image from resource properties + media = buildMedia(componentResource); + if (!media.isValid() && media.getMediaInvalidReason() == MediaInvalidReason.MEDIA_REFERENCE_MISSING) { + // fallback to image from page if no reference was given + imageFromPageImage = true; + } + } if (imageFromPageImage) { // try to get feature image from target page @@ -145,10 +155,6 @@ public ComponentFeatureImageResolver altValueFromDam(boolean value) { media = buildMedia(wrapFeatureImageResource(featuredImageResource)); } } - else { - // image from teaser resource - media = buildMedia(componentResource); - } return media; } diff --git a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3ImplTest.java b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3ImplTest.java index 57522a9..1606748 100644 --- a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3ImplTest.java +++ b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3ImplTest.java @@ -23,7 +23,6 @@ import static com.adobe.cq.wcm.core.components.models.Image.PN_DESIGN_LAZY_LOADING_ENABLED; import static com.adobe.cq.wcm.core.components.models.Image.PN_DESIGN_LAZY_THRESHOLD; import static com.adobe.cq.wcm.core.components.models.Image.PN_DISPLAY_POPUP_TITLE; -import static com.adobe.cq.wcm.core.components.models.Image.PN_IMAGE_FROM_PAGE_IMAGE; import static com.adobe.cq.wcm.core.components.models.Image.PN_IS_DECORATIVE; import static com.adobe.cq.wcm.core.components.models.Image.PN_MAP; import static com.adobe.cq.wcm.core.components.models.Image.PN_TITLE_VALUE_FROM_DAM; @@ -159,7 +158,6 @@ void testInvalidAssetReference() { void testWithAssetImage() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath(), JCR_TITLE, "Resource Title", PN_ALT, "Resource Alt")); @@ -190,7 +188,6 @@ void testWithAssetImage_SVG() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, svgAsset.getPath())); Image underTest = AdaptTo.notNull(context.request(), Image.class); @@ -238,7 +235,6 @@ void testWithAssetImageFromPage() { void testWithUploadedImage() { Resource imageResource = context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, NN_MEDIA_INLINE_STANDARD + "Name", "file1.png"); context.load().binaryFile("/files/test.png", imageResource.getPath() + "/" + NN_MEDIA_INLINE_STANDARD, ContentType.PNG); context.currentResource(imageResource); @@ -270,7 +266,6 @@ void testWithImageAndLink() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath(), PN_LINK_TITLE, ExternalLinkType.ID, PN_LINK_EXTERNAL_REF, "http://myhost")); @@ -299,7 +294,6 @@ void testWithImageAndLink() { void testWithImageAndLink_Decorative() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath(), PN_LINK_TITLE, ExternalLinkType.ID, PN_LINK_EXTERNAL_REF, "http://myhost", @@ -324,7 +318,6 @@ void testWithImageAndLink_Decorative_ContentPolicy() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath(), PN_LINK_TITLE, ExternalLinkType.ID, PN_LINK_EXTERNAL_REF, "http://myhost")); @@ -343,7 +336,6 @@ void testWithImageAndLink_Decorative_ContentPolicy() { void testWithImage_TitleAltNotFormAsset() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath(), JCR_TITLE, "Resource Title", PN_ALT, "Resource Alt", @@ -364,7 +356,6 @@ void testWithImage_TitleAltNotFormAsset_ContentPolicy() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath(), JCR_TITLE, "Resource Title", PN_ALT, "Resource Alt")); @@ -381,7 +372,6 @@ void testWithNoImageAsset() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, pdfAsset.getPath())); Image underTest = AdaptTo.notNull(context.request(), Image.class); @@ -393,7 +383,6 @@ void testWithNoImageAsset() { void testDisplayPopupTitle() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath(), PN_DISPLAY_POPUP_TITLE, false)); @@ -409,7 +398,6 @@ void testDisplayPopupTitle_ContentPolicy() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath())); Image underTest = AdaptTo.notNull(context.request(), Image.class); @@ -424,7 +412,6 @@ void testLazyEnabled_ContentPolicy() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath())); Image underTest = AdaptTo.notNull(context.request(), Image.class); @@ -440,7 +427,6 @@ void testUUID() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath())); Image underTest = AdaptTo.notNull(context.request(), Image.class); @@ -459,7 +445,6 @@ void testUUID_Disabled() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath())); Image underTest = AdaptTo.notNull(context.request(), Image.class); @@ -477,7 +462,6 @@ void testWidths() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath())); Image underTest = AdaptTo.notNull(context.request(), Image.class); @@ -494,7 +478,6 @@ void testWidths() { void testAreas() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath(), PN_MAP, ImageAreaTestData.MAP_STRING)); @@ -511,7 +494,6 @@ void testWithImageAutoCropping_ContentPolicy() { context.currentResource(context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath())); Image underTest = AdaptTo.notNull(context.request(), Image.class); @@ -533,7 +515,6 @@ void testWithImageAutoCropping_ContentPolicy_WrappedResource() { Resource resource = context.create().resource(page, "image", PROPERTY_RESOURCE_TYPE, DELEGATE_RESOURCE_TYPE, - PN_IMAGE_FROM_PAGE_IMAGE, false, PN_MEDIA_REF_STANDARD, asset.getPath()); // set context resource to wrapped resource diff --git a/changes.xml b/changes.xml index a405cea..36f63c3 100644 --- a/changes.xml +++ b/changes.xml @@ -27,9 +27,12 @@ Add Image (v3). - + Update to AEM WCM Core Components 2.23.2. + + ComponentFeatureImageResolver: Switch to image from page by default if no image reference is given in image/teaser resource. + From 4d13107708ef43a5309c5ed87a77b0c75b244838 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Mon, 4 Sep 2023 20:06:16 +0200 Subject: [PATCH 07/12] Navigation: Fix navigation item level numbering when structureStart = 0. --- .../impl/models/v2/NavigationV2Impl.java | 3 + .../impl/models/v2/NavigationV2ImplTest.java | 99 +++++++++---------- .../components/testcontext/TestUtils.java | 8 ++ changes.xml | 3 + 4 files changed, 63 insertions(+), 50 deletions(-) diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/NavigationV2Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/NavigationV2Impl.java index 33b48a0..1c42990 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/NavigationV2Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/NavigationV2Impl.java @@ -240,6 +240,9 @@ private List getItems(NavigationRoot navigationRoot, Page subtre Page page = it.next(); int pageLevel = page.getDepth(); int level = pageLevel - navigationRoot.startLevel; + if (structureStart == 0) { + level++; + } List children = getItems(navigationRoot, page); Link link = linkHandler.get(page).build(); boolean active = isActive(page, link); diff --git a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/NavigationV2ImplTest.java b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/NavigationV2ImplTest.java index 4e95666..1a57a3a 100644 --- a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/NavigationV2ImplTest.java +++ b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/v2/NavigationV2ImplTest.java @@ -94,14 +94,13 @@ void testDefault() { assertNotNull(underTest.getId()); assertNull(underTest.getData()); - assertNavigationItems(underTest.getItems(), page1, page3); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page11, page12); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), page111, page112); - assertNavigationItems(underTest.getItems().get(1).getChildren()); + assertNavigationItems(underTest.getItems(), 1, page1, page3); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 2, page11, page12); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), 3, page111, page112); + assertNavigationItems(underTest.getItems().get(1).getChildren(), 2); } @Test - @SuppressWarnings("null") void testDefault_DataLayer() { enableDataLayer(context, true); @@ -131,11 +130,11 @@ void testStructureStart_0() { assertEquals("my-label", underTest.getAccessibilityLabel()); assertEquals(RESOURCE_TYPE, underTest.getExportedType()); - assertNavigationItems(underTest.getItems(), root); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page1, page3); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), page11, page12); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren().get(0).getChildren(), page111, page112); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(1).getChildren()); + assertNavigationItems(underTest.getItems(), 0, root); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 1, page1, page3); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), 2, page11, page12); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren().get(0).getChildren(), 3, page111, page112); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(1).getChildren(), 2); } @Test @@ -151,11 +150,11 @@ void testStructureStart_0_structureDepth_2() { assertEquals("my-label", underTest.getAccessibilityLabel()); assertEquals(RESOURCE_TYPE, underTest.getExportedType()); - assertNavigationItems(underTest.getItems(), root); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page1, page3); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), page11, page12); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren().get(0).getChildren()); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(1).getChildren()); + assertNavigationItems(underTest.getItems(), 0, root); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 1, page1, page3); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), 2, page11, page12); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren().get(0).getChildren(), 3); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(1).getChildren(), 2); } @Test @@ -169,10 +168,10 @@ void testStructureStart_1() { assertEquals("my-label", underTest.getAccessibilityLabel()); assertEquals(RESOURCE_TYPE, underTest.getExportedType()); - assertNavigationItems(underTest.getItems(), page1, page3); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page11, page12); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), page111, page112); - assertNavigationItems(underTest.getItems().get(1).getChildren()); + assertNavigationItems(underTest.getItems(), 1, page1, page3); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 2, page11, page12); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), 3, page111, page112); + assertNavigationItems(underTest.getItems().get(1).getChildren(), 2); } @Test @@ -186,8 +185,8 @@ void testStructureStart_2() { assertEquals("my-label", underTest.getAccessibilityLabel()); assertEquals(RESOURCE_TYPE, underTest.getExportedType()); - assertNavigationItems(underTest.getItems(), page11, page12); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page111, page112); + assertNavigationItems(underTest.getItems(), 1, page11, page12); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 2, page111, page112); } @Test @@ -198,8 +197,8 @@ void testNavigationRoot_RelativeRootPath() { PN_NAVIGATION_ROOT, "page1")); Navigation underTest = AdaptTo.notNull(context.request(), Navigation.class); - assertNavigationItems(underTest.getItems(), page11, page12); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page111, page112); + assertNavigationItems(underTest.getItems(), 1, page11, page12); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 2, page111, page112); } @Test @@ -211,8 +210,8 @@ void testNavigationRoot_RelativeRootPath_ContentPolicy() { PROPERTY_RESOURCE_TYPE, RESOURCE_TYPE)); Navigation underTest = AdaptTo.notNull(context.request(), Navigation.class); - assertNavigationItems(underTest.getItems(), page11, page12); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page111, page112); + assertNavigationItems(underTest.getItems(), 1, page11, page12); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 2, page111, page112); } @Test @@ -223,7 +222,7 @@ void testNavigationRoot_RelativeRootPath_Invalid() { PN_NAVIGATION_ROOT, "page_not_existing")); Navigation underTest = AdaptTo.notNull(context.request(), Navigation.class); - assertNavigationItems(underTest.getItems()); + assertNavigationItems(underTest.getItems(), 1); } @Test @@ -234,8 +233,8 @@ void testNavigationRoot_AbsoluteRootPath() { PN_NAVIGATION_ROOT, "/content/sample/en/page1")); Navigation underTest = AdaptTo.notNull(context.request(), Navigation.class); - assertNavigationItems(underTest.getItems(), page11, page12); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page111, page112); + assertNavigationItems(underTest.getItems(), 1, page11, page12); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 2, page111, page112); } @Test @@ -246,8 +245,8 @@ void testNavigationRoot_AbsoluteRootPath_RewriteContext() { PN_NAVIGATION_ROOT, "/content/other-sample/fr/page1")); Navigation underTest = AdaptTo.notNull(context.request(), Navigation.class); - assertNavigationItems(underTest.getItems(), page11, page12); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page111, page112); + assertNavigationItems(underTest.getItems(), 1, page11, page12); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 2, page111, page112); } @Test @@ -258,9 +257,9 @@ void testNavigationRoot_AbsoluteRootPath_OutsideContext() { PN_NAVIGATION_ROOT, "/content/sample")); Navigation underTest = AdaptTo.notNull(context.request(), Navigation.class); - assertNavigationItems(underTest.getItems(), languageRoot); - assertNavigationItems(underTest.getItems().get(0).getChildren(), root); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), page1, page3); + assertNavigationItems(underTest.getItems(), 0, languageRoot); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 1, root); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), 2, page1, page3); } @Test @@ -270,7 +269,7 @@ void testNavigationRoot_AbsoluteRootPath_Invalid() { PN_NAVIGATION_ROOT, "/content/sample/en/page_not_existing")); Navigation underTest = AdaptTo.notNull(context.request(), Navigation.class); - assertNavigationItems(underTest.getItems()); + assertNavigationItems(underTest.getItems(), 1); } @Test @@ -281,9 +280,9 @@ void testStructureDepth() { PN_COLLECT_ALL_PAGES, false)); Navigation underTest = AdaptTo.notNull(context.request(), Navigation.class); - assertNavigationItems(underTest.getItems(), page1, page3); - assertNavigationItems(underTest.getItems().get(0).getChildren()); - assertNavigationItems(underTest.getItems().get(1).getChildren()); + assertNavigationItems(underTest.getItems(), 1, page1, page3); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 2); + assertNavigationItems(underTest.getItems().get(1).getChildren(), 2); } @Test @@ -296,11 +295,11 @@ void testIncludeNavigationRoot_SkipNavigationRoot() { assertTrue(underTest.getItems().get(0).isActive()); - assertNavigationItems(underTest.getItems(), root); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page1, page3); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), page11, page12); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren().get(0).getChildren(), page111, page112); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(1).getChildren()); + assertNavigationItems(underTest.getItems(), 0, root); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 1, page1, page3); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), 2, page11, page12); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren().get(0).getChildren(), 3, page111, page112); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(1).getChildren(), 2); } @Test @@ -317,10 +316,10 @@ void testIncludeNavigationRootAndStructureDepth_SkipNavigationRoot() { assertFalse(underTest.getItems().get(0).getChildren().get(0).isActive()); assertTrue(underTest.getItems().get(0).getChildren().get(1).isActive()); - assertNavigationItems(underTest.getItems(), root); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page1, page3); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren()); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(1).getChildren()); + assertNavigationItems(underTest.getItems(), 0, root); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 1, page1, page3); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), 2); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(1).getChildren(), 2); } @Test @@ -338,10 +337,10 @@ void testIncludeNavigationRootAndStructureDepth_ContentPolicy_SkipNavigationRoot assertFalse(underTest.getItems().get(0).getChildren().get(0).isActive()); assertTrue(underTest.getItems().get(0).getChildren().get(1).isActive()); - assertNavigationItems(underTest.getItems(), root); - assertNavigationItems(underTest.getItems().get(0).getChildren(), page1, page3); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren()); - assertNavigationItems(underTest.getItems().get(0).getChildren().get(1).getChildren()); + assertNavigationItems(underTest.getItems(), 0, root); + assertNavigationItems(underTest.getItems().get(0).getChildren(), 1, page1, page3); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(0).getChildren(), 2); + assertNavigationItems(underTest.getItems().get(0).getChildren().get(1).getChildren(), 2); } } diff --git a/bundles/core/src/test/java/io/wcm/wcm/core/components/testcontext/TestUtils.java b/bundles/core/src/test/java/io/wcm/wcm/core/components/testcontext/TestUtils.java index 070c26e..20c990a 100644 --- a/bundles/core/src/test/java/io/wcm/wcm/core/components/testcontext/TestUtils.java +++ b/bundles/core/src/test/java/io/wcm/wcm/core/components/testcontext/TestUtils.java @@ -134,6 +134,14 @@ public static void assertNavigationItems(Collection items, Page. assertListItems((Collection)items, pages); } + @SuppressWarnings("unchecked") + public static void assertNavigationItems(Collection items, int level, Page... pages) { + assertListItems((Collection)items, pages); + for (NavigationItem item : items) { + assertEquals(level, item.getLevel(), "Navigation Item Level"); + } + } + public static void assertListItems(Collection items, Page... pages) { List expected = Arrays.stream(pages) .map(Page::getPath) diff --git a/changes.xml b/changes.xml index 36f63c3..281213f 100644 --- a/changes.xml +++ b/changes.xml @@ -33,6 +33,9 @@ ComponentFeatureImageResolver: Switch to image from page by default if no image reference is given in image/teaser resource. + + Navigation: Fix navigation item level numbering when structureStart = 0. + From 858b22197162f30ee9b4181759b72deb90119f73 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Wed, 6 Sep 2023 11:40:06 +0200 Subject: [PATCH 08/12] Overwrite imageFromPageImage property to switch default value to unchecked --- .../webapp/app-root/components/image/v3/image.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bundles/core/src/main/webapp/app-root/components/image/v3/image.json b/bundles/core/src/main/webapp/app-root/components/image/v3/image.json index 174824b..e0b4576 100644 --- a/bundles/core/src/main/webapp/app-root/components/image/v3/image.json +++ b/bundles/core/src/main/webapp/app-root/components/image/v3/image.json @@ -88,6 +88,17 @@ "column": { "items": { + /** Overwrite property to switch default value to unchecked */ + "imageFromPageImage": { + "uncheckedValue": "false", + "name": "./imageFromPageImage", + "text": "Inherit featured image from page", + "value": true, + "checked": "${false}", + "sling:resourceType": "granite/ui/components/coral/foundation/form/checkbox", + "fieldDescription": "Use the featured image defined in the properties of the linked page, or in the properties of the current page when no link is defined." + }, + /* Does not work with media handler */ "pageImageThumbnail": { "sling:hideResource": true From 95cdc400fe0187698eb724f703a89bad64e69ad2 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Thu, 7 Sep 2023 11:51:24 +0200 Subject: [PATCH 09/12] add link to aem-guides-wknd-wcmio --- src/site/markdown/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index cfd5eb2..1faa433 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -75,6 +75,7 @@ To use this module you have to deploy also: ### Further Resources * [adaptTo() 2019 Talk: Assets and Links in AEM Projects][adaptto-talk-2019-assets-links-in-aem-projects] +* [AEM Sites WKND Tutorial adapted for demonstrating wcm.io Features][aem-guides-wknd-wcmio] ### GitHub Repository @@ -95,3 +96,4 @@ Sources: https://github.com/wcm-io/io.wcm.wcm.core.components [component-library]: component-library.html [components]: components.html [adaptto-talk-2019-assets-links-in-aem-projects]: https://adapt.to/2019/en/schedule/assets-and-links-in-aem-projects.html +[aem-guides-wknd-wcmio]: https://github.com/wcm-io/aem-guides-wknd-wcmio \ No newline at end of file From 409fea6e9766d131f2f33d106ebd06a5f87aa544 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Thu, 7 Sep 2023 15:05:45 +0200 Subject: [PATCH 10/12] Export LinkWrapper and LinkHtmlAttributesSerializer via OSGi to make them reusable in project code (#15) --- .../link/LinkHtmlAttributesSerializer.java | 6 ++--- .../{impl => commons}/link/LinkWrapper.java | 5 ++-- .../components/commons/link/package-info.java | 24 +++++++++++++++++++ .../impl/models/helpers/ImageAreaV2Impl.java | 2 +- .../models/helpers/LinkListItemV1Impl.java | 2 +- .../models/helpers/LinkListItemV2Impl.java | 2 +- .../models/helpers/PageListItemV4Impl.java | 2 +- .../impl/models/v1/TeaserV1Impl.java | 2 +- .../impl/models/v2/ButtonV2Impl.java | 2 +- .../impl/models/v2/TeaserV2Impl.java | 2 +- .../impl/models/v3/ImageV3Impl.java | 2 +- .../impl/models/v3/TitleV3Impl.java | 2 +- .../components/impl/models/v4/ListV4Impl.java | 2 +- .../link/LinkWrapperTest.java | 3 ++- .../helpers/LinkListItemV1ImplTest.java | 2 +- .../helpers/LinkListItemV2ImplTest.java | 2 +- changes.xml | 3 +++ 17 files changed, 47 insertions(+), 18 deletions(-) rename bundles/core/src/main/java/io/wcm/wcm/core/components/{impl => commons}/link/LinkHtmlAttributesSerializer.java (90%) rename bundles/core/src/main/java/io/wcm/wcm/core/components/{impl => commons}/link/LinkWrapper.java (93%) create mode 100644 bundles/core/src/main/java/io/wcm/wcm/core/components/commons/link/package-info.java rename bundles/core/src/test/java/io/wcm/wcm/core/components/{impl => commons}/link/LinkWrapperTest.java (97%) diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/link/LinkHtmlAttributesSerializer.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/commons/link/LinkHtmlAttributesSerializer.java similarity index 90% rename from bundles/core/src/main/java/io/wcm/wcm/core/components/impl/link/LinkHtmlAttributesSerializer.java rename to bundles/core/src/main/java/io/wcm/wcm/core/components/commons/link/LinkHtmlAttributesSerializer.java index 737dca4..e8bd409 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/link/LinkHtmlAttributesSerializer.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/commons/link/LinkHtmlAttributesSerializer.java @@ -17,7 +17,7 @@ * limitations under the License. * #L% */ -package io.wcm.wcm.core.components.impl.link; +package io.wcm.wcm.core.components.commons.link; import java.io.IOException; import java.util.Map; @@ -31,9 +31,9 @@ import com.fasterxml.jackson.databind.ser.std.StdSerializer; /** - * Serialized map of link attributes, omitting the "href" property. + * Serializes a map of link attributes, omitting the "href" property. */ -public class LinkHtmlAttributesSerializer extends StdSerializer> { +public final class LinkHtmlAttributesSerializer extends StdSerializer> { private static final long serialVersionUID = 1L; /** diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/link/LinkWrapper.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/commons/link/LinkWrapper.java similarity index 93% rename from bundles/core/src/main/java/io/wcm/wcm/core/components/impl/link/LinkWrapper.java rename to bundles/core/src/main/java/io/wcm/wcm/core/components/commons/link/LinkWrapper.java index 695a1f0..d1cf7cf 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/link/LinkWrapper.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/commons/link/LinkWrapper.java @@ -17,7 +17,7 @@ * limitations under the License. * #L% */ -package io.wcm.wcm.core.components.impl.link; +package io.wcm.wcm.core.components.commons.link; import java.util.Map; @@ -34,8 +34,9 @@ import io.wcm.handler.link.Link; /** - * Link wrapper around wcm.io Link. + * Wraps a wcm.io Link object into a Core Components Link. */ +@SuppressWarnings("java:S3740") // unable to provide generic for Core Component Link here public final class LinkWrapper implements com.adobe.cq.wcm.core.components.commons.link.Link { private final Link link; diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/commons/link/package-info.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/commons/link/package-info.java new file mode 100644 index 0000000..625ca44 --- /dev/null +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/commons/link/package-info.java @@ -0,0 +1,24 @@ +/* + * #%L + * wcm.io + * %% + * Copyright (C) 2023 wcm.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +/** + * Bridges wcm.io Link to Core Components Link. + */ +@org.osgi.annotation.versioning.Version("1.0.0") +package io.wcm.wcm.core.components.commons.link; diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/ImageAreaV2Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/ImageAreaV2Impl.java index dd80c7a..3e4beba 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/ImageAreaV2Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/ImageAreaV2Impl.java @@ -31,7 +31,7 @@ import com.adobe.cq.wcm.core.components.models.ImageArea; import io.wcm.handler.media.imagemap.ImageMapArea; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; /** * Implementation of {@link ImageArea}. diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV1Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV1Impl.java index 60869e4..25c74af 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV1Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV1Impl.java @@ -28,7 +28,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import io.wcm.handler.link.Link; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; import io.wcm.wcm.core.components.models.mixin.LinkMixin; /** diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV2Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV2Impl.java index 91ca987..4c5ede1 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV2Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV2Impl.java @@ -31,7 +31,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import io.wcm.handler.link.SyntheticLinkResource; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; /** * {@link ListItem} implementation for any links. diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/PageListItemV4Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/PageListItemV4Impl.java index 4f105fb..5d0fd5b 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/PageListItemV4Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/helpers/PageListItemV4Impl.java @@ -48,7 +48,7 @@ import io.wcm.handler.link.Link; import io.wcm.handler.link.type.InternalLinkType; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; import io.wcm.wcm.core.components.impl.util.CoreResourceWrapper; /** diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v1/TeaserV1Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v1/TeaserV1Impl.java index 5b97ea4..7afbd93 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v1/TeaserV1Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v1/TeaserV1Impl.java @@ -32,7 +32,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.wcm.handler.link.Link; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; import io.wcm.wcm.core.components.impl.models.helpers.LinkListItemV1Impl; import io.wcm.wcm.core.components.impl.models.v2.TeaserV2Impl; import io.wcm.wcm.core.components.models.mixin.LinkMixin; diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ButtonV2Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ButtonV2Impl.java index 431ea67..865a3e5 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ButtonV2Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/ButtonV2Impl.java @@ -39,7 +39,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.wcm.handler.link.LinkHandler; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; import io.wcm.wcm.core.components.impl.models.helpers.AbstractComponentImpl; import io.wcm.wcm.core.components.impl.util.HandlerUnwrapper; diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/TeaserV2Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/TeaserV2Impl.java index 23c8727..8e967d6 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/TeaserV2Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v2/TeaserV2Impl.java @@ -55,7 +55,7 @@ import io.wcm.handler.richtext.RichTextHandler; import io.wcm.handler.richtext.TextMode; import io.wcm.sling.models.annotations.AemObject; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; import io.wcm.wcm.core.components.impl.models.helpers.AbstractComponentImpl; import io.wcm.wcm.core.components.impl.models.helpers.LinkListItemV2Impl; import io.wcm.wcm.core.components.impl.util.ComponentFeatureImageResolver; diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java index 51d281d..22a1061 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/ImageV3Impl.java @@ -62,7 +62,7 @@ import io.wcm.handler.media.format.Ratio; import io.wcm.handler.url.UrlHandler; import io.wcm.sling.models.annotations.AemObject; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; import io.wcm.wcm.core.components.impl.models.helpers.AbstractComponentImpl; import io.wcm.wcm.core.components.impl.models.helpers.ImageAreaV2Impl; import io.wcm.wcm.core.components.impl.util.ComponentFeatureImageResolver; diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/TitleV3Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/TitleV3Impl.java index 9b2294c..527f6cc 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/TitleV3Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v3/TitleV3Impl.java @@ -40,7 +40,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.wcm.handler.link.LinkHandler; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; import io.wcm.wcm.core.components.impl.models.helpers.AbstractComponentImpl; import io.wcm.wcm.core.components.impl.util.HandlerUnwrapper; diff --git a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v4/ListV4Impl.java b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v4/ListV4Impl.java index 3c4269c..fbca855 100644 --- a/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v4/ListV4Impl.java +++ b/bundles/core/src/main/java/io/wcm/wcm/core/components/impl/models/v4/ListV4Impl.java @@ -52,7 +52,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.wcm.handler.link.Link; import io.wcm.handler.link.LinkHandler; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; import io.wcm.wcm.core.components.impl.models.helpers.AbstractComponentImpl; import io.wcm.wcm.core.components.impl.models.helpers.LinkListItemV2Impl; import io.wcm.wcm.core.components.impl.models.helpers.PageListItemV4Impl; diff --git a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/link/LinkWrapperTest.java b/bundles/core/src/test/java/io/wcm/wcm/core/components/commons/link/LinkWrapperTest.java similarity index 97% rename from bundles/core/src/test/java/io/wcm/wcm/core/components/impl/link/LinkWrapperTest.java rename to bundles/core/src/test/java/io/wcm/wcm/core/components/commons/link/LinkWrapperTest.java index bddb9b2..67b5c57 100644 --- a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/link/LinkWrapperTest.java +++ b/bundles/core/src/test/java/io/wcm/wcm/core/components/commons/link/LinkWrapperTest.java @@ -17,7 +17,7 @@ * limitations under the License. * #L% */ -package io.wcm.wcm.core.components.impl.link; +package io.wcm.wcm.core.components.commons.link; import static io.wcm.handler.link.LinkNameConstants.PN_LINK_EXTERNAL_REF; import static io.wcm.handler.link.LinkNameConstants.PN_LINK_TYPE; @@ -48,6 +48,7 @@ import io.wcm.testing.mock.aem.junit5.AemContext; import io.wcm.testing.mock.aem.junit5.AemContextExtension; import io.wcm.wcm.commons.contenttype.ContentType; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; import io.wcm.wcm.core.components.testcontext.AppAemContext; @ExtendWith(AemContextExtension.class) diff --git a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV1ImplTest.java b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV1ImplTest.java index 13996a3..9a17831 100644 --- a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV1ImplTest.java +++ b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV1ImplTest.java @@ -36,7 +36,7 @@ import io.wcm.sling.commons.adapter.AdaptTo; import io.wcm.testing.mock.aem.junit5.AemContext; import io.wcm.testing.mock.aem.junit5.AemContextExtension; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; import io.wcm.wcm.core.components.testcontext.AppAemContext; @ExtendWith(AemContextExtension.class) diff --git a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV2ImplTest.java b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV2ImplTest.java index 9b46482..8cb87da 100644 --- a/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV2ImplTest.java +++ b/bundles/core/src/test/java/io/wcm/wcm/core/components/impl/models/helpers/LinkListItemV2ImplTest.java @@ -35,7 +35,7 @@ import io.wcm.sling.commons.adapter.AdaptTo; import io.wcm.testing.mock.aem.junit5.AemContext; import io.wcm.testing.mock.aem.junit5.AemContextExtension; -import io.wcm.wcm.core.components.impl.link.LinkWrapper; +import io.wcm.wcm.core.components.commons.link.LinkWrapper; import io.wcm.wcm.core.components.testcontext.AppAemContext; @ExtendWith(AemContextExtension.class) diff --git a/changes.xml b/changes.xml index 281213f..4e54840 100644 --- a/changes.xml +++ b/changes.xml @@ -30,6 +30,9 @@ Update to AEM WCM Core Components 2.23.2. + + Export LinkWrapper and LinkHtmlAttributesSerializer via OSGi to make them reusable in project code. + ComponentFeatureImageResolver: Switch to image from page by default if no image reference is given in image/teaser resource. From a82d3fe51ef65e416e2d2edfb2c87d719c1e79b9 Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Fri, 8 Sep 2023 16:13:22 +0200 Subject: [PATCH 11/12] prepare release --- changes.xml | 2 +- examples/content-packages/examples-libs/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/changes.xml b/changes.xml index 4e54840..c6cb227 100644 --- a/changes.xml +++ b/changes.xml @@ -23,7 +23,7 @@ xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/plugins/maven-changes-plugin/xsd/changes-1.0.0.xsd"> - + Add Image (v3). diff --git a/examples/content-packages/examples-libs/pom.xml b/examples/content-packages/examples-libs/pom.xml index de330e5..5e9cf4c 100644 --- a/examples/content-packages/examples-libs/pom.xml +++ b/examples/content-packages/examples-libs/pom.xml @@ -173,7 +173,7 @@ io.wcm io.wcm.handler.media - 1.15.6 + 1.15.8 io.wcm From 8512af25db0b2aa27f714b73c95a878d2107c44d Mon Sep 17 00:00:00 2001 From: Stefan Seifert Date: Fri, 8 Sep 2023 16:17:32 +0200 Subject: [PATCH 12/12] [gitflow-maven-plugin] Update versions for release 1.14.0-2.23.2 --- bundles/core/pom.xml | 4 ++-- examples/bundles/examples-core/pom.xml | 6 +++--- examples/content-packages/examples-libs/pom.xml | 6 +++--- examples/content-packages/examples-sample-content/pom.xml | 4 ++-- examples/content-packages/examples/pom.xml | 6 +++--- examples/pom.xml | 4 ++-- parent/pom.xml | 4 ++-- pom.xml | 4 ++-- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/bundles/core/pom.xml b/bundles/core/pom.xml index 582489b..347f2bc 100644 --- a/bundles/core/pom.xml +++ b/bundles/core/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 ../../parent/pom.xml io.wcm io.wcm.wcm.core.components - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 jar WCM Core Components diff --git a/examples/bundles/examples-core/pom.xml b/examples/bundles/examples-core/pom.xml index 10cfaa9..77211de 100644 --- a/examples/bundles/examples-core/pom.xml +++ b/examples/bundles/examples-core/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-core - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 jar WCM Core Components Examples Core @@ -44,7 +44,7 @@ io.wcm io.wcm.wcm.core.components - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 compile diff --git a/examples/content-packages/examples-libs/pom.xml b/examples/content-packages/examples-libs/pom.xml index 5e9cf4c..33f4521 100644 --- a/examples/content-packages/examples-libs/pom.xml +++ b/examples/content-packages/examples-libs/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-libs - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 content-package WCM Core Components Examples wcm.io Libraries @@ -42,7 +42,7 @@ io.wcm io.wcm.wcm.core.components - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 compile diff --git a/examples/content-packages/examples-sample-content/pom.xml b/examples/content-packages/examples-sample-content/pom.xml index 6968846..466e5e3 100644 --- a/examples/content-packages/examples-sample-content/pom.xml +++ b/examples/content-packages/examples-sample-content/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples-sample-content - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 content-package WCM Core Components Examples Content diff --git a/examples/content-packages/examples/pom.xml b/examples/content-packages/examples/pom.xml index a73590f..09e3026 100644 --- a/examples/content-packages/examples/pom.xml +++ b/examples/content-packages/examples/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 ../../../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 content-package WCM Core Components Examples @@ -42,7 +42,7 @@ io.wcm.samples io.wcm.wcm.core.components.examples-core - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 compile diff --git a/examples/pom.xml b/examples/pom.xml index d21b4a3..e3036b3 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 ../parent/pom.xml io.wcm.samples io.wcm.wcm.core.components.examples.root - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 pom diff --git a/parent/pom.xml b/parent/pom.xml index 73b5e87..24543a4 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -31,7 +31,7 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 pom WCM Core Components @@ -54,7 +54,7 @@ http://localhost:4503 - 2023-09-04T13:32:18Z + 2023-09-08T14:17:30Z diff --git a/pom.xml b/pom.xml index 72e7a59..5aa565d 100644 --- a/pom.xml +++ b/pom.xml @@ -25,13 +25,13 @@ io.wcm io.wcm.wcm.core.components.parent - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 parent/pom.xml io.wcm io.wcm.wcm.core.components.root - 1.14.0-2.23.2-SNAPSHOT + 1.14.0-2.23.2 pom ${site.url}/${site.url.module.prefix}/