1313import org .w3c .css .values .CssIdent ;
1414import org .w3c .css .values .CssTypes ;
1515import org .w3c .css .values .CssValue ;
16+ import org .w3c .css .values .CssValueList ;
17+
18+ import static org .w3c .css .values .CssOperator .SPACE ;
1619
1720/**
18- * @spec http ://www.w3.org/TR/2007 /WD-css3-box-20070809/#the-lsquo
21+ * @spec https ://www.w3.org/TR/2015 /WD-css-display-3-20151015/#propdef-display
1922 * @spec https://www.w3.org/TR/2016/CR-css-flexbox-1-20160526/#flex-containers
20- * @spec http://www.w3.org/TR/2011/WD-css3-lists-20110524/#display-marker
2123 */
2224public class CssDisplay extends org .w3c .css .properties .css .CssDisplay {
2325
24- public static CssIdent [] allowed_values ;
26+ public static CssIdent [] display_outside ;
27+ public static CssIdent [] display_inside ;
28+ public static CssIdent [] display_listitem ;
29+ public static CssIdent [] display_internal ;
30+ public static CssIdent [] display_box ;
31+ public static CssIdent [] display_legacy ;
32+ // for display-listitem
33+ public static CssIdent [] display_flow ;
34+
2535
2636 static {
27- String [] DISPLAY = {
28- "inline" , "block" , "inline-block" , "list-item" , "run-in" ,
29- "compact" , "table" , "inline-table" , "table-row-group" ,
30- "table-header-group" , "table-footer-group" , "table-row" ,
31- "table-column-group" , "table-column" , "table-cell" ,
32- "table-caption" , "ruby" , "ruby-base" , "ruby-text" ,
33- "ruby-base-group" , "ruby-text-group" , "none"
34- };
35- String [] FLEX_DISPLAY = {"flex" , "inline-flex" };
36- String [] LISTS_DISPLAY = {"marker" };
37- allowed_values = new CssIdent [DISPLAY .length +FLEX_DISPLAY .length +LISTS_DISPLAY .length ];
37+ String [] DISPLAY_OUTSIDE = {"block" , "inline" , "run-in" };
38+ String [] DISPLAY_INSIDE = {"flow" , "flow-root" , "table" , "flex" , "grid" , "ruby" };
39+ String [] DISPLAY_LISTITEM = {"list-item" };
40+ String [] DISPLAY_INTERNAL = {"table-row-group" , "table-header-group" , "table-footer-group" ,
41+ "table-row" , "table-cell" , "table-column-group" , "table-column" , "table-caption" ,
42+ "ruby-base" , "ruby-text" , "ruby-base-container" , "ruby-text-container" };
43+ String [] DISPLAY_BOX = {"contents" , "none" };
44+ String [] DISPLAY_LEGACY = {"inline-block" , "inline-list-item" , "inline-table" ,
45+ "inline-flex" , "inline-grid" };
46+ String [] DISPLAY_FLOW = {"flow" , "flow-root" };
47+
48+ display_outside = new CssIdent [DISPLAY_OUTSIDE .length ];
3849 int i = 0 ;
39- for (String aDISPLAY : DISPLAY ) {
40- allowed_values [i ++] = CssIdent .getIdent (aDISPLAY );
50+ for (String aDISPLAY : DISPLAY_OUTSIDE ) {
51+ display_outside [i ++] = CssIdent .getIdent (aDISPLAY );
52+ }
53+ i = 0 ;
54+ display_inside = new CssIdent [DISPLAY_INSIDE .length ];
55+ for (String aDISPLAY : DISPLAY_INSIDE ) {
56+ display_inside [i ++] = CssIdent .getIdent (aDISPLAY );
57+ }
58+ i = 0 ;
59+ display_listitem = new CssIdent [DISPLAY_LISTITEM .length ];
60+ for (String aDISPLAY : DISPLAY_LISTITEM ) {
61+ display_listitem [i ++] = CssIdent .getIdent (aDISPLAY );
4162 }
42- for (String aDISPLAY : FLEX_DISPLAY ) {
43- allowed_values [i ++] = CssIdent .getIdent (aDISPLAY );
63+ i = 0 ;
64+ display_internal = new CssIdent [DISPLAY_INTERNAL .length ];
65+ for (String aDISPLAY : DISPLAY_INTERNAL ) {
66+ display_internal [i ++] = CssIdent .getIdent (aDISPLAY );
4467 }
45- for (String aDISPLAY : LISTS_DISPLAY ) {
46- allowed_values [i ++] = CssIdent .getIdent (aDISPLAY );
68+ i = 0 ;
69+ display_box = new CssIdent [DISPLAY_BOX .length ];
70+ for (String aDISPLAY : DISPLAY_BOX ) {
71+ display_box [i ++] = CssIdent .getIdent (aDISPLAY );
72+ }
73+ i = 0 ;
74+ display_legacy = new CssIdent [DISPLAY_LEGACY .length ];
75+ for (String aDISPLAY : DISPLAY_LEGACY ) {
76+ display_legacy [i ++] = CssIdent .getIdent (aDISPLAY );
77+ }
78+ i = 0 ;
79+ display_flow = new CssIdent [DISPLAY_FLOW .length ];
80+ for (String aDISPLAY : DISPLAY_FLOW ) {
81+ display_flow [i ++] = CssIdent .getIdent (aDISPLAY );
4782 }
4883 }
4984
50- public static CssIdent getMatchingIdent (CssIdent ident ) {
51- for (CssIdent id : allowed_values ) {
85+ public static CssIdent getMatchingIdentInArray (CssIdent ident , CssIdent [] identArray ) {
86+ for (CssIdent id : identArray ) {
5287 if (id .equals (ident )) {
5388 return id ;
5489 }
@@ -74,33 +109,96 @@ public CssDisplay() {
74109 */
75110 public CssDisplay (ApplContext ac , CssExpression expression ,
76111 boolean check ) throws InvalidParamException {
77-
78- if (check && expression . getCount () > 1 ) {
112+ int count = expression . getCount ();
113+ if (check && count > 3 ) {
79114 throw new InvalidParamException ("unrecognize" , ac );
80115 }
81116
82- CssValue val = expression .getValue ();
83-
84117 setByUser ();
85118
86- if (val .getType () == CssTypes .CSS_IDENT ) {
87- CssIdent id_val = (CssIdent ) val ;
88- if (inherit .equals (id_val )) {
89- value = inherit ;
119+ CssValue val ;
120+ char op ;
121+
122+ boolean inside = false ;
123+ boolean outside = false ;
124+ boolean listitem = false ;
125+ // flow can be in listitem and inside...
126+ boolean flow = false ;
127+
128+ CssValueList v = new CssValueList ();
129+ CssIdent id ;
130+
131+ while (!expression .end ()) {
132+ val = expression .getValue ();
133+ op = expression .getOperator ();
134+
135+ if (val .getType () == CssTypes .CSS_IDENT ) {
136+ CssIdent id_val = (CssIdent ) val ;
137+ id = null ;
138+ // let's check the values which can occur only once.
139+ if (count == 1 ) {
140+ if (inherit .equals (id_val )) {
141+ value = inherit ;
142+ } else if ((id = getMatchingIdentInArray (id_val , display_box )) != null ) {
143+ value = id ;
144+ } else if ((id = getMatchingIdentInArray (id_val , display_internal )) != null ) {
145+ value = id ;
146+ } else if ((id = getMatchingIdentInArray (id_val , display_legacy )) != null ) {
147+ value = id ;
148+ }
149+ }
150+ if (id == null ) {
151+ // oustide, list-item and inside (flow) remains.
152+ id = getMatchingIdentInArray (id_val , display_outside );
153+ if (id != null ) {
154+ if (!outside ) {
155+ outside = true ;
156+ v .add (id );
157+ } else {
158+ throw new InvalidParamException ("value" , id_val ,
159+ getPropertyName (), ac );
160+ }
161+ } else {
162+ id = getMatchingIdentInArray (id_val , display_listitem );
163+ if (id != null ) {
164+ // valid only if we don't have inside, or if inside is flow
165+
166+ if (!listitem && (!inside || flow )) {
167+ listitem = true ;
168+ v .add (id );
169+ } else {
170+ throw new InvalidParamException ("value" , id_val ,
171+ getPropertyName (), ac );
172+ }
173+
174+ } else { // inside, with special casing for flow.
175+ id = getMatchingIdentInArray (id_val , display_inside );
176+ if (id == null || inside ) {
177+ throw new InvalidParamException ("value" , id_val ,
178+ getPropertyName (), ac );
179+ }
180+ v .add (id );
181+ inside = true ;
182+ flow = (getMatchingIdentInArray (id_val , display_flow ) != null );
183+ }
184+ }
185+ }
90186 } else {
91- value = getMatchingIdent (id_val );
187+ throw new InvalidParamException ("value" , expression .getValue (),
188+ getPropertyName (), ac );
92189 }
93- if (value == null ) {
94- // do templates...
95- }
96- if (value != null ) {
97- expression .next ();
98- return ;
190+
191+ if (op != SPACE ) {
192+ throw new InvalidParamException ("operator" ,
193+ ((new Character (op )).toString ()),
194+ ac );
99195 }
196+ expression .next ();
100197 }
101198
102- throw new InvalidParamException ("value" , expression .getValue (),
103- getPropertyName (), ac );
199+ if (v .size () > 0 ) {
200+ value = v .size () == 1 ? v .get (0 ) : v ;
201+ }
104202 }
105203
106204 public CssDisplay (ApplContext ac , CssExpression expression )
@@ -112,6 +210,7 @@ public CssDisplay(ApplContext ac, CssExpression expression)
112210 * Is the value of this property is a default value.
113211 * It is used by all macro for the function <code>print</code>
114212 */
213+
115214 public boolean isDefault () {
116215 return (value == inline );
117216 }
0 commit comments