Skip to content

Commit 769c3e2

Browse files
introfogiText-CI
authored andcommitted
Add linear gradient support to ListStyleShorthandResolver class
DEVSIX-4138
1 parent e704355 commit 769c3e2

File tree

6 files changed

+145
-35
lines changed

6 files changed

+145
-35
lines changed

styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/resolve/shorthand/impl/BackgroundShorthandResolver.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,16 @@ This file is part of the iText (R) project.
4343
package com.itextpdf.styledxmlparser.css.resolve.shorthand.impl;
4444

4545
import com.itextpdf.styledxmlparser.css.CommonCssConstants;
46-
import org.slf4j.Logger;
47-
import org.slf4j.LoggerFactory;
48-
4946
import com.itextpdf.io.util.MessageFormatUtil;
5047
import com.itextpdf.styledxmlparser.LogMessageConstant;
5148
import com.itextpdf.styledxmlparser.css.CssDeclaration;
52-
import com.itextpdf.styledxmlparser.css.parse.CssDeclarationValueTokenizer;
53-
import com.itextpdf.styledxmlparser.css.parse.CssDeclarationValueTokenizer.Token;
54-
import com.itextpdf.styledxmlparser.css.parse.CssDeclarationValueTokenizer.TokenType;
5549
import com.itextpdf.styledxmlparser.css.resolve.shorthand.IShorthandResolver;
5650
import com.itextpdf.styledxmlparser.css.util.CssGradientUtil;
5751
import com.itextpdf.styledxmlparser.css.util.CssUtils;
58-
import java.util.ArrayList;
52+
53+
import org.slf4j.Logger;
54+
import org.slf4j.LoggerFactory;
55+
5956
import java.util.Arrays;
6057
import java.util.List;
6158

@@ -113,14 +110,8 @@ public List<CssDeclaration> resolveShorthand(String shorthandExpression) {
113110
);
114111
}
115112

116-
List<String> props = new ArrayList<>();
117-
CssDeclarationValueTokenizer tokenizer = new CssDeclarationValueTokenizer(shorthandExpression);
118-
Token nextToken = tokenizer.getNextValidToken();
119113
// TODO: DEVSIX-2027 ignore multiple backgrounds at the moment (stop parsing after comma)
120-
while (nextToken != null && nextToken.getType() != TokenType.COMMA) {
121-
props.add(nextToken.getValue());
122-
nextToken = tokenizer.getNextValidToken();
123-
}
114+
List<String> props = CssUtils.extractShorthandProperties(shorthandExpression).get(0);
124115

125116
String[] resolvedProps = new String[8];
126117
boolean slashEncountered = false;

styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/resolve/shorthand/impl/ListStyleShorthandResolver.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,15 @@ This file is part of the iText (R) project.
4545
import com.itextpdf.styledxmlparser.css.CommonCssConstants;
4646
import com.itextpdf.styledxmlparser.css.CssDeclaration;
4747
import com.itextpdf.styledxmlparser.css.resolve.shorthand.IShorthandResolver;
48+
import com.itextpdf.styledxmlparser.css.util.CssGradientUtil;
49+
import com.itextpdf.styledxmlparser.css.util.CssUtils;
4850

4951
import java.util.ArrayList;
5052
import java.util.Arrays;
5153
import java.util.HashSet;
5254
import java.util.List;
5355
import java.util.Set;
5456

55-
5657
/**
5758
* {@link IShorthandResolver} implementation for list styles.
5859
*/
@@ -84,14 +85,15 @@ public List<CssDeclaration> resolveShorthand(String shorthandExpression) {
8485
new CssDeclaration(CommonCssConstants.LIST_STYLE_IMAGE, shorthandExpression));
8586
}
8687

87-
String[] props = shorthandExpression.split("\\s+");
88+
List<String> props = CssUtils.extractShorthandProperties(shorthandExpression).get(0);
8889

8990
String listStyleTypeValue = null;
9091
String listStylePositionValue = null;
9192
String listStyleImageValue = null;
9293

9394
for (String value : props) {
94-
if (value.contains("url(") || CommonCssConstants.NONE.equals(value) && listStyleTypeValue != null) {
95+
if (value.contains("url(") || CssGradientUtil.isCssLinearGradientValue(value) ||
96+
(CommonCssConstants.NONE.equals(value) && listStyleTypeValue != null)) {
9597
listStyleImageValue = value;
9698
} else if (LIST_STYLE_TYPE_VALUES.contains(value)) {
9799
listStyleTypeValue = value;

styled-xml-parser/src/main/java/com/itextpdf/styledxmlparser/css/util/CssUtils.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ This file is part of the iText (R) project.
4949
import com.itextpdf.layout.property.UnitValue;
5050
import com.itextpdf.styledxmlparser.LogMessageConstant;
5151
import com.itextpdf.styledxmlparser.css.CommonCssConstants;
52+
import com.itextpdf.styledxmlparser.css.parse.CssDeclarationValueTokenizer;
53+
import com.itextpdf.styledxmlparser.css.parse.CssDeclarationValueTokenizer.Token;
54+
import com.itextpdf.styledxmlparser.css.parse.CssDeclarationValueTokenizer.TokenType;
5255
import com.itextpdf.styledxmlparser.exceptions.StyledXMLParserException;
5356

5457
import java.util.ArrayList;
@@ -84,6 +87,33 @@ public class CssUtils {
8487
private CssUtils() {
8588
}
8689

90+
/**
91+
* Extracts shorthand properties as list of string lists from a string, where the top level
92+
* list is shorthand property and the lower level list is properties included in shorthand property.
93+
*
94+
* @param str the source string with shorthand properties
95+
* @return the list of string lists
96+
*/
97+
public static List<List<String>> extractShorthandProperties(String str) {
98+
List<List<String>> result = new ArrayList<>();
99+
List<String> currentLayer = new ArrayList<>();
100+
CssDeclarationValueTokenizer tokenizer = new CssDeclarationValueTokenizer(str);
101+
102+
Token currentToken = tokenizer.getNextValidToken();
103+
while (currentToken != null) {
104+
if (currentToken.getType() == TokenType.COMMA) {
105+
result.add(currentLayer);
106+
currentLayer = new ArrayList<>();
107+
} else {
108+
currentLayer.add(currentToken.getValue());
109+
}
110+
currentToken = tokenizer.getNextValidToken();
111+
}
112+
result.add(currentLayer);
113+
114+
return result;
115+
}
116+
87117
/**
88118
* Normalizes a CSS property.
89119
*

styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/resolve/CssDeclarationValueTokenizerTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,16 @@ This file is part of the iText (R) project.
4545
import com.itextpdf.styledxmlparser.css.parse.CssDeclarationValueTokenizer;
4646
import com.itextpdf.test.ExtendedITextTest;
4747
import com.itextpdf.test.annotations.type.UnitTest;
48-
import org.junit.Assert;
49-
import org.junit.Test;
50-
import org.junit.experimental.categories.Category;
5148

5249
import java.util.Arrays;
5350
import java.util.List;
5451

52+
import org.junit.Assert;
53+
import org.junit.Test;
54+
import org.junit.experimental.categories.Category;
55+
5556
@Category(UnitTest.class)
5657
public class CssDeclarationValueTokenizerTest extends ExtendedITextTest {
57-
5858
@Test
5959
public void functionTest01() {
6060
runTest("func(param)", Arrays.asList("func(param)"), Arrays.asList(CssDeclarationValueTokenizer.TokenType.FUNCTION));

styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/resolve/shorthand/CssShorthandResolverTest.java

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,63 @@ This file is part of the iText (R) project.
4646
import com.itextpdf.styledxmlparser.css.CssDeclaration;
4747
import com.itextpdf.test.ExtendedITextTest;
4848
import com.itextpdf.test.annotations.type.UnitTest;
49-
import org.junit.Test;
50-
import org.junit.experimental.categories.Category;
5149

5250
import java.util.Set;
5351
import java.util.HashSet;
5452
import java.util.Arrays;
5553
import java.util.List;
5654
import java.util.TreeSet;
5755

58-
import static org.junit.Assert.assertNotNull;
59-
import static org.junit.Assert.fail;
56+
import org.junit.Assert;
57+
import org.junit.Test;
58+
import org.junit.experimental.categories.Category;
6059

6160
@Category(UnitTest.class)
6261
public class CssShorthandResolverTest extends ExtendedITextTest {
62+
@Test
63+
public void linearGradientInlistStyleImageTest() {
64+
String shorthandExpression = "inside linear-gradient(red, green, blue)";
65+
Set<String> expectedResolvedProperties = new HashSet<>(Arrays.asList(
66+
"list-style-type: initial",
67+
"list-style-position: inside",
68+
"list-style-image: linear-gradient(red,green,blue)"
69+
));
70+
71+
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver(CommonCssConstants.LIST_STYLE);
72+
Assert.assertNotNull(resolver);
73+
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand(shorthandExpression);
74+
compareResolvedProps(resolvedShorthandProps, expectedResolvedProperties);
75+
}
6376

77+
@Test
78+
public void repeatingLinearGradientInlistStyleImageTest() {
79+
String shorthandExpression = "square inside repeating-linear-gradient(45deg, blue 7%, red 10%)";
80+
Set<String> expectedResolvedProperties = new HashSet<>(Arrays.asList(
81+
"list-style-type: square",
82+
"list-style-position: inside",
83+
"list-style-image: repeating-linear-gradient(45deg,blue 7%,red 10%)"
84+
));
85+
86+
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver(CommonCssConstants.LIST_STYLE);
87+
Assert.assertNotNull(resolver);
88+
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand(shorthandExpression);
89+
compareResolvedProps(resolvedShorthandProps, expectedResolvedProperties);
90+
}
91+
92+
@Test
93+
public void noneInlistStyleImageTest() {
94+
String shorthandExpression = "circle none inside";
95+
Set<String> expectedResolvedProperties = new HashSet<>(Arrays.asList(
96+
"list-style-type: circle",
97+
"list-style-position: inside",
98+
"list-style-image: none"
99+
));
100+
101+
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver(CommonCssConstants.LIST_STYLE);
102+
Assert.assertNotNull(resolver);
103+
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand(shorthandExpression);
104+
compareResolvedProps(resolvedShorthandProps, expectedResolvedProperties);
105+
}
64106

65107
@Test
66108
public void fontTest01() {
@@ -75,7 +117,7 @@ public void fontTest01() {
75117
) );
76118

77119
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver( CommonCssConstants.FONT );
78-
assertNotNull( resolver );
120+
Assert.assertNotNull( resolver );
79121
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand( shorthandExpression );
80122
compareResolvedProps( resolvedShorthandProps, expectedResolvedProperties );
81123
}
@@ -93,7 +135,7 @@ public void fontTest02() {
93135
) );
94136

95137
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver( CommonCssConstants.FONT );
96-
assertNotNull( resolver );
138+
Assert.assertNotNull( resolver );
97139
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand( shorthandExpression );
98140
compareResolvedProps( resolvedShorthandProps, expectedResolvedProperties );
99141
}
@@ -111,7 +153,7 @@ public void fontTest03() {
111153
) );
112154

113155
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver( CommonCssConstants.FONT );
114-
assertNotNull( resolver );
156+
Assert.assertNotNull( resolver );
115157
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand( shorthandExpression );
116158
compareResolvedProps( resolvedShorthandProps, expectedResolvedProperties );
117159
}
@@ -129,7 +171,7 @@ public void fontTest04() {
129171
) );
130172

131173
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver( CommonCssConstants.FONT );
132-
assertNotNull( resolver );
174+
Assert.assertNotNull( resolver );
133175
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand( shorthandExpression );
134176
compareResolvedProps( resolvedShorthandProps, expectedResolvedProperties );
135177
}
@@ -147,7 +189,7 @@ public void fontTest05() {
147189
) );
148190

149191
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver( CommonCssConstants.FONT );
150-
assertNotNull( resolver );
192+
Assert.assertNotNull( resolver );
151193
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand( shorthandExpression );
152194
compareResolvedProps( resolvedShorthandProps, expectedResolvedProperties );
153195
}
@@ -165,7 +207,7 @@ public void fontTest06() {
165207
) );
166208

167209
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver( CommonCssConstants.FONT );
168-
assertNotNull( resolver );
210+
Assert.assertNotNull( resolver );
169211
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand( shorthandExpression );
170212
compareResolvedProps( resolvedShorthandProps, expectedResolvedProperties );
171213
}
@@ -183,7 +225,7 @@ public void fontTest07() {
183225
) );
184226

185227
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver( CommonCssConstants.FONT );
186-
assertNotNull( resolver );
228+
Assert.assertNotNull( resolver );
187229
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand( shorthandExpression );
188230
compareResolvedProps( resolvedShorthandProps, expectedResolvedProperties );
189231
}
@@ -201,7 +243,7 @@ public void fontTest08() {
201243
) );
202244

203245
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver( CommonCssConstants.FONT );
204-
assertNotNull( resolver );
246+
Assert.assertNotNull( resolver );
205247
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand( shorthandExpression );
206248
compareResolvedProps( resolvedShorthandProps, expectedResolvedProperties );
207249
}
@@ -219,7 +261,7 @@ public void fontTest09() {
219261
) );
220262

221263
IShorthandResolver resolver = ShorthandResolverFactory.getShorthandResolver( CommonCssConstants.FONT );
222-
assertNotNull( resolver );
264+
Assert.assertNotNull( resolver );
223265
List<CssDeclaration> resolvedShorthandProps = resolver.resolveShorthand( shorthandExpression );
224266
compareResolvedProps( resolvedShorthandProps, expectedResolvedProperties );
225267
}
@@ -253,7 +295,7 @@ private void compareResolvedProps(List<CssDeclaration> actual, Set<String> expec
253295
}
254296

255297
if (areDifferent) {
256-
fail( sb.toString() );
298+
Assert.fail( sb.toString() );
257299
}
258300
}
259301
}

styled-xml-parser/src/test/java/com/itextpdf/styledxmlparser/css/util/CssUtilsTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ This file is part of the iText (R) project.
5050
import com.itextpdf.test.annotations.LogMessage;
5151
import com.itextpdf.test.annotations.LogMessages;
5252
import com.itextpdf.test.annotations.type.UnitTest;
53+
54+
import java.util.ArrayList;
55+
import java.util.List;
56+
5357
import org.junit.Assert;
5458
import org.junit.Rule;
5559
import org.junit.Test;
@@ -64,6 +68,47 @@ public class CssUtilsTest extends ExtendedITextTest {
6468
@Rule
6569
public ExpectedException junitExpectedException = ExpectedException.none();
6670

71+
@Test
72+
public void extractShorthandPropertiesFromEmptyStringTest() {
73+
String sourceString = "";
74+
List<List<String>> expected = new ArrayList<>();
75+
expected.add(new ArrayList<String>());
76+
77+
Assert.assertEquals(expected, CssUtils.extractShorthandProperties(sourceString));
78+
}
79+
80+
@Test
81+
public void extractShorthandPropertiesFromStringWithOnePropertyTest() {
82+
String sourceString = "square inside url('sqpurple.gif')";
83+
List<List<String>> expected = new ArrayList<>();
84+
List<String> layer = new ArrayList<>();
85+
layer.add("square");
86+
layer.add("inside");
87+
layer.add("url('sqpurple.gif')");
88+
expected.add(layer);
89+
90+
Assert.assertEquals(expected, CssUtils.extractShorthandProperties(sourceString));
91+
}
92+
93+
@Test
94+
public void extractShorthandPropertiesFromStringWithMultiplyPropertiesTest() {
95+
String sourceString = "center no-repeat url('sqpurple.gif'), #eee 35% url('sqpurple.gif')";
96+
List<List<String>> expected = new ArrayList<>();
97+
List<String> layer = new ArrayList<>();
98+
layer.add("center");
99+
layer.add("no-repeat");
100+
layer.add("url('sqpurple.gif')");
101+
expected.add(layer);
102+
103+
layer = new ArrayList<>();
104+
layer.add("#eee");
105+
layer.add("35%");
106+
layer.add("url('sqpurple.gif')");
107+
expected.add(layer);
108+
109+
Assert.assertEquals(expected, CssUtils.extractShorthandProperties(sourceString));
110+
}
111+
67112
@Test
68113
public void parseAbsoluteLengthFromNAN() {
69114
junitExpectedException.expect(StyledXMLParserException.class);

0 commit comments

Comments
 (0)