diff --git a/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/constants/MarginBoxName.java b/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/constants/MarginBoxName.java index b7dde4355..f30e9a18e 100644 --- a/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/constants/MarginBoxName.java +++ b/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/constants/MarginBoxName.java @@ -19,6 +19,9 @@ */ package org.xhtmlrenderer.css.constants; +import com.google.errorprone.annotations.CheckReturnValue; +import org.jspecify.annotations.Nullable; + import java.util.HashMap; import java.util.Map; @@ -73,6 +76,8 @@ public String toString() { return _ident; } + @Nullable + @CheckReturnValue public static MarginBoxName valueOf(String ident) { return ALL.get(ident); } diff --git a/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/parser/CSSParser.java b/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/parser/CSSParser.java index 022e7487a..d4929d9d9 100644 --- a/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/parser/CSSParser.java +++ b/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/parser/CSSParser.java @@ -519,21 +519,23 @@ private void page(Stylesheet stylesheet) throws IOException { //System.out.println("page()"); Token t = next(); try { - PageRule pageRule = new PageRule(stylesheet.getOrigin()); if (t == Token.TK_PAGE_SYM) { + String pageName = null; + String pseudoPage = null; + Map> margins = new HashMap<>(); + skip_whitespace(); t = la(); if (t == Token.TK_IDENT) { - String pageName = getTokenValue(t); + pageName = getTokenValue(t); if (pageName.equals("auto")) { throw new CSSParseException("page name may not be auto", getCurrentLine()); } next(); - pageRule.setName(pageName); t = la(); } if (t == Token.TK_COLON) { - pageRule.setPseudoPage(pseudo_page()); + pseudoPage = pseudo_page(); } Ruleset ruleset = new Ruleset(stylesheet.getOrigin()); @@ -548,7 +550,7 @@ private void page(Stylesheet stylesheet) throws IOException { skip_whitespace(); break; } else if (t == Token.TK_AT_RULE) { - margin(stylesheet, pageRule); + margins = margin(stylesheet); } else { declaration_list(ruleset, false, true, false); } @@ -558,7 +560,7 @@ private void page(Stylesheet stylesheet) throws IOException { throw new CSSParseException(t, Token.TK_LBRACE, getCurrentLine()); } - pageRule.addContent(ruleset); + PageRule pageRule = new PageRule(stylesheet.getOrigin(), pageName, pseudoPage, margins, ruleset); stylesheet.addContent(pageRule); } else { push(t); @@ -573,19 +575,22 @@ private void page(Stylesheet stylesheet) throws IOException { // margin : // margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S* // ; - private void margin(Stylesheet stylesheet, PageRule pageRule) throws IOException { + private Map> margin(Stylesheet stylesheet) throws IOException { + Map> margins = new HashMap<>(); + Token t = next(); if (t != Token.TK_AT_RULE) { error(new CSSParseException(t, Token.TK_AT_RULE, getCurrentLine()), "at rule", true); recover(true, false); - return; + return margins; } + String name = getTokenValue(t); MarginBoxName marginBoxName = MarginBoxName.valueOf(name); if (marginBoxName == null) { error(new CSSParseException(name + " is not a valid margin box name", getCurrentLine()), "at rule", true); recover(true, false); - return; + return margins; } skip_whitespace(); @@ -600,7 +605,7 @@ private void margin(Stylesheet stylesheet, PageRule pageRule) throws IOException push(t); throw new CSSParseException(t, Token.TK_RBRACE, getCurrentLine()); } - pageRule.addMarginBoxProperties(marginBoxName, ruleset.getPropertyDeclarations()); + margins.put(marginBoxName, ruleset.getPropertyDeclarations()); } else { push(t); throw new CSSParseException(t, Token.TK_LBRACE, getCurrentLine()); @@ -609,6 +614,7 @@ private void margin(Stylesheet stylesheet, PageRule pageRule) throws IOException error(e, "margin box", true); recover(false, false); } + return margins; } diff --git a/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/sheet/PageRule.java b/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/sheet/PageRule.java index 1b37cf99c..582b89e84 100644 --- a/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/sheet/PageRule.java +++ b/flying-saucer-core/src/main/java/org/xhtmlrenderer/css/sheet/PageRule.java @@ -28,50 +28,41 @@ import java.util.Map; public class PageRule implements RulesetContainer { - private String _name; - private String _pseudoPage; - private Ruleset _ruleset; + private final String _name; + private final String _pseudoPage; + private final Ruleset _ruleset; private final Origin _origin; private final Map> _marginBoxes = new HashMap<>(); private int _pos; - private int _specificityF; - private int _specificityG; - private int _specificityH; + private final int _specificityF; + private final int _specificityG; + private final int _specificityH; - public PageRule(Origin origin) { + public PageRule(Origin origin, @Nullable String name, @Nullable String pseudoPage, Map> marginBoxes, Ruleset ruleset) { _origin = origin; + _name = name; + _specificityF = name == null ? 0 : 1; + _ruleset = ruleset; + _pseudoPage = pseudoPage; + _specificityG = "first".equals(pseudoPage) ? 1 : 0; + _specificityH = "first".equals(pseudoPage) ? 0 : 1; + _marginBoxes.putAll(marginBoxes); } public String getPseudoPage() { return _pseudoPage; } - public void setPseudoPage(String pseudoPage) { - _pseudoPage = pseudoPage; - if (pseudoPage.equals("first")) { - _specificityG = 1; - } else { - _specificityH = 1; - } - } - public Ruleset getRuleset() { return _ruleset; } - public void setRuleset(Ruleset ruleset) { - _ruleset = ruleset; - } - @Override public void addContent(Ruleset ruleset) { - if (_ruleset != null) { - throw new IllegalStateException("Ruleset has already been set"); - } - _ruleset = ruleset; + throw new IllegalStateException("Ruleset has already been set"); } @Override @@ -83,19 +74,10 @@ public String getName() { return _name; } - public void setName(String name) { - _name = name; - _specificityF = 1; - } - public List getMarginBoxProperties(MarginBoxName name) { return _marginBoxes.get(name); } - public void addMarginBoxProperties(MarginBoxName name, List props) { - _marginBoxes.put(name, props); - } - public Map> getMarginBoxes() { return _marginBoxes; }