Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
b839caa
FORMS-21799 fixing aria-label to display plain text (#1715)
im-shiv Sep 23, 2025
3bbcc32
Merge pull request #1713 from adobe/FORMS-21742
armaang1729 Sep 24, 2025
2b9a0e7
Fixing js doc (#1721)
rismehta Sep 25, 2025
a361cfb
@releng updating af-core (#1726)
rismehta Oct 7, 2025
6bdc21b
Merge branch 'dev' into devMaster8Oct
rismehta Oct 8, 2025
951cb08
Dev master8 oct (#1727)
rismehta Oct 8, 2025
2639103
@releng [maven-scm] :prepare release core-forms-components-reactor-3.…
rismehta Oct 8, 2025
a3f13e1
@releng [maven-scm] :prepare for next development iteration
rismehta Oct 8, 2025
6fa8105
Update VERSIONS.md and README.md to include version 3.0.124
Oct 8, 2025
7ce021b
Checkbox boolean value doesn't work in rule editor (#1728)
armaang1729 Oct 9, 2025
84d1c47
FORMS-18328 default date localization changes (#1722)
im-shiv Oct 9, 2025
e9ffe92
FORMS-18632: Info or functionality is unavailable at 320px width equi…
CezarSTF Oct 3, 2025
40df4de
FORMS-18632: Info or functionality is unavailable at 320px width equi…
CezarSTF Oct 9, 2025
1ecac89
FORMS-18632: Info or functionality is unavailable at 320px width equi…
CezarSTF Oct 13, 2025
ff3bd0a
FORMS-18632: Info or functionality is unavailable at 320px width equi…
CezarSTF Oct 13, 2025
aa10a23
Merge pull request #1724 from adobe/ens83070/FORMS-18632
CezarSTF Oct 28, 2025
4a2a4f5
Unload (#1752)
rismehta Nov 20, 2025
94bf161
Merge branch 'dev' into devMaster2011
rismehta Nov 20, 2025
8504ef9
Merge pull request #1753 from adobe/devMaster2011
rismehta Nov 20, 2025
80a8047
@releng [maven-scm] :prepare release core-forms-components-reactor-3.…
rismehta Nov 20, 2025
801fce4
@releng [maven-scm] :prepare for next development iteration
rismehta Nov 20, 2025
ed6f4e7
Update VERSIONS.md and README.md to include version 3.0.126
Nov 20, 2025
e76276c
FORMS-22032 Added support for reading associate properties container …
ard1498 Nov 28, 2025
a723bd2
Merge branch 'dev' into devMaster112
rismehta Dec 1, 2025
53d5d13
Merge pull request #1760 from adobe/devMaster112
rismehta Dec 1, 2025
054b7ff
@releng [maven-scm] :prepare release core-forms-components-reactor-3.…
rismehta Dec 1, 2025
e9c8994
@releng [maven-scm] :prepare for next development iteration
rismehta Dec 1, 2025
291b4c5
Update VERSIONS.md and README.md to include version 3.0.128
Dec 1, 2025
659cedd
Merge pull request #1744 from adobe/FORMS-18096
armaang1729 Dec 2, 2025
b77f020
FORMS-23027 updating dependencies to support java 21 (#1695)
rismehta Dec 3, 2025
48ced2c
Merged branch 'origin/dev' into devMaster4Dec
Dec 4, 2025
2456e26
Merge pull request #1766 from adobe/devMaster4Dec
im-shiv Dec 4, 2025
c644906
@releng [maven-scm] :prepare release core-forms-components-reactor-3.…
Dec 4, 2025
4474b8d
@releng [maven-scm] :prepare for next development iteration
Dec 4, 2025
3149491
Update VERSIONS.md and README.md to include version 3.0.130
Dec 4, 2025
506afa3
FORMS-23288 updating logic to get locale from url (#1768)
im-shiv Dec 9, 2025
5d77618
Revert "FORMS-23288 updating logic to get locale from url (#1768)" (#…
im-shiv Dec 9, 2025
d2c077d
FORMS-23288 updating logic to get locale from url (#1772)
im-shiv Dec 9, 2025
af2162b
Merge branch 'origin/dev' into devMaster9Dec
Dec 9, 2025
85fae01
Merge pull request #1773 from adobe/devMaster9Dec
im-shiv Dec 9, 2025
1236bd4
@releng [maven-scm] :prepare release core-forms-components-reactor-3.…
Dec 9, 2025
f3dd1f8
@releng [maven-scm] :prepare for next development iteration
Dec 9, 2025
b2fba72
Merge branch 'master' into masterTo650dec
Dec 9, 2025
865c071
Revert FORMS-22032 Added support for reading associate properties con…
Dec 10, 2025
0e2fe1a
fixing failing tests
Dec 11, 2025
9d55ae6
updating to latest 6.5.24 build
Dec 11, 2025
8691607
fixing rule editor rules
Dec 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ executors:
forms_executor_java8:
docker:
- image: cimg/openjdk:8.0-browsers
forms_executor_java21:
docker:
- image: cimg/openjdk:21.0-browsers
test_executor_cloudready:
docker:
- image: docker-adobe-cif-release.dr-uw2.adobeitc.com/circleci-qp:6.4.6-openjdk11
Expand All @@ -137,7 +140,7 @@ executors:
docker:
- image: docker-adobe-cif-release.dr-uw2.adobeitc.com/circleci-qp:6.4.6-openjdk11
<<: *docker_auth
- image: docker-adobe-cif-release.dr-uw2.adobeitc.com/circleci-aem:6.5.24-load4-openjdk11
- image: docker-adobe-cif-release.dr-uw2.adobeitc.com/circleci-aem:6.5.24.0-openjdk11
<<: *docker_auth

jobs:
Expand Down Expand Up @@ -185,6 +188,30 @@ jobs:
conf: .circleci/codecov.yml
flags: unittests

build-java-21:
executor: forms_executor_java21
working_directory: /home/circleci/build
steps:
- checkout
- restore_cache:
keys:
- maven-repo-java21-v1-{{ checksum "pom.xml" }}
- maven-repo-java21-v1-
- run:
name: Update permissions
command: sudo chown -R circleci /usr/local/lib/node_modules
- run:
name: Build with Java 21
command: node .circleci/ci/build.js
- save_cache:
paths:
- ~/.m2
key: maven-repo-java21-v1-{{ .Branch }}-{{ checksum "pom.xml" }}
- store_test_results:
path: bundles/core/target/surefire-reports
- store_artifacts:
path: bundles/core/target/surefire-reports

build-java-8:
executor: forms_executor_java8
working_directory: /home/circleci/build
Expand Down Expand Up @@ -416,6 +443,10 @@ workflows:
filters:
tags:
only: /.*/
- build-java-21:
filters:
tags:
only: /.*/
- build-java-8:
filters:
tags:
Expand Down
2 changes: 1 addition & 1 deletion bundles/af-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>1.5.2</version>
<version>1.10.2</version>
<scope>test</scope>
</dependency>
<!--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.day.cq.commons.jcr.JcrConstants;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

public class ComponentDataImpl implements FormComponentData {

Expand All @@ -41,7 +42,25 @@ public class ComponentDataImpl implements FormComponentData {

protected final Resource resource;

/**
* Creates a new ComponentDataImpl instance.
*
* Note: This constructor stores references to FormComponent and Resource objects.
* These objects are designed to be immutable and shared across the system.
* The FormComponent interface provides read-only access to form component data,
* and the Resource interface represents an immutable JCR resource.
*
* @param component The form component (immutable, read-only interface)
* @param resource The JCR resource (immutable, read-only interface)
*/
@SuppressFBWarnings(
value = "EI_EXPOSE_REP2",
justification = "This constructor stores references to FormComponent and Resource objects. These objects are designed to be immutable and shared across the system. The FormComponent interface provides read-only access to form component data, and the Resource interface represents an immutable JCR resource. This is safe from a security perspective as these objects cannot be modified through the stored references.")
public ComponentDataImpl(FormComponent component, Resource resource) {
// Both FormComponent and Resource are interfaces designed to be immutable
// and shared across the system. They provide read-only access to data.
// This is safe from a security perspective as these objects cannot be
// modified through the stored references.
this.component = component;
this.resource = resource;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,6 @@ private static Set<String> aggregateReservedProperties() {
}

public static Set<String> getReservedProperties() {
return reservedProperties;
return new HashSet<>(reservedProperties);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public String getFragmentPath() {
if (itemModels == null) {
itemModels = getChildrenModels(request, ComponentExporter.class);
}
return itemModels;
return new LinkedHashMap<>(itemModels);
}

protected <T> Map<String, T> getChildrenModels(@Nullable SlingHttpServletRequest request, @NotNull Class<T> modelClass) {
Expand Down Expand Up @@ -180,7 +180,7 @@ public List<Resource> getFragmentChildren() {
if (filteredChildComponents == null) {
filteredChildComponents = getFilteredChildrenResources(fragmentContainer);
}
return filteredChildComponents;
return new ArrayList<>(filteredChildComponents);
}

@JsonIgnore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.osgi.annotation.versioning.ProviderType;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
Expand Down Expand Up @@ -58,4 +59,13 @@ default boolean isEnforceEnum() {
* @since com.adobe.cq.forms.core.components.models.form 0.0.1
*/
String[] getEnumNames();

/**
* Returns screen reader friendly aria labels for the options.
*
* @return the list of aria labels for the options
* @since com.adobe.cq.forms.core.components.models.form 5.12.3
*/
@JsonIgnore
String[] getOptionScreenReaderLabels();
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
* </p>
*/

@Version("5.12.2")
@Version("5.12.3")
package com.adobe.cq.forms.core.components.models.form;

import org.osgi.annotation.versioning.Version;
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ protected String getConstraintMessage(ConstraintType type) {
putConstraintMessage(ConstraintType.VALIDATION_EXPRESSION, msgs.getValidationExpressionConstraintMessage());
putConstraintMessage(ConstraintType.UNIQUE_ITEMS, msgs.getUniqueItemsConstraintMessage());
}
return constraintMessages;
return new LinkedHashMap<>(constraintMessages);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public List<? extends ComponentExporter> getItems() {
if (childrenModels == null) {
childrenModels = new ArrayList<>(getChildrenModels(request, ComponentExporter.class).values());
}
return childrenModels;
return new ArrayList<>(childrenModels);
}

@NotNull
Expand Down Expand Up @@ -172,7 +172,7 @@ protected <T> Map<String, T> getChildrenModels(@Nullable SlingHttpServletRequest
if (itemModels == null) {
itemModels = getChildrenModels(request, ComponentExporter.class);
}
return itemModels;
return new LinkedHashMap<>(itemModels);
}

protected List<Resource> getFilteredChildrenResources() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ private boolean isAllowedType(Object value) {
* @return {@code Map<String, String>} returns all custom property key value pairs associated with the resource
*/
private Map<String, Object> getCustomProperties() {
Map<String, Object> customProperties = new HashMap<>();
Map<String, Object> customProperties = new LinkedHashMap<>();
Map<String, String> templateBasedCustomProperties;
List<String> excludedPrefixes = Arrays.asList("fd:", "jcr:", "sling:");
Set<String> reservedProperties = ReservedProperties.getReservedProperties();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import com.adobe.cq.forms.core.components.internal.form.ReservedProperties;
import com.adobe.cq.forms.core.components.models.form.Field;
import com.adobe.cq.forms.core.components.models.form.Label;
import com.adobe.cq.forms.core.components.models.form.OptionsConstraint;

/**
Expand Down Expand Up @@ -137,4 +138,28 @@ public Object[] getDefault() {
}
return typedDefaultValue;
}

@Override
public String[] getOptionScreenReaderLabels() {
String[] enumNames = getEnumNames();
if (enumNames == null) {
return null;
}

Label label = getLabel();
String labelValue = (label != null && label.getValue() != null) ? label.getValue() : "";
boolean hasRichTextLabel = label != null && label.isRichText() != null && label.isRichText();

// Strip HTML from label once if needed
String cleanLabel = hasRichTextLabel ? labelValue.replaceAll("<[^>]*>", "") : labelValue;

String[] ariaLabels = new String[enumNames.length];
for (int i = 0; i < enumNames.length; i++) {
// Strip HTML from enum name for screen readers
String cleanEnumName = enumNames[i].replaceAll("<[^>]*>", "");
ariaLabels[i] = cleanLabel + ": " + cleanEnumName;
}

return ariaLabels;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@
import io.wcm.testing.mock.aem.junit5.AemContext;
import io.wcm.testing.mock.aem.junit5.AemContextExtension;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;

Expand All @@ -57,6 +54,7 @@ public class CheckBoxGroupImplTest {
private static final String PATH_CHECKBOX_GROUP_FOR_INSERTION_ORDER = CONTENT_ROOT + "/checkboxgroup-insertion-order";
private static final String PATH_CHECKBOX_GROUP_FOR_BOOLEAN = CONTENT_ROOT + "/checkboxgroup-boolean";
private static final String PATH_CHECKBOX_GROUP_NO_FIELDTYPE = CONTENT_ROOT + "/checkboxgroup-without-fieldtype";
private static final String PATH_CHECKBOX_GROUP_OPTION_SCREEN_READER_LABEL = CONTENT_ROOT + "/checkboxgroup-option-screenreader-label";

private final AemContext context = FormsCoreComponentTestContext.newAemContext();

Expand Down Expand Up @@ -388,6 +386,33 @@ void testInsertionOrderForEnumNames() {
assertArrayEquals(set.toArray(new String[0]), checkboxGroup.getEnumNames());
}

@Test
void testGetOptionScreenReaderLabels() {
CheckBoxGroup checkboxGroup = getCheckBoxGroupUnderTest(PATH_CHECKBOX_GROUP_OPTION_SCREEN_READER_LABEL);
String[] screenReaderLabels = checkboxGroup.getOptionScreenReaderLabels();
assertEquals("<b>Gender</b>: Male", screenReaderLabels[0]);
assertEquals("<b>Gender</b>: Female", screenReaderLabels[1]);

CheckBoxGroup spyCheckboxGroup1 = Mockito.spy(checkboxGroup);
Mockito.when(spyCheckboxGroup1.getEnumNames()).thenReturn(null);
assertNull(spyCheckboxGroup1.getOptionScreenReaderLabels());

CheckBoxGroup spyCheckboxGroup2 = Mockito.spy(checkboxGroup);
Mockito.when(spyCheckboxGroup2.getLabel()).thenReturn(null);
screenReaderLabels = spyCheckboxGroup2.getOptionScreenReaderLabels();
assertEquals(": Male", screenReaderLabels[0]);
assertEquals(": Female", screenReaderLabels[1]);

Label label = Mockito.mock(Label.class);
Mockito.when(label.getValue()).thenReturn(null);
Mockito.when(label.isRichText()).thenReturn(null);
CheckBoxGroup spyCheckboxGroup3 = Mockito.spy(checkboxGroup);
Mockito.when(spyCheckboxGroup3.getLabel()).thenReturn(label);
screenReaderLabels = spyCheckboxGroup3.getOptionScreenReaderLabels();
assertEquals(": Male", screenReaderLabels[0]);
assertEquals(": Female", screenReaderLabels[1]);
}

@Test
void testNoFieldType() {
CheckBoxGroup checkboxGroup = getCheckBoxGroupUnderTest(PATH_CHECKBOX_GROUP_NO_FIELDTYPE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public class RadioButtonImplTest {
private static final String PATH_RADIOBUTTON_WITH_DUPLICATE_ENUMS = CONTENT_ROOT + "/radiobutton-duplicate-enum";
private static final String PATH_RADIOBUTTON_FOR_INSERTION_ORDER = CONTENT_ROOT + "/radiobutton-insertion-order";
private static final String PATH_RADIOBUTTON_WITHOUT_FIELDTYPE = CONTENT_ROOT + "/radiobutton-without-fieldtype";
private static final String PATH_RADIOBUTTON_OPTION_SCREEN_READER_LABEL = CONTENT_ROOT + "/radiobutton-option-screenreader-label";

private final AemContext context = FormsCoreComponentTestContext.newAemContext();

Expand Down Expand Up @@ -395,6 +396,14 @@ void testInsertionOrderForEnumNames() {
assertArrayEquals(set.toArray(new String[0]), radioButton.getEnumNames());
}

@Test
void testGetOptionScreenReaderLabels() {
RadioButton radioButton = getRadioButtonUnderTest(PATH_RADIOBUTTON_OPTION_SCREEN_READER_LABEL);
String[] screenReaderLabels = radioButton.getOptionScreenReaderLabels();
assertEquals("Gender: Male", screenReaderLabels[0]);
assertEquals("Gender: Female", screenReaderLabels[1]);
}

@Test
void testGetScreenReaderTextWithLabel() {
RadioButton radioButton = getRadioButtonUnderTest(PATH_RADIOBUTTON_CUSTOMIZED_WITH_LABEL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class SwitchImplTest {
private static final String PATH_SWITCH_ENABLEUNCHECKED_BOOLEAN = CONTENT_ROOT + "/switch-boolean";
private static final String PATH_SWITCH_ENABLEUNCHECKEDOFF_BOOLEAN = CONTENT_ROOT + "/switch-enableUncheckedValueFalse-boolean";
private static final String PATH_SWITCH_WITHOUT_FIELDTYPE = CONTENT_ROOT + "/switch-without-fieldtype";
private static final String PATH_SWITCH_OPTION_SCREEN_READER_LABEL = CONTENT_ROOT + "/switch-option-screenreader-label";
private final AemContext context = FormsCoreComponentTestContext.newAemContext();

@BeforeEach
Expand Down Expand Up @@ -346,6 +347,14 @@ private Switch getSwitchUnderTest(String resourcePath) {
return request.adaptTo(Switch.class);
}

@Test
void testGetOptionScreenReaderLabels() {
Switch switchObject = getSwitchUnderTest(PATH_SWITCH_OPTION_SCREEN_READER_LABEL);
String[] screenReaderLabels = switchObject.getOptionScreenReaderLabels();
assertEquals("SWITCH: OFF", screenReaderLabels[0]);
assertEquals("SWITCH: ON", screenReaderLabels[1]);
}

@Test
void testNoFieldType() {
Switch switchComp = getSwitchUnderTest(PATH_SWITCH_WITHOUT_FIELDTYPE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,5 +269,24 @@
],
"jcr:lastModified": "Tue Jul 30 2024 15:16:00 GMT+0530",
"sling:resourceType": "forms-components-examples/components/form/checkboxgroup"
},
"checkboxgroup-option-screenreader-label": {
"id": "checkboxgroup-1076f3bd737",
"jcr:primaryType": "nt:unstructured",
"sling:resourceType": "core/fd/components/form/checkboxgroup/v1/checkboxgroup",
"name": "checkboxgroup",
"fieldType": "checkbox-group",
"jcr:title": "<b>Gender</b>",
"orientation": "vertical",
"type": "number[]",
"enum": [
"0",
"1"
],
"enforceEnum": true,
"enumNames": [
"<p><i>Male</i></p>",
"<p><i>Female</i></p>"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -350,5 +350,23 @@
"<p>Item 2</p>"
],
"fieldType": "radio-group"
},
"radiobutton-option-screenreader-label": {
"id": "radiobutton-1076f3bd737",
"jcr:primaryType": "nt:unstructured",
"sling:resourceType": "core/fd/components/form/radiobutton/v1/radiobutton",
"name": "radiobutton",
"isTitleRichText": "true",
"jcr:title": "<b>Gender</b>",
"orientation": "vertical",
"enum": [
"0",
"1"
],
"enumNames": [
"<p><i>Male</i></p>",
"<p><i>Female</i></p>"
],
"fieldType": "radio-group"
}
}
Loading
Loading