diff --git a/bundles/core/src/main/java/com/adobe/cq/email/core/components/config/StylesInlinerContextAwareConfiguration.java b/bundles/core/src/main/java/com/adobe/cq/email/core/components/config/StylesInlinerContextAwareConfiguration.java deleted file mode 100644 index d5c5ae22..00000000 --- a/bundles/core/src/main/java/com/adobe/cq/email/core/components/config/StylesInlinerContextAwareConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ~ Copyright 2022 Adobe - ~ - ~ 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. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ -package com.adobe.cq.email.core.components.config; - -import org.apache.sling.caconfig.annotation.Configuration; -import org.apache.sling.caconfig.annotation.Property; - -@Configuration(label = "Styles inliner configuration", - description = "Context-aware configuration for style inliner service") -public @interface StylesInlinerContextAwareConfiguration { - - @Property(label = "Style merger mode", description = "HTML sanitizing mode.", property = { - "widgetType=dropdown", - "dropdownOptions=[" - + "{'value':'PROCESS_SPECIFICITY','description':'Evaluate specificity'}," - + "{'value':'IGNORE_SPECIFICITY','description':'Ignore specificity'}," - + "{'value':'ALWAYS_APPEND','description':'Always append'}" - + "]" - }) - String stylesMergingMode() default "PROCESS_SPECIFICITY"; - - @Property(label = "Sanitizing", description = "HTML sanitizing mode.", property = { - "widgetType=dropdown", - "dropdownOptions=[" - + "{'value':'FULL','description':'Full sanitizing'}," - + "{'value':'REMOVE_SCRIPT_TAGS_ONLY','description':'Remove script tags only'}," - + "{'value':'NONE','description':'Do not remove anything.'}" - + "]" - }) - String htmlSanitizingMode() default "FULL"; - -} diff --git a/bundles/core/src/main/java/com/adobe/cq/email/core/components/config/package-info.java b/bundles/core/src/main/java/com/adobe/cq/email/core/components/config/package-info.java deleted file mode 100644 index e6863e80..00000000 --- a/bundles/core/src/main/java/com/adobe/cq/email/core/components/config/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ~ Copyright 2022 Adobe - ~ - ~ 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. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ -/** - *

- * This package defines utility classes exposed by the Adobe Experience Manager Core Email Components Bundle. - *

- */ -@Version("1.4.0") -package com.adobe.cq.email.core.components.config; - -import org.osgi.annotation.versioning.Version; \ No newline at end of file diff --git a/bundles/core/src/main/java/com/adobe/cq/email/core/components/filters/StylesInlinerFilter.java b/bundles/core/src/main/java/com/adobe/cq/email/core/components/filters/StylesInlinerFilter.java index 9d2355b4..9e8ce15a 100644 --- a/bundles/core/src/main/java/com/adobe/cq/email/core/components/filters/StylesInlinerFilter.java +++ b/bundles/core/src/main/java/com/adobe/cq/email/core/components/filters/StylesInlinerFilter.java @@ -18,7 +18,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintWriter; -import java.lang.annotation.Annotation; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; @@ -35,14 +34,13 @@ import org.apache.jackrabbit.JcrConstants; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; -import org.apache.sling.caconfig.ConfigurationBuilder; +import org.apache.sling.api.resource.ValueMap; import org.apache.sling.engine.SlingRequestProcessor; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.adobe.cq.email.core.components.config.StylesInlinerContextAwareConfiguration; import com.adobe.cq.email.core.components.enumerations.HtmlSanitizingMode; import com.adobe.cq.email.core.components.enumerations.StyleMergerMode; import com.adobe.cq.email.core.components.internal.css.CssInliner; @@ -62,6 +60,8 @@ public class StylesInlinerFilter implements Filter { private static final Logger LOG = LoggerFactory.getLogger(CssInliner.class); static final String RESOURCE_TYPE = "core/email/components/page"; static final String PROCESSED_ATTRIBUTE = "styles_filter_processed"; + static final String STYLE_MERGER_MODE_PROPERTY = "styleMergerMode"; + static final String HTML_SANITIZING_MODE_PROPERTY = "htmlSanitizingMode"; @Reference private transient RequestResponseFactory requestResponseFactory; @@ -101,11 +101,10 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo HttpServletResponse response = requestResponseFactory.createResponse(out); response.setCharacterEncoding(StandardCharsets.UTF_8.name()); requestProcessor.processRequest(req, response, request.getResourceResolver()); - StylesInlinerContextAwareConfiguration configuration = getConfiguration(resource); + StyleInlinerConfig config = getConfig(contentResource); String htmlWithInlineStyles = stylesInlinerService.getHtmlWithInlineStyles(request.getResourceResolver(), out.toString(StandardCharsets.UTF_8.name()), - StyleMergerMode.getByValue(configuration.stylesMergingMode()), - HtmlSanitizingMode.getByValue(configuration.htmlSanitizingMode())); + config.getStyleMergerMode(), config.getHtmlSanitizingMode()); servletResponse.setContentType("text/html"); servletResponse.setCharacterEncoding(StandardCharsets.UTF_8.name()); PrintWriter pw = servletResponse.getWriter(); @@ -144,33 +143,36 @@ private boolean hasBeenProcessed(SlingHttpServletRequest request) { } } - private StylesInlinerContextAwareConfiguration getConfiguration(Resource resource) { - StylesInlinerContextAwareConfiguration fallback = new StylesInlinerContextAwareConfiguration() { - @Override - public Class annotationType() { - return StylesInlinerContextAwareConfiguration.class; - } - - @Override - public String stylesMergingMode() { - return null; - } - - @Override - public String htmlSanitizingMode() { - return null; - } - }; + private StyleInlinerConfig getConfig(Resource contentResource) { + StyleInlinerConfig fallback = new StyleInlinerConfig(StyleMergerMode.PROCESS_SPECIFICITY, HtmlSanitizingMode.FULL); try { - ConfigurationBuilder configurationBuilder = resource.adaptTo(ConfigurationBuilder.class); - if (Objects.isNull(configurationBuilder)) { - return fallback; - } - return configurationBuilder.as(StylesInlinerContextAwareConfiguration.class); + ValueMap valueMap = contentResource.getValueMap(); + String styleMergerMode = valueMap.get(STYLE_MERGER_MODE_PROPERTY, String.class); + String htmlSanitizingMode = valueMap.get(HTML_SANITIZING_MODE_PROPERTY, String.class); + return new StyleInlinerConfig(StyleMergerMode.getByValue(styleMergerMode), HtmlSanitizingMode.getByValue(htmlSanitizingMode)); } catch (Throwable e) { - LOG.warn("Error retrieving configuration: " + e.getMessage(), e); + LOG.warn("Error retrieving Style Inliner config: " + e.getMessage(), e); } return fallback; } + private static class StyleInlinerConfig { + private final StyleMergerMode styleMergerMode; + private final HtmlSanitizingMode htmlSanitizingMode; + + public StyleInlinerConfig(StyleMergerMode styleMergerMode, + HtmlSanitizingMode htmlSanitizingMode) { + this.styleMergerMode = styleMergerMode; + this.htmlSanitizingMode = htmlSanitizingMode; + } + + public StyleMergerMode getStyleMergerMode() { + return styleMergerMode; + } + + public HtmlSanitizingMode getHtmlSanitizingMode() { + return htmlSanitizingMode; + } + } + } diff --git a/bundles/core/src/test/java/com/adobe/cq/email/core/components/filters/StylesInlinerFilterTest.java b/bundles/core/src/test/java/com/adobe/cq/email/core/components/filters/StylesInlinerFilterTest.java index e3088c7a..102a2480 100644 --- a/bundles/core/src/test/java/com/adobe/cq/email/core/components/filters/StylesInlinerFilterTest.java +++ b/bundles/core/src/test/java/com/adobe/cq/email/core/components/filters/StylesInlinerFilterTest.java @@ -18,8 +18,6 @@ import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; -import java.lang.annotation.Annotation; -import java.util.Objects; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -31,7 +29,7 @@ import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; -import org.apache.sling.caconfig.ConfigurationBuilder; +import org.apache.sling.api.resource.ValueMap; import org.apache.sling.engine.SlingRequestProcessor; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -41,7 +39,6 @@ import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; -import com.adobe.cq.email.core.components.config.StylesInlinerContextAwareConfiguration; import com.adobe.cq.email.core.components.enumerations.HtmlSanitizingMode; import com.adobe.cq.email.core.components.enumerations.StyleMergerMode; import com.adobe.cq.email.core.components.services.StylesInlinerService; @@ -75,9 +72,9 @@ class StylesInlinerFilterTest { @Mock Resource resource; @Mock - Resource jcrContentNode; + Resource contentResource; @Mock - ConfigurationBuilder configurationBuilder; + ValueMap valueMap; @Mock SlingHttpServletRequest request; @Mock @@ -99,8 +96,9 @@ void setUp() throws IOException { ); when(request.getResource()).thenReturn(resource); when(resource.getPath()).thenReturn("TEST_PATH"); - when(resource.getChild(eq(JcrConstants.JCR_CONTENT))).thenReturn(jcrContentNode); - when(jcrContentNode.getResourceType()).thenReturn(StylesInlinerFilter.RESOURCE_TYPE); + when(resource.getChild(eq(JcrConstants.JCR_CONTENT))).thenReturn(contentResource); + when(contentResource.getResourceType()).thenReturn(StylesInlinerFilter.RESOURCE_TYPE); + when(contentResource.getValueMap()).thenReturn(valueMap); HttpServletRequest httpServletRequest = mock(HttpServletRequest.class); when(requestResponseFactory.createRequest(eq("GET"), eq("TEST_PATH.html"), anyMap())).thenReturn(httpServletRequest); doAnswer(i -> { @@ -133,7 +131,8 @@ void noGetRenderedHtmlAttributeInRequest() throws ServletException, IOException @Test void noConfig() throws ServletException, IOException { - when(resource.adaptTo(eq(ConfigurationBuilder.class))).thenReturn(null); + when(valueMap.get(eq(StylesInlinerFilter.STYLE_MERGER_MODE_PROPERTY), eq(String.class))).thenReturn(null); + when(valueMap.get(eq(StylesInlinerFilter.HTML_SANITIZING_MODE_PROPERTY), eq(String.class))).thenReturn(null); sut.doFilter(request, resp, filterChain); verifyZeroInteractions(filterChain); verify(printWriter).write(eq(OUTPUT_PROCESSING_CSS_SPECIFICITY)); @@ -142,7 +141,8 @@ void noConfig() throws ServletException, IOException { @Test @MockitoSettings(strictness = Strictness.LENIENT) void noConfig_GetRenderedHtmlAttributeInRequest() throws ServletException, IOException { - when(resource.adaptTo(eq(ConfigurationBuilder.class))).thenReturn(null); + when(valueMap.get(eq(StylesInlinerFilter.STYLE_MERGER_MODE_PROPERTY), eq(String.class))).thenReturn(null); + when(valueMap.get(eq(StylesInlinerFilter.HTML_SANITIZING_MODE_PROPERTY), eq(String.class))).thenReturn(null); when(request.getAttribute(StylesInlinerFilter.PROCESSED_ATTRIBUTE)).thenReturn(true); sut.doFilter(request, resp, filterChain); verify(filterChain).doFilter(eq(request), eq(resp)); @@ -151,8 +151,9 @@ void noConfig_GetRenderedHtmlAttributeInRequest() throws ServletException, IOExc @Test void noStyleMergerMode() throws ServletException, IOException { - when(resource.adaptTo(eq(ConfigurationBuilder.class))).thenReturn(configurationBuilder); - when(configurationBuilder.as(StylesInlinerContextAwareConfiguration.class)).thenReturn(create(null)); + when(valueMap.get(eq(StylesInlinerFilter.STYLE_MERGER_MODE_PROPERTY), eq(String.class))).thenReturn(null); + when(valueMap.get(eq(StylesInlinerFilter.HTML_SANITIZING_MODE_PROPERTY), eq(String.class))).thenReturn( + HtmlSanitizingMode.FULL.name()); sut.doFilter(request, resp, filterChain); verifyZeroInteractions(filterChain); verify(printWriter).write(eq(OUTPUT_PROCESSING_CSS_SPECIFICITY)); @@ -161,9 +162,10 @@ void noStyleMergerMode() throws ServletException, IOException { @Test @MockitoSettings(strictness = Strictness.LENIENT) void noStyleMergerMode_GetRenderedHtmlAttributeInRequest() throws ServletException, IOException { - when(resource.adaptTo(eq(ConfigurationBuilder.class))).thenReturn(configurationBuilder); + when(valueMap.get(eq(StylesInlinerFilter.STYLE_MERGER_MODE_PROPERTY), eq(String.class))).thenReturn(null); + when(valueMap.get(eq(StylesInlinerFilter.HTML_SANITIZING_MODE_PROPERTY), eq(String.class))).thenReturn( + HtmlSanitizingMode.FULL.name()); when(request.getAttribute(StylesInlinerFilter.PROCESSED_ATTRIBUTE)).thenReturn(true); - when(configurationBuilder.as(StylesInlinerContextAwareConfiguration.class)).thenReturn(create(null)); sut.doFilter(request, resp, filterChain); verify(filterChain).doFilter(eq(request), eq(resp)); verifyZeroInteractions(printWriter); @@ -171,8 +173,10 @@ void noStyleMergerMode_GetRenderedHtmlAttributeInRequest() throws ServletExcepti @Test void processingCssSpecificity() throws Exception { - when(resource.adaptTo(eq(ConfigurationBuilder.class))).thenReturn(configurationBuilder); - when(configurationBuilder.as(StylesInlinerContextAwareConfiguration.class)).thenReturn(create(StyleMergerMode.PROCESS_SPECIFICITY)); + when(valueMap.get(eq(StylesInlinerFilter.STYLE_MERGER_MODE_PROPERTY), eq(String.class))).thenReturn( + StyleMergerMode.PROCESS_SPECIFICITY.name()); + when(valueMap.get(eq(StylesInlinerFilter.HTML_SANITIZING_MODE_PROPERTY), eq(String.class))).thenReturn( + HtmlSanitizingMode.FULL.name()); sut.doFilter(request, resp, filterChain); verifyZeroInteractions(filterChain); verify(printWriter).write(eq(OUTPUT_PROCESSING_CSS_SPECIFICITY)); @@ -181,9 +185,11 @@ void processingCssSpecificity() throws Exception { @Test @MockitoSettings(strictness = Strictness.LENIENT) void processingCssSpecificity_GetRenderedHtmlAttributeInRequest() throws Exception { - when(resource.adaptTo(eq(ConfigurationBuilder.class))).thenReturn(configurationBuilder); + when(valueMap.get(eq(StylesInlinerFilter.STYLE_MERGER_MODE_PROPERTY), eq(String.class))).thenReturn( + StyleMergerMode.PROCESS_SPECIFICITY.name()); + when(valueMap.get(eq(StylesInlinerFilter.HTML_SANITIZING_MODE_PROPERTY), eq(String.class))).thenReturn( + HtmlSanitizingMode.FULL.name()); when(request.getAttribute(StylesInlinerFilter.PROCESSED_ATTRIBUTE)).thenReturn(true); - when(configurationBuilder.as(StylesInlinerContextAwareConfiguration.class)).thenReturn(create(StyleMergerMode.PROCESS_SPECIFICITY)); sut.doFilter(request, resp, filterChain); verify(filterChain).doFilter(eq(request), eq(resp)); verifyZeroInteractions(printWriter); @@ -191,8 +197,10 @@ void processingCssSpecificity_GetRenderedHtmlAttributeInRequest() throws Excepti @Test void ignoringCssSpecificity() throws Exception { - when(resource.adaptTo(eq(ConfigurationBuilder.class))).thenReturn(configurationBuilder); - when(configurationBuilder.as(StylesInlinerContextAwareConfiguration.class)).thenReturn(create(StyleMergerMode.IGNORE_SPECIFICITY)); + when(valueMap.get(eq(StylesInlinerFilter.STYLE_MERGER_MODE_PROPERTY), eq(String.class))).thenReturn( + StyleMergerMode.IGNORE_SPECIFICITY.name()); + when(valueMap.get(eq(StylesInlinerFilter.HTML_SANITIZING_MODE_PROPERTY), eq(String.class))).thenReturn( + HtmlSanitizingMode.FULL.name()); sut.doFilter(request, resp, filterChain); verifyZeroInteractions(filterChain); verify(printWriter).write(eq(OUTPUT_IGNORING_CSS_SPECIFICITY)); @@ -201,9 +209,11 @@ void ignoringCssSpecificity() throws Exception { @Test @MockitoSettings(strictness = Strictness.LENIENT) void ignoringCssSpecificity_GetRenderedHtmlAttributeInRequest() throws Exception { - when(resource.adaptTo(eq(ConfigurationBuilder.class))).thenReturn(configurationBuilder); + when(valueMap.get(eq(StylesInlinerFilter.STYLE_MERGER_MODE_PROPERTY), eq(String.class))).thenReturn( + StyleMergerMode.IGNORE_SPECIFICITY.name()); + when(valueMap.get(eq(StylesInlinerFilter.HTML_SANITIZING_MODE_PROPERTY), eq(String.class))).thenReturn( + HtmlSanitizingMode.FULL.name()); when(request.getAttribute(StylesInlinerFilter.PROCESSED_ATTRIBUTE)).thenReturn(true); - when(configurationBuilder.as(StylesInlinerContextAwareConfiguration.class)).thenReturn(create(StyleMergerMode.IGNORE_SPECIFICITY)); sut.doFilter(request, resp, filterChain); verify(filterChain).doFilter(eq(request), eq(resp)); verifyZeroInteractions(printWriter); @@ -211,8 +221,10 @@ void ignoringCssSpecificity_GetRenderedHtmlAttributeInRequest() throws Exception @Test void alwaysAppendingCssProperties() throws Exception { - when(resource.adaptTo(eq(ConfigurationBuilder.class))).thenReturn(configurationBuilder); - when(configurationBuilder.as(StylesInlinerContextAwareConfiguration.class)).thenReturn(create(StyleMergerMode.ALWAYS_APPEND)); + when(valueMap.get(eq(StylesInlinerFilter.STYLE_MERGER_MODE_PROPERTY), eq(String.class))).thenReturn( + StyleMergerMode.ALWAYS_APPEND.name()); + when(valueMap.get(eq(StylesInlinerFilter.HTML_SANITIZING_MODE_PROPERTY), eq(String.class))).thenReturn( + HtmlSanitizingMode.FULL.name()); sut.doFilter(request, resp, filterChain); verifyZeroInteractions(filterChain); verify(printWriter).write(eq(OUTPUT_ALWAYS_APPENDING_CSS_PROPERTIES)); @@ -221,30 +233,14 @@ void alwaysAppendingCssProperties() throws Exception { @Test @MockitoSettings(strictness = Strictness.LENIENT) void alwaysAppendingCssProperties_GetRenderedHtmlAttributeInRequest() throws Exception { - when(resource.adaptTo(eq(ConfigurationBuilder.class))).thenReturn(configurationBuilder); + when(valueMap.get(eq(StylesInlinerFilter.STYLE_MERGER_MODE_PROPERTY), eq(String.class))).thenReturn( + StyleMergerMode.ALWAYS_APPEND.name()); + when(valueMap.get(eq(StylesInlinerFilter.HTML_SANITIZING_MODE_PROPERTY), eq(String.class))).thenReturn( + HtmlSanitizingMode.FULL.name()); when(request.getAttribute(StylesInlinerFilter.PROCESSED_ATTRIBUTE)).thenReturn(true); - when(configurationBuilder.as(StylesInlinerContextAwareConfiguration.class)).thenReturn(create(StyleMergerMode.ALWAYS_APPEND)); sut.doFilter(request, resp, filterChain); verify(filterChain).doFilter(eq(request), eq(resp)); verifyZeroInteractions(printWriter); } - private StylesInlinerContextAwareConfiguration create(StyleMergerMode mode) { - return new StylesInlinerContextAwareConfiguration() { - @Override - public Class annotationType() { - return StylesInlinerContextAwareConfiguration.class; - } - - @Override - public String stylesMergingMode() { - return Objects.isNull(mode) ? null : mode.name(); - } - - @Override - public String htmlSanitizingMode() { - return HtmlSanitizingMode.FULL.name(); - } - }; - } } diff --git a/content/src/content/jcr_root/apps/core/email/components/page/_cq_dialog/.content.xml b/content/src/content/jcr_root/apps/core/email/components/page/_cq_dialog/.content.xml index 74c3e5f8..61151c61 100644 --- a/content/src/content/jcr_root/apps/core/email/components/page/_cq_dialog/.content.xml +++ b/content/src/content/jcr_root/apps/core/email/components/page/_cq_dialog/.content.xml @@ -15,13 +15,13 @@ ~ limitations under the License. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> + xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" + xmlns:granite="http://www.adobe.com/jcr/granite/1.0" + jcr:primaryType="nt:unstructured" + jcr:title="Page" + sling:resourceType="cq/gui/components/authoring/dialog" + extraClientlibs="[cq.common.wcm,core.wcm.components.page.v3.editor,cq.wcm.msm.properties,granite.contexthub.configuration,cq.siteadmin.admin.properties,core.wcm.components.image.v3.editor,cq.mcm.campaign.touch]" + mode="edit"> - + + + + + + + + + + + + + +