From 3de6aae8579a449315400a6ee2fa3c0a1112538c Mon Sep 17 00:00:00 2001 From: Ronald Brill Date: Sat, 14 Oct 2023 18:58:51 +0200 Subject: [PATCH] move more css code away from the javascript peers --- src/main/java/org/htmlunit/WebWindowImpl.java | 47 +++++++++++++------ src/main/java/org/htmlunit/html/DomNode.java | 2 +- src/main/java/org/htmlunit/html/HtmlLink.java | 23 +++++++++ .../javascript/host/css/StyleSheetList.java | 36 +++----------- 4 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/main/java/org/htmlunit/WebWindowImpl.java b/src/main/java/org/htmlunit/WebWindowImpl.java index c60ab07a145..ce918bebad2 100644 --- a/src/main/java/org/htmlunit/WebWindowImpl.java +++ b/src/main/java/org/htmlunit/WebWindowImpl.java @@ -14,6 +14,7 @@ */ package org.htmlunit; +import static org.htmlunit.BrowserVersionFeatures.JS_STYLESHEETLIST_ACTIVE_ONLY; import static org.htmlunit.BrowserVersionFeatures.JS_WINDOW_COMPUTED_STYLE_PSEUDO_ACCEPT_WITHOUT_COLON; import static org.htmlunit.BrowserVersionFeatures.JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_131; import static org.htmlunit.BrowserVersionFeatures.JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_139; @@ -29,17 +30,18 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.htmlunit.css.ComputedCssStyleDeclaration; +import org.htmlunit.css.CssStyleSheet; import org.htmlunit.css.ElementCssStyleDeclaration; import org.htmlunit.html.DomElement; +import org.htmlunit.html.HtmlElement; +import org.htmlunit.html.HtmlLink; import org.htmlunit.html.HtmlPage; +import org.htmlunit.html.HtmlStyle; import org.htmlunit.javascript.HtmlUnitScriptable; import org.htmlunit.javascript.background.BackgroundJavaScriptFactory; import org.htmlunit.javascript.background.JavaScriptJobManager; -import org.htmlunit.javascript.host.Element; import org.htmlunit.javascript.host.Window; -import org.htmlunit.javascript.host.css.CSSStyleSheet; -import org.htmlunit.javascript.host.css.StyleSheetList; -import org.htmlunit.javascript.host.html.HTMLDocument; +import org.w3c.dom.Document; /** * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
@@ -401,21 +403,36 @@ else if (getWebClient().getBrowserVersion().hasFeature(JS_WINDOW_COMPUTED_STYLE_ } } - final Element e = element.getScriptableObject(); final ComputedCssStyleDeclaration computedsStyleDeclaration = new ComputedCssStyleDeclaration(new ElementCssStyleDeclaration(element)); - final Object ownerDocument = e.getOwnerDocument(); - if (ownerDocument instanceof HTMLDocument) { - final StyleSheetList sheets = ((HTMLDocument) ownerDocument).getStyleSheets(); - final boolean trace = LOG.isTraceEnabled(); - for (int i = 0; i < sheets.getLength(); i++) { - final CSSStyleSheet sheet = (CSSStyleSheet) sheets.item(i); - if (sheet.getCssStyleSheet().isActive() && sheet.getCssStyleSheet().isEnabled()) { - if (trace) { - LOG.trace("modifyIfNecessary: " + sheet + ", " + computedsStyleDeclaration + ", " + e); + final Document ownerDocument = element.getOwnerDocument(); + if (ownerDocument instanceof HtmlPage) { + final HtmlPage htmlPage = (HtmlPage) ownerDocument; + + final WebClient webClient = getWebClient(); + + if (webClient.getOptions().isCssEnabled()) { + final boolean onlyActive = webClient.getBrowserVersion().hasFeature(JS_STYLESHEETLIST_ACTIVE_ONLY); + + final boolean trace = LOG.isTraceEnabled(); + for (final HtmlElement htmlElement : htmlPage.getHtmlElementDescendants()) { + CssStyleSheet cssStyleSheet = null; + if (htmlElement instanceof HtmlStyle) { + cssStyleSheet = ((HtmlStyle) htmlElement).getSheet(); + } + else if (htmlElement instanceof HtmlLink) { + cssStyleSheet = ((HtmlLink) htmlElement).getSheet(); + } + + if (cssStyleSheet != null && cssStyleSheet.isEnabled() + && (!onlyActive || cssStyleSheet.isActive())) { + if (trace) { + LOG.trace("modifyIfNecessary: " + cssStyleSheet + + ", " + computedsStyleDeclaration + ", " + element); + } + cssStyleSheet.modifyIfNecessary(computedsStyleDeclaration, element, normalizedPseudo); } - sheet.getCssStyleSheet().modifyIfNecessary(computedsStyleDeclaration, element, normalizedPseudo); } } diff --git a/src/main/java/org/htmlunit/html/DomNode.java b/src/main/java/org/htmlunit/html/DomNode.java index 0c2060c650b..57f579f0651 100644 --- a/src/main/java/org/htmlunit/html/DomNode.java +++ b/src/main/java/org/htmlunit/html/DomNode.java @@ -701,7 +701,7 @@ public boolean isDisplayed() { final Page page = getPage(); final WebWindow window = page.getEnclosingWindow(); final WebClient webClient = window.getWebClient(); - if (webClient.getOptions().isCssEnabled() && webClient.isJavaScriptEnabled()) { + if (webClient.getOptions().isCssEnabled()) { // display: iterate top to bottom, because if a parent is display:none, // there's nothing that a child can do to override it final List ancestors = getAncestors(); diff --git a/src/main/java/org/htmlunit/html/HtmlLink.java b/src/main/java/org/htmlunit/html/HtmlLink.java index 042887bcf33..8d9ad540250 100644 --- a/src/main/java/org/htmlunit/html/HtmlLink.java +++ b/src/main/java/org/htmlunit/html/HtmlLink.java @@ -31,6 +31,7 @@ import org.htmlunit.WebRequest; import org.htmlunit.WebResponse; import org.htmlunit.css.CssStyleSheet; +import org.htmlunit.cssparser.dom.MediaListImpl; import org.htmlunit.javascript.AbstractJavaScriptEngine; import org.htmlunit.javascript.PostponedAction; import org.htmlunit.javascript.host.event.Event; @@ -354,4 +355,26 @@ public boolean isStyleSheetLink() { } return false; } + + /** + *

Experimental API: May be changed in next release + * and may not yet work perfectly!

+ * + * Verifies if the provided node is a link node pointing to an active stylesheet. + * + * @return true if the provided node is a stylesheet link + */ + public boolean isActiveStyleSheetLink() { + if (isStyleSheetLink()) { + final String media = getMediaAttribute(); + if (org.apache.commons.lang3.StringUtils.isBlank(media)) { + return true; + } + + final MediaListImpl mediaList = + CssStyleSheet.parseMedia(getPage().getWebClient().getCssErrorHandler(), media); + return CssStyleSheet.isActive(mediaList, getPage().getEnclosingWindow()); + } + return false; + } } diff --git a/src/main/java/org/htmlunit/javascript/host/css/StyleSheetList.java b/src/main/java/org/htmlunit/javascript/host/css/StyleSheetList.java index 4a1e128d4de..bb68c5e0969 100644 --- a/src/main/java/org/htmlunit/javascript/host/css/StyleSheetList.java +++ b/src/main/java/org/htmlunit/javascript/host/css/StyleSheetList.java @@ -23,13 +23,9 @@ import java.io.Serializable; import java.util.function.Predicate; -import org.apache.commons.lang3.StringUtils; import org.htmlunit.WebClient; -import org.htmlunit.WebWindow; import org.htmlunit.corejs.javascript.Scriptable; import org.htmlunit.corejs.javascript.Undefined; -import org.htmlunit.css.CssStyleSheet; -import org.htmlunit.cssparser.dom.MediaListImpl; import org.htmlunit.html.DomNode; import org.htmlunit.html.HtmlAttributeChangeEvent; import org.htmlunit.html.HtmlElement; @@ -71,29 +67,6 @@ public class StyleSheetList extends HtmlUnitScriptable { */ private HTMLCollection nodes_; - /** - * Verifies if the provided node is a link node pointing to an active stylesheet. - * - * @param domNode the mode to check - * @return true if the provided node is a stylesheet link - */ - boolean isActiveStyleSheetLink(final DomNode domNode) { - if (domNode instanceof HtmlLink) { - final HtmlLink link = (HtmlLink) domNode; - if (link.isStyleSheetLink()) { - final String media = link.getMediaAttribute(); - if (StringUtils.isBlank(media)) { - return true; - } - final WebWindow webWindow = getWindow().getWebWindow(); - final MediaListImpl mediaList = - CssStyleSheet.parseMedia(webWindow.getWebClient().getCssErrorHandler(), media); - return CssStyleSheet.isActive(mediaList, webWindow); - } - } - return false; - } - /** * Creates an instance. */ @@ -132,10 +105,13 @@ public StyleSheetList(final Document document) { if (node instanceof HtmlStyle) { return true; } - if (onlyActive) { - return isActiveStyleSheetLink(node); + if (node instanceof HtmlLink) { + if (onlyActive) { + return ((HtmlLink) node).isActiveStyleSheetLink(); + } + return ((HtmlLink) node).isStyleSheetLink(); } - return node instanceof HtmlLink && ((HtmlLink) node).isStyleSheetLink(); + return false; }); } else {