Skip to content

Commit 39d7f0e

Browse files
committed
support lab color declaration
1 parent 71f73cb commit 39d7f0e

9 files changed

Lines changed: 550 additions & 15 deletions

File tree

src/main/java/org/htmlunit/cssparser/dom/CSSValueImpl.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ else if (value.getLexicalUnitType() == LexicalUnitType.HWBCOLOR) {
203203
// HWBColor
204204
value_ = new HWBColorImpl(value.getFunctionName(), value.getParameters());
205205
}
206+
else if (value.getLexicalUnitType() == LexicalUnitType.LABCOLOR) {
207+
// LABColor
208+
value_ = new LABColorImpl(value.getFunctionName(), value.getParameters());
209+
}
206210
else if (value.getLexicalUnitType() == LexicalUnitType.COUNTER_FUNCTION) {
207211
// Counter
208212
value_ = new CounterImpl(false, value.getParameters());

src/main/java/org/htmlunit/cssparser/dom/HWBColorImpl.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ public HWBColorImpl(final String function, final LexicalUnit lu) throws DOMExcep
6969
if (next == null) {
7070
throw new DOMException(DOMException.SYNTAX_ERR, "hwb requires at least three values.");
7171
}
72-
if (next.getLexicalUnitType() == LexicalUnitType.OPERATOR_COMMA) {
73-
throw new DOMException(DOMException.SYNTAX_ERR,
74-
"hwb requires consitent separators (blank or comma).");
75-
}
7672

7773
if (LexicalUnitType.NONE != next.getLexicalUnitType()
7874
&& LexicalUnitType.PERCENTAGE != next.getLexicalUnitType()) {
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*
2+
* Copyright (c) 2019-2024 Ronald Brill.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
package org.htmlunit.cssparser.dom;
16+
17+
import java.io.Serializable;
18+
import java.util.Locale;
19+
20+
import org.htmlunit.cssparser.parser.LexicalUnit;
21+
import org.htmlunit.cssparser.parser.LexicalUnit.LexicalUnitType;
22+
import org.w3c.dom.DOMException;
23+
24+
/**
25+
* Implementation of LABColor.
26+
*
27+
* @author Ronald Brill
28+
*/
29+
public class LABColorImpl implements Serializable {
30+
private CSSValueImpl lightness_;
31+
private CSSValueImpl aDistance_;
32+
private CSSValueImpl bDistance_;
33+
private CSSValueImpl alpha_;
34+
35+
/**
36+
* Constructor that reads the values from the given
37+
* chain of LexicalUnits.
38+
* @param function the name of the function lab
39+
* @param lu the values
40+
* @throws DOMException in case of error
41+
*/
42+
public LABColorImpl(final String function, final LexicalUnit lu) throws DOMException {
43+
if (function == null) {
44+
throw new DOMException(DOMException.SYNTAX_ERR, "Color space lab is required.");
45+
}
46+
final String functionLC = function.toLowerCase(Locale.ROOT);
47+
if (!"lab".equals(functionLC)) {
48+
throw new DOMException(DOMException.SYNTAX_ERR, "Color space '" + functionLC + "' not supported.");
49+
}
50+
51+
LexicalUnit next = lu;
52+
if (next == null) {
53+
throw new DOMException(DOMException.SYNTAX_ERR, "lab requires at least three values.");
54+
}
55+
56+
lightness_ = getPart(next);
57+
58+
next = next.getNextLexicalUnit();
59+
if (next == null) {
60+
throw new DOMException(DOMException.SYNTAX_ERR, "lab requires at least three values.");
61+
}
62+
63+
aDistance_ = getPart(next);
64+
next = next.getNextLexicalUnit();
65+
if (next == null) {
66+
throw new DOMException(DOMException.SYNTAX_ERR, "lab requires at least three values.");
67+
}
68+
69+
bDistance_ = getPart(next);
70+
next = next.getNextLexicalUnit();
71+
if (next == null) {
72+
return;
73+
}
74+
75+
if (next.getLexicalUnitType() != LexicalUnitType.OPERATOR_SLASH) {
76+
throw new DOMException(DOMException.SYNTAX_ERR, "lab alpha value must be separated by '/'.");
77+
}
78+
next = next.getNextLexicalUnit();
79+
if (next == null) {
80+
throw new DOMException(DOMException.SYNTAX_ERR, "Missing alpha value.");
81+
}
82+
83+
alpha_ = getPart(next);
84+
next = next.getNextLexicalUnit();
85+
if (next != null) {
86+
throw new DOMException(DOMException.SYNTAX_ERR, "Too many parameters for lab function.");
87+
}
88+
}
89+
90+
private static CSSValueImpl getPart(final LexicalUnit next) {
91+
if (LexicalUnitType.PERCENTAGE == next.getLexicalUnitType()
92+
|| LexicalUnitType.INTEGER == next.getLexicalUnitType()
93+
|| LexicalUnitType.REAL == next.getLexicalUnitType()
94+
|| LexicalUnitType.NONE == next.getLexicalUnitType()) {
95+
return new CSSValueImpl(next, true);
96+
}
97+
98+
throw new DOMException(DOMException.SYNTAX_ERR, "Color part has to be numeric or percentage.");
99+
}
100+
101+
/**
102+
* @return the lightness part.
103+
*/
104+
public CSSValueImpl getLightness() {
105+
return lightness_;
106+
}
107+
108+
/**
109+
* Sets the lightness part to a new value.
110+
* @param lightness the new CSSValueImpl
111+
*/
112+
public void setLightness(final CSSValueImpl lightness) {
113+
lightness_ = lightness;
114+
}
115+
116+
/**
117+
* <p>getA.</p>
118+
*
119+
* @return the a part.
120+
*/
121+
public CSSValueImpl getA() {
122+
return aDistance_;
123+
}
124+
125+
/**
126+
* Sets the a part to a new value.
127+
* @param a the new CSSValueImpl
128+
*/
129+
public void setA(final CSSValueImpl a) {
130+
aDistance_ = a;
131+
}
132+
133+
/**
134+
* <p>getB.</p>
135+
*
136+
* @return the b part.
137+
*/
138+
public CSSValueImpl getB() {
139+
return bDistance_;
140+
}
141+
142+
/**
143+
* Sets the b part to a new value.
144+
* @param b the new CSSValueImpl
145+
*/
146+
public void setB(final CSSValueImpl b) {
147+
bDistance_ = b;
148+
}
149+
150+
/**
151+
* @return the alpha part.
152+
*/
153+
public CSSValueImpl getAlpha() {
154+
return alpha_;
155+
}
156+
157+
/**
158+
* Sets the alpha part to a new value.
159+
* @param alpha the new CSSValueImpl
160+
*/
161+
public void setAlpha(final CSSValueImpl alpha) {
162+
alpha_ = alpha;
163+
}
164+
165+
/**
166+
* {@inheritDoc}
167+
*/
168+
@Override
169+
public String toString() {
170+
final StringBuilder sb = new StringBuilder();
171+
172+
sb
173+
.append("lab(")
174+
.append(lightness_)
175+
.append(" ")
176+
.append(aDistance_)
177+
.append(" ")
178+
.append(bDistance_);
179+
180+
if (null != alpha_) {
181+
sb.append(" / ").append(alpha_);
182+
}
183+
184+
sb.append(")");
185+
186+
return sb.toString();
187+
}
188+
}

src/main/java/org/htmlunit/cssparser/parser/AbstractCSSParser.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,11 @@ protected LexicalUnit hwbColorInternal(final LexicalUnit prev, final String func
804804
return LexicalUnitImpl.createHwbColor(prev, funct, param);
805805
}
806806

807+
protected LexicalUnit labColorInternal(final LexicalUnit prev, final String funct,
808+
final LexicalUnit param) {
809+
return LexicalUnitImpl.createLabColor(prev, funct, param);
810+
}
811+
807812
/**
808813
* Processes a hexadecimal color definition.
809814
*

src/main/java/org/htmlunit/cssparser/parser/LexicalUnit.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ enum LexicalUnitType {
100100
HSLCOLOR,
101101
/** HWBCOLOR. */
102102
HWBCOLOR,
103+
/** LABCOLOR. */
104+
LABCOLOR,
103105
/** NONE. */
104106
NONE,
105107

src/main/java/org/htmlunit/cssparser/parser/LexicalUnitImpl.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.text.DecimalFormatSymbols;
2020
import java.util.Locale;
2121

22+
import org.htmlunit.cssparser.dom.HWBColorImpl;
23+
2224
/**
2325
* Implementation of {@link LexicalUnit}.
2426
*
@@ -409,6 +411,16 @@ public String getCssText() {
409411
appendParams(sb);
410412
sb.append(")");
411413
break;
414+
case HWBCOLOR:
415+
sb.append("hwb(");
416+
appendParams(sb);
417+
sb.append(")");
418+
break;
419+
case LABCOLOR:
420+
sb.append("lab(");
421+
appendParams(sb);
422+
sb.append(")");
423+
break;
412424
case NONE:
413425
sb.append("none");
414426
break;
@@ -693,6 +705,17 @@ public String toDebugString() {
693705
appendParams(sb);
694706
sb.append("))");
695707
break;
708+
case HWBCOLOR:
709+
sb.append("HWBCOLOR(hwb(");
710+
appendParams(sb);
711+
sb.append("))");
712+
break;
713+
case LABCOLOR:
714+
sb.append("LABCOLOR(lab(");
715+
appendParams(sb);
716+
sb.append("))");
717+
break;
718+
696719
case IDENT:
697720
sb.append("IDENT(")
698721
.append(getStringValue())
@@ -1073,7 +1096,7 @@ public static LexicalUnit createRgbColor(final LexicalUnit prev, final String fu
10731096
* @param prev the previous LexicalUnit
10741097
* @param funct the name hsl or hsla
10751098
* @param params the params
1076-
* @return lexical unit with type rgb color
1099+
* @return lexical unit with type hsl color
10771100
*/
10781101
public static LexicalUnit createHslColor(final LexicalUnit prev, final String funct, final LexicalUnit params) {
10791102
return new LexicalUnitImpl(prev, LexicalUnitType.HSLCOLOR, funct, params);
@@ -1083,12 +1106,22 @@ public static LexicalUnit createHslColor(final LexicalUnit prev, final String fu
10831106
* @param prev the previous LexicalUnit
10841107
* @param funct the name hwb
10851108
* @param params the params
1086-
* @return lexical unit with type rgb color
1109+
* @return lexical unit with type hwb color
10871110
*/
10881111
public static LexicalUnit createHwbColor(final LexicalUnit prev, final String funct, final LexicalUnit params) {
10891112
return new LexicalUnitImpl(prev, LexicalUnitType.HWBCOLOR, funct, params);
10901113
}
10911114

1115+
/**
1116+
* @param prev the previous LexicalUnit
1117+
* @param funct the name lab
1118+
* @param params the params
1119+
* @return lexical unit with type lab color
1120+
*/
1121+
public static LexicalUnit createLabColor(final LexicalUnit prev, final String funct, final LexicalUnit params) {
1122+
return new LexicalUnitImpl(prev, LexicalUnitType.LABCOLOR, funct, params);
1123+
}
1124+
10921125
/**
10931126
* @param prev the previous LexicalUnit
10941127
* @return lexical unit with type rgb color

0 commit comments

Comments
 (0)