diff --git a/apps/content/core/pom.xml b/apps/content/core/pom.xml
index bcdf08dd..824aef10 100644
--- a/apps/content/core/pom.xml
+++ b/apps/content/core/pom.xml
@@ -94,10 +94,6 @@
javax.servletjavax.servlet-api
-
- org.junit.jupiter
- junit-jupiter
- org.osgiosgi.core
diff --git a/apps/docs/app/jcr_root/apps/dx-docs/configs/config.author/com.adobe.dx.domtagging.internal.IDTaggerImpl.config b/apps/docs/app/jcr_root/apps/dx-docs/configs/config.author/com.adobe.dx.domtagging.internal.IDTaggerImpl.config
new file mode 100644
index 00000000..938f6ad2
--- /dev/null
+++ b/apps/docs/app/jcr_root/apps/dx-docs/configs/config.author/com.adobe.dx.domtagging.internal.IDTaggerImpl.config
@@ -0,0 +1,5 @@
+acceptedTypes=["dx/structure/.*","dx-docs/components/.*"]
+tagOnPublication=B"true"
+tagOnModification=B"true"
+referenceTypes=["cq/experience-fragments/editor/components/experiencefragment"]
+shouldRewriteComponentHash=B"true"
\ No newline at end of file
diff --git a/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.domtagging.internal.IDTagger.config b/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.domtagging.internal.IDTagger.config
deleted file mode 100644
index cdb858dc..00000000
--- a/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.domtagging.internal.IDTagger.config
+++ /dev/null
@@ -1 +0,0 @@
-acceptedTypes=["dx/components/structure/.*","dx-docs/components/.*"]
\ No newline at end of file
diff --git a/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.domtagging.internal.IDTaggerImpl.config b/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.domtagging.internal.IDTaggerImpl.config
new file mode 100644
index 00000000..eaab9b0f
--- /dev/null
+++ b/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.domtagging.internal.IDTaggerImpl.config
@@ -0,0 +1 @@
+acceptedTypes=["dx/structure/.*","dx-docs/components/.*"]
diff --git a/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.inlinestyle.internal.Background.config b/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.inlinestyle.internal.Background.config
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.inlinestyle.internal.Border.config b/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.inlinestyle.internal.Border.config
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.inlinestyle.internal.Color.config b/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.inlinestyle.internal.Color.config
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.inlinestyle.internal.InlineStyleServiceImpl.config b/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.inlinestyle.internal.InlineStyleServiceImpl.config
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.inlinestyle.internal.Shadow.config b/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.inlinestyle.internal.Shadow.config
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.structure.flex.FlexGeneralStyle.config b/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.structure.flex.FlexGeneralStyle.config
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.structure.flex.FlexItemsDefinitions.config b/apps/docs/app/jcr_root/apps/dx-docs/configs/config/com.adobe.dx.structure.flex.FlexItemsDefinitions.config
new file mode 100644
index 00000000..e69de29b
diff --git a/apps/docs/app/pom.xml b/apps/docs/app/pom.xml
index 760c7938..2b3753be 100644
--- a/apps/docs/app/pom.xml
+++ b/apps/docs/app/pom.xml
@@ -140,7 +140,7 @@
com.adobe.dxstructure
- 0.0.6
+ 0.0.7-SNAPSHOTzip
@@ -152,7 +152,7 @@
com.adobe.dxcore
- 0.0.12
+ 0.0.13-SNAPSHOTcom.adobe.dx
diff --git a/apps/docs/content/jcr_root/conf/dx-docs/.content.xml b/apps/docs/content/jcr_root/conf/dx-docs/.content.xml
index 4df3ed84..32f179e9 100755
--- a/apps/docs/content/jcr_root/conf/dx-docs/.content.xml
+++ b/apps/docs/content/jcr_root/conf/dx-docs/.content.xml
@@ -7,4 +7,6 @@
jcr:primaryType="sling:OrderedFolder"
jcr:title="DX">
+ <_cq_styleguide/>
+ <_sling_configs/>
diff --git a/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/.content.xml b/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/.content.xml
new file mode 100644
index 00000000..735f38ab
--- /dev/null
+++ b/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/.content.xml
@@ -0,0 +1,3 @@
+
+
diff --git a/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/com.adobe.dx.admin.rendercondition.RenderConditionConfiguration/.content.xml b/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/com.adobe.dx.admin.rendercondition.RenderConditionConfiguration/.content.xml
new file mode 100644
index 00000000..6678e0f8
--- /dev/null
+++ b/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/com.adobe.dx.admin.rendercondition.RenderConditionConfiguration/.content.xml
@@ -0,0 +1,4 @@
+
+
diff --git a/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/com.adobe.dx.responsive.ResponsiveConfiguration/.content.xml b/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/com.adobe.dx.responsive.ResponsiveConfiguration/.content.xml
new file mode 100644
index 00000000..339cc0f3
--- /dev/null
+++ b/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/com.adobe.dx.responsive.ResponsiveConfiguration/.content.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/com.adobe.dx.styleguide.StyleGuide/.content.xml b/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/com.adobe.dx.styleguide.StyleGuide/.content.xml
new file mode 100644
index 00000000..f67d70d1
--- /dev/null
+++ b/apps/docs/content/jcr_root/conf/dx-docs/_sling_configs/com.adobe.dx.styleguide.StyleGuide/.content.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/docs/content/jcr_root/conf/dx-docs/settings/wcm/template-types/base-page/policies/.content.xml b/apps/docs/content/jcr_root/conf/dx-docs/settings/wcm/template-types/base-page/policies/.content.xml
index 9a8db6ce..ebc00441 100755
--- a/apps/docs/content/jcr_root/conf/dx-docs/settings/wcm/template-types/base-page/policies/.content.xml
+++ b/apps/docs/content/jcr_root/conf/dx-docs/settings/wcm/template-types/base-page/policies/.content.xml
@@ -2,7 +2,7 @@
+ sling:resourceType="dx/structure/components/flex"/>
diff --git a/apps/docs/content/jcr_root/content/dx-docs/us/en/.content.xml b/apps/docs/content/jcr_root/content/dx-docs/us/en/.content.xml
index 4bae8fbc..4a574fa8 100644
--- a/apps/docs/content/jcr_root/content/dx-docs/us/en/.content.xml
+++ b/apps/docs/content/jcr_root/content/dx-docs/us/en/.content.xml
@@ -5,5 +5,65 @@
jcr:primaryType="cq:PageContent"
jcr:title="DX Documentation"
cq:template="/conf/dx-docs/settings/wcm/templates/content-page-template"
- sling:resourceType="dx-docs/components/structure/page"/>
+ sling:resourceType="dx-docs/components/structure/page">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/structure/app/jcr_root/apps/dx/structure/components/flex/.content.xml b/apps/structure/app/jcr_root/apps/dx/structure/components/flex/.content.xml
index a0986c7b..002882e5 100644
--- a/apps/structure/app/jcr_root/apps/dx/structure/components/flex/.content.xml
+++ b/apps/structure/app/jcr_root/apps/dx/structure/components/flex/.content.xml
@@ -2,4 +2,5 @@
\ No newline at end of file
+ jcr:title="Flex"
+ styleWorkers="[background,color,shadow,border,flex-general,flex-definitions]"/>
\ No newline at end of file
diff --git a/apps/structure/app/jcr_root/apps/dx/structure/components/flex/flex.html b/apps/structure/app/jcr_root/apps/dx/structure/components/flex/flex.html
index 5f898e57..765f0ed4 100644
--- a/apps/structure/app/jcr_root/apps/dx/structure/components/flex/flex.html
+++ b/apps/structure/app/jcr_root/apps/dx/structure/components/flex/flex.html
@@ -13,6 +13,12 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/-->
-
${model.hello}
-
-Sup
\ No newline at end of file
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/structure/app/jcr_root/apps/dx/structure/components/parlite/parlite.html b/apps/structure/app/jcr_root/apps/dx/structure/components/parlite/parlite.html
index 39cf5b1d..250abda7 100644
--- a/apps/structure/app/jcr_root/apps/dx/structure/components/parlite/parlite.html
+++ b/apps/structure/app/jcr_root/apps/dx/structure/components/parlite/parlite.html
@@ -1,4 +1,4 @@
-<
-
javax.annotation
javax.annotation-api
-
- org.junit.jupiter
- junit-jupiter
- org.osgiosgi.core
@@ -116,7 +112,17 @@ Bundle-DocURL:
com.adobe.dxtesting
- 0.0.10
+ 0.0.11-SNAPSHOT
+
+
+ com.adobe.dx
+ testing-extensions
+ 0.0.1-SNAPSHOT
+
+
+ com.adobe.dx
+ core
+ 0.0.13-SNAPSHOT
diff --git a/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/FlexGeneralStyle.java b/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/FlexGeneralStyle.java
new file mode 100644
index 00000000..93cfe025
--- /dev/null
+++ b/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/FlexGeneralStyle.java
@@ -0,0 +1,100 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.structure.flex;
+
+import static com.adobe.dx.inlinestyle.Constants.DEL_SPACE;
+import static com.adobe.dx.inlinestyle.Constants.RULE_DELIMITER;
+import static com.adobe.dx.structure.flex.FlexModel.PN_MINHEIGHT;
+import static com.adobe.dx.structure.flex.FlexModel.PN_MINHEIGHT_TYPE;
+
+import com.adobe.dx.inlinestyle.InlineStyleWorker;
+import com.adobe.dx.responsive.Breakpoint;
+import com.adobe.dx.utils.RequestUtil;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+
+/**
+ * Sets up general inline style for items container (min height, and gap)
+ */
+@Component(configurationPolicy = ConfigurationPolicy.REQUIRE)
+public class FlexGeneralStyle implements InlineStyleWorker {
+ private static final String FLEX_GENERAL = "flex-general";
+ private static final String RULE_CONTAINER = "#%s > .dx-flex-items {\n%s\n}";
+ private static final String RULE_ITEM = "#%s > .dx-flex-items > * {\n%s\n}";
+ private static final String PN_GAP = "gap";
+ private static final String MIN_HEIGHT_PREFIX = "min-height: ";
+ private static final String GAP_CONTAINER = "margin: -%spx";
+ private static final String GAP_ITEM_DECLARATION = "border: 0 solid transparent; border-width: %spx";
+
+ @Override
+ public String getKey() {
+ return FLEX_GENERAL;
+ }
+
+ @Override
+ public @Nullable String getDeclaration(@Nullable Breakpoint breakpoint, SlingHttpServletRequest request) {
+ return null;
+ }
+
+ String computeMinHeight(Breakpoint breakpoint, SlingHttpServletRequest request) {
+ Long minHeight = RequestUtil.getFromRespProps(request, breakpoint, PN_MINHEIGHT, Long.class);
+ if ( minHeight != null) {
+ String minHeightType = RequestUtil.getFromRespProps(request, breakpoint, PN_MINHEIGHT_TYPE, String.class);
+ if (minHeightType != null) {
+ return MIN_HEIGHT_PREFIX + minHeight.toString() + minHeightType;
+ }
+ }
+ return null;
+ }
+
+ String computeGapContainer(Long gap) {
+ if (gap != null) {
+ return String.format(GAP_CONTAINER, gap.toString());
+ }
+ return null;
+ }
+
+ @Override
+ public @Nullable String getRule(Breakpoint breakpoint, @Nullable String id,
+ SlingHttpServletRequest request) {
+ List rules = null;
+ String minHeight = computeMinHeight(breakpoint, request);
+ Long gap = RequestUtil.getFromRespProps(request, breakpoint, PN_GAP, Long.class);
+ gap = gap != null ? gap / 2 : null;
+ String gapContainer = computeGapContainer(gap);
+ if (StringUtils.isNotBlank(minHeight) || StringUtils.isNotBlank(gapContainer)) {
+ rules = new ArrayList<>();
+ rules.add(String.format(RULE_CONTAINER, id, Arrays.asList(minHeight, gapContainer).stream()
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.joining(DEL_SPACE))));
+ }
+ if (gap != null) {
+ rules = rules == null ? new ArrayList<>() : rules;
+ rules.add(String.format(RULE_ITEM, id, String.format(GAP_ITEM_DECLARATION, gap.toString())));
+ }
+ return rules != null ? String.join(RULE_DELIMITER, rules) : null;
+ }
+
+}
diff --git a/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/FlexItemsDefinitions.java b/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/FlexItemsDefinitions.java
new file mode 100644
index 00000000..406a6694
--- /dev/null
+++ b/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/FlexItemsDefinitions.java
@@ -0,0 +1,216 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.structure.flex;
+
+import static com.adobe.dx.inlinestyle.Constants.DEL_SPACE;
+import static com.adobe.dx.inlinestyle.Constants.PERCENT;
+import static com.adobe.dx.inlinestyle.Constants.RULE_DELIMITER;
+import static com.adobe.dx.structure.flex.FlexModel.PN_MINHEIGHT;
+import static com.adobe.dx.structure.flex.FlexModel.PN_MINHEIGHT_TYPE;
+import static com.adobe.dx.utils.RequestUtil.getInheritedMap;
+
+import com.adobe.dx.inlinestyle.InlineStyleWorker;
+import com.adobe.dx.responsive.Breakpoint;
+import com.day.cq.wcm.api.policies.ContentPolicy;
+import com.day.cq.wcm.api.policies.ContentPolicyManager;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+
+/**
+ * Sets up style for each item of the flex container
+ */
+@Component(configurationPolicy = ConfigurationPolicy.REQUIRE)
+public class FlexItemsDefinitions implements InlineStyleWorker {
+ private static final String FLEX_DEFINITIONS = "flex-definitions";
+
+ private static final String NN_DEFINITIONS = "definitions";
+ private static final String PN_WIDTH = "width";
+ private static final String PN_WIDTH_CUSTOMVALUE = PN_WIDTH + "CustomValue";
+ private static final String PN_WIDTH_CUSTOMTYPE = PN_WIDTH + "CustomType";
+ private static final String PN_MINHEIGHT_VALUE = PN_MINHEIGHT + "Value";
+ private static final String PN_ORDER = "order";
+ private static final String PN_JUSTIFICATION = "justification";
+ private static final String PV_AUTO = "auto";
+ private static final String PV_CUSTOM = "custom";
+ private static final String PV_JUSTIFY_STRETCH = "JustifyStretch";
+
+ private static final String CSS_WIDTH = "width: ";
+ private static final String CSS_ORDER = "order: ";
+ private static final String CSS_STRETCH_AUTO_WIDTH = "flex: 1 1 1%; max-width: 100%";
+ private static final String CSS_AUTO_WIDTH = "flex: 0 0 auto; max-width: 100%; width: auto";
+ private static final String CSS_MIN_HEIGHT = "min-height: ";
+ private static final String CSS_AUTO = "auto";
+
+ private static final String FORMAT_WIDTH = CSS_WIDTH + "%s; max-width: %s";
+ private static final String FORMAT_COLUMNWIDTH = FORMAT_WIDTH + "; flex: 1 1 auto";
+ private static final String FORMAT_RULE_DEFINITIONS = "#%s > .dx-flex-items > *:nth-child(%s) {\n%s\n}";
+
+ @Override
+ public String getKey() {
+ return FLEX_DEFINITIONS;
+ }
+
+ @Override
+ public @Nullable String getDeclaration(@Nullable Breakpoint breakpoint, SlingHttpServletRequest request) {
+ return null;
+ }
+
+ @Override
+ public @Nullable String getRule(Breakpoint breakpoint, @Nullable String id,
+ SlingHttpServletRequest request) {
+ Resource parent = getParent(breakpoint, request);
+ if (parent != null) {
+ List definitions = null;
+ int declarationIndex = 1;
+ for (Iterator children = parent.listChildren(); children.hasNext();) {
+ String declaration = getDefinitionDeclaration(breakpoint, request, children.next());
+ if (StringUtils.isNotBlank(declaration)) {
+ if (definitions == null) {
+ definitions = new ArrayList<>();
+ }
+ definitions.add(String.format(FORMAT_RULE_DEFINITIONS, id, declarationIndex++, declaration));
+ }
+ }
+ if (definitions != null) {
+ return String.join(RULE_DELIMITER, definitions);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * looks for a definition parent for the given breakpoint
+ * @param breakpoint
+ * @param request
+ * @return
+ */
+ private Resource getParent(Breakpoint breakpoint, SlingHttpServletRequest request) {
+ String resourceName = NN_DEFINITIONS + breakpoint.propertySuffix();
+ Resource parent = request.getResource().getChild(resourceName);
+ if (parent != null) {
+ return parent;
+ }
+ ResourceResolver resolver = request.getResourceResolver();
+ ContentPolicyManager policyManager = resolver.adaptTo(ContentPolicyManager.class);
+ if (policyManager != null) {
+ ContentPolicy contentPolicy = policyManager.getPolicy(request.getResource());
+ if (contentPolicy != null) {
+ String path = contentPolicy.getPath();
+ return resolver.getResource(path + "/" + resourceName);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Computes definition String
+ * @param breakpoint
+ * @param request
+ * @param resource
+ * @return
+ */
+ private String getDefinitionDeclaration(Breakpoint breakpoint, SlingHttpServletRequest request, Resource resource) {
+ String declaration = Arrays.asList(buildWidth(breakpoint, request, resource.getValueMap()),
+ buildCustomMinHeight(resource.getValueMap()),
+ buildOrder(resource.getValueMap()))
+ .stream().filter(StringUtils::isNotBlank).collect(Collectors.joining(DEL_SPACE));
+ if (StringUtils.isNotBlank(declaration)) {
+ return declaration;
+ }
+ return null;
+ }
+
+ private String buildWidth(Breakpoint breakpoint, SlingHttpServletRequest request, ValueMap properties) {
+ String width = properties.get(PN_WIDTH, String.class);
+ // Check for custom width
+ String widthValue = buildCustomWidth(properties, width);
+
+ // Check for auto width
+ if (StringUtils.equals(width, "auto")) {
+ String justification = getInheritedMap(request).getInheritedValue(PN_JUSTIFICATION, breakpoint, PV_JUSTIFY_STRETCH);
+ if (StringUtils.equals(justification, PV_JUSTIFY_STRETCH)) {
+ widthValue = CSS_STRETCH_AUTO_WIDTH;
+ } else {
+ widthValue = CSS_AUTO_WIDTH;
+ }
+ }
+
+ // Attempt Column Width
+ if (StringUtils.isBlank(widthValue)) {
+ widthValue = buildColumnWidth(width);
+ }
+ return widthValue;
+ }
+
+ private String buildCustomWidth(ValueMap properties, String width) {
+ if (StringUtils.equals(width, "custom")) {
+ long value = properties.get(PN_WIDTH_CUSTOMVALUE, 0L);
+ String type = properties.get(PN_WIDTH_CUSTOMTYPE, String.class);
+ if (value > 0 && StringUtils.isNotEmpty(type)) {
+ String widthString = value + type;
+ return String.format(FORMAT_WIDTH , widthString, widthString);
+ }
+ }
+ return StringUtils.EMPTY;
+ }
+
+
+ private String buildColumnWidth(String width) {
+ if (StringUtils.contains(width, PERCENT)) {
+ return String.format(FORMAT_COLUMNWIDTH, width, width);
+ }
+ return StringUtils.EMPTY;
+ }
+
+ private String buildCustomMinHeight(ValueMap properties) {
+ String minHeight = properties.get(PN_MINHEIGHT, String.class);
+ if (StringUtils.equals(minHeight, PV_CUSTOM)) {
+ long value = properties.get(PN_MINHEIGHT_VALUE, 0L);
+ String type = properties.get(PN_MINHEIGHT_TYPE, String.class);
+ /*if (wcmModeEnabled) {
+ authorItemVh = StringUtils.equals("vh", type) ? Long.toString(value) : "0";
+ }*/
+ if (value > 0 && StringUtils.isNotEmpty(type)) {
+ return CSS_MIN_HEIGHT + value + type;
+ }
+ } else if (PV_AUTO.equals(minHeight)) {
+ return CSS_MIN_HEIGHT + CSS_AUTO;
+ }
+ return StringUtils.EMPTY;
+ }
+
+ private String buildOrder(ValueMap properties) {
+ Long order = properties.get(PN_ORDER, Long.class);
+ if (order != null) {
+ return CSS_ORDER + order;
+ }
+ return StringUtils.EMPTY;
+ }
+
+}
diff --git a/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/FlexModel.java b/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/FlexModel.java
index d6c199a3..2b876764 100644
--- a/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/FlexModel.java
+++ b/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/FlexModel.java
@@ -13,24 +13,54 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
package com.adobe.dx.structure.flex;
+import com.adobe.dx.domtagging.IDTagger;
+import com.adobe.dx.inlinestyle.InlineStyleService;
+
+import javax.annotation.PostConstruct;
+
import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.annotations.injectorspecific.OSGiService;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
-@Model(adaptables = { SlingHttpServletRequest.class,
- Resource.class }, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
+@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class FlexModel {
+ public static final String PN_MINHEIGHT = "minHeight";
+ public static final String PN_MINHEIGHT_TYPE = PN_MINHEIGHT + "Type";
+ private static final String ID_PREFIX = "flex-";
+
@SlingObject
- protected Resource resource;
+ protected SlingHttpServletRequest request;
+
+ @OSGiService
+ IDTagger idTagger;
+
+ @OSGiService
+ InlineStyleService styleService;
- public String getHello() {
- return "Hello";
+ String id;
+
+ String style;
+
+ @PostConstruct
+ void init() {
+ if (idTagger != null) {
+ id = ID_PREFIX + idTagger.computeComponentId(request, null);
+ }
+ if (styleService != null) {
+ style = styleService.getInlineStyle(getId(), request);
+ }
}
+ public String getId() {
+ return id;
+ }
+
+ public String getStyle() {
+ return style;
+ }
}
diff --git a/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/package-info.java b/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/package-info.java
index 1883a919..1814befa 100644
--- a/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/package-info.java
+++ b/apps/structure/core/src/main/java/com/adobe/dx/structure/flex/package-info.java
@@ -13,7 +13,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- @Version("0.0.1")
+ @Version("0.0.2")
package com.adobe.dx.structure.flex;
import org.osgi.annotation.versioning.Version;
\ No newline at end of file
diff --git a/apps/structure/core/src/main/java/com/adobe/dx/structure/utils/BackgroundGradient.java b/apps/structure/core/src/main/java/com/adobe/dx/structure/utils/BackgroundGradient.java
index 2965fef2..7789c2e5 100644
--- a/apps/structure/core/src/main/java/com/adobe/dx/structure/utils/BackgroundGradient.java
+++ b/apps/structure/core/src/main/java/com/adobe/dx/structure/utils/BackgroundGradient.java
@@ -25,7 +25,7 @@
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
-@Model(adaptables = { SlingHttpServletRequest.class, Resource.class }, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
+@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class BackgroundGradient {
private static final String CQ_STYLEGUIDE_BUCKETNAME = "cq:styleguide";
diff --git a/apps/structure/core/src/test/java/com/adobe/dx/structure/flex/FlexGeneralStyleTest.java b/apps/structure/core/src/test/java/com/adobe/dx/structure/flex/FlexGeneralStyleTest.java
new file mode 100644
index 00000000..dc66af0a
--- /dev/null
+++ b/apps/structure/core/src/test/java/com/adobe/dx/structure/flex/FlexGeneralStyleTest.java
@@ -0,0 +1,46 @@
+package com.adobe.dx.structure.flex;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.adobe.dx.inlinestyle.InlineStyleWorker;
+import com.adobe.dx.testing.AbstractInlineStyleWorkerTest;
+
+import org.junit.jupiter.api.Test;
+
+class FlexGeneralStyleTest extends AbstractInlineStyleWorkerTest {
+
+ @Test
+ public void testRule() {
+ context.build().resource(CONTENT_ROOT, "minHeightMobile",
+ 20L, "minHeightTypeMobile", "px",
+ "gapMobile", 30L);
+ assertEquals("#this-is-my-flex > .dx-flex-items {\n"
+ + "min-height: 20px; margin: -15px\n"
+ + "}\n"
+ + "#this-is-my-flex > .dx-flex-items > * {\n"
+ + "border: 0 solid transparent; border-width: 15px\n"
+ + "}", getRule("mobile", "this-is-my-flex"));
+ }
+
+ @Test
+ public void testRuleNoGap() {
+ context.build().resource(CONTENT_ROOT, "minHeightMobile",
+ 30L, "minHeightTypeMobile", "%");
+ assertEquals("#this-is-my-flex > .dx-flex-items {\n"
+ + "min-height: 30%\n"
+ + "}", getRule("mobile", "this-is-my-flex"));
+ }
+
+ @Test
+ public void testNothing() {
+ context.build().resource(CONTENT_ROOT, "minHeightMobile",
+ 20L, "minHeightTypeMobile", "px",
+ "gapMobile", 30L);
+ assertNull(getRule("tablet", "this-is-my-flex"));
+ }
+
+ @Override
+ protected InlineStyleWorker getWorker() {
+ return new FlexGeneralStyle();
+ }
+}
\ No newline at end of file
diff --git a/apps/structure/core/src/test/java/com/adobe/dx/structure/flex/FlexItemsDefinitionsTest.java b/apps/structure/core/src/test/java/com/adobe/dx/structure/flex/FlexItemsDefinitionsTest.java
new file mode 100644
index 00000000..f5b91df5
--- /dev/null
+++ b/apps/structure/core/src/test/java/com/adobe/dx/structure/flex/FlexItemsDefinitionsTest.java
@@ -0,0 +1,78 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.structure.flex;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.adobe.dx.inlinestyle.InlineStyleWorker;
+import com.adobe.dx.testing.AbstractInlineStyleWorkerTest;
+
+import org.junit.jupiter.api.Test;
+
+class FlexItemsDefinitionsTest extends AbstractInlineStyleWorkerTest {
+
+ @Override
+ protected InlineStyleWorker getWorker() {
+ return new FlexItemsDefinitions();
+ }
+
+ @Test
+ public void lockKey() {
+ assertEquals("flex-definitions", getWorker().getKey());
+ }
+
+ @Test
+ protected void getDefinition() {
+ assertNull(getDeclaration("mobile"));
+ }
+
+ @Test
+ protected void getRule(){
+ context.build().resource(CONTENT_ROOT, "justificationMobile", "someJustification", "sling:resourceType", "dx/components/structure/flex");
+ context.build().resource(CONTENT_ROOT +"/definitionsMobile")
+ .siblingsMode()
+ .resource("item0", "minHeight", "auto", "minHeightType", "px", "width", "custom",
+ "widthCustomValue", 200L, "widthCustomType", "px")
+ .resource("item1", "minHeight", "custom", "minHeightValue", 92L, "minHeightType", "px", "width", "auto")
+ .resource("item2", "minHeight", "auto", "minHeightType", "px", "width", "100%");
+ context.contentPolicyMapping("dx/components/structure/flex","definitionsTablet/item0/minHeight", "auto");
+ context.build().resource(CONTENT_ROOT +"/definitionsDesktop")
+ .siblingsMode()
+ .resource("item0", "minHeight", "auto", "minHeightType", "px", "width", "auto", "widthCustomType", "px", "order", 1L)
+ .resource("item1", "minHeight", "auto", "minHeightType", "px", "width", "33.33%", "widthCustomType", "px")
+ .resource("item2", "minHeight", "auto", "minHeightType", "px", "width", "33.33%", "widthCustomType", "px");
+ context.currentResource(CONTENT_ROOT);
+ assertNull(getRule("tablet", "a-flex"));
+ assertEquals("#a-flex > .dx-flex-items > *:nth-child(1) {\n"
+ + "width: 200px; max-width: 200px; min-height: auto\n"
+ + "}\n"
+ + "#a-flex > .dx-flex-items > *:nth-child(2) {\n"
+ + "flex: 0 0 auto; max-width: 100%; width: auto; min-height: 92px\n"
+ + "}\n"
+ + "#a-flex > .dx-flex-items > *:nth-child(3) {\n"
+ + "width: 100%; max-width: 100%; flex: 1 1 auto; min-height: auto\n"
+ + "}", getRule("mobile","a-flex"));
+ assertEquals("#a-flex > .dx-flex-items > *:nth-child(1) {\n"
+ + "flex: 1 1 1%; max-width: 100%; min-height: auto; order: 1\n"
+ + "}\n"
+ + "#a-flex > .dx-flex-items > *:nth-child(2) {\n"
+ + "width: 33.33%; max-width: 33.33%; flex: 1 1 auto; min-height: auto\n"
+ + "}\n"
+ + "#a-flex > .dx-flex-items > *:nth-child(3) {\n"
+ + "width: 33.33%; max-width: 33.33%; flex: 1 1 auto; min-height: auto\n"
+ + "}", getRule("desktop","a-flex"));
+ }
+}
\ No newline at end of file
diff --git a/apps/structure/core/src/test/java/com/adobe/dx/structure/flex/FlexModelTest.java b/apps/structure/core/src/test/java/com/adobe/dx/structure/flex/FlexModelTest.java
index 76688e2a..e1716fea 100644
--- a/apps/structure/core/src/test/java/com/adobe/dx/structure/flex/FlexModelTest.java
+++ b/apps/structure/core/src/test/java/com/adobe/dx/structure/flex/FlexModelTest.java
@@ -16,15 +16,28 @@
package com.adobe.dx.structure.flex;
import static org.junit.jupiter.api.Assertions.*;
-
import com.adobe.dx.testing.AbstractRequestModelTest;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class FlexModelTest extends AbstractRequestModelTest {
+ FlexModel model;
+
+ @BeforeEach
+ public void setup() {
+ model = getModel(FlexModel.class, CONTENT_ROOT);
+ }
+
@Test
- void getHello() throws ReflectiveOperationException {
- assertEquals("Hello", getModel(FlexModel.class).getHello());
+ public void testId() {
+ assertNotNull(model.getId());
}
+
+ @Test
+ public void testStyle() {
+ assertNotNull(model.getStyle());
+ }
+
}
\ No newline at end of file
diff --git a/apps/structure/core/src/test/java/com/adobe/dx/structure/utils/BackgroundGradientTest.java b/apps/structure/core/src/test/java/com/adobe/dx/structure/utils/BackgroundGradientTest.java
index fb867a4c..e7a4cb63 100644
--- a/apps/structure/core/src/test/java/com/adobe/dx/structure/utils/BackgroundGradientTest.java
+++ b/apps/structure/core/src/test/java/com/adobe/dx/structure/utils/BackgroundGradientTest.java
@@ -18,11 +18,13 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import com.adobe.dx.testing.AbstractRequestModelTest;
+import com.adobe.dx.testing.AbstractTest;
+import org.apache.sling.models.factory.ModelFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-public class BackgroundGradientTest extends AbstractRequestModelTest {
+public class BackgroundGradientTest extends AbstractTest {
private BackgroundGradient backgroundGradient;
@@ -32,7 +34,9 @@ private void setup() throws ReflectiveOperationException {
context.load().json("/mocks/gradients/gradients-app.json", "/apps");
context.addModelsForClasses(BackgroundGradient.class);
- backgroundGradient = getModel(BackgroundGradient.class, "/apps/component/style");
+ context.addModelsForClasses(BackgroundGradient.class);
+ context.currentResource("/apps/component/style");
+ backgroundGradient = context.getService(ModelFactory.class).createModel(context.request(), BackgroundGradient.class);
}
@Test
diff --git a/bundles/core/pom.xml b/bundles/core/pom.xml
index 9563e291..bed7fc74 100644
--- a/bundles/core/pom.xml
+++ b/bundles/core/pom.xml
@@ -116,6 +116,12 @@ Bundle-DocURL:
org.jetbrainsannotations
+
+ org.apache.sling
+ org.apache.sling.api
+ 2.18.4
+ test
+ com.adobe.dxtesting
diff --git a/bundles/core/src/main/java/com/adobe/dx/bindings/internal/DxBindingsValueProvider.java b/bundles/core/src/main/java/com/adobe/dx/bindings/internal/DxBindingsValueProvider.java
index 6ace9341..eb52ae68 100644
--- a/bundles/core/src/main/java/com/adobe/dx/bindings/internal/DxBindingsValueProvider.java
+++ b/bundles/core/src/main/java/com/adobe/dx/bindings/internal/DxBindingsValueProvider.java
@@ -17,10 +17,14 @@
import static com.day.cq.wcm.scripting.WCMBindingsConstants.NAME_CURRENT_CONTENT_POLICY;
+import com.adobe.dx.responsive.Breakpoint;
import com.adobe.dx.responsive.ResponsiveConfiguration;
-import com.adobe.dx.responsive.internal.ResponsiveProperties;
+import com.adobe.dx.responsive.internal.ResponsivePropertiesImpl;
import com.day.cq.wcm.api.policies.ContentPolicy;
+import java.util.Arrays;
+import java.util.List;
+
import javax.script.Bindings;
import org.apache.sling.api.resource.Resource;
@@ -33,7 +37,6 @@
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
-import org.osgi.service.component.annotations.Reference;
@Component(service = BindingsValuesProvider.class,
property = {
@@ -48,9 +51,11 @@
*/
public class DxBindingsValueProvider implements BindingsValuesProvider {
- private static final String POLICY_KEY = "dxPolicy";
+ public static final String POLICY_KEY = "dxPolicy";
+
+ public static final String RESP_PROPS_KEY = "resprops";
- private static final String RESP_PROPS_KEY = "respProperties";
+ public static final String BP_KEY = "breakpoints";
@Override
public void addBindings(@NotNull Bindings bindings) {
@@ -66,7 +71,9 @@ public void addBindings(@NotNull Bindings bindings) {
ResponsiveConfiguration configuration = resource
.adaptTo(ConfigurationBuilder.class)
.as(ResponsiveConfiguration.class);
- bindings.put(RESP_PROPS_KEY, new ResponsiveProperties(configuration, dxPolicy));
+ List breakpointList = Arrays.asList(configuration.breakpoints());
+ bindings.put(BP_KEY, breakpointList);
+ bindings.put(RESP_PROPS_KEY, new ResponsivePropertiesImpl(breakpointList, dxPolicy));
}
}
}
diff --git a/bundles/core/src/main/java/com/adobe/dx/domtagging/internal/IDTaggerImpl.java b/bundles/core/src/main/java/com/adobe/dx/domtagging/internal/IDTaggerImpl.java
index 068b3c34..4f5f86b4 100644
--- a/bundles/core/src/main/java/com/adobe/dx/domtagging/internal/IDTaggerImpl.java
+++ b/bundles/core/src/main/java/com/adobe/dx/domtagging/internal/IDTaggerImpl.java
@@ -308,7 +308,7 @@ public void process(SlingHttpServletRequest request, List list) {
}
boolean isCurrentRequestForRootPage(SlingHttpServletRequest request, String pageId) {
- return pageId.equals(request.getAttribute(ATT_ROOTID));
+ return pageId != null && pageId.equals(request.getAttribute(ATT_ROOTID));
}
/**
@@ -426,7 +426,7 @@ public Resource next() {
+ "for resource types that should be tagged with an id"
)
@SuppressWarnings("squid:S00100")
- String[] acceptedTypes() default { "dx/components/structure/.*" };
+ String[] acceptedTypes() default { "dx/structure/components/.*" };
@AttributeDefinition(
name = "Reference type",
diff --git a/bundles/core/src/main/java/com/adobe/dx/inlinestyle/Constants.java b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/Constants.java
new file mode 100644
index 00000000..4d98cfcc
--- /dev/null
+++ b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/Constants.java
@@ -0,0 +1,30 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.inlinestyle;
+
+public class Constants {
+ private Constants() {
+ }
+ public static final String DECLARATION_DELIMITER = ";";
+ public static final String RULE_DELIMITER = "\n";
+ public static final String DECLARATION = ": ";
+ public static final String SPACE = " ";
+ public static final String PX = "px";
+ public static final String PERCENT = "%";
+ public static final String PX_SPACE = PX + SPACE;
+ public static final String DEL_SPACE = DECLARATION_DELIMITER + SPACE;
+
+}
diff --git a/bundles/core/src/main/java/com/adobe/dx/inlinestyle/InlineStyleService.java b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/InlineStyleService.java
new file mode 100644
index 00000000..4dc32ab5
--- /dev/null
+++ b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/InlineStyleService.java
@@ -0,0 +1,32 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.inlinestyle;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.jetbrains.annotations.Nullable;
+
+public interface InlineStyleService {
+
+ /**
+ * Computes a list of CSS declarations relatives of the given request. If an id is provided,
+ * encapsulate those declarations in that id rule (for nested usage).
+ *
+ * @param id optional ID to encapsulate declarations with
+ * @param request current request
+ * @return declaration set, or local rule
+ */
+ String getInlineStyle(@Nullable String id, SlingHttpServletRequest request);
+}
diff --git a/bundles/core/src/main/java/com/adobe/dx/inlinestyle/InlineStyleWorker.java b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/InlineStyleWorker.java
new file mode 100644
index 00000000..f3caa555
--- /dev/null
+++ b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/InlineStyleWorker.java
@@ -0,0 +1,53 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.inlinestyle;
+
+import com.adobe.dx.responsive.Breakpoint;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Single CSS declaration or rule generator,
+ * for very specific usage in a style tag or attribute,
+ * fed in the component context
+ */
+public interface InlineStyleWorker {
+
+ /**
+ * @return key with which the worker can be identified
+ */
+ String getKey();
+
+ /**
+ * Generates a declaration specific to that generator
+ *
+ * @param breakpoint breakpoint corresponding to that declaration
+ * @param request current request
+ * @return single or several declarations split by ';', or null if not necessary or able to generate some
+ */
+ @Nullable String getDeclaration(Breakpoint breakpoint, SlingHttpServletRequest request);
+
+ /**
+ * Generates a rule specific to that generator
+ *
+ * @param breakpoint if rule is specific to it, null otherwise
+ * @param id rules can reuse in format ${id} current
+ * @param request current request
+ * @return one or several rules
+ */
+ @Nullable String getRule(@Nullable Breakpoint breakpoint, @Nullable String id, SlingHttpServletRequest request);
+}
diff --git a/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Background.java b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Background.java
new file mode 100644
index 00000000..52d9c3e5
--- /dev/null
+++ b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Background.java
@@ -0,0 +1,122 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.inlinestyle.internal;
+
+import static com.adobe.dx.inlinestyle.Constants.DEL_SPACE;
+import static com.adobe.dx.utils.RequestUtil.getFromRespProps;
+
+import com.adobe.dx.responsive.Breakpoint;
+import com.adobe.dx.inlinestyle.InlineStyleWorker;
+import com.adobe.dx.styleguide.StyleGuideUtil;
+import com.day.text.Text;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+
+@Component(configurationPolicy = ConfigurationPolicy.REQUIRE)
+public class Background implements InlineStyleWorker {
+ private static final String KEY = "background";
+ private static final String PN_BACKGROUNDCOLOR = "backgroundColor";
+ private static final String PN_GRADIENT = "gradient";
+ private static final String PN_IMAGE = "fileReference";
+ private static final String PN_FOCUSX = "focusX";
+ private static final String PN_FOCUSY = "focusY";
+ private static final String COLOR_FORMAT = "background-color: %s";
+ private static final String IMAGE_FORMAT = "background-image: %s";
+ private static final String BG_SIZE = "background-size: cover";
+ private static final String POSITION_PREFIX = "background-position: ";
+ private static final String POSITION_UNIT = "% ";
+ private static final String IMAGE_DECLARATION = "url(%s)";
+ private static final String IMG_DECLARATION_DELIMITER = ",";
+
+ @Override
+ public String getKey() {
+ return KEY;
+ }
+
+
+ private String generateColorDeclaration(String bgColor) {
+ if (StringUtils.isNotBlank(bgColor)) {
+ return String.format(COLOR_FORMAT, bgColor);
+ }
+ return null;
+ }
+
+ private String generateImageDeclaration(String gradient, String image) {
+ if (StringUtils.isNotBlank(gradient) || StringUtils.isNotBlank(image)) {
+ String imageDeclaration = null;
+ if (StringUtils.isNotBlank(image)) {
+ imageDeclaration = String.format(IMAGE_DECLARATION, Text.escape(image));
+ }
+ return String.format(IMAGE_FORMAT, Arrays.asList(gradient, imageDeclaration).stream()
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.joining(IMG_DECLARATION_DELIMITER)));
+ }
+ return null;
+ }
+
+ private String generateSize(String image) {
+ if (StringUtils.isNotBlank(image)) {
+ return BG_SIZE;
+ }
+ return null;
+ }
+
+ private String generatePosition(String image, @Nullable Breakpoint breakpoint, SlingHttpServletRequest request) {
+ if (StringUtils.isNotBlank(image)) {
+ Long focusX = getFromRespProps(request, breakpoint, PN_FOCUSX, Long.class);
+ Long focusY = getFromRespProps(request, breakpoint, PN_FOCUSY, Long.class);
+ if (focusX != null && focusY != null) {
+ return POSITION_PREFIX + focusX + POSITION_UNIT + focusY + POSITION_UNIT;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public @Nullable String getDeclaration(@Nullable Breakpoint breakpoint, SlingHttpServletRequest request) {
+ String bgColorKey = getFromRespProps(request, breakpoint, PN_BACKGROUNDCOLOR, String.class);
+ String bgColor = StyleGuideUtil.getColor(request, bgColorKey);
+ String gradientKey = getFromRespProps(request, breakpoint, PN_GRADIENT, String.class);
+ String gradient = StyleGuideUtil.getGradient(request, gradientKey);
+ String image = getFromRespProps(request, breakpoint, PN_IMAGE, String.class);
+ if (bgColor != null || gradient != null || image != null) {
+ List declarations = new ArrayList<>();
+ declarations.add(generateColorDeclaration(bgColor));
+ declarations.add(generateImageDeclaration(gradient, image));
+ declarations.add(generateSize(image));
+ declarations.add(generatePosition(image, breakpoint, request));
+ return declarations.stream()
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.joining(DEL_SPACE));
+ }
+ return null;
+ }
+
+ @Override
+ public @Nullable String getRule(@Nullable Breakpoint breakpoint, @Nullable String id,
+ SlingHttpServletRequest request) {
+ return null;
+ }
+}
diff --git a/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Border.java b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Border.java
new file mode 100644
index 00000000..fc2d85a4
--- /dev/null
+++ b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Border.java
@@ -0,0 +1,177 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.inlinestyle.internal;
+
+import static com.adobe.dx.inlinestyle.Constants.DECLARATION;
+import static com.adobe.dx.inlinestyle.Constants.DEL_SPACE;
+import static com.adobe.dx.inlinestyle.Constants.PX;
+import static com.adobe.dx.inlinestyle.Constants.PX_SPACE;
+import static com.adobe.dx.inlinestyle.Constants.SPACE;
+import static com.adobe.dx.utils.RequestUtil.getPolicy;
+
+import com.adobe.dx.responsive.Breakpoint;
+import com.adobe.dx.inlinestyle.InlineStyleWorker;
+import com.adobe.dx.styleguide.StyleGuideUtil;
+import com.adobe.dx.utils.RequestUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.ValueMap;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+
+@Component(configurationPolicy = ConfigurationPolicy.REQUIRE)
+public class Border implements InlineStyleWorker {
+ private static final String DECL_PREFIX = "border";
+ private static final String KEY = DECL_PREFIX;
+ private static final String PREFIX = KEY;
+ private static final String COLOR_SUFFIX = "Color";
+ private static final String STYLE_SUFFIX = "Style";
+ private static final String WIDTH_SUFFIX = "Width";
+ private static final String RADIUS = "Radius";
+ private static final String TOP = "Top";
+ private static final String RIGHT = "Right";
+ private static final String LEFT = "Left";
+ private static final String BOTTOM = "Bottom";
+ private static final String DECL_RADIUS = "border-radius: ";
+ private static final String DECL_TOP = DECL_PREFIX + "-top";
+ private static final String DECL_BOTTOM = DECL_PREFIX + "-bottom";
+ private static final String DECL_RIGHT = DECL_PREFIX + "-right";
+ private static final String DECL_LEFT = DECL_PREFIX + "-left";
+ private static final String ALL = "all";
+ private static final String EACH = "each";
+ private static final String ALL_CAP = "All";
+ private static final String PN_BORDERRADIUS = PREFIX + RADIUS;
+ private static final String PN_ALLRADIUS = PREFIX + ALL_CAP + RADIUS;
+ private static final String PN_RADIUS_TOPLEFT = PREFIX + RADIUS + TOP + LEFT;
+ private static final String PN_RADIUS_TOPRIGHT = PREFIX + RADIUS + TOP + RIGHT;
+ private static final String PN_RADIUS_BOTTOMLEFT = PREFIX + RADIUS + BOTTOM + LEFT;
+ private static final String PN_RADIUS_BOTTOMRIGHT = PREFIX + RADIUS + BOTTOM + RIGHT;
+ private static final String PN_SIDES = PREFIX + "Sides";
+
+ @Override
+ public String getKey() {
+ return KEY;
+ }
+
+ @Override
+ public @Nullable String getDeclaration(Breakpoint breakpoint, SlingHttpServletRequest request) {
+ if (StringUtils.isBlank(breakpoint.mediaQuery())) {
+ //we only do border for all
+ ValueMap dxPolicy = getPolicy(request);
+ String border = buildBorder(request, dxPolicy);
+ String radius = buildRadius(dxPolicy);
+ if (border != null) {
+ if (radius != null) {
+ return border + DEL_SPACE + radius;
+ } else {
+ return border;
+ }
+ } else if (radius != null) {
+ return radius;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public @Nullable String getRule(@Nullable Breakpoint breakpoint, @Nullable String id,
+ SlingHttpServletRequest request) {
+ return null;
+ }
+
+ private String buildBorder(SlingHttpServletRequest request, ValueMap policy) {
+ String borderSides = policy.get(PN_SIDES, String.class);
+ if (StringUtils.equals(ALL, borderSides)) {
+ return getAllBorders(request, policy);
+ } else if (StringUtils.equals(EACH, borderSides)) {
+ return getEachBorder(request, policy);
+ }
+ return null;
+ }
+
+ private String getAllBorders(SlingHttpServletRequest request, ValueMap policy) {
+ return getBorderStyle(request, policy, ALL_CAP, DECL_PREFIX);
+ }
+
+ private String getEachBorder(SlingHttpServletRequest request, ValueMap policy) {
+ List borders = new ArrayList<>();
+ final String topBorder = getBorderStyle(request, policy, TOP, DECL_TOP);
+ final String rightBorder = getBorderStyle(request, policy, RIGHT, DECL_RIGHT);
+ final String bottomBorder = getBorderStyle(request, policy, BOTTOM, DECL_BOTTOM);
+ final String leftBorder = getBorderStyle(request, policy, LEFT, DECL_LEFT);
+ if (topBorder != null) {
+ borders.add(topBorder);
+ }
+ if (rightBorder != null) {
+ borders.add(rightBorder);
+ }
+ if (bottomBorder != null) {
+ borders.add(bottomBorder);
+ }
+ if (leftBorder != null) {
+ borders.add(leftBorder);
+ }
+ return borders.isEmpty() ? null : String.join(DEL_SPACE, borders);
+ }
+
+ private String getBorderStyle(SlingHttpServletRequest request, ValueMap policy, String side, String propertyName) {
+ String borderStyle = policy.get(PREFIX + side + STYLE_SUFFIX, String.class);
+ long borderThickness = policy.get(PREFIX + side + WIDTH_SUFFIX, 0L);
+ String borderColorKey = policy.get(PREFIX + side + COLOR_SUFFIX, String.class);
+ String borderColor = StyleGuideUtil.getColor(request, borderColorKey);
+ if (borderStyle != null && borderThickness > 0 && borderColor != null) {
+ return propertyName + DECLARATION + borderStyle + SPACE + borderThickness + PX_SPACE + borderColor;
+ }
+ return null;
+ }
+
+ private String buildRadius(ValueMap policy) {
+ String borderRadius = policy.get(PN_BORDERRADIUS, String.class);
+ if (StringUtils.equals(ALL, borderRadius)) {
+ return getAllBorderRadius(policy);
+ } else if (StringUtils.equals(EACH, borderRadius)) {
+ return getEachBorderRadius(policy);
+ }
+ return null;
+ }
+
+ private String getAllBorderRadius(ValueMap policy) {
+ long borderRadius = policy.get(PN_ALLRADIUS, 0L);
+ if (borderRadius > 0) {
+ return DECL_RADIUS + borderRadius + PX;
+ }
+ return null;
+ }
+
+ private String getEachBorderRadius(ValueMap policy) {
+ long radiusTopLeft = policy.get(PN_RADIUS_TOPLEFT, 0L);
+ long radiusTopRight = policy.get(PN_RADIUS_TOPRIGHT, 0L);
+ long radiusBottomRight = policy.get(PN_RADIUS_BOTTOMRIGHT, 0L);
+ long radiusBottomLeft = policy.get(PN_RADIUS_BOTTOMLEFT, 0L);
+
+ if (radiusTopLeft > 0 || radiusTopRight > 0 || radiusBottomLeft > 0 || radiusBottomRight > 0) {
+ return DECL_RADIUS
+ + radiusTopLeft + PX_SPACE + radiusTopRight + PX_SPACE
+ + radiusBottomRight + PX_SPACE + radiusBottomLeft + PX;
+ }
+ return null;
+ }
+}
diff --git a/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Color.java b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Color.java
new file mode 100644
index 00000000..ad8a631a
--- /dev/null
+++ b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Color.java
@@ -0,0 +1,58 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.inlinestyle.internal;
+
+import static com.adobe.dx.utils.RequestUtil.getFromRespProps;
+
+import com.adobe.dx.responsive.Breakpoint;
+import com.adobe.dx.inlinestyle.InlineStyleWorker;
+import com.adobe.dx.styleguide.StyleGuideUtil;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+
+@Component(configurationPolicy = ConfigurationPolicy.REQUIRE)
+public class Color implements InlineStyleWorker {
+ private final static String KEY = "color";
+
+ private final static String PN_COLOR = "foregroundColor";
+ private final static String FORMAT = "color: %s";
+
+ @Override
+ public String getKey() {
+ return KEY;
+ }
+
+ @Override
+ public @Nullable String getDeclaration(@Nullable Breakpoint breakpoint, SlingHttpServletRequest request) {
+ String colorKey = getFromRespProps(request, breakpoint, PN_COLOR, String.class);
+ String color = StyleGuideUtil.getColor(request, colorKey);
+ if (StringUtils.isNotBlank(color)) {
+ return String.format(FORMAT, color);
+ }
+ return null;
+ }
+
+ @Override
+ public @Nullable String getRule(@Nullable Breakpoint breakpoint, @Nullable String id,
+ SlingHttpServletRequest request) {
+ return null;
+ }
+}
diff --git a/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/InlineStyleServiceImpl.java b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/InlineStyleServiceImpl.java
new file mode 100644
index 00000000..da04db0e
--- /dev/null
+++ b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/InlineStyleServiceImpl.java
@@ -0,0 +1,156 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.inlinestyle.internal;
+
+import static com.adobe.dx.inlinestyle.Constants.DECLARATION_DELIMITER;
+import static com.adobe.dx.inlinestyle.Constants.RULE_DELIMITER;
+import static com.day.cq.wcm.commons.Constants.EMPTY_STRING_ARRAY;
+import static org.apache.commons.lang3.StringUtils.EMPTY;
+
+import com.adobe.dx.responsive.Breakpoint;
+import com.adobe.dx.inlinestyle.InlineStyleWorker;
+import com.adobe.dx.inlinestyle.InlineStyleService;
+import com.adobe.dx.utils.RequestUtil;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.jetbrains.annotations.NotNull;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(configurationPolicy = ConfigurationPolicy.REQUIRE)
+public class InlineStyleServiceImpl implements InlineStyleService {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ private static final String FORMAT_ID = "#%s {%s}";
+ private static final String FORMAT_BP = "\n%s {\n%s\n}";
+ private static final String SLASH = "/";
+ private static final String TYPE_PREFIX = "/apps/";
+ private static final String STYLEWORKERS_SUFFIX = "/styleWorkers";
+
+ @Reference(service= InlineStyleWorker.class,
+ cardinality= ReferenceCardinality.MULTIPLE,
+ policy= ReferencePolicy.DYNAMIC, policyOption= ReferencePolicyOption.GREEDY,
+ bind = "bindWorker", unbind = "unbindWorker")
+ volatile List workers = new ArrayList<>();
+
+ Map workerMap = MapUtils.EMPTY_MAP;
+
+ String getStylePerBreakpoint(String id, Breakpoint breakpoint, String[] keys, SlingHttpServletRequest request) {
+ String returnValue = EMPTY;
+ List declarations = null;
+ List rules = null;
+ for (String workerKey : keys) {
+ InlineStyleWorker worker = workerMap.get(workerKey);
+ if (worker != null) {
+ logger.debug("found {}", worker);
+ String declaration = worker.getDeclaration(breakpoint, request);
+ if (StringUtils.isNotBlank(declaration)) {
+ logger.debug("generated {}", declaration);
+ if (declarations == null) {
+ declarations = new ArrayList<>();
+ }
+ declarations.add(declaration);
+ }
+ String rule = worker.getRule(breakpoint, id, request);
+ if (StringUtils.isNotBlank(rule)) {
+ logger.debug("generated {}", rule);
+ if (rules == null) {
+ rules = new ArrayList<>();
+ }
+ rules.add(rule);
+ }
+ }
+ }
+ if (declarations != null && !declarations.isEmpty()) {
+ String concat = String.join(DECLARATION_DELIMITER, declarations);
+ returnValue = StringUtils.isNotBlank(id) ? String.format(FORMAT_ID, id, concat) : concat;
+ }
+ if (rules != null && !rules.isEmpty()) {
+ String concat = String.join(RULE_DELIMITER, rules);
+ returnValue = (returnValue.isEmpty() ? EMPTY : returnValue + RULE_DELIMITER) + concat;
+ }
+ return returnValue;
+ }
+
+ @Override
+ public String getInlineStyle(String id, SlingHttpServletRequest request) {
+ Resource resource = request.getResource();
+ String[] keys = getWorkerKeys(resource);
+ if (keys.length > 0) {
+ StringBuilder style = new StringBuilder();
+ List breakpoints = RequestUtil.getBreakpoints(request);
+ if (breakpoints != null) {
+ for (Breakpoint breakpoint : breakpoints) {
+ String bpStyle = getStylePerBreakpoint(id, breakpoint, keys, request);
+ if (StringUtils.isNotBlank(bpStyle)) {
+ style.append(StringUtils.isNotBlank(breakpoint.mediaQuery()) ?
+ String.format(FORMAT_BP, breakpoint.mediaQuery(), bpStyle):
+ bpStyle);
+ }
+ }
+ }
+ if (style.length() > 0) {
+ return style.toString().trim();
+ }
+ }
+ return EMPTY;
+ }
+
+ /**
+ * returns ordered list of workers for that given resource (or null)
+ */
+ @NotNull String[] getWorkerKeys(Resource resource) {
+ String type = resource.getResourceType();
+ String typePath = (type.startsWith(SLASH) ? type : TYPE_PREFIX + type) + STYLEWORKERS_SUFFIX;
+ Resource keys = resource.getResourceResolver().getResource(typePath);
+ if (keys != null) {
+ return keys.adaptTo(String[].class);
+ }
+ return EMPTY_STRING_ARRAY;
+ }
+
+ void refreshWorkers() {
+ Map map = new HashMap<>();
+ for (InlineStyleWorker worker : workers) {
+ map.put(worker.getKey(), worker);
+ }
+ workerMap = map;
+ }
+
+ void bindWorker(InlineStyleWorker worker) {
+ workers.add(worker);
+ refreshWorkers();
+ }
+
+ void unbindWorker(InlineStyleWorker worker) {
+ workers.remove(worker);
+ refreshWorkers();
+ }
+}
diff --git a/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Shadow.java b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Shadow.java
new file mode 100644
index 00000000..120aeaee
--- /dev/null
+++ b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/internal/Shadow.java
@@ -0,0 +1,80 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.inlinestyle.internal;
+
+import static com.adobe.dx.inlinestyle.Constants.PX_SPACE;
+import static com.adobe.dx.utils.RequestUtil.getPolicy;
+
+import com.adobe.dx.responsive.Breakpoint;
+import com.adobe.dx.inlinestyle.InlineStyleWorker;
+import com.adobe.dx.styleguide.StyleGuideUtil;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.ValueMap;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+
+@Component(configurationPolicy = ConfigurationPolicy.REQUIRE)
+public class Shadow implements InlineStyleWorker {
+
+ private static final String KEY = "shadow";
+ private static final String RULE = "box-shadow: ";
+ private static final String INSET_SUFFIX = " inset";
+ private static final String PREFIX = KEY;
+ private static final String PN_COLOR = PREFIX + "Color";
+ private static final String PN_OFFSETX = PREFIX + "OffsetX";
+ private static final String PN_OFFSETY = PREFIX + "OffsetY";
+ private static final String PN_BLUR = PREFIX + "Blur";
+ private static final String PN_SPREAD = PREFIX + "Spread";
+ private static final String PN_INSET = PREFIX + "Inset";
+
+ @Override
+ public String getKey() {
+ return KEY;
+ }
+
+ @Override
+ public @Nullable String getDeclaration(Breakpoint breakpoint, SlingHttpServletRequest request) {
+ if (StringUtils.isBlank(breakpoint.mediaQuery())) {
+ //we only do border for all
+ ValueMap dxPolicy = getPolicy(request);
+ String colorKey = dxPolicy.get(PN_COLOR, String.class);
+ String color = StyleGuideUtil.getColor(request, colorKey);
+ if (color != null) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(RULE)
+ .append(dxPolicy.get(PN_OFFSETX, 0L)).append(PX_SPACE)
+ .append(dxPolicy.get(PN_OFFSETY, 0L)).append(PX_SPACE)
+ .append(dxPolicy.get(PN_BLUR, 0L)).append(PX_SPACE)
+ .append(dxPolicy.get(PN_SPREAD, 0L)).append(PX_SPACE)
+ .append(color);
+ if (dxPolicy.containsKey(PN_INSET)) {
+ sb.append(INSET_SUFFIX);
+ }
+ return sb.toString();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public @Nullable String getRule(@Nullable Breakpoint breakpoint, @Nullable String id,
+ SlingHttpServletRequest request) {
+ return null;
+ }
+}
diff --git a/bundles/core/src/main/java/com/adobe/dx/inlinestyle/package-info.java b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/package-info.java
new file mode 100644
index 00000000..221abadd
--- /dev/null
+++ b/bundles/core/src/main/java/com/adobe/dx/inlinestyle/package-info.java
@@ -0,0 +1,19 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2019 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.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+ @Version("0.0.1")
+ package com.adobe.dx.inlinestyle;
+
+ import org.osgi.annotation.versioning.Version;
\ No newline at end of file
diff --git a/bundles/core/src/main/java/com/adobe/dx/responsive/Breakpoint.java b/bundles/core/src/main/java/com/adobe/dx/responsive/Breakpoint.java
new file mode 100644
index 00000000..2eb2ad36
--- /dev/null
+++ b/bundles/core/src/main/java/com/adobe/dx/responsive/Breakpoint.java
@@ -0,0 +1,44 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.responsive;
+
+import org.apache.sling.caconfig.annotation.Configuration;
+import org.apache.sling.caconfig.annotation.Property;
+
+@Configuration(collection = true)
+public @interface Breakpoint {
+ @Property(label = "name")
+ String getLabel();
+
+ @Property(label = "property suffix", description = "suffix to append to a property to get the responsive version of it")
+ String propertySuffix();
+
+ @Property(label = "map key", description = "key from where a value will be available")
+ String key();
+
+ @Property(label = "media Query", description = "media query that defines this breakpoint")
+ String mediaQuery();
+
+ @Property(label = "inherit property", description = "if, for a given breakpoint, for a given resource, this property is set to true,"
+ + "this gives the green light to fetch the value to next breakpoint")
+ String inheritProperty();
+
+ @Property(label = "start", description = "screen width from which this breakpoint is set")
+ int start();
+
+ @Property(label = "end", description = "screen width to which this breakpoint is set")
+ int end();
+}
diff --git a/bundles/core/src/main/java/com/adobe/dx/responsive/InheritedMap.java b/bundles/core/src/main/java/com/adobe/dx/responsive/InheritedMap.java
new file mode 100644
index 00000000..66c9f0df
--- /dev/null
+++ b/bundles/core/src/main/java/com/adobe/dx/responsive/InheritedMap.java
@@ -0,0 +1,31 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.responsive;
+
+public interface InheritedMap {
+
+ /**
+ * Get value from current breakpoint, or inherited (if set)
+ *
+ * @param propertyName name of the property fetched
+ * @param breakpoint breakpoint for which we do want the value
+ * @param defaultValue default value
+ * @param generic type
+ * @return value (in given type), or default value
+ */
+ T getInheritedValue(String propertyName, Breakpoint breakpoint, T defaultValue);
+}
diff --git a/bundles/core/src/main/java/com/adobe/dx/responsive/ResponsiveConfiguration.java b/bundles/core/src/main/java/com/adobe/dx/responsive/ResponsiveConfiguration.java
index 8e5d9763..4887aa28 100644
--- a/bundles/core/src/main/java/com/adobe/dx/responsive/ResponsiveConfiguration.java
+++ b/bundles/core/src/main/java/com/adobe/dx/responsive/ResponsiveConfiguration.java
@@ -1,9 +1,23 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Copyright 2020 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.dx.responsive;
import org.apache.sling.caconfig.annotation.Configuration;
@Configuration(label="Responsive Configuration", description = "sets the responsive behaviour")
public @interface ResponsiveConfiguration {
-
- String[] breakpoints() default {"Mobile", "Tablet", "Desktop"};
+ Breakpoint[] breakpoints();
}
diff --git a/bundles/core/src/main/java/com/adobe/dx/responsive/internal/ResponsiveProperties.java b/bundles/core/src/main/java/com/adobe/dx/responsive/internal/ResponsivePropertiesImpl.java
similarity index 50%
rename from bundles/core/src/main/java/com/adobe/dx/responsive/internal/ResponsiveProperties.java
rename to bundles/core/src/main/java/com/adobe/dx/responsive/internal/ResponsivePropertiesImpl.java
index 699b273d..30ad10fa 100644
--- a/bundles/core/src/main/java/com/adobe/dx/responsive/internal/ResponsiveProperties.java
+++ b/bundles/core/src/main/java/com/adobe/dx/responsive/internal/ResponsivePropertiesImpl.java
@@ -16,10 +16,12 @@
package com.adobe.dx.responsive.internal;
-import com.adobe.dx.responsive.ResponsiveConfiguration;
+import com.adobe.dx.responsive.Breakpoint;
+import com.adobe.dx.responsive.InheritedMap;
import java.util.Collection;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -32,26 +34,30 @@
* simply check for get operation the required property with and ordered list of
* suffix. Allowing several properties
*/
-public class ResponsiveProperties implements Map {
+public class ResponsivePropertiesImpl implements Map>, InheritedMap {
- private final String[] breakpoints;
+ private final List breakpoints;
private ValueMap properties;
- public ResponsiveProperties(final ResponsiveConfiguration configuration, ValueMap properties) {
- this.breakpoints = configuration.breakpoints();
+ public ResponsivePropertiesImpl(final List breakpoints, ValueMap properties) {
+ this.breakpoints = breakpoints;
this.properties = properties;
}
+ private String computeResponsiveResourceName(String name, Breakpoint breakpoint) {
+ return name + breakpoint.propertySuffix();
+ }
+
@Override
- public Object get(Object key) {
+ public LinkedHashMap get(Object key) {
if (key != null) {
boolean empty = true;
- LinkedHashMap breakpointValues = new LinkedHashMap<>();
- for (String breakpoint : breakpoints) {
- String respKey = key + breakpoint;
- String value = properties.get(respKey, String.class);
- empty &= StringUtils.isBlank(value);
- breakpointValues.put(breakpoint.toLowerCase(), value);
+ LinkedHashMap breakpointValues = new LinkedHashMap<>();
+ for (Breakpoint breakpoint : breakpoints) {
+ String respKey = computeResponsiveResourceName(key.toString(), breakpoint);
+ Object value = properties.get(respKey);
+ empty &= value == null || StringUtils.isBlank(value.toString());
+ breakpointValues.put(breakpoint.key(), value);
}
if (!empty) {
return breakpointValues;
@@ -60,6 +66,35 @@ public Object get(Object key) {
return null;
}
+ private @Nullable Breakpoint getPreviousBreakpoint(Breakpoint breakpoint) {
+ Breakpoint previous = null;
+ for (Breakpoint candidate : breakpoints) {
+ if (breakpoint.key().equals(candidate.key())) {
+ break;
+ }
+ previous = candidate;
+ }
+ return previous;
+ }
+
+ @Override
+ public T getInheritedValue(String propertyName, Breakpoint breakpoint, T defaultValue) {
+ LinkedHashMap values = get(propertyName);
+ if (values != null) {
+ if (values.get(breakpoint.key()) != null) {
+ return (T) values.get(breakpoint.key());
+ }
+ if (StringUtils.isNotBlank(breakpoint.inheritProperty())
+ && properties.get(breakpoint.inheritProperty(), false)) {
+ Breakpoint previous = getPreviousBreakpoint(breakpoint);
+ if (previous != null) {
+ return getInheritedValue(propertyName, previous, defaultValue);
+ }
+ }
+ }
+ return defaultValue;
+ }
+
@Override
public int size() {
throw new UnsupportedOperationException();
@@ -82,17 +117,17 @@ public boolean containsValue(Object value) {
@Nullable
@Override
- public Object put(String key, Object value) {
+ public LinkedHashMap put(String key, LinkedHashMap value) {
throw new UnsupportedOperationException();
}
@Override
- public Object remove(Object key) {
+ public LinkedHashMap remove(Object key) {
throw new UnsupportedOperationException();
}
@Override
- public void putAll(@NotNull Map extends String, ?> m) {
+ public void putAll(@NotNull Map extends String, ? extends LinkedHashMap> m) {
throw new UnsupportedOperationException();
}
@@ -109,13 +144,14 @@ public Set keySet() {
@NotNull
@Override
- public Collection
+
org.junit.jupiterjunit-jupiter
+ ${junit.version}
+ compile
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.version}compile
+
+ org.mockito
+ mockito-all
+ 1.9.5
+ test
+ io.wcmio.wcm.testing.aem-mock.junit5
diff --git a/bundles/testing/src/main/java/com/adobe/dx/testing/AbstractTest.java b/bundles/testing/src/main/java/com/adobe/dx/testing/AbstractTest.java
index a45327b6..a369c4f8 100644
--- a/bundles/testing/src/main/java/com/adobe/dx/testing/AbstractTest.java
+++ b/bundles/testing/src/main/java/com/adobe/dx/testing/AbstractTest.java
@@ -29,10 +29,10 @@
@ExtendWith(AemContextExtension.class)
public class AbstractTest {
- protected static final String CONTENT_ROOT = "/content/foo";
- protected static final String CONF_ROOT = "/conf/foo";
+ public static final String CONTENT_ROOT = "/content/foo";
+ public static final String CONF_ROOT = "/conf/foo";
- protected AemContext context = buildContext(getType());
+ public AemContext context = buildContext(getType());
protected ResourceResolverType getType() {
return ResourceResolverType.RESOURCERESOLVER_MOCK;
@@ -44,11 +44,15 @@ protected static AemContext buildContext(ResourceResolverType type) {
.build();
}
- protected ValueMap getVM(String path) {
+ public static ValueMap getVM(AemContext context, String path) {
Resource resource = context.resourceResolver().getResource(path);
if (resource != null) {
return resource.getValueMap();
}
return null;
}
+
+ protected ValueMap getVM(String path) {
+ return getVM(context, path);
+ }
}
\ No newline at end of file
diff --git a/parent/main/pom.xml b/parent/main/pom.xml
index e12a613e..d7e7b95f 100644
--- a/parent/main/pom.xml
+++ b/parent/main/pom.xml
@@ -604,19 +604,6 @@ ${bundle.additional.properties}
apisprovided
-
-
- org.junit.jupiter
- junit-jupiter
- 5.6.0
- test
-
-
- org.mockito
- mockito-all
- 1.9.5
- test
-
diff --git a/pom.xml b/pom.xml
index b213e8be..9ba1895f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,8 @@
parentbundles/testingbundles/core
- apps/admin
+ bundles/testing-extensions
+ apps/adminapps/structureapps/contentapps/all