| 1 | package fr.sii.ogham.html.inliner.impl.jsoup; | |
| 2 | ||
| 3 | import static fr.sii.ogham.core.util.HtmlUtils.getCssUrlFunctions; | |
| 4 | import static fr.sii.ogham.core.util.HtmlUtils.relativize; | |
| 5 | import static fr.sii.ogham.html.inliner.impl.jsoup.CssInlineUtils.isInlineModeAllowed; | |
| 6 | ||
| 7 | import java.util.List; | |
| 8 | import java.util.StringTokenizer; | |
| 9 | import java.util.regex.Pattern; | |
| 10 | ||
| 11 | import org.jsoup.Jsoup; | |
| 12 | import org.jsoup.nodes.DataNode; | |
| 13 | import org.jsoup.nodes.Document; | |
| 14 | import org.jsoup.nodes.Element; | |
| 15 | import org.jsoup.parser.Tag; | |
| 16 | import org.jsoup.select.Elements; | |
| 17 | import org.slf4j.Logger; | |
| 18 | import org.slf4j.LoggerFactory; | |
| 19 | ||
| 20 | import fr.sii.ogham.core.util.CssUrlFunction; | |
| 21 | import fr.sii.ogham.html.inliner.CssInliner; | |
| 22 | import fr.sii.ogham.html.inliner.CssInlinerConstants.InlineModes; | |
| 23 | import fr.sii.ogham.html.inliner.ExternalCss; | |
| 24 | ||
| 25 | public class JsoupCssInliner implements CssInliner { | |
| 26 | private static final Logger LOG = LoggerFactory.getLogger(JsoupCssInliner.class); | |
| 27 | | |
| 28 | private static final String HREF_ATTR = "href"; | |
| 29 | private static final String TEMP_STYLE_ATTR = "data-cssstyle"; | |
| 30 | private static final String STYLE_ATTR = "style"; | |
| 31 | private static final String STYLE_TAG = "style"; | |
| 32 | private static final String CSS_LINKS_SELECTOR = "link[rel*=\"stylesheet\"], link[type=\"text/css\"], link[href$=\".css\"]"; | |
| 33 | private static final Pattern NEW_LINES = Pattern.compile("\n"); | |
| 34 | private static final Pattern COMMENTS = Pattern.compile("/\\*.*?\\*/"); | |
| 35 | private static final Pattern SPACES = Pattern.compile(" +"); | |
| 36 | private static final String QUOTE_ENTITY = """; | |
| 37 | ||
| 38 | @Override | |
| 39 | public String inline(String htmlContent, List<ExternalCss> cssContents) { | |
| 40 | Document doc = Jsoup.parse(htmlContent); | |
| 41 | ||
| 42 |
3
1. inline : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::internStyles → NO_COVERAGE 2. inline : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::internStyles → KILLED 3. inline : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::internStyles → KILLED |
internStyles(doc, cssContents); |
| 43 | String stylesheet = fetchStyles(doc); | |
| 44 |
3
1. inline : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::extractStyles → NO_COVERAGE 2. inline : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::extractStyles → KILLED 3. inline : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::extractStyles → KILLED |
extractStyles(doc, stylesheet); |
| 45 |
3
1. inline : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::applyStyles → NO_COVERAGE 2. inline : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::applyStyles → KILLED 3. inline : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::applyStyles → KILLED |
applyStyles(doc); |
| 46 | ||
| 47 |
3
1. inline : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::inline → NO_COVERAGE 2. inline : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::inline → KILLED 3. inline : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::inline → KILLED |
return doc.outerHtml(); |
| 48 | } | |
| 49 | ||
| 50 | /** | |
| 51 | * Applies the styles to a <code>data-cssstyle</code> attribute. This is | |
| 52 | * because the styles need to be applied sequentially, but before the | |
| 53 | * <code>style</code> defined for the element inline. | |
| 54 | * | |
| 55 | * @param doc | |
| 56 | * the html document | |
| 57 | */ | |
| 58 | private static void extractStyles(Document doc, String stylesheet) { | |
| 59 | String cleanedStylesheet = ignoreAtRules(stylesheet); | |
| 60 | cleanedStylesheet = NEW_LINES.matcher(cleanedStylesheet).replaceAll(""); | |
| 61 | cleanedStylesheet = COMMENTS.matcher(cleanedStylesheet).replaceAll(""); | |
| 62 | cleanedStylesheet = SPACES.matcher(cleanedStylesheet).replaceAll(" "); | |
| 63 | String styleRules = cleanedStylesheet.trim(); | |
| 64 | String delims = "{}"; | |
| 65 | StringTokenizer st = new StringTokenizer(styleRules, delims); | |
| 66 |
5
1. extractStyles : changed conditional boundary → SURVIVED 2. extractStyles : changed conditional boundary → NO_COVERAGE 3. extractStyles : negated conditional → NO_COVERAGE 4. extractStyles : negated conditional → KILLED 5. extractStyles : negated conditional → KILLED |
while (st.countTokens() > 1) { |
| 67 | String selector = st.nextToken(); | |
| 68 | String properties = st.nextToken(); | |
| 69 | Elements selectedElements = doc.select(selector.trim()); | |
| 70 | for (Element selElem : selectedElements) { | |
| 71 | String oldProperties = selElem.attr(TEMP_STYLE_ATTR); | |
| 72 |
6
1. extractStyles : changed conditional boundary → NO_COVERAGE 2. extractStyles : negated conditional → NO_COVERAGE 3. extractStyles : changed conditional boundary → KILLED 4. extractStyles : changed conditional boundary → KILLED 5. extractStyles : negated conditional → KILLED 6. extractStyles : negated conditional → KILLED |
selElem.attr(TEMP_STYLE_ATTR, oldProperties.length() > 0 ? concatenateProperties(oldProperties, properties) : properties); |
| 73 | } | |
| 74 | } | |
| 75 | } | |
| 76 | | |
| 77 | /** | |
| 78 | * Replace link tags with style tags in order to keep the same inclusion | |
| 79 | * order | |
| 80 | * | |
| 81 | * @param doc | |
| 82 | * the html document | |
| 83 | * @param cssContents | |
| 84 | * the list of external css files with their content | |
| 85 | */ | |
| 86 | private static void internStyles(Document doc, List<ExternalCss> cssContents) { | |
| 87 | Elements els = doc.select(CSS_LINKS_SELECTOR); | |
| 88 | for (Element e : els) { | |
| 89 |
3
1. internStyles : negated conditional → NO_COVERAGE 2. internStyles : negated conditional → KILLED 3. internStyles : negated conditional → KILLED |
if (isInlineModeAllowed(e, InlineModes.STYLE_ATTR)) { |
| 90 | String path = e.attr(HREF_ATTR); | |
| 91 | ExternalCss css = getCss(cssContents, path); | |
| 92 |
3
1. internStyles : negated conditional → NO_COVERAGE 2. internStyles : negated conditional → KILLED 3. internStyles : negated conditional → KILLED |
if (css != null) { |
| 93 | Element style = new Element(Tag.valueOf(STYLE_TAG), ""); | |
| 94 | style.appendChild(new DataNode(getCssContent(css))); | |
| 95 |
3
1. internStyles : removed call to org/jsoup/nodes/Element::replaceWith → NO_COVERAGE 2. internStyles : removed call to org/jsoup/nodes/Element::replaceWith → KILLED 3. internStyles : removed call to org/jsoup/nodes/Element::replaceWith → KILLED |
e.replaceWith(style); |
| 96 | } | |
| 97 | } | |
| 98 | } | |
| 99 | } | |
| 100 | ||
| 101 | private static ExternalCss getCss(List<ExternalCss> cssContents, String path) { | |
| 102 | for (ExternalCss css : cssContents) { | |
| 103 |
3
1. getCss : negated conditional → NO_COVERAGE 2. getCss : negated conditional → KILLED 3. getCss : negated conditional → KILLED |
if (css.getPath().getOriginalPath().contains(path)) { |
| 104 |
3
1. getCss : replaced return value with null for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::getCss → NO_COVERAGE 2. getCss : replaced return value with null for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::getCss → KILLED 3. getCss : replaced return value with null for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::getCss → KILLED |
return css; |
| 105 | } | |
| 106 | } | |
| 107 | return null; | |
| 108 | } | |
| 109 | ||
| 110 | /** | |
| 111 | * Generates a stylesheet from an html document | |
| 112 | * | |
| 113 | * @param doc | |
| 114 | * the html document | |
| 115 | * @return a string representing the stylesheet. | |
| 116 | */ | |
| 117 | private static String fetchStyles(Document doc) { | |
| 118 | Elements els = doc.select(STYLE_TAG); | |
| 119 | StringBuilder styles = new StringBuilder(); | |
| 120 | for (Element e : els) { | |
| 121 |
3
1. fetchStyles : negated conditional → NO_COVERAGE 2. fetchStyles : negated conditional → KILLED 3. fetchStyles : negated conditional → KILLED |
if (isInlineModeAllowed(e, InlineModes.STYLE_ATTR)) { |
| 122 | styles.append(e.data()); | |
| 123 |
3
1. fetchStyles : removed call to org/jsoup/nodes/Element::remove → NO_COVERAGE 2. fetchStyles : removed call to org/jsoup/nodes/Element::remove → KILLED 3. fetchStyles : removed call to org/jsoup/nodes/Element::remove → KILLED |
e.remove(); |
| 124 | } | |
| 125 | } | |
| 126 |
3
1. fetchStyles : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::fetchStyles → NO_COVERAGE 2. fetchStyles : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::fetchStyles → KILLED 3. fetchStyles : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::fetchStyles → KILLED |
return styles.toString(); |
| 127 | } | |
| 128 | ||
| 129 | /** | |
| 130 | * Transfers styles from the <code>data-cssstyle</code> attribute to the | |
| 131 | * <code>style</code> attribute. | |
| 132 | * | |
| 133 | * @param doc | |
| 134 | * the html document | |
| 135 | */ | |
| 136 | private static void applyStyles(Document doc) { | |
| 137 | Elements allStyledElements = doc.getElementsByAttribute(TEMP_STYLE_ATTR); | |
| 138 | ||
| 139 | for (Element e : allStyledElements) { | |
| 140 |
3
1. applyStyles : negated conditional → NO_COVERAGE 2. applyStyles : negated conditional → KILLED 3. applyStyles : negated conditional → KILLED |
if (isInlineModeAllowed(e, InlineModes.STYLE_ATTR)) { |
| 141 | String newStyle = e.attr(TEMP_STYLE_ATTR); | |
| 142 | String oldStyle = e.attr(STYLE_ATTR); | |
| 143 | e.attr(STYLE_ATTR, (trimAll(newStyle) + ";" + trimAll(oldStyle)).replaceAll(";+", ";").trim()); | |
| 144 | } | |
| 145 | e.removeAttr(TEMP_STYLE_ATTR); | |
| 146 | } | |
| 147 | } | |
| 148 | ||
| 149 | private static String concatenateProperties(String oldProp, String newProp) { | |
| 150 | String prop = oldProp; | |
| 151 |
2
1. concatenateProperties : negated conditional → SURVIVED 2. concatenateProperties : negated conditional → NO_COVERAGE |
if (!prop.endsWith(";")) { |
| 152 | prop += ";"; | |
| 153 | } | |
| 154 |
3
1. concatenateProperties : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::concatenateProperties → NO_COVERAGE 2. concatenateProperties : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::concatenateProperties → KILLED 3. concatenateProperties : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::concatenateProperties → KILLED |
return trimAll(prop) + " " + trimAll(newProp) + ";"; |
| 155 | } | |
| 156 | | |
| 157 | private static String trimAll(String str) { | |
| 158 |
3
1. trimAll : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::trimAll → NO_COVERAGE 2. trimAll : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::trimAll → KILLED 3. trimAll : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::trimAll → KILLED |
return str.replaceAll("\\s+", " ").trim(); |
| 159 | } | |
| 160 | | |
| 161 | ||
| 162 | private static String ignoreAtRules(String stylesheet) { | |
| 163 | StringBuilder sb = new StringBuilder(); | |
| 164 | AtRuleParserContext ctx = new AtRuleParserContext(); | |
| 165 |
9
1. ignoreAtRules : changed conditional boundary → NO_COVERAGE 2. ignoreAtRules : Changed increment from 1 to -1 → NO_COVERAGE 3. ignoreAtRules : negated conditional → NO_COVERAGE 4. ignoreAtRules : changed conditional boundary → KILLED 5. ignoreAtRules : changed conditional boundary → KILLED 6. ignoreAtRules : Changed increment from 1 to -1 → KILLED 7. ignoreAtRules : Changed increment from 1 to -1 → KILLED 8. ignoreAtRules : negated conditional → KILLED 9. ignoreAtRules : negated conditional → KILLED |
for (int i=0 ; i<stylesheet.length() ; i++) { |
| 166 | char c = stylesheet.charAt(i); | |
| 167 |
2
1. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::updateLineNumberIfNewLine → NO_COVERAGE 2. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::updateLineNumberIfNewLine → SURVIVED |
updateLineNumberIfNewLine(ctx, c); |
| 168 |
3
1. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::markAsStartOfAtRuleIfAtChar → NO_COVERAGE 2. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::markAsStartOfAtRuleIfAtChar → SURVIVED 3. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::markAsStartOfAtRuleIfAtChar → KILLED |
markAsStartOfAtRuleIfAtChar(ctx, c); |
| 169 |
3
1. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket → NO_COVERAGE 2. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket → SURVIVED 3. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket → KILLED |
markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket(ctx, c); |
| 170 |
3
1. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket → SURVIVED 2. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket → NO_COVERAGE 3. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket → KILLED |
markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket(ctx, c); |
| 171 |
3
1. ignoreAtRules : negated conditional → NO_COVERAGE 2. ignoreAtRules : negated conditional → KILLED 3. ignoreAtRules : negated conditional → KILLED |
if (ignoreAtRuleIfAtEndOfAtRule(ctx, c)) { |
| 172 | continue; | |
| 173 | } | |
| 174 |
3
1. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::updateStylesAndAtRuleContent → NO_COVERAGE 2. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::updateStylesAndAtRuleContent → KILLED 3. ignoreAtRules : removed call to fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::updateStylesAndAtRuleContent → KILLED |
updateStylesAndAtRuleContent(ctx, sb, c); |
| 175 | } | |
| 176 |
3
1. ignoreAtRules : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::ignoreAtRules → NO_COVERAGE 2. ignoreAtRules : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::ignoreAtRules → KILLED 3. ignoreAtRules : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::ignoreAtRules → KILLED |
return sb.toString(); |
| 177 | } | |
| 178 | ||
| 179 | private static boolean ignoreAtRuleIfAtEndOfAtRule(AtRuleParserContext ctx, char c) { | |
| 180 |
7
1. ignoreAtRuleIfAtEndOfAtRule : negated conditional → NO_COVERAGE 2. ignoreAtRuleIfAtEndOfAtRule : negated conditional → NO_COVERAGE 3. ignoreAtRuleIfAtEndOfAtRule : negated conditional → NO_COVERAGE 4. ignoreAtRuleIfAtEndOfAtRule : negated conditional → KILLED 5. ignoreAtRuleIfAtEndOfAtRule : negated conditional → KILLED 6. ignoreAtRuleIfAtEndOfAtRule : negated conditional → KILLED 7. ignoreAtRuleIfAtEndOfAtRule : negated conditional → KILLED |
if (ctx.inAtRule && !ctx.inNestedAtRule && c == ';') { |
| 181 | ctx.inAtRule = false; | |
| 182 | LOG.warn("{} rule is not handled by JsoupCssInliner implementation. Line {}:'{}' is skipped", rulename(ctx.rule), ctx.startLineOfCurrentAtRule, ctx.rule); | |
| 183 |
2
1. ignoreAtRuleIfAtEndOfAtRule : replaced boolean return with false for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::ignoreAtRuleIfAtEndOfAtRule → NO_COVERAGE 2. ignoreAtRuleIfAtEndOfAtRule : replaced boolean return with false for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::ignoreAtRuleIfAtEndOfAtRule → KILLED |
return true; |
| 184 | } | |
| 185 |
7
1. ignoreAtRuleIfAtEndOfAtRule : negated conditional → NO_COVERAGE 2. ignoreAtRuleIfAtEndOfAtRule : negated conditional → SURVIVED 3. ignoreAtRuleIfAtEndOfAtRule : negated conditional → NO_COVERAGE 4. ignoreAtRuleIfAtEndOfAtRule : negated conditional → NO_COVERAGE 5. ignoreAtRuleIfAtEndOfAtRule : negated conditional → KILLED 6. ignoreAtRuleIfAtEndOfAtRule : negated conditional → KILLED 7. ignoreAtRuleIfAtEndOfAtRule : negated conditional → KILLED |
if (ctx.inAtRule && ctx.inNestedAtRule && ctx.numberOfOpenedAtRules == 0) { |
| 186 | ctx.inAtRule = false; | |
| 187 | ctx.inNestedAtRule = false; | |
| 188 | LOG.warn("{} rule is not handled by JsoupCssInliner implementation. Lines {}-{} are skipped", rulename(ctx.rule), ctx.startLineOfCurrentAtRule, ctx.line); | |
| 189 |
2
1. ignoreAtRuleIfAtEndOfAtRule : replaced boolean return with false for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::ignoreAtRuleIfAtEndOfAtRule → SURVIVED 2. ignoreAtRuleIfAtEndOfAtRule : replaced boolean return with false for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::ignoreAtRuleIfAtEndOfAtRule → NO_COVERAGE |
return true; |
| 190 | } | |
| 191 |
3
1. ignoreAtRuleIfAtEndOfAtRule : replaced boolean return with true for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::ignoreAtRuleIfAtEndOfAtRule → NO_COVERAGE 2. ignoreAtRuleIfAtEndOfAtRule : replaced boolean return with true for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::ignoreAtRuleIfAtEndOfAtRule → KILLED 3. ignoreAtRuleIfAtEndOfAtRule : replaced boolean return with true for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::ignoreAtRuleIfAtEndOfAtRule → KILLED |
return false; |
| 192 | } | |
| 193 | ||
| 194 | private static void updateStylesAndAtRuleContent(AtRuleParserContext ctx, StringBuilder sb, char c) { | |
| 195 |
3
1. updateStylesAndAtRuleContent : negated conditional → NO_COVERAGE 2. updateStylesAndAtRuleContent : negated conditional → KILLED 3. updateStylesAndAtRuleContent : negated conditional → KILLED |
if (!ctx.inAtRule) { |
| 196 | sb.append(c); | |
| 197 | ctx.rule = new StringBuilder(); | |
| 198 | } else { | |
| 199 | ctx.rule.append(c); | |
| 200 | } | |
| 201 | } | |
| 202 | ||
| 203 | private static void markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket(AtRuleParserContext ctx, char c) { | |
| 204 |
7
1. markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket : negated conditional → SURVIVED 2. markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket : negated conditional → NO_COVERAGE 3. markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket : negated conditional → NO_COVERAGE 4. markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket : negated conditional → NO_COVERAGE 5. markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket : negated conditional → KILLED 6. markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket : negated conditional → KILLED 7. markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket : negated conditional → KILLED |
if (ctx.inAtRule && ctx.inNestedAtRule && c == '}') { |
| 205 |
2
1. markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket : Replaced integer subtraction with addition → NO_COVERAGE 2. markAsEndOfNestedAtRuleIfAlreadyInAtRuleAndIsClosingBracket : Replaced integer subtraction with addition → KILLED |
ctx.numberOfOpenedAtRules--; |
| 206 | } | |
| 207 | } | |
| 208 | ||
| 209 | private static void markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket(AtRuleParserContext ctx, char c) { | |
| 210 |
5
1. markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket : negated conditional → NO_COVERAGE 2. markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket : negated conditional → SURVIVED 3. markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket : negated conditional → NO_COVERAGE 4. markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket : negated conditional → KILLED 5. markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket : negated conditional → KILLED |
if (ctx.inAtRule && c == '{') { |
| 211 | ctx.inNestedAtRule = true; | |
| 212 |
2
1. markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket : Replaced integer addition with subtraction → NO_COVERAGE 2. markAsStartOfNestedAtRuleIfAlreadyInAtRuleAndIsOpeningBracket : Replaced integer addition with subtraction → KILLED |
ctx.numberOfOpenedAtRules++; |
| 213 | } | |
| 214 | } | |
| 215 | ||
| 216 | private static void markAsStartOfAtRuleIfAtChar(AtRuleParserContext ctx, char c) { | |
| 217 |
5
1. markAsStartOfAtRuleIfAtChar : negated conditional → NO_COVERAGE 2. markAsStartOfAtRuleIfAtChar : negated conditional → NO_COVERAGE 3. markAsStartOfAtRuleIfAtChar : negated conditional → KILLED 4. markAsStartOfAtRuleIfAtChar : negated conditional → KILLED 5. markAsStartOfAtRuleIfAtChar : negated conditional → KILLED |
if (c == '@' && !ctx.inAtRule) { |
| 218 | ctx.inAtRule = true; | |
| 219 | ctx.startLineOfCurrentAtRule = ctx.line; | |
| 220 | } | |
| 221 | } | |
| 222 | ||
| 223 | private static void updateLineNumberIfNewLine(AtRuleParserContext ctx, char c) { | |
| 224 |
2
1. updateLineNumberIfNewLine : negated conditional → NO_COVERAGE 2. updateLineNumberIfNewLine : negated conditional → SURVIVED |
if (c == '\n') { |
| 225 |
2
1. updateLineNumberIfNewLine : Replaced integer addition with subtraction → NO_COVERAGE 2. updateLineNumberIfNewLine : Replaced integer addition with subtraction → SURVIVED |
ctx.line++; |
| 226 | } | |
| 227 | } | |
| 228 | | |
| 229 | private static String rulename(StringBuilder rule) { | |
| 230 | StringBuilder name = new StringBuilder(); | |
| 231 |
6
1. rulename : changed conditional boundary → SURVIVED 2. rulename : changed conditional boundary → NO_COVERAGE 3. rulename : Changed increment from 1 to -1 → NO_COVERAGE 4. rulename : negated conditional → NO_COVERAGE 5. rulename : negated conditional → SURVIVED 6. rulename : Changed increment from 1 to -1 → KILLED |
for (int i=0 ; i<rule.length() ; i++) { |
| 232 | char c = rule.charAt(i); | |
| 233 |
8
1. rulename : negated conditional → SURVIVED 2. rulename : negated conditional → NO_COVERAGE 3. rulename : negated conditional → SURVIVED 4. rulename : negated conditional → NO_COVERAGE 5. rulename : negated conditional → SURVIVED 6. rulename : negated conditional → NO_COVERAGE 7. rulename : negated conditional → NO_COVERAGE 8. rulename : negated conditional → SURVIVED |
if (c != '@' && c != '-' && !Character.isAlphabetic(c) && !Character.isDigit(c)) { |
| 234 | break; | |
| 235 | } | |
| 236 | name.append(c); | |
| 237 | } | |
| 238 |
2
1. rulename : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::rulename → NO_COVERAGE 2. rulename : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::rulename → SURVIVED |
return name.toString(); |
| 239 | } | |
| 240 | ||
| 241 | ||
| 242 | private static String getCssContent(ExternalCss css) { | |
| 243 | String content = css.getContent(); | |
| 244 |
3
1. getCssContent : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::getCssContent → NO_COVERAGE 2. getCssContent : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::getCssContent → KILLED 3. getCssContent : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::getCssContent → KILLED |
return updateRelativeUrls(content, css); |
| 245 | } | |
| 246 | ||
| 247 | private static String updateRelativeUrls(String content, ExternalCss css) { | |
| 248 | String newContent = content; | |
| 249 | for (CssUrlFunction match : getCssUrlFunctions(content, QUOTE_ENTITY)) { | |
| 250 | newContent = match.rewriteUrl(newContent, relativize(css.getPath().getOriginalPath(), match.getUrl())); | |
| 251 | } | |
| 252 |
3
1. updateRelativeUrls : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::updateRelativeUrls → NO_COVERAGE 2. updateRelativeUrls : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::updateRelativeUrls → KILLED 3. updateRelativeUrls : replaced return value with "" for fr/sii/ogham/html/inliner/impl/jsoup/JsoupCssInliner::updateRelativeUrls → KILLED |
return newContent; |
| 253 | } | |
| 254 | ||
| 255 | private static class AtRuleParserContext { | |
| 256 | protected int line; | |
| 257 | protected int startLineOfCurrentAtRule; | |
| 258 | protected boolean inAtRule; | |
| 259 | protected boolean inNestedAtRule; | |
| 260 | protected int numberOfOpenedAtRules; | |
| 261 | protected StringBuilder rule; | |
| 262 | | |
| 263 | public AtRuleParserContext() { | |
| 264 | super(); | |
| 265 | this.line = 1; | |
| 266 | this.startLineOfCurrentAtRule = 0; | |
| 267 | this.inAtRule = false; | |
| 268 | this.inNestedAtRule = false; | |
| 269 | this.numberOfOpenedAtRules = 0; | |
| 270 | this.rule = new StringBuilder(); | |
| 271 | } | |
| 272 | | |
| 273 | | |
| 274 | } | |
| 275 | } | |
Mutations | ||
| 42 |
1.1 2.2 3.3 |
|
| 44 |
1.1 2.2 3.3 |
|
| 45 |
1.1 2.2 3.3 |
|
| 47 |
1.1 2.2 3.3 |
|
| 66 |
1.1 2.2 3.3 4.4 5.5 |
|
| 72 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
| 89 |
1.1 2.2 3.3 |
|
| 92 |
1.1 2.2 3.3 |
|
| 95 |
1.1 2.2 3.3 |
|
| 103 |
1.1 2.2 3.3 |
|
| 104 |
1.1 2.2 3.3 |
|
| 121 |
1.1 2.2 3.3 |
|
| 123 |
1.1 2.2 3.3 |
|
| 126 |
1.1 2.2 3.3 |
|
| 140 |
1.1 2.2 3.3 |
|
| 151 |
1.1 2.2 |
|
| 154 |
1.1 2.2 3.3 |
|
| 158 |
1.1 2.2 3.3 |
|
| 165 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 |
|
| 167 |
1.1 2.2 |
|
| 168 |
1.1 2.2 3.3 |
|
| 169 |
1.1 2.2 3.3 |
|
| 170 |
1.1 2.2 3.3 |
|
| 171 |
1.1 2.2 3.3 |
|
| 174 |
1.1 2.2 3.3 |
|
| 176 |
1.1 2.2 3.3 |
|
| 180 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |
|
| 183 |
1.1 2.2 |
|
| 185 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |
|
| 189 |
1.1 2.2 |
|
| 191 |
1.1 2.2 3.3 |
|
| 195 |
1.1 2.2 3.3 |
|
| 204 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |
|
| 205 |
1.1 2.2 |
|
| 210 |
1.1 2.2 3.3 4.4 5.5 |
|
| 212 |
1.1 2.2 |
|
| 217 |
1.1 2.2 3.3 4.4 5.5 |
|
| 224 |
1.1 2.2 |
|
| 225 |
1.1 2.2 |
|
| 231 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
| 233 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 |
|
| 238 |
1.1 2.2 |
|
| 244 |
1.1 2.2 3.3 |
|
| 252 |
1.1 2.2 3.3 |