diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index e87dec424b0..ef22ff24806 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -14,6 +14,9 @@
of the various WebClient properties should be clear in every case. This results in some minor changes the might have
some impact for the backward compatibility.
+
+ Properties ownerNode and href moved from CSSStyleSheet to StyleSheet.
+
Upgrade Apache commons-io to 2.15.0.
diff --git a/src/main/java/org/htmlunit/javascript/host/css/CSSStyleSheet.java b/src/main/java/org/htmlunit/javascript/host/css/CSSStyleSheet.java
index cb1d58c5da8..4309c257693 100644
--- a/src/main/java/org/htmlunit/javascript/host/css/CSSStyleSheet.java
+++ b/src/main/java/org/htmlunit/javascript/host/css/CSSStyleSheet.java
@@ -15,7 +15,6 @@
package org.htmlunit.javascript.host.css;
import static org.htmlunit.BrowserVersionFeatures.STYLESHEET_ADD_RULE_RETURNS_POS;
-import static org.htmlunit.BrowserVersionFeatures.STYLESHEET_HREF_EMPTY_IS_NULL;
import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
@@ -24,11 +23,8 @@
import java.io.IOException;
import java.io.StringReader;
-import java.net.MalformedURLException;
-import java.net.URL;
import java.util.ArrayList;
import java.util.List;
-import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -42,9 +38,6 @@
import org.htmlunit.cssparser.parser.InputSource;
import org.htmlunit.cssparser.parser.selector.SelectorList;
import org.htmlunit.html.DomNode;
-import org.htmlunit.html.HtmlLink;
-import org.htmlunit.html.HtmlPage;
-import org.htmlunit.html.HtmlStyle;
import org.htmlunit.javascript.configuration.JsxClass;
import org.htmlunit.javascript.configuration.JsxConstructor;
import org.htmlunit.javascript.configuration.JsxFunction;
@@ -71,15 +64,9 @@ public class CSSStyleSheet extends StyleSheet {
private static final Log LOG = LogFactory.getLog(CSSStyleSheet.class);
- private static final Pattern NTH_NUMERIC = Pattern.compile("\\d+");
- private static final Pattern NTH_COMPLEX = Pattern.compile("[+-]?\\d*n\\w*([+-]\\w\\d*)?");
-
/** The parsed stylesheet which this host object wraps. */
private final CssStyleSheet styleSheet_;
- /** The HTML element which owns this stylesheet. */
- private final HTMLElement ownerNode_;
-
/** The collection of rules defined in this style sheet. */
private CSSRuleList cssRules_;
private List cssRulesIndexFix_;
@@ -89,8 +76,8 @@ public class CSSStyleSheet extends StyleSheet {
*/
@JsxConstructor({CHROME, EDGE, FF, FF_ESR})
public CSSStyleSheet() {
+ super(null);
styleSheet_ = new CssStyleSheet(null, (InputSource) null, null);
- ownerNode_ = null;
}
/**
@@ -100,11 +87,12 @@ public CSSStyleSheet() {
* @param uri this stylesheet's URI (used to resolved contained @import rules)
*/
public CSSStyleSheet(final HTMLElement element, final InputSource source, final String uri) {
+ super(element);
+
setParentScope(element.getWindow());
setPrototype(getPrototype(CSSStyleSheet.class));
styleSheet_ = new CssStyleSheet(element.getDomNodeOrDie(), source, uri);
- ownerNode_ = element;
}
/**
@@ -114,6 +102,8 @@ public CSSStyleSheet(final HTMLElement element, final InputSource source, final
* @param uri this stylesheet's URI (used to resolved contained @import rules)
*/
public CSSStyleSheet(final HTMLElement element, final String styleSheet, final String uri) {
+ super(element);
+
final Window win = element.getWindow();
CssStyleSheet css = null;
@@ -128,7 +118,6 @@ public CSSStyleSheet(final HTMLElement element, final String styleSheet, final S
setPrototype(getPrototype(CSSStyleSheet.class));
styleSheet_ = css;
- ownerNode_ = element;
}
/**
@@ -139,10 +128,11 @@ public CSSStyleSheet(final HTMLElement element, final String styleSheet, final S
*/
public CSSStyleSheet(final HTMLElement element, final Scriptable parentScope,
final CssStyleSheet cssStyleSheet) {
+ super(element);
+
setParentScope(parentScope);
setPrototype(getPrototype(CSSStyleSheet.class));
styleSheet_ = cssStyleSheet;
- ownerNode_ = element;
}
/**
@@ -158,8 +148,9 @@ public CssStyleSheet getCssStyleSheet() {
* @return the owner node
*/
@JsxGetter(IE)
+ @Override
public HTMLElement getOwnerNode() {
- return ownerNode_;
+ return super.getOwnerNode();
}
/**
@@ -168,7 +159,7 @@ public HTMLElement getOwnerNode() {
*/
@JsxGetter(IE)
public HTMLElement getOwningElement() {
- return ownerNode_;
+ return getOwnerNode();
}
/**
@@ -191,37 +182,12 @@ public CSSRuleList getCssRules() {
}
/**
- * Returns the URL of the stylesheet.
- * @return the URL of the stylesheet
+ * {@inheritDoc}
*/
@JsxGetter(IE)
+ @Override
public String getHref() {
- if (ownerNode_ != null) {
- final DomNode node = ownerNode_.getDomNodeOrDie();
- if (node instanceof HtmlStyle) {
- return null;
- }
- if (node instanceof HtmlLink) {
- //
- final HtmlLink link = (HtmlLink) node;
- final String href = link.getHrefAttribute();
- if ("".equals(href) && getBrowserVersion().hasFeature(STYLESHEET_HREF_EMPTY_IS_NULL)) {
- return null;
- }
- // Expand relative URLs.
- try {
- final HtmlPage page = (HtmlPage) link.getPage();
- final URL url = page.getFullyQualifiedUrl(href);
- return url.toExternalForm();
- }
- catch (final MalformedURLException e) {
- // Log the error and fall through to the return values below.
- LOG.warn(e.getMessage(), e);
- }
- }
- }
-
- return getUri();
+ return super.getHref();
}
/**
@@ -371,6 +337,7 @@ public void removeRule(final int position) {
* For inline styles this is the page uri.
* @return this stylesheet's URI (used to resolved contained @import rules)
*/
+ @Override
public String getUri() {
return getCssStyleSheet().getUri();
}
diff --git a/src/main/java/org/htmlunit/javascript/host/css/StyleSheet.java b/src/main/java/org/htmlunit/javascript/host/css/StyleSheet.java
index 5e7a4d1e4fb..bae504b4ded 100644
--- a/src/main/java/org/htmlunit/javascript/host/css/StyleSheet.java
+++ b/src/main/java/org/htmlunit/javascript/host/css/StyleSheet.java
@@ -14,14 +14,26 @@
*/
package org.htmlunit.javascript.host.css;
+import static org.htmlunit.BrowserVersionFeatures.STYLESHEET_HREF_EMPTY_IS_NULL;
import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static org.htmlunit.javascript.configuration.SupportedBrowser.FF_ESR;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.htmlunit.html.DomNode;
+import org.htmlunit.html.HtmlLink;
+import org.htmlunit.html.HtmlPage;
+import org.htmlunit.html.HtmlStyle;
import org.htmlunit.javascript.HtmlUnitScriptable;
import org.htmlunit.javascript.configuration.JsxClass;
import org.htmlunit.javascript.configuration.JsxConstructor;
+import org.htmlunit.javascript.configuration.JsxGetter;
+import org.htmlunit.javascript.host.html.HTMLElement;
/**
* A JavaScript object for {@code StyleSheet}.
@@ -32,10 +44,72 @@
@JsxClass
public class StyleSheet extends HtmlUnitScriptable {
+ private static final Log LOG = LogFactory.getLog(StyleSheet.class);
+
+ /** The HTML element which owns this stylesheet. */
+ private final HTMLElement ownerNode_;
+
/**
* Default constructor.
*/
@JsxConstructor({CHROME, EDGE, FF, FF_ESR})
public StyleSheet() {
+ ownerNode_ = null;
+ }
+
+ public StyleSheet(final HTMLElement ownerNode) {
+ ownerNode_ = ownerNode;
+ }
+
+ /**
+ * Returns the owner node.
+ * @return the owner node
+ */
+ @JsxGetter
+ public HTMLElement getOwnerNode() {
+ return ownerNode_;
+ }
+
+ /**
+ * Returns the URL of the stylesheet.
+ * @return the URL of the stylesheet
+ */
+ @JsxGetter
+ public String getHref() {
+ if (ownerNode_ != null) {
+ final DomNode node = ownerNode_.getDomNodeOrDie();
+ if (node instanceof HtmlStyle) {
+ return null;
+ }
+ if (node instanceof HtmlLink) {
+ //
+ final HtmlLink link = (HtmlLink) node;
+ final String href = link.getHrefAttribute();
+ if ("".equals(href) && getBrowserVersion().hasFeature(STYLESHEET_HREF_EMPTY_IS_NULL)) {
+ return null;
+ }
+ // Expand relative URLs.
+ try {
+ final HtmlPage page = (HtmlPage) link.getPage();
+ final URL url = page.getFullyQualifiedUrl(href);
+ return url.toExternalForm();
+ }
+ catch (final MalformedURLException e) {
+ // Log the error and fall through to the return values below.
+ LOG.warn(e.getMessage(), e);
+ }
+ }
+ }
+
+ return getUri();
+ }
+
+ /**
+ * Returns this stylesheet's URI (used to resolved contained @import rules).
+ * For inline styles this is the page uri.
+ * @return this stylesheet's URI (used to resolved contained @import rules)
+ */
+ public String getUri() {
+ return null;
}
}
diff --git a/src/test/java/org/htmlunit/general/ElementOwnPropertiesTest.java b/src/test/java/org/htmlunit/general/ElementOwnPropertiesTest.java
index a3a0d2afd20..0cd124012c4 100644
--- a/src/test/java/org/htmlunit/general/ElementOwnPropertiesTest.java
+++ b/src/test/java/org/htmlunit/general/ElementOwnPropertiesTest.java
@@ -148,6 +148,9 @@ private void testString(final String preparation, final String string) throws Ex
+ " @font-face { font-family: Delicious; src: url('Delicious-Bold.otf'); };\n"
+ " \n"
+ " \n"
+ + " \n"
@@ -18572,6 +18575,24 @@ public void cssFontFaceRule() throws Exception {
testString("", "document.styleSheets[2].cssRules[0]");
}
+ /**
+ * Test CSSImportRule.
+ *
+ * @throws Exception if the test fails
+ */
+ @Test
+ @Alerts(DEFAULT = "constructor(),href[GCE],layerName[GCE],media[GSCE],styleSheet[GCE]",
+ FF = "constructor(),href[GCE],layerName[GCE],media[GSCE],styleSheet[GCE],supportsText[GCE]",
+ FF_ESR = "constructor(),href[GCE],layerName[GCE],media[GSCE],styleSheet[GCE],supportsText[GCE]",
+ IE = "constructor[],href[GCE],media[GCE],styleSheet[GCE]")
+ @HtmlUnitNYI(CHROME = "constructor(),href[GCE],media[GCE],styleSheet[GCE]",
+ EDGE = "constructor(),href[GCE],media[GCE],styleSheet[GCE]",
+ FF = "constructor(),href[GCE],media[GCE],styleSheet[GCE]",
+ FF_ESR = "constructor(),href[GCE],media[GCE],styleSheet[GCE]")
+ public void cssImportRule() throws Exception {
+ testString("", "document.styleSheets[3].cssRules[0]");
+ }
+
/**
* Test CSSRule.
*
@@ -18588,6 +18609,6 @@ public void cssFontFaceRule() throws Exception {
FF = "constructor(),selectorText[GSCE],style[GCE]",
FF_ESR = "constructor(),selectorText[GSCE],style[GCE]")
public void cssStyleRule() throws Exception {
- testString("", "document.styleSheets[3].cssRules[0]");
+ testString("", "document.styleSheets[4].cssRules[0]");
}
}
diff --git a/src/test/java/org/htmlunit/general/ElementOwnPropertySymbolsTest.java b/src/test/java/org/htmlunit/general/ElementOwnPropertySymbolsTest.java
index 42cc3bacc76..495387a52fd 100644
--- a/src/test/java/org/htmlunit/general/ElementOwnPropertySymbolsTest.java
+++ b/src/test/java/org/htmlunit/general/ElementOwnPropertySymbolsTest.java
@@ -141,6 +141,9 @@ private void testString(final String preparation, final String string) throws Ex
+ " @font-face { font-family: Delicious; src: url('Delicious-Bold.otf'); };\n"
+ " \n"
+ " \n"
+ + " \n"
@@ -3851,6 +3854,18 @@ public void cssFontFaceRule() throws Exception {
testString("", "document.styleSheets[2].cssRules[0]");
}
+ /**
+ * Test CSSImportRule.
+ *
+ * @throws Exception if the test fails
+ */
+ @Test
+ @Alerts(DEFAULT = "Symbol(Symbol.toStringTag) [CSSImportRule]",
+ IE = "exception")
+ public void cssImportRule() throws Exception {
+ testString("", "document.styleSheets[3].cssRules[0]");
+ }
+
/**
* Test CSSRule.
*
@@ -3860,6 +3875,6 @@ public void cssFontFaceRule() throws Exception {
@Alerts(DEFAULT = "Symbol(Symbol.toStringTag) [CSSStyleRule]",
IE = "exception")
public void cssStyleRule() throws Exception {
- testString("", "document.styleSheets[3].cssRules[0]");
+ testString("", "document.styleSheets[4].cssRules[0]");
}
}
diff --git a/src/test/java/org/htmlunit/general/ElementPropertiesTest.java b/src/test/java/org/htmlunit/general/ElementPropertiesTest.java
index fd05eb10a93..d9005da2c98 100644
--- a/src/test/java/org/htmlunit/general/ElementPropertiesTest.java
+++ b/src/test/java/org/htmlunit/general/ElementPropertiesTest.java
@@ -148,6 +148,9 @@ private void testString(final String preparation, final String string) throws Ex
+ " @font-face { font-family: Delicious; src: url('Delicious-Bold.otf'); };\n"
+ " \n"
+ " \n"
+ + " \n"
@@ -9474,10 +9477,10 @@ public void webKitMutationObserver() throws Exception {
+ "ownerRule,parentStyleSheet,removeRule(),replace(),replaceSync(),rules,title,type",
IE = "addRule(),cssRules,deleteRule(),href,insertRule(),ownerNode,"
+ "owningElement,removeRule(),rules")
- @HtmlUnitNYI(CHROME = "addRule(),cssRules,deleteRule(),insertRule(),removeRule(),rules",
- EDGE = "addRule(),cssRules,deleteRule(),insertRule(),removeRule(),rules",
- FF = "addRule(),cssRules,deleteRule(),insertRule(),removeRule(),rules",
- FF_ESR = "addRule(),cssRules,deleteRule(),insertRule(),removeRule(),rules")
+ @HtmlUnitNYI(CHROME = "addRule(),cssRules,deleteRule(),href,insertRule(),ownerNode,removeRule(),rules",
+ EDGE = "addRule(),cssRules,deleteRule(),href,insertRule(),ownerNode,removeRule(),rules",
+ FF = "addRule(),cssRules,deleteRule(),href,insertRule(),ownerNode,removeRule(),rules",
+ FF_ESR = "addRule(),cssRules,deleteRule(),href,insertRule(),ownerNode,removeRule(),rules")
public void cssStyleSheet() throws Exception {
testString("", "document.styleSheets[0]");
}
@@ -9542,6 +9545,40 @@ public void cssFontFaceRule() throws Exception {
testString("", "document.styleSheets[2].cssRules[0]");
}
+ /**
+ * Test CSSImportRule.
+ *
+ * @throws Exception if the test fails
+ */
+ @Test
+ @Alerts(DEFAULT = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,href,"
+ + "IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,layerName,media,MEDIA_RULE,NAMESPACE_RULE,"
+ + "PAGE_RULE,parentRule,parentStyleSheet,STYLE_RULE,styleSheet,SUPPORTS_RULE,type",
+ FF = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,href,"
+ + "IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,layerName,media,MEDIA_RULE,NAMESPACE_RULE,"
+ + "PAGE_RULE,parentRule,parentStyleSheet,STYLE_RULE,styleSheet,SUPPORTS_RULE,supportsText,type",
+ FF_ESR = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,href,"
+ + "IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,layerName,media,MEDIA_RULE,NAMESPACE_RULE,"
+ + "PAGE_RULE,parentRule,parentStyleSheet,STYLE_RULE,styleSheet,SUPPORTS_RULE,supportsText,type",
+ IE = "CHARSET_RULE,cssText,FONT_FACE_RULE,href,IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,media,"
+ + "MEDIA_RULE,NAMESPACE_RULE,PAGE_RULE,parentRule,parentStyleSheet,STYLE_RULE,styleSheet,type,"
+ + "UNKNOWN_RULE,VIEWPORT_RULE")
+ @HtmlUnitNYI(CHROME = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,href,"
+ + "IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,media,MEDIA_RULE,NAMESPACE_RULE,PAGE_RULE,"
+ + "parentRule,parentStyleSheet,STYLE_RULE,styleSheet,SUPPORTS_RULE,type",
+ EDGE = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,href,"
+ + "IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,media,MEDIA_RULE,NAMESPACE_RULE,PAGE_RULE,"
+ + "parentRule,parentStyleSheet,STYLE_RULE,styleSheet,SUPPORTS_RULE,type",
+ FF = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,href,"
+ + "IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,media,MEDIA_RULE,NAMESPACE_RULE,PAGE_RULE,"
+ + "parentRule,parentStyleSheet,STYLE_RULE,styleSheet,SUPPORTS_RULE,type",
+ FF_ESR = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,href,"
+ + "IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,media,MEDIA_RULE,NAMESPACE_RULE,PAGE_RULE,"
+ + "parentRule,parentStyleSheet,STYLE_RULE,styleSheet,SUPPORTS_RULE,type")
+ public void cssImportRule() throws Exception {
+ testString("", "document.styleSheets[3].cssRules[0]");
+ }
+
/**
* Test CSSRule.
*
@@ -9552,13 +9589,13 @@ public void cssFontFaceRule() throws Exception {
+ "FONT_FEATURE_VALUES_RULE,IMPORT_RULE,insertRule(),KEYFRAME_RULE,KEYFRAMES_RULE,"
+ "MEDIA_RULE,NAMESPACE_RULE,PAGE_RULE,parentRule,parentStyleSheet,selectorText,"
+ "style,STYLE_RULE,styleMap,SUPPORTS_RULE,type",
- FF = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,"
+ FF = "CHARSET_RULE,COUNTER_STYLE_RULE,cssRules,cssText,deleteRule(),FONT_FACE_RULE,"
+ + "FONT_FEATURE_VALUES_RULE,IMPORT_RULE,insertRule(),KEYFRAME_RULE,KEYFRAMES_RULE,"
+ + "MEDIA_RULE,NAMESPACE_RULE,PAGE_RULE,parentRule,parentStyleSheet,selectorText,"
+ + "style,STYLE_RULE,SUPPORTS_RULE,type",
+ FF_ESR = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,"
+ "IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,MEDIA_RULE,NAMESPACE_RULE,PAGE_RULE,parentRule,"
+ "parentStyleSheet,selectorText,style,STYLE_RULE,SUPPORTS_RULE,type",
- FF_ESR = "CHARSET_RULE,COUNTER_STYLE_RULE,cssRules,cssText,deleteRule(),FONT_FACE_RULE,"
- + "FONT_FEATURE_VALUES_RULE,IMPORT_RULE,insertRule(),KEYFRAME_RULE,KEYFRAMES_RULE,MEDIA_RULE,"
- + "NAMESPACE_RULE,PAGE_RULE,parentRule,parentStyleSheet,selectorText,style,"
- + "STYLE_RULE,SUPPORTS_RULE,type",
IE = "CHARSET_RULE,cssText,FONT_FACE_RULE,IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,MEDIA_RULE,"
+ "NAMESPACE_RULE,PAGE_RULE,parentRule,parentStyleSheet,readOnly,selectorText,style,"
+ "STYLE_RULE,type,UNKNOWN_RULE,VIEWPORT_RULE")
@@ -9568,10 +9605,10 @@ public void cssFontFaceRule() throws Exception {
EDGE = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,"
+ "IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,MEDIA_RULE,NAMESPACE_RULE,PAGE_RULE,parentRule,"
+ "parentStyleSheet,selectorText,style,STYLE_RULE,SUPPORTS_RULE,type",
- FF_ESR = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,"
+ FF = "CHARSET_RULE,COUNTER_STYLE_RULE,cssText,FONT_FACE_RULE,FONT_FEATURE_VALUES_RULE,"
+ "IMPORT_RULE,KEYFRAME_RULE,KEYFRAMES_RULE,MEDIA_RULE,NAMESPACE_RULE,PAGE_RULE,parentRule,"
+ "parentStyleSheet,selectorText,style,STYLE_RULE,SUPPORTS_RULE,type")
public void cssStyleRule() throws Exception {
- testString("", "document.styleSheets[3].cssRules[0]");
+ testString("", "document.styleSheets[4].cssRules[0]");
}
}