core-js is now in sync with the latest Rhino codebase.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/AbstractPage.java b/src/main/java/com/gargoylesoftware/htmlunit/AbstractPage.java
index e30a7288c9a..7d585bb4dbc 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/AbstractPage.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/AbstractPage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/AjaxController.java b/src/main/java/com/gargoylesoftware/htmlunit/AjaxController.java
index 0ad9cb46102..fa924c9c322 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/AjaxController.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/AjaxController.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/AlertHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/AlertHandler.java
index b263dedc907..44e2cc28feb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/AlertHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/AlertHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,13 +14,16 @@
*/
package com.gargoylesoftware.htmlunit;
+import java.io.Serializable;
+
/**
* A handler for JavaScript alerts. Alerts are triggered when the JavaScript method Window.alert()
* is called.
*
* @author Mike Bowler
+ * @author Ronald Brill
*/
-public interface AlertHandler {
+public interface AlertHandler extends Serializable {
/**
* Handle an alert for the given page.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/AppletConfirmHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/AppletConfirmHandler.java
index 48ea60793cd..8fc895f50fa 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/AppletConfirmHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/AppletConfirmHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,8 @@
*/
package com.gargoylesoftware.htmlunit;
+import java.io.Serializable;
+
import com.gargoylesoftware.htmlunit.html.HtmlApplet;
import com.gargoylesoftware.htmlunit.html.HtmlObject;
@@ -23,7 +25,7 @@
*
* @author Ronald Brill
*/
-public interface AppletConfirmHandler {
+public interface AppletConfirmHandler extends Serializable {
/**
* Handles a confirm for the specified page.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersion.java b/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersion.java
index 868e3ef931d..d9158466cc6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersion.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersion.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.AbstractJavaScriptConfiguration;
import com.gargoylesoftware.htmlunit.javascript.configuration.BrowserFeature;
import com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser;
+import com.gargoylesoftware.htmlunit.util.MimeType;
/**
* Objects of this class represent one specific version of a given browser. Predefined
@@ -37,18 +38,18 @@
*
* You can create a different browser setup by using the BrowserVersionFactory.
*
- * String applicationName = "APPNAME";
- * String applicationVersion = "APPVERSION";
- * String userAgent = "USERAGENT";
- * int browserVersionNumeric = NUMERIC;
+ * final String applicationName = "APPNAME";
+ * final String applicationVersion = "APPVERSION";
+ * final String userAgent = "USERAGENT";
*
- * BrowserVersion browser = new BrowserVersion.BrowserVersionFactory(FF52)
- * .setApplicationName(applicationName)
- * .setApplicationVersion(applicationVersion)
- * .setUserAgent(userAgent)
- * .build();
+ * final BrowserVersion browser =
+ * new BrowserVersion.BrowserVersionBuilder(BrowserVersion.FIREFOX_68)
+ * .setApplicationName(applicationName)
+ * .setApplicationVersion(applicationVersion)
+ * .setUserAgent(userAgent)
+ * .build();
*
- * But keep in mind this now one still behaves like a FF52, only the stuff reported to the
+ *
But keep in mind this now one still behaves like a FF68, only the stuff reported to the
* outside is changed. This is more or less the same you can do with real browsers installing
* plugins like UserAgentSwitcher.
*
@@ -93,27 +94,22 @@ public final class BrowserVersion implements Serializable {
private static final String PLATFORM_WIN64 = "Win64";
/**
- * Firefox 45 ESR.
- * @since 2.21
- * @deprecated As of 2.31
+ * Firefox 60 ESR.
+ * @since 2.32
*/
- @Deprecated
- public static final BrowserVersion FIREFOX_45 = new BrowserVersion(45, "FF45");
+ public static final BrowserVersion FIREFOX_60 = new BrowserVersion(60, "FF60");
/**
- * Firefox 52 ESR.
- * @since 2.26
+ * Firefox 68 ESR.
+ * @since 2.37
*/
- public static final BrowserVersion FIREFOX_52 = new BrowserVersion(52, "FF52");
+ public static final BrowserVersion FIREFOX_68 = new BrowserVersion(68, "FF68");
/** Internet Explorer 11. */
public static final BrowserVersion INTERNET_EXPLORER = new BrowserVersion(11, "IE");
/** Latest Chrome. */
- public static final BrowserVersion CHROME = new BrowserVersion(60, "Chrome");
-
- /** Microsoft Edge. Work In Progress!!! */
- public static final BrowserVersion EDGE = new BrowserVersion(14, "Edge");
+ public static final BrowserVersion CHROME = new BrowserVersion(67, "Chrome");
/**
* The best supported browser version at the moment.
@@ -125,13 +121,12 @@ public final class BrowserVersion implements Serializable {
/** Register plugins for the browser versions. */
static {
- // FF45
- FIREFOX_45.applicationVersion_ = "5.0 (Windows)";
- FIREFOX_45.userAgent_ = "Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0";
- FIREFOX_45.platform_ = PLATFORM_WIN32;
- FIREFOX_45.buildId_ = "20170411115307";
- FIREFOX_45.productSub_ = "20100101";
- FIREFOX_45.headerNamesOrdered_ = new String[] {
+ // FF60
+ FIREFOX_60.applicationVersion_ = "5.0 (Windows)";
+ FIREFOX_60.userAgent_ = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0";
+ FIREFOX_60.buildId_ = "20190124141046";
+ FIREFOX_60.productSub_ = "20100101";
+ FIREFOX_60.headerNamesOrdered_ = new String[] {
HttpHeader.HOST,
HttpHeader.USER_AGENT,
HttpHeader.ACCEPT,
@@ -140,11 +135,11 @@ public final class BrowserVersion implements Serializable {
HttpHeader.REFERER,
HttpHeader.COOKIE,
HttpHeader.CONNECTION};
- FIREFOX_45.htmlAcceptHeader_ = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
- FIREFOX_45.xmlHttpRequestAcceptHeader_ = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
- FIREFOX_45.imgAcceptHeader_ = "image/png,image/*;q=0.8,*/*;q=0.5";
- FIREFOX_45.cssAcceptHeader_ = "text/css,*/*;q=0.1";
- FIREFOX_45.fontHeights_ = new int[] {
+ FIREFOX_60.htmlAcceptHeader_ = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
+ FIREFOX_60.xmlHttpRequestAcceptHeader_ = "*/*";
+ FIREFOX_60.imgAcceptHeader_ = "*/*";
+ FIREFOX_60.cssAcceptHeader_ = "text/css,*/*;q=0.1";
+ FIREFOX_60.fontHeights_ = new int[] {
0, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
30, 31, 32, 33, 34, 35, 36, 37, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48, 50, 51, 52, 53, 53, 55, 57, 58,
59, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 82, 84, 85, 86, 87, 88,
@@ -152,30 +147,32 @@ public final class BrowserVersion implements Serializable {
116, 117, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130, 131, 132, 133, 135, 136, 138, 139,
139, 141, 142, 143, 144, 146, 147, 148, 149};
- // FF52
- FIREFOX_52.applicationVersion_ = "5.0 (Windows)";
- FIREFOX_52.userAgent_ = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0";
- FIREFOX_52.buildId_ = "20180315163333";
- FIREFOX_52.productSub_ = "20100101";
- FIREFOX_52.headerNamesOrdered_ = new String[] {
+ // FF68
+ FIREFOX_68.applicationVersion_ = "5.0 (Windows)";
+ FIREFOX_68.userAgent_ = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0";
+ FIREFOX_68.buildId_ = "20181001000000";
+ FIREFOX_68.productSub_ = "20100101";
+ FIREFOX_68.headerNamesOrdered_ = new String[] {
HttpHeader.HOST,
HttpHeader.USER_AGENT,
HttpHeader.ACCEPT,
HttpHeader.ACCEPT_LANGUAGE,
HttpHeader.ACCEPT_ENCODING,
HttpHeader.REFERER,
- HttpHeader.COOKIE,
HttpHeader.CONNECTION,
- "Upgrade-Insecure-Requests"};
- FIREFOX_52.htmlAcceptHeader_ = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
- FIREFOX_52.cssAcceptHeader_ = "text/css,*/*;q=0.1";
- FIREFOX_52.fontHeights_ = new int[] {
- 0, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48, 50, 51, 52, 53, 53, 55, 57, 58,
- 59, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 82, 84, 85, 86, 87, 88,
- 89, 90, 91, 93, 94, 95, 96, 96, 98, 99, 100, 101, 103, 104, 105, 106, 106, 108, 109, 111, 112, 113, 115,
- 116, 117, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130, 131, 132, 133, 135, 136, 138, 139,
- 139, 141, 142, 143, 144, 146, 147, 148, 149};
+ HttpHeader.COOKIE};
+ FIREFOX_68.htmlAcceptHeader_ = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
+ FIREFOX_68.xmlHttpRequestAcceptHeader_ = "*/*";
+ FIREFOX_68.imgAcceptHeader_ = "image/webp,*/*";
+ FIREFOX_68.cssAcceptHeader_ = "text/css,*/*;q=0.1";
+ FIREFOX_68.fontHeights_ = new int[] {
+ 0, 2, 3, 5, 6, 6, 7, 9, 10, 11, 12, 13, 15, 16, 16, 17, 18, 20, 21, 22, 23, 25, 26, 26, 28, 29,
+ 31, 32, 33, 34, 35, 37, 38, 38, 39, 41, 42, 43, 44, 45, 47, 48, 48, 49, 51, 52, 53, 54, 56, 58, 59, 59,
+ 60, 61, 63, 64, 65, 66, 68, 69, 69, 70, 71, 73, 74, 75, 76, 77, 79, 79,
+ 80, 82, 84, 85, 86, 87, 88, 90, 91, 91, 92, 94, 95, 96, 97, 98,
+ 100, 101, 101, 102, 103, 105, 106, 107, 108, 111, 112, 112, 113, 114, 116, 117, 118, 119,
+ 120, 122, 122, 123, 124, 126, 127, 128, 129, 130, 132, 132, 133, 134, 137, 138, 139,
+ 140, 141, 143, 143, 144, 145, 146, 148};
// IE
INTERNET_EXPLORER.applicationVersion_ = "5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko";
@@ -203,18 +200,9 @@ public final class BrowserVersion implements Serializable {
115, 116, 117, 118, 120, 121, 122, 123, 124, 125, 126, 128, 129, 130, 131, 132, 133, 135, 136, 137, 138,
139, 140, 141, 143, 144, 145, 146, 147};
- // EDGE
- EDGE.applicationVersion_ = "5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393";
- EDGE.userAgent_ = "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393";
-
- EDGE.htmlAcceptHeader_ = "text/html, application/xhtml+xml, image/jxr, */*";
- EDGE.cssAcceptHeader_ = "text/css, */*";
- EDGE.imgAcceptHeader_ = "image/png, image/svg+xml, image/jxr, image/*;q=0.8, */*;q=0.5";
- EDGE.scriptAcceptHeader_ = "application/javascript, */*;q=0.8";
-
// CHROME
- CHROME.applicationVersion_ = "5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36";
- CHROME.userAgent_ = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36";
+ CHROME.applicationVersion_ = "5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36";
+ CHROME.userAgent_ = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36";
CHROME.applicationCodeName_ = "Mozilla";
CHROME.vendor_ = "Google Inc.";
@@ -226,12 +214,17 @@ public final class BrowserVersion implements Serializable {
HttpHeader.CONNECTION,
"Upgrade-Insecure-Requests",
HttpHeader.USER_AGENT,
+ HttpHeader.SEC_FETCH_USER,
HttpHeader.ACCEPT,
+ HttpHeader.SEC_FETCH_SITE,
+ HttpHeader.SEC_FETCH_MODE,
HttpHeader.REFERER,
HttpHeader.ACCEPT_ENCODING,
HttpHeader.ACCEPT_LANGUAGE,
HttpHeader.COOKIE};
- CHROME.htmlAcceptHeader_ = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
+ CHROME.acceptEncodingHeader_ = "gzip, deflate, br";
+ CHROME.htmlAcceptHeader_ = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;"
+ + "q=0.8,application/signed-exchange;v=b3;q=0.9";
CHROME.imgAcceptHeader_ = "image/webp,image/apng,image/*,*/*;q=0.8";
CHROME.cssAcceptHeader_ = "text/css,*/*;q=0.1";
CHROME.scriptAcceptHeader_ = "*/*";
@@ -245,13 +238,14 @@ public final class BrowserVersion implements Serializable {
138, 139, 140, 142, 142, 143, 144, 145, 147};
// default file upload mime types
- CHROME.registerUploadMimeType("html", "text/html");
- CHROME.registerUploadMimeType("htm", "text/html");
- CHROME.registerUploadMimeType("css", "text/css");
- CHROME.registerUploadMimeType("xml", "text/xml");
+ CHROME.registerUploadMimeType("html", MimeType.TEXT_HTML);
+ CHROME.registerUploadMimeType("htm", MimeType.TEXT_HTML);
+ CHROME.registerUploadMimeType("css", MimeType.TEXT_CSS);
+ CHROME.registerUploadMimeType("xml", MimeType.TEXT_XML);
CHROME.registerUploadMimeType("gif", "image/gif");
CHROME.registerUploadMimeType("jpeg", "image/jpeg");
CHROME.registerUploadMimeType("jpg", "image/jpeg");
+ CHROME.registerUploadMimeType("png", "image/png");
CHROME.registerUploadMimeType("webp", "image/webp");
CHROME.registerUploadMimeType("mp4", "video/mp4");
CHROME.registerUploadMimeType("m4v", "video/mp4");
@@ -268,63 +262,66 @@ public final class BrowserVersion implements Serializable {
CHROME.registerUploadMimeType("xhtml", "application/xhtml+xml");
CHROME.registerUploadMimeType("xht", "application/xhtml+xml");
CHROME.registerUploadMimeType("xhtm", "application/xhtml+xml");
- CHROME.registerUploadMimeType("txt", "text/plain");
- CHROME.registerUploadMimeType("text", "text/plain");
-
- FIREFOX_45.registerUploadMimeType("html", "text/html");
- FIREFOX_45.registerUploadMimeType("htm", "text/html");
- FIREFOX_45.registerUploadMimeType("css", "text/css");
- FIREFOX_45.registerUploadMimeType("xml", "text/xml");
- FIREFOX_45.registerUploadMimeType("gif", "image/gif");
- FIREFOX_45.registerUploadMimeType("jpeg", "image/jpeg");
- FIREFOX_45.registerUploadMimeType("jpg", "image/jpeg");
- FIREFOX_45.registerUploadMimeType("mp4", "video/mp4");
- FIREFOX_45.registerUploadMimeType("m4v", "video/mp4");
- FIREFOX_45.registerUploadMimeType("m4a", "audio/mp4");
- FIREFOX_45.registerUploadMimeType("mp3", "audio/mpeg");
- FIREFOX_45.registerUploadMimeType("ogv", "video/ogg");
- FIREFOX_45.registerUploadMimeType("ogm", "video/x-ogm");
- FIREFOX_45.registerUploadMimeType("ogg", "video/ogg");
- FIREFOX_45.registerUploadMimeType("oga", "audio/ogg");
- FIREFOX_45.registerUploadMimeType("opus", "audio/ogg");
- FIREFOX_45.registerUploadMimeType("webm", "video/webm");
- FIREFOX_45.registerUploadMimeType("wav", "audio/wav");
- FIREFOX_45.registerUploadMimeType("flac", "audio/x-flac");
- FIREFOX_45.registerUploadMimeType("xhtml", "application/xhtml+xml");
- FIREFOX_45.registerUploadMimeType("xht", "application/xhtml+xml");
- FIREFOX_45.registerUploadMimeType("txt", "text/plain");
- FIREFOX_45.registerUploadMimeType("text", "text/plain");
-
- FIREFOX_52.registerUploadMimeType("html", "text/html");
- FIREFOX_52.registerUploadMimeType("htm", "text/html");
- FIREFOX_52.registerUploadMimeType("css", "text/css");
- FIREFOX_52.registerUploadMimeType("xml", "text/xml");
- FIREFOX_52.registerUploadMimeType("gif", "image/gif");
- FIREFOX_52.registerUploadMimeType("jpeg", "image/jpeg");
- FIREFOX_52.registerUploadMimeType("jpg", "image/jpeg");
- FIREFOX_52.registerUploadMimeType("mp4", "video/mp4");
- FIREFOX_52.registerUploadMimeType("m4v", "video/mp4");
- FIREFOX_52.registerUploadMimeType("m4a", "audio/mp4");
- FIREFOX_52.registerUploadMimeType("mp3", "audio/mpeg");
- FIREFOX_52.registerUploadMimeType("ogv", "video/ogg");
- FIREFOX_52.registerUploadMimeType("ogm", "video/x-ogm");
- FIREFOX_52.registerUploadMimeType("ogg", "video/ogg");
- FIREFOX_52.registerUploadMimeType("oga", "audio/ogg");
- FIREFOX_52.registerUploadMimeType("opus", "audio/ogg");
- FIREFOX_52.registerUploadMimeType("webm", "video/webm");
- FIREFOX_52.registerUploadMimeType("wav", "audio/wav");
- FIREFOX_52.registerUploadMimeType("xhtml", "application/xhtml+xml");
- FIREFOX_52.registerUploadMimeType("xht", "application/xhtml+xml");
- FIREFOX_52.registerUploadMimeType("txt", "text/plain");
- FIREFOX_52.registerUploadMimeType("text", "text/plain");
-
- INTERNET_EXPLORER.registerUploadMimeType("html", "text/html");
- INTERNET_EXPLORER.registerUploadMimeType("htm", "text/html");
- INTERNET_EXPLORER.registerUploadMimeType("css", "text/css");
- INTERNET_EXPLORER.registerUploadMimeType("xml", "text/xml");
+ CHROME.registerUploadMimeType("txt", MimeType.TEXT_PLAIN);
+ CHROME.registerUploadMimeType("text", MimeType.TEXT_PLAIN);
+
+ FIREFOX_60.registerUploadMimeType("html", MimeType.TEXT_HTML);
+ FIREFOX_60.registerUploadMimeType("htm", MimeType.TEXT_HTML);
+ FIREFOX_60.registerUploadMimeType("css", MimeType.TEXT_CSS);
+ FIREFOX_60.registerUploadMimeType("xml", MimeType.TEXT_XML);
+ FIREFOX_60.registerUploadMimeType("gif", "image/gif");
+ FIREFOX_60.registerUploadMimeType("jpeg", "image/jpeg");
+ FIREFOX_60.registerUploadMimeType("jpg", "image/jpeg");
+ FIREFOX_60.registerUploadMimeType("png", "image/png");
+ FIREFOX_60.registerUploadMimeType("mp4", "video/mp4");
+ FIREFOX_60.registerUploadMimeType("m4v", "video/mp4");
+ FIREFOX_60.registerUploadMimeType("m4a", "audio/mp4");
+ FIREFOX_60.registerUploadMimeType("mp3", "audio/mpeg");
+ FIREFOX_60.registerUploadMimeType("ogv", "video/ogg");
+ FIREFOX_60.registerUploadMimeType("ogm", "video/x-ogm");
+ FIREFOX_60.registerUploadMimeType("ogg", "video/ogg");
+ FIREFOX_60.registerUploadMimeType("oga", "audio/ogg");
+ FIREFOX_60.registerUploadMimeType("opus", "audio/ogg");
+ FIREFOX_60.registerUploadMimeType("webm", "video/webm");
+ FIREFOX_60.registerUploadMimeType("wav", "audio/wav");
+ FIREFOX_60.registerUploadMimeType("xhtml", "application/xhtml+xml");
+ FIREFOX_60.registerUploadMimeType("xht", "application/xhtml+xml");
+ FIREFOX_60.registerUploadMimeType("txt", MimeType.TEXT_PLAIN);
+ FIREFOX_60.registerUploadMimeType("text", MimeType.TEXT_PLAIN);
+
+ FIREFOX_68.registerUploadMimeType("html", MimeType.TEXT_HTML);
+ FIREFOX_68.registerUploadMimeType("htm", MimeType.TEXT_HTML);
+ FIREFOX_68.registerUploadMimeType("css", MimeType.TEXT_CSS);
+ FIREFOX_68.registerUploadMimeType("xml", MimeType.TEXT_XML);
+ FIREFOX_68.registerUploadMimeType("gif", "image/gif");
+ FIREFOX_68.registerUploadMimeType("jpeg", "image/jpeg");
+ FIREFOX_68.registerUploadMimeType("jpg", "image/jpeg");
+ FIREFOX_68.registerUploadMimeType("mp4", "video/mp4");
+ FIREFOX_68.registerUploadMimeType("m4v", "video/mp4");
+ FIREFOX_68.registerUploadMimeType("m4a", "audio/mp4");
+ FIREFOX_68.registerUploadMimeType("png", "image/png");
+ FIREFOX_68.registerUploadMimeType("mp3", "audio/mpeg");
+ FIREFOX_68.registerUploadMimeType("ogv", "video/ogg");
+ FIREFOX_68.registerUploadMimeType("ogm", "video/x-ogm");
+ FIREFOX_68.registerUploadMimeType("ogg", "video/ogg");
+ FIREFOX_68.registerUploadMimeType("oga", "audio/ogg");
+ FIREFOX_68.registerUploadMimeType("opus", "audio/ogg");
+ FIREFOX_68.registerUploadMimeType("webm", "video/webm");
+ FIREFOX_68.registerUploadMimeType("webp", "image/webp");
+ FIREFOX_68.registerUploadMimeType("wav", "audio/wav");
+ FIREFOX_68.registerUploadMimeType("xhtml", "application/xhtml+xml");
+ FIREFOX_68.registerUploadMimeType("xht", "application/xhtml+xml");
+ FIREFOX_68.registerUploadMimeType("txt", MimeType.TEXT_PLAIN);
+ FIREFOX_68.registerUploadMimeType("text", MimeType.TEXT_PLAIN);
+
+ INTERNET_EXPLORER.registerUploadMimeType("html", MimeType.TEXT_HTML);
+ INTERNET_EXPLORER.registerUploadMimeType("htm", MimeType.TEXT_HTML);
+ INTERNET_EXPLORER.registerUploadMimeType("css", MimeType.TEXT_CSS);
+ INTERNET_EXPLORER.registerUploadMimeType("xml", MimeType.TEXT_XML);
INTERNET_EXPLORER.registerUploadMimeType("gif", "image/gif");
INTERNET_EXPLORER.registerUploadMimeType("jpeg", "image/jpeg");
INTERNET_EXPLORER.registerUploadMimeType("jpg", "image/jpeg");
+ INTERNET_EXPLORER.registerUploadMimeType("png", "image/png");
INTERNET_EXPLORER.registerUploadMimeType("mp4", "video/mp4");
INTERNET_EXPLORER.registerUploadMimeType("m4v", "video/mp4");
INTERNET_EXPLORER.registerUploadMimeType("m4a", "audio/mp4");
@@ -334,50 +331,14 @@ public final class BrowserVersion implements Serializable {
INTERNET_EXPLORER.registerUploadMimeType("wav", "audio/wav");
INTERNET_EXPLORER.registerUploadMimeType("xhtml", "application/xhtml+xml");
INTERNET_EXPLORER.registerUploadMimeType("xht", "application/xhtml+xml");
- INTERNET_EXPLORER.registerUploadMimeType("txt", "text/plain");
-
- EDGE.registerUploadMimeType("html", "text/html");
- EDGE.registerUploadMimeType("htm", "text/html");
- EDGE.registerUploadMimeType("css", "text/css");
- EDGE.registerUploadMimeType("xml", "text/xml");
- EDGE.registerUploadMimeType("gif", "image/gif");
- EDGE.registerUploadMimeType("jpeg", "image/jpeg");
- EDGE.registerUploadMimeType("jpg", "image/jpeg");
- EDGE.registerUploadMimeType("mp4", "video/mp4");
- EDGE.registerUploadMimeType("m4v", "video/mp4");
- EDGE.registerUploadMimeType("m4a", "audio/mp4");
- EDGE.registerUploadMimeType("mp3", "audio/mpeg");
- EDGE.registerUploadMimeType("ogm", "video/x-ogm");
- EDGE.registerUploadMimeType("ogg", "application/ogg");
- EDGE.registerUploadMimeType("wav", "audio/wav");
- EDGE.registerUploadMimeType("xhtml", "application/xhtml+xml");
- EDGE.registerUploadMimeType("xht", "application/xhtml+xml");
- EDGE.registerUploadMimeType("txt", "text/plain");
+ INTERNET_EXPLORER.registerUploadMimeType("txt", MimeType.TEXT_PLAIN);
// flush plugin (windows version)
- PluginConfiguration flash = new PluginConfiguration("Shockwave Flash",
- "Shockwave Flash 29.0 r0", "29.0.0.140", "NPSWF32_29_0_0_140.dll");
- flash.getMimeTypes().add(new PluginConfiguration.MimeType("application/x-shockwave-flash",
- "Shockwave Flash", "swf"));
- FIREFOX_45.plugins_.add(flash);
-
- flash = new PluginConfiguration("Shockwave Flash",
- "Shockwave Flash 29.0 r0", "29.0.0.140", "NPSWF64_29_0_0_140.dll");
- flash.getMimeTypes().add(new PluginConfiguration.MimeType("application/x-shockwave-flash",
- "Shockwave Flash", "swf"));
- FIREFOX_52.plugins_.add(flash);
-
- flash = new PluginConfiguration("Shockwave Flash",
- "Shockwave Flash 29.0 r0", "29.0.0.140", "Flash32_29_0_0_140.ocx");
+ final PluginConfiguration flash = new PluginConfiguration("Shockwave Flash",
+ "Shockwave Flash 30.0 r0", "30.0.0.113", "Flash32_30_0_0_113.ocx"); //NOPMD
flash.getMimeTypes().add(new PluginConfiguration.MimeType("application/x-shockwave-flash",
"Shockwave Flash", "swf"));
INTERNET_EXPLORER.plugins_.add(flash);
-
- flash = new PluginConfiguration("Shockwave Flash",
- "Shockwave Flash 18.0 r0", "18.0.0.232", "Flash.ocx");
- flash.getMimeTypes().add(new PluginConfiguration.MimeType("application/x-shockwave-flash",
- "Shockwave Flash", "swf"));
- EDGE.plugins_.add(flash);
}
private final int browserVersionNumeric_;
@@ -400,6 +361,7 @@ public final class BrowserVersion implements Serializable {
private String userLanguage_ = LANGUAGE_ENGLISH_US;
private final Set plugins_;
private final Set features_;
+ private String acceptEncodingHeader_;
private String htmlAcceptHeader_;
private String imgAcceptHeader_;
private String cssAcceptHeader_;
@@ -413,13 +375,14 @@ public final class BrowserVersion implements Serializable {
* Creates a new browser version instance.
*
* @param browserVersionNumeric the floating number version of the browser
- * @param nickname the short name of the browser (like "FF52", "IE", ...) - has to be unique
+ * @param nickname the short name of the browser (like "FF68", "IE", ...) - has to be unique
*/
private BrowserVersion(final int browserVersionNumeric, final String nickname) {
browserVersionNumeric_ = browserVersionNumeric;
nickname_ = nickname;
applicationName_ = NETSCAPE;
+ acceptEncodingHeader_ = "gzip, deflate";
htmlAcceptHeader_ = "*/*";
imgAcceptHeader_ = "*/*";
cssAcceptHeader_ = "*/*";
@@ -438,17 +401,14 @@ private void initFeatures() {
if (isChrome()) {
expectedBrowser = SupportedBrowser.CHROME;
}
- else if (isFirefox52()) {
- expectedBrowser = SupportedBrowser.FF52;
+ else if (isFirefox60()) {
+ expectedBrowser = SupportedBrowser.FF60;
}
else if (isFirefox()) {
- expectedBrowser = SupportedBrowser.FF45;
- }
- else if (isIE()) {
- expectedBrowser = SupportedBrowser.IE;
+ expectedBrowser = SupportedBrowser.FF68;
}
else {
- expectedBrowser = SupportedBrowser.EDGE;
+ expectedBrowser = SupportedBrowser.IE;
}
for (final BrowserVersionFeatures features : BrowserVersionFeatures.values()) {
@@ -507,15 +467,6 @@ public boolean isChrome() {
return getNickname().startsWith("Chrome");
}
- /**
- * Returns {@code true} if this BrowserVersion instance represents some
- * version of Microsoft Edge.
- * @return whether or not this version is a version of an Edge browser
- */
- public boolean isEdge() {
- return getNickname().startsWith("Edge");
- }
-
/**
* Returns {@code true} if this BrowserVersion instance represents some
* version of Firefox.
@@ -527,10 +478,10 @@ public boolean isFirefox() {
/**
* INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
- * @return whether or not this version version 52 of a Firefox browser
+ * @return whether or not this version version 60 of a Firefox browser
*/
- public boolean isFirefox52() {
- return isFirefox() && getBrowserVersionNumeric() == 52;
+ public boolean isFirefox60() {
+ return isFirefox() && getBrowserVersionNumeric() == 60;
}
/**
@@ -671,6 +622,14 @@ public String getUserLanguage() {
return userLanguage_;
}
+ /**
+ * Returns the value used by the browser for the {@code Accept_Encoding} header.
+ * @return the accept encoding header string
+ */
+ public String getAcceptEncodingHeader() {
+ return acceptEncodingHeader_;
+ }
+
/**
* Returns the value used by the browser for the {@code Accept} header if requesting a page.
* @return the accept header string
@@ -842,17 +801,17 @@ public BrowserVersionBuilder(final BrowserVersion version) {
.setPlatform(version.getPlatform())
.setSystemLanguage(version.getSystemLanguage())
.setSystemTimezone(version.getSystemTimezone())
- .setUserLanguage(version.getUserLanguage());
-
- workPiece_.buildId_ = version.getBuildId();
- workPiece_.productSub_ = version.getProductSub();
- workPiece_.htmlAcceptHeader_ = version.getHtmlAcceptHeader();
- workPiece_.imgAcceptHeader_ = version.getImgAcceptHeader();
- workPiece_.cssAcceptHeader_ = version.getCssAcceptHeader();
- workPiece_.scriptAcceptHeader_ = version.getScriptAcceptHeader();
- workPiece_.xmlHttpRequestAcceptHeader_ = version.getXmlHttpRequestAcceptHeader();
- workPiece_.headerNamesOrdered_ = version.getHeaderNamesOrdered();
- workPiece_.fontHeights_ = version.fontHeights_;
+ .setUserLanguage(version.getUserLanguage())
+ .setBuildId(version.getBuildId())
+ .setProductSub(version.getProductSub())
+ .setAcceptEncodingHeader(version.getAcceptEncodingHeader())
+ .setHtmlAcceptHeader(version.getHtmlAcceptHeader())
+ .setImgAcceptHeader(version.getImgAcceptHeader())
+ .setCssAcceptHeader(version.getCssAcceptHeader())
+ .setScriptAcceptHeader(version.getScriptAcceptHeader())
+ .setXmlHttpRequestAcceptHeader(version.getXmlHttpRequestAcceptHeader())
+ .setHeaderNamesOrdered(version.getHeaderNamesOrdered())
+ .setFontHeights(version.fontHeights_);
for (final PluginConfiguration pluginConf : version.getPlugins()) {
workPiece_.plugins_.add(pluginConf.clone());
@@ -986,6 +945,15 @@ public BrowserVersionBuilder setUserLanguage(final String userLanguage) {
return this;
}
+ /**
+ * @param acceptEncodingHeader the {@code Accept-Encoding} header
+ * @return this for fluent use
+ */
+ public BrowserVersionBuilder setAcceptEncodingHeader(final String acceptEncodingHeader) {
+ workPiece_.acceptEncodingHeader_ = acceptEncodingHeader;
+ return this;
+ }
+
/**
* @param htmlAcceptHeader the {@code Accept} header to be used when retrieving pages
* @return this for fluent use
@@ -1031,5 +999,41 @@ public BrowserVersionBuilder setXmlHttpRequestAcceptHeader(final String xmlHttpR
workPiece_.xmlHttpRequestAcceptHeader_ = xmlHttpRequestAcceptHeader;
return this;
}
+
+ /**
+ * @param productSub the productSub
+ * @return this for fluent use
+ */
+ BrowserVersionBuilder setProductSub(final String productSub) {
+ workPiece_.productSub_ = productSub;
+ return this;
+ }
+
+ /**
+ * @param headerNamesOrdered the headerNamesOrdered
+ * @return this for fluent use
+ */
+ BrowserVersionBuilder setHeaderNamesOrdered(final String[] headerNamesOrdered) {
+ workPiece_.headerNamesOrdered_ = headerNamesOrdered;
+ return this;
+ }
+
+ /**
+ * @param headerNamesOrdered the headerNamesOrdered
+ * @return this for fluent use
+ */
+ BrowserVersionBuilder setFontHeights(final int[] fontHeights) {
+ workPiece_.fontHeights_ = fontHeights;
+ return this;
+ }
+
+ /**
+ * @param buildId the buildId
+ * @return this for fluent use
+ */
+ BrowserVersionBuilder setBuildId(final String buildId) {
+ workPiece_.buildId_ = buildId;
+ return this;
+ }
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java b/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java
index de679977c7e..2d8e7be2c1d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/BrowserVersionFeatures.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,10 +15,9 @@
package com.gargoylesoftware.htmlunit;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF68;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import com.gargoylesoftware.htmlunit.javascript.configuration.BrowserFeature;
@@ -48,26 +47,22 @@ public enum BrowserVersionFeatures {
/** Ignore target when {@code href} is a javascript snippet. */
@BrowserFeature(CHROME)
- ANCHOR_IGNORE_TARGET_FOR_JS_HREF,
-
- /** Is the default display style of Applet is 'inline-block'. */
- @BrowserFeature(FF45)
- APPLET_INLINE_BLOCK,
+ ANCHOR_SEND_PING_REQUEST,
/** Background image is 'initial'. */
@BrowserFeature(CHROME)
CSS_BACKGROUND_INITIAL,
- /** Computed {@code display} is {@code block} for non-attached elements. */
+ /** Background image is 'rgba(0, 0, 0, 0)'. */
@BrowserFeature(FF)
- CSS_COMPUTED_BLOCK_IF_NOT_ATTACHED,
+ CSS_BACKGROUND_RGBA,
/** Computed {@code zIndex} is not considered. */
@BrowserFeature(CHROME)
CSS_COMPUTED_NO_Z_INDEX,
/** Is display style of HtmlDialog is 'none'. */
- @BrowserFeature(CHROME)
+ @BrowserFeature({CHROME, FF})
CSS_DIALOG_NONE,
/** Is display style 'block'. */
@@ -78,18 +73,27 @@ public enum BrowserVersionFeatures {
@BrowserFeature({CHROME, FF})
CSS_DISPLAY_BLOCK2,
- /** {@code CSSFontFaceRule.cssText} uses {@code \r\n} to break lines. */
- @BrowserFeature(IE)
- CSS_FONTFACERULE_CSSTEXT_CRLF,
-
/** {@code CSSFontFaceRule.cssText} has no {@code \n}. */
@BrowserFeature(CHROME)
- CSS_FONTFACERULE_CSSTEXT_NO_CRLF,
+ CSS_FONTFACERULE_CSSTEXT_CHROME_STYLE,
+
+ /** {@code CSSFontFaceRule.cssText} has no {@code \n}. */
+ @BrowserFeature(FF60)
+ CSS_FONTFACERULE_CSSTEXT_FF60_STYLE,
+
+ /** {@code CSSFontFaceRule.cssText} uses {@code \n\t} to break lines. */
+ @BrowserFeature(IE)
+ CSS_FONTFACERULE_CSSTEXT_IE_STYLE,
/** The default value of the display property for the 'input' tags is 'inline-block'. */
@BrowserFeature({CHROME, IE})
CSS_INPUT_DISPLAY_INLINE_BLOCK,
+ /** The default value of the display property for the 'input' tags of type
+ * radio or checkbox is 'inline-block'. */
+ @BrowserFeature(FF)
+ CSS_INPUT_DISPLAY_RADIO_CHECKBOX_INLINE_BLOCK,
+
/** 'initial' is a valid length value. */
@BrowserFeature({CHROME, FF})
CSS_LENGTH_INITIAL,
@@ -126,6 +130,14 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
CSS_SET_NULL_THROWS,
+ /** For disconnectd items style properties are blank. */
+ @BrowserFeature({CHROME, FF68})
+ CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY,
+
+ /** For disconnectd items style font property is blank. */
+ @BrowserFeature(CHROME)
+ CSS_STYLE_PROP_FONT_DISCONNECTED_IS_EMPTY,
+
/** Internet Explorer versions 5 and later support the behavior property. The behavior property lets
* you use CSS to attach a script to a specific element in order to implement
* DHTML (Dynamic HTML) components.
@@ -149,9 +161,9 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
DOM_NORMALIZE_REMOVE_CHILDREN,
- /** Event false result. */
- @BrowserFeature(IE)
- EVENT_FALSE_RESULT,
+ /** Indicates whether returnValue behaves HTML5-like with an empty string default. */
+ @BrowserFeature({CHROME, FF})
+ EVENT_BEFORE_UNLOAD_RETURN_VALUE_IS_HTML5_LIKE,
/** Triggers the onfocus onfocusin blur onfocusout events in this order. */
@BrowserFeature(CHROME)
@@ -161,6 +173,10 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
EVENT_FOCUS_IN_FOCUS_OUT_BLUR,
+ /** Indicates whether returning 'null' from a property handler is meaningful. */
+ @BrowserFeature(IE)
+ EVENT_HANDLER_NULL_RETURN_IS_MEANINGFUL,
+
/** Mouse events are triggered on disabled elements also. */
@BrowserFeature(FF)
EVENT_MOUSE_ON_DISABLED,
@@ -189,16 +205,12 @@ public enum BrowserVersionFeatures {
@BrowserFeature({CHROME, IE})
EVENT_ONHASHCHANGE_BUBBLES_FALSE,
- /** Event.cancelable is false in 'onload' event handler. */
- @BrowserFeature({CHROME, FF, IE})
- EVENT_ONLOAD_CANCELABLE_FALSE,
-
/** Triggers "onload" event if internal javascript loaded. */
@BrowserFeature(IE)
EVENT_ONLOAD_INTERNAL_JAVASCRIPT,
/** MessageEvent default data value is null. */
- @BrowserFeature({CHROME, FF52})
+ @BrowserFeature({CHROME, FF})
EVENT_ONMESSAGE_DEFAULT_DATA_NULL,
/** Does not trigger "onmousedown" event handler for the select options. */
@@ -225,6 +237,10 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
EVENT_ONMOUSEUP_NOT_FOR_SELECT_OPTION,
+ /** PopStateEvent can not be created by calling document.createEvent('PopStateEvent'). */
+ @BrowserFeature(FF)
+ EVENT_ONPOPSTATE_DOCUMENT_CREATE_NOT_SUPPORTED,
+
/** Supports event type 'BeforeUnloadEvent'. */
@BrowserFeature({CHROME, FF})
EVENT_TYPE_BEFOREUNLOADEVENT,
@@ -237,6 +253,10 @@ public enum BrowserVersionFeatures {
@BrowserFeature(FF)
EVENT_TYPE_KEY_EVENTS,
+ /** Supports vendor specific event type 'MouseWheelEvent'. */
+ @BrowserFeature(IE)
+ EVENT_TYPE_MOUSEWHEELEVENT,
+
/** Supports event type 'PointerEvent'. */
@BrowserFeature(IE)
EVENT_TYPE_POINTEREVENT,
@@ -245,6 +265,10 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
EVENT_TYPE_PROGRESSEVENT,
+ /** Supports event type 'WheelEvent'. */
+ @BrowserFeature({CHROME, IE})
+ EVENT_TYPE_WHEELEVENT,
+
/** For new pages the focus points to the body node. */
@BrowserFeature(IE)
FOCUS_BODY_ELEMENT_AT_START,
@@ -290,15 +314,15 @@ public enum BrowserVersionFeatures {
HTMLABBREVIATED,
/** HtmlAllCollection.item returns null instead of undefined if an element was not found. */
- @BrowserFeature({IE, FF})
+ @BrowserFeature({IE, FF60})
HTMLALLCOLLECTION_DO_NOT_CONVERT_STRINGS_TO_NUMBER,
/** HtmlAllCollection.item(int) is not supported. */
- @BrowserFeature(FF)
+ @BrowserFeature(FF60)
HTMLALLCOLLECTION_DO_NOT_SUPPORT_PARANTHESES,
/** HtmlAllCollection.item(int) requires int parameter. */
- @BrowserFeature(CHROME)
+ @BrowserFeature({CHROME, FF68})
HTMLALLCOLLECTION_INTEGER_INDEX,
/** HtmlCollection returns the first hit instead of a collection if many elements found. */
@@ -318,7 +342,7 @@ public enum BrowserVersionFeatures {
HTMLBASE_HREF_DEFAULT_EMPTY,
/** HtmlCollection.item() supports also doubles as index. */
- @BrowserFeature({IE, FF})
+ @BrowserFeature({IE, FF60})
HTMLCOLLECTION_ITEM_FUNCT_SUPPORTS_DOUBLE_INDEX_ALSO,
/** HtmlCollection.item[] supports also doubles as index. */
@@ -345,6 +369,10 @@ public enum BrowserVersionFeatures {
@BrowserFeature(FF)
HTMLDEFINITION_INLINE_IN_QUIRKS,
+ /** {@code document.applets} returns a NodeList. */
+ @BrowserFeature(FF60)
+ HTMLDOCUMENT_APPLETS_NODELIST,
+
/** Is {@code document.charset} lower-case. */
@BrowserFeature(IE)
HTMLDOCUMENT_CHARSET_LOWERCASE,
@@ -353,6 +381,12 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
HTMLDOCUMENT_COLOR,
+ /**
+ /** {@code document.getElementsByName} returns an empty list if called with the empty string.
+ */
+ @BrowserFeature(FF)
+ HTMLDOCUMENT_ELEMENTS_BY_NAME_EMPTY,
+
/** We can used function in detached documents. */
@BrowserFeature(IE)
HTMLDOCUMENT_FUNCTION_DETACHED,
@@ -376,6 +410,10 @@ public enum BrowserVersionFeatures {
@BrowserFeature({CHROME, FF})
HTMLELEMENT_ALIGN_INVALID,
+ /** Detaching the active element from the dom tree triggers no keyup event. */
+ @BrowserFeature(IE)
+ HTMLELEMENT_DETACH_ACTIVE_TRIGGERS_NO_KEYUP_EVENT,
+
/** Removing the active element from the dom tree triggers the onblur event. */
@BrowserFeature(CHROME)
HTMLELEMENT_REMOVE_ACTIVE_TRIGGERS_BLUR_EVENT,
@@ -385,7 +423,7 @@ public enum BrowserVersionFeatures {
HTMLIMAGE_BLANK_SRC_AS_EMPTY,
/** Empty src attribute sets display to false. */
- @BrowserFeature({IE, FF52})
+ @BrowserFeature({IE, FF})
HTMLIMAGE_EMPTY_SRC_DISPLAY_FALSE,
/** Is document.cretaeElement('image') an HTMLElement. */
@@ -417,12 +455,20 @@ public enum BrowserVersionFeatures {
HTMLINPUT_FILES_UNDEFINED,
/** HTMLInputElement: type {@code file} selectionSart/End are null. */
- @BrowserFeature({CHROME, FF52})
+ @BrowserFeature({CHROME, FF})
HTMLINPUT_FILE_SELECTION_START_END_NULL,
- /** HTMLInputElement: type {@code file} value to be {@code fakepath}. */
- @BrowserFeature({CHROME, IE})
- HTMLINPUT_FILE_VALUE_FAKEPATH,
+ /** HTMLInputElement color type is not supported. */
+ @BrowserFeature(IE)
+ HTMLINPUT_TYPE_COLOR_NOT_SUPPORTED,
+
+ /** HTMLInputElement date and time types are supported. */
+ @BrowserFeature({CHROME, FF})
+ HTMLINPUT_TYPE_DATETIME_SUPPORTED,
+
+ /** HTMLInputElement date and time types are not supported. */
+ @BrowserFeature(FF)
+ HTMLINPUT_TYPE_MONTH_NOT_SUPPORTED,
/** Should the HTMLElement of {@code keygen} have no end tag. */
@BrowserFeature(IE)
@@ -432,10 +478,6 @@ public enum BrowserVersionFeatures {
@BrowserFeature(CHROME)
HTMLLINK_CHECK_TYPE_FOR_STYLESHEET,
- /** If the single select has exact one option, this options gets never deselected. */
- @BrowserFeature(FF45)
- HTMLOPTION_EXACT_ONE_OPTION_GETS_NERVER_DESELECTED,
-
/** */
@BrowserFeature(IE)
HTMLOPTION_PREVENT_DISABLED,
@@ -481,7 +523,7 @@ public enum BrowserVersionFeatures {
HTML_COMMAND_TAG,
/** HTML parser supports the 'isindex' tag. */
- @BrowserFeature(CHROME)
+ @BrowserFeature({CHROME, FF})
HTML_ISINDEX_TAG,
/** HTML parser supports the 'main' tag. */
@@ -497,13 +539,13 @@ public enum BrowserVersionFeatures {
HTTP_COOKIE_EXTENDED_DATE_PATTERNS_1,
/** Dates format pattern 2. */
- @BrowserFeature({CHROME, EDGE})
+ @BrowserFeature(CHROME)
HTTP_COOKIE_EXTENDED_DATE_PATTERNS_2,
/** Indicates that the path is extracted from the location.
* Sample: from the location /foo/boo only /foo is used.
*/
- @BrowserFeature({IE, EDGE})
+ @BrowserFeature(IE)
HTTP_COOKIE_EXTRACT_PATH_FROM_LOCATION,
/** domain '.org' is handled as 'org'. */
@@ -514,11 +556,15 @@ public enum BrowserVersionFeatures {
* instead of 2000 (Two digits years are interpreted as 20xx
* if before 1970 and as 19xx otherwise).
*/
- @BrowserFeature({CHROME, FF, EDGE})
+ @BrowserFeature({CHROME, FF})
HTTP_COOKIE_START_DATE_1970,
+ /** Browser sends Sec-Fetch headers. */
+ @BrowserFeature(CHROME)
+ HTTP_HEADER_SEC_FETCH,
+
/** Browser sends Upgrade-Insecure-Requests header. */
- @BrowserFeature({CHROME, FF52})
+ @BrowserFeature({CHROME, FF})
HTTP_HEADER_UPGRADE_INSECURE_REQUEST,
/** Supports redirect via 308 code. */
@@ -548,7 +594,7 @@ public enum BrowserVersionFeatures {
JS_ANCHOR_PATHNAME_DETECT_WIN_DRIVES_URL,
/** The anchor pathname property returns nothing for broken http(s) url's. */
- @BrowserFeature(CHROME)
+ @BrowserFeature({CHROME, FF})
JS_ANCHOR_PATHNAME_NONE_FOR_BROKEN_URL,
/** The anchor pathname property returns nothing for none http(s) url's. */
@@ -567,6 +613,10 @@ public enum BrowserVersionFeatures {
@BrowserFeature(CHROME)
JS_ANCHOR_PROTOCOL_COLON_UPPER_CASE_DRIVE_LETTERS,
+ /** The anchor protocol property returns 'http' for broken http(s) url's. */
+ @BrowserFeature(FF)
+ JS_ANCHOR_PROTOCOL_HTTP_FOR_BROKEN_URL,
+
/** Indicates that "someFunction.arguments" is a read-only view of the function's argument. */
@BrowserFeature({CHROME, FF})
JS_ARGUMENTS_READ_ONLY_ACCESSED_FROM_FUNCTION,
@@ -595,10 +645,6 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_BOUNDINGCLIENTRECT_THROWS_IF_DISCONNECTED,
- /** If we're emulating IE, the overall JavaScript return value is the last return value. */
- @BrowserFeature(IE)
- JS_CALL_RESULT_IS_LAST_RETURN_VALUE,
-
/** toDataURL for canvas returns the CHROME version of the PNG. */
@BrowserFeature(CHROME)
JS_CANVAS_DATA_URL_CHROME_PNG,
@@ -607,10 +653,6 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_CANVAS_DATA_URL_IE_PNG,
- /** draw for canvas throws an error if no image available. */
- @BrowserFeature(FF45)
- JS_CANVAS_DRAW_THROWS_FOR_MISSING_IMG,
-
/** Do not allow invalid clear values. */
@BrowserFeature(IE)
JS_CLEAR_RESTRICT,
@@ -619,8 +661,12 @@ public enum BrowserVersionFeatures {
@BrowserFeature(CHROME)
JS_CLIENTHIGHT_INPUT_17,
+ /** ClientHeight for input is 21. */
+ @BrowserFeature(FF60)
+ JS_CLIENTHIGHT_INPUT_21,
+
/** ClientRectList toString reports the first item. */
- @BrowserFeature(FF)
+ @BrowserFeature(FF60)
JS_CLIENTRECTLIST_DEFAUL_VALUE_FROM_FIRST,
/** ClientRectList.item throws instead of returning null if an element was not found. */
@@ -636,17 +682,13 @@ public enum BrowserVersionFeatures {
JS_CLIENTWIDTH_INPUT_TEXT_169,
/** Is window can be used as Console. */
- @BrowserFeature({CHROME, FF52})
+ @BrowserFeature({CHROME, FF})
JS_CONSOLE_HANDLE_WINDOW,
/** item is enumerated before length property of CSSRuleList. */
@BrowserFeature(FF)
JS_CSSRULELIST_ENUM_ITEM_LENGTH,
- /** Uses {@code MozCSSKeyframesRule}. */
- @BrowserFeature(FF45)
- JS_CSS_MOZ_CSS_KEYFRAMES_RULE,
-
/** Date.toLocaleDateString() returns a short form (d.M.yyyy). */
@BrowserFeature({CHROME, FF})
JS_DATE_LOCALE_DATE_SHORT,
@@ -671,10 +713,6 @@ public enum BrowserVersionFeatures {
@BrowserFeature({CHROME, FF})
JS_DOCUMENT_CREATE_ATTRUBUTE_LOWER_CASE,
- /** Javascript function document.createElement accepts only tag names. */
- @BrowserFeature({CHROME, FF, IE})
- JS_DOCUMENT_CREATE_ELEMENT_STRICT,
-
/** The browser supports the design mode 'Inherit'. */
@BrowserFeature(IE)
JS_DOCUMENT_DESIGN_MODE_INHERIT,
@@ -691,10 +729,6 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_DOCUMENT_SETTING_DOMAIN_THROWS_FOR_ABOUT_BLANK,
- /** If setting the document.location inside onclick() of anchor element should be triggered. */
- @BrowserFeature({IE, FF})
- JS_DOCUMENT_SET_LOCATION_EXECUTED_IN_ANCHOR,
-
/** createHTMLDucument requires a title. */
@BrowserFeature(IE)
JS_DOMIMPLEMENTATION_CREATE_HTMLDOCOMENT_REQUIRES_TITLE,
@@ -764,7 +798,7 @@ public enum BrowserVersionFeatures {
JS_DOMIMPLEMENTATION_FEATURE_STYLESHEETS,
/** If document.implementation.hasFeature() supports 'http://www.w3.org/TR/SVG11/feature#BasicStructure 1.2'. */
- @BrowserFeature({CHROME, FF52})
+ @BrowserFeature({CHROME, FF})
JS_DOMIMPLEMENTATION_FEATURE_SVG_BASICSTRUCTURE_1_2,
/** If document.implementation.hasFeature() supports 'MutationNameEvents'. */
@@ -804,7 +838,7 @@ public enum BrowserVersionFeatures {
JS_DOMPARSER_PARSERERROR_ON_ERROR,
/** DOMTokenList returns false instead of throwing an exception when receiver is blank. */
- @BrowserFeature({CHROME, FF52})
+ @BrowserFeature({CHROME, FF})
JS_DOMTOKENLIST_CONTAINS_RETURNS_FALSE_FOR_BLANK,
/** DOMTokenList uses an enhanced set of whitespace chars. */
@@ -816,19 +850,15 @@ public enum BrowserVersionFeatures {
JS_DOMTOKENLIST_GET_NULL_IF_OUTSIDE,
/** DOMTokenList ignores duplicates when determining the length. */
- @BrowserFeature(CHROME)
+ @BrowserFeature({CHROME, FF})
JS_DOMTOKENLIST_LENGTH_IGNORES_DUPLICATES,
/** DOMTokenList removed all whitespace chars during add. */
- @BrowserFeature(CHROME)
+ @BrowserFeature({CHROME, FF})
JS_DOMTOKENLIST_REMOVE_WHITESPACE_CHARS_ON_ADD,
- /** DOMTokenList removed all whitespace chars during edit. */
- @BrowserFeature({CHROME, IE})
- JS_DOMTOKENLIST_REMOVE_WHITESPACE_CHARS_ON_EDIT,
-
/** DOMTokenList removed all whitespace chars during remove. */
- @BrowserFeature({CHROME, FF52})
+ @BrowserFeature({CHROME, FF})
JS_DOMTOKENLIST_REMOVE_WHITESPACE_CHARS_ON_REMOVE,
/** Javascript property function {@code delete} throws an exception if the given count is negative. */
@@ -843,11 +873,6 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_ENUMERATOR_CONSTRUCTOR_THROWS,
- /** Indicates that for(x in y) should enumerate the numbers first. */
- @BrowserFeature({CHROME, FF,
- IE})
- JS_ENUM_NUMBERS_FIRST,
-
/** Javascript {@code Error.captureStackTrace}. */
@BrowserFeature(CHROME)
JS_ERROR_CAPTURE_STACK_TRACE,
@@ -864,10 +889,6 @@ public enum BrowserVersionFeatures {
@BrowserFeature(FF)
JS_EVENT_DISTINGUISH_PRINTABLE_KEY,
- /** Executes the window event listeners if the node is detached from the document. */
- @BrowserFeature(CHROME)
- JS_EVENT_WINDOW_EXECUTE_IF_DITACHED,
-
/** Whether {@code FileReader} includes content type or not. */
@BrowserFeature(FF)
JS_FILEREADER_CONTENT_TYPE,
@@ -881,8 +902,12 @@ public enum BrowserVersionFeatures {
JS_FILE_SHORT_DATE_FORMAT,
/** Indicates that the action property will not be expanded if defined as empty string. */
- @BrowserFeature(FF)
- JS_FORM_ACTION_EXPANDURL_IGNORE_EMPTY,
+ @BrowserFeature({CHROME, FF})
+ JS_FORM_ACTION_EXPANDURL_NOT_DEFINED,
+
+ /** use content-type text/plain if the file type is unknown'. */
+ @BrowserFeature(IE)
+ JS_FORM_DATA_CONTENT_TYPE_PLAIN_IF_FILE_TYPE_UNKNOWN,
/** form.dispatchEvent(e) submits the form if the event is of type 'submit'. */
@BrowserFeature(FF)
@@ -900,10 +925,6 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_FORM_USABLE_AS_FUNCTION,
- /** Indicates that function is defined even before its declaration, inside a block. */
- @BrowserFeature({CHROME, FF52, IE})
- JS_FUNCTION_DECLARED_FORWARD_IN_BLOCK,
-
/** Indicates if the method toSource exists on the native objects. */
@BrowserFeature(FF)
JS_FUNCTION_TOSOURCE,
@@ -942,6 +963,12 @@ public enum BrowserVersionFeatures {
@BrowserFeature({FF, IE})
JS_IMAGE_PROTOTYPE_SAME_AS_HTML_IMAGE,
+ /**
+ * Getting the width and height of an image tag with an empty source returns 0x0.
+ */
+ @BrowserFeature({CHROME, FF})
+ JS_IMAGE_WIDTH_HEIGHT_EMPTY_SOURCE_RETURNS_0x0,
+
/**
* Getting the width and height of an image tag without a source returns 16x16;
* for invalid values returns 0.
@@ -950,8 +977,8 @@ public enum BrowserVersionFeatures {
JS_IMAGE_WIDTH_HEIGHT_RETURNS_16x16_0x0,
/**
- * Getting the width and height of an image tag without a source returns 18x20;
- * for invalid values returns 1.
+ * Getting the width and height of an image tag without a source returns 24x24;
+ * for invalid values returns 0x0.
*/
@BrowserFeature(FF)
JS_IMAGE_WIDTH_HEIGHT_RETURNS_24x24_0x0,
@@ -967,28 +994,28 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_INNER_HTML_ADD_CHILD_FOR_NULL_VALUE,
- /** Indicates that innerHTML uses {@code crnl} instead of {@code nl}. */
+ /** Indicates that innerHTML uses {@code lf} instead of {@code lf}. */
@BrowserFeature(IE)
- JS_INNER_TEXT_CR_NL,
+ JS_INNER_TEXT_LF,
/** Indicates that innerText setter supports null values. */
- @BrowserFeature({CHROME, FF52})
+ @BrowserFeature({CHROME, FF})
JS_INNER_TEXT_VALUE_NULL,
- /** Chrome ignores negative selection starts. */
- @BrowserFeature(CHROME)
+ /** Ignore negative selection starts. */
+ @BrowserFeature({CHROME, FF})
JS_INPUT_IGNORE_NEGATIVE_SELECTION_START,
/** Chrome/FF returns null for selectionStart/selectionEnd. */
- @BrowserFeature({CHROME, FF52})
+ @BrowserFeature({CHROME, FF})
JS_INPUT_NUMBER_SELECTION_START_END_NULL,
/** Setting the type property of an input converts the type to lowercase. */
@BrowserFeature(IE)
JS_INPUT_SET_TYPE_LOWERCASE,
- /** Setting the value of an Input Date to blank will result in an empty value. */
- @BrowserFeature(CHROME)
+ /** Setting the value of an Input Date will check for correct format. */
+ @BrowserFeature({CHROME, FF})
JS_INPUT_SET_VALUE_DATE_SUPPORTED,
/** Setting the value of an Input Email to blank will result in an empty value. */
@@ -1007,16 +1034,16 @@ public enum BrowserVersionFeatures {
@BrowserFeature(CHROME)
JS_INTL_V8_BREAK_ITERATOR,
- /** Supports Iterator and StopIteration. */
- @BrowserFeature(FF)
- JS_Iterator,
+ /** Indicates that isSearchProviderInstalled returns zero instead of undefined. */
+ @BrowserFeature({CHROME, FF60, IE})
+ JS_IS_SEARCH_PROVIDER_INSTALLED_ZERO,
/** Property form for label always returns null. */
- @BrowserFeature({CHROME, FF52})
+ @BrowserFeature({CHROME, FF})
JS_LABEL_FORM_NULL,
/** location.hash returns an encoded hash. */
- @BrowserFeature(FF)
+ @BrowserFeature({CHROME, FF})
JS_LOCATION_HASH_HASH_IS_ENCODED,
/**
@@ -1025,7 +1052,7 @@ public enum BrowserVersionFeatures {
* for url 'http://localhost/something/#%C3%BC'.
* IE evaluates to #%C3%BC.
*/
- @BrowserFeature(FF)
+ @BrowserFeature({CHROME, FF})
JS_LOCATION_HASH_IS_DECODED,
/**
@@ -1041,12 +1068,12 @@ public enum BrowserVersionFeatures {
* for url 'http://localhost/something/#ü'.
* IE evaluates to #ü.
*/
- @BrowserFeature(FF)
+ @BrowserFeature({CHROME, FF})
JS_LOCATION_HREF_HASH_IS_ENCODED,
- /** Map ignores the argument constructor. */
- @BrowserFeature(IE)
- JS_MAP_CONSTRUCTOR_IGNORE_ARGUMENT,
+ /** Reload sends a referrer header. */
+ @BrowserFeature(CHROME)
+ JS_LOCATION_RELOAD_REFERRER,
/** Indicates that an empty media list is represented by the string 'all'. */
@BrowserFeature(IE)
@@ -1060,14 +1087,22 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_MENU_TYPE_EMPTY,
+ /** Type property of menu returns the current (maybe invalid) value. */
+ @BrowserFeature(FF)
+ JS_MENU_TYPE_PASS,
+
/** Indicates if the String representation of a native function is without newline. */
- @BrowserFeature({CHROME, EDGE})
+ @BrowserFeature(CHROME)
JS_NATIVE_FUNCTION_TOSTRING_COMPACT,
/** Indicates if the String representation of a native function begins and ends with a {@code \n}.*/
@BrowserFeature(IE)
JS_NATIVE_FUNCTION_TOSTRING_NEW_LINE,
+ /** Indicates if the String representation of a native function has a newline for empty parameter list. */
+ @BrowserFeature(FF)
+ JS_NATIVE_FUNCTION_TOSTRING_NL,
+
/** Navigator.doNotTrack returns unspecified if not set. */
@BrowserFeature(FF)
JS_NAVIGATOR_DO_NOT_TRACK_UNSPECIFIED,
@@ -1130,7 +1165,7 @@ public enum BrowserVersionFeatures {
JS_PROPERTY_DESCRIPTOR_NEW_LINE,
/** Support {@code Reflect}. */
- @BrowserFeature({CHROME, FF, EDGE})
+ @BrowserFeature({CHROME, FF})
JS_REFLECT,
/** RegExp.lastParen returns an empty string if the RegExp has too many groups. */
@@ -1141,9 +1176,15 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_REGEXP_GROUP0_RETURNS_WHOLE_MATCH,
- /** Javascript script tags supports the 'for' and the 'event' attribute.
+ /**
+ * Javascript script tags handles a 204 (no content) response for the src
+ * attrib as error.
*/
@BrowserFeature(IE)
+ JS_SCRIPT_HANDLE_204_AS_ERROR,
+
+ /** Javascript script tags supports the 'for' and the 'event' attribute. */
+ @BrowserFeature(IE)
JS_SCRIPT_SUPPORTS_FOR_AND_EVENT_WINDOW,
/** Javascript selectorText property returns selectors in lower case. */
@@ -1154,17 +1195,17 @@ public enum BrowserVersionFeatures {
@BrowserFeature({CHROME, FF})
JS_SELECT_FILE_THROWS,
- /** When expanding the collection by setting the length don't add
+ /** When expanding the options collection by setting the length don't add
* an empty text node. */
- @BrowserFeature({CHROME, IE})
- JS_SELECT_OPTIONS_DONT_ADD_EMPTY_TEXT_CHILD_WHEN_EXPANDING,
+ @BrowserFeature(FF60)
+ JS_SELECT_OPTIONS_ADD_EMPTY_TEXT_CHILD_WHEN_EXPANDING,
/** Indicates that select.options has a wong class name. */
@BrowserFeature(IE)
JS_SELECT_OPTIONS_HAS_SELECT_CLASS_NAME,
/** Ignore negative value when setting the length. */
- @BrowserFeature({CHROME, FF})
+ @BrowserFeature(CHROME)
JS_SELECT_OPTIONS_IGNORE_NEGATIVE_LENGTH,
/** The 'in' operator returns always true for HtmlOptionsCollection. */
@@ -1176,14 +1217,14 @@ public enum BrowserVersionFeatures {
JS_SELECT_OPTIONS_NULL_FOR_OUTSIDE,
/** Indicates that select.options.remove ignores the call if index is too large. */
- @BrowserFeature(CHROME)
+ @BrowserFeature({CHROME, FF68})
JS_SELECT_OPTIONS_REMOVE_IGNORE_IF_INDEX_NEGATIVE,
/** Indicates that select.options.remove ignores the call if index is too large. */
- @BrowserFeature({CHROME, IE})
+ @BrowserFeature({CHROME, FF68, IE})
JS_SELECT_OPTIONS_REMOVE_IGNORE_IF_INDEX_TOO_LARGE,
- /** Indicates that select.options[i] throws an exception if the requested index is neagtive. */
+ /** Indicates that select.options[i] throws an exception if the requested index is negative. */
@BrowserFeature(IE)
JS_SELECT_OPTIONS_REMOVE_THROWS_IF_NEGATIV,
@@ -1196,10 +1237,6 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_SELECT_SET_VALUES_CHECKS_ONLY_VALUE_ATTRIBUTE,
- /** Set ignores the constructor argument. */
- @BrowserFeature(IE)
- JS_SET_CONSTRUCTOR_IGNORE_ARGUMENT,
-
/** Whether to get any property from the items first. */
@BrowserFeature(IE)
JS_STORAGE_GET_FROM_ITEMS,
@@ -1213,7 +1250,7 @@ public enum BrowserVersionFeatures {
JS_STYLESHEETLIST_ACTIVE_ONLY,
/** Indicates if style.setProperty ignores case when determining the priority. */
- @BrowserFeature({CHROME, IE})
+ @BrowserFeature({CHROME, FF68, IE})
JS_STYLE_SET_PROPERTY_IMPORTANT_IGNORES_CASE,
/** IE supports accessing unsupported style elements via getter
@@ -1232,13 +1269,9 @@ public enum BrowserVersionFeatures {
JS_STYLE_WRONG_INDEX_RETURNS_UNDEFINED,
/** Supports Symbol. */
- @BrowserFeature({CHROME, FF, EDGE})
+ @BrowserFeature({CHROME, FF})
JS_SYMBOL,
- /** Symbol support is limited in FF45. */
- @BrowserFeature(FF45)
- JS_SYMBOL_FF45,
-
/** The width cell height does not return negative values. */
@BrowserFeature(IE)
JS_TABLE_CELL_HEIGHT_DOES_NOT_RETURN_NEGATIVE_VALUES,
@@ -1290,7 +1323,7 @@ public enum BrowserVersionFeatures {
/** Setting the property cols throws an exception, if the provided value is not convertible into an integer.
* FF ignores the provided value in this case and sets cols to 0.
*/
- @BrowserFeature({IE, FF45})
+ @BrowserFeature(IE)
JS_TEXT_AREA_SET_COLS_THROWS_EXCEPTION,
/** Setting the property {@code maxLength} throws an exception, if the provided value is less than 0. */
@@ -1304,7 +1337,7 @@ public enum BrowserVersionFeatures {
/** Setting the property rows throws an exception, if the provided value is not convertible into an integer.
* FF ignores the provided value in this case and sets rows to 0.
*/
- @BrowserFeature({IE, FF45})
+ @BrowserFeature(IE)
JS_TEXT_AREA_SET_ROWS_THROWS_EXCEPTION,
/** Setting the value processes null as null value. */
@@ -1322,17 +1355,13 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_TREEWALKER_FILTER_FUNCTION_ONLY,
- /** Types arrays can be constructed with {@code null}. */
- @BrowserFeature(CHROME)
- JS_TYPED_ARRAYS_NULL,
-
/** Setting the property align to arbitrary values is allowed. */
@BrowserFeature({CHROME, FF})
JS_TYPE_ACCEPTS_ARBITRARY_VALUES,
- /** WeakMap ignores the constructor argument. */
+ /** Setting the property valign converts to lowercase. */
@BrowserFeature(IE)
- JS_WEAKMAP_CONSTRUCTOR_IGNORE_ARGUMENT,
+ JS_VALIGN_CONVERTS_TO_LOWERCASE,
/** Allow inheriting parent constants
* in {@link com.gargoylesoftware.htmlunit.javascript.host.event.WebGLContextEvent}. */
@@ -1370,12 +1399,6 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_WINDOW_FRAME_BY_ID_RETURNS_WINDOW,
- /**
- * Difference of window.outer/inner height is 89.
- */
- @BrowserFeature(CHROME)
- JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_132,
-
/**
* Difference of window.outer/inner height is 63.
*/
@@ -1383,10 +1406,16 @@ public enum BrowserVersionFeatures {
JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_63,
/**
- * Difference of window.outer/inner height is 94.
+ * Difference of window.outer/inner height is 86.
*/
@BrowserFeature(FF)
- JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_94,
+ JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_86,
+
+ /**
+ * Difference of window.outer/inner height is 92.
+ */
+ @BrowserFeature(CHROME)
+ JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_92,
/** Window.getSelection returns null, if the window is not visible. */
@BrowserFeature(FF)
@@ -1428,6 +1457,10 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
JS_XML_SUPPORT_VIA_ACTIVEXOBJECT,
+ /** {@code XSLTProcessor.transformToDocument} supports output indent attribute. */
+ @BrowserFeature(CHROME)
+ JS_XSLT_TRANSFORM_INDENT,
+
/** With special keys [in .type(int)], should we trigger onkeypress event or not. */
@BrowserFeature(FF)
KEYBOARD_EVENT_SPECIAL_KEYPRESS,
@@ -1465,10 +1498,6 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
QUERYSELECTORALL_NOT_IN_QUIRKS,
- /** Indicates {@code .querySelectorAll()} ignores {@code :target} condition. */
- @BrowserFeature(CHROME)
- QUERYSELECTORALL_NO_TARGET,
-
/** IE throws a syntax error if a css3 pseudo selector is used on a detached node. */
@BrowserFeature(IE)
QUERYSELECTOR_CSS3_PSEUDO_REQUIRE_ATTACHED_NODE,
@@ -1477,21 +1506,10 @@ public enum BrowserVersionFeatures {
@BrowserFeature(IE)
RESETINPUT_DEFAULT_VALUE_IF_VALUE_NOT_DEFINED,
- /**
- * Indicates that all options of a select are deselected,
- * if the select state is changed for an unknown option.
- */
- @BrowserFeature({CHROME, FF52, IE})
- SELECT_DESELECT_ALL_IF_SWITCHING_UNKNOWN,
-
/** The default display style of slot is 'content'. */
- @BrowserFeature(CHROME)
+ @BrowserFeature({CHROME, FF})
SLOT_CONTENTS,
- /** Indicates that string.contains() is supported. */
- @BrowserFeature(FF45)
- STRING_CONTAINS,
-
/** Indicates that string.includes() is supported. */
@BrowserFeature({CHROME, FF})
STRING_INCLUDES,
@@ -1534,16 +1552,9 @@ public enum BrowserVersionFeatures {
* Indicates, that the pathname for the url 'blank' is empty;
* instead of 'blank'.
*/
- @BrowserFeature({CHROME, FF52})
+ @BrowserFeature({CHROME, FF})
URL_ABOUT_BLANK_HAS_BLANK_PATH,
- /**
- * Indicates, that the pathname for the url {@code about:blank} is empty;
- * instead of '/blank'.
- */
- @BrowserFeature(FF45)
- URL_ABOUT_BLANK_HAS_EMPTY_PATH,
-
/**
* Indicates, that the browser supports username and password as
* part of the url (e.g. http://john.smith:secret@localhost).
@@ -1559,13 +1570,25 @@ public enum BrowserVersionFeatures {
@BrowserFeature({CHROME, FF})
URL_MISSING_SLASHES,
+ /** Set the origin property for web socket events. */
+ @BrowserFeature({CHROME, FF})
+ WEBSOCKET_ORIGIN_SET,
+
+ /** Set the srcElement property for web socket events. */
+ @BrowserFeature({CHROME, FF68, IE})
+ WEBSOCKET_SRC_ELEMENT_SET,
+
/** Execute window events. */
@BrowserFeature(IE)
WINDOW_EXECUTE_EVENTS,
- /** XMLHttpRequest.getAllResponseHeaders() has a trailing CrLf. */
+ /** XMLHttpRequest.getAllResponseHeaders() has a trailing separator. */
@BrowserFeature(IE)
- XHR_ALL_RESPONSE_HEADERS_APPEND_CRLF,
+ XHR_ALL_RESPONSE_HEADERS_APPEND_SEPARATOR,
+
+ /** XMLHttpRequest.getAllResponseHeaders() uses only Lf as separator. */
+ @BrowserFeature({FF, IE})
+ XHR_ALL_RESPONSE_HEADERS_SEPARATE_BY_LF,
/** XMLHttpRequest triggers the opened event at the beginning of the send method again. */
@BrowserFeature(IE)
@@ -1581,7 +1604,7 @@ public enum BrowserVersionFeatures {
XHR_IGNORE_PORT_FOR_SAME_ORIGIN,
/** ProgressEvent.lengthComputable is true. */
- @BrowserFeature({FF45, IE})
+ @BrowserFeature(IE)
XHR_LENGTH_COMPUTABLE,
/** A cross origin request to {@code about:blank} is not allowed. */
@@ -1592,33 +1615,14 @@ public enum BrowserVersionFeatures {
@BrowserFeature({CHROME, FF})
XHR_OPEN_ALLOW_EMTPY_URL,
- /** Indicates that open() throws an exception in sync mode if 'withCredentials' is set to true. */
- @BrowserFeature(FF45)
- XHR_OPEN_WITHCREDENTIALS_TRUE_IN_SYNC_EXCEPTION,
-
- /** Indicates that method overrideMimeType throws if msg was already sent. */
- @BrowserFeature({CHROME, FF52, IE})
- XHR_OVERRIDE_MIME_TYPE_BEFORE_SEND,
-
/** Indicates that the content charset is used for response parsing. */
- @BrowserFeature(FF)
+ @BrowserFeature({FF, CHROME})
XHR_USE_CONTENT_CHARSET,
- /** Indicates that the request uses the charset from the requesting page. */
- @BrowserFeature(CHROME)
- XHR_USE_DEFAULT_CHARSET_FROM_PAGE,
-
/** Indicates that the "*" pattern is allowed when withCredential is enabled. */
@BrowserFeature(IE)
XHR_WITHCREDENTIALS_ALLOW_ORIGIN_ALL,
- /**
- * Indicates that the property withCredentials is not writable for sync requests.
- * Setting the property throws an exception.
- */
- @BrowserFeature(FF45)
- XHR_WITHCREDENTIALS_NOT_WRITEABLE_IN_SYNC_EXCEPTION,
-
/** Indicates that the XPath attribute is case sensitive. */
@BrowserFeature(CHROME)
XPATH_ATTRIBUTE_CASE_SENSITIVE,
@@ -1626,5 +1630,4 @@ public enum BrowserVersionFeatures {
/** Indicates that the 'SelectionNamespaces' property is supported by XPath expressions. */
@BrowserFeature({IE, CHROME})
XPATH_SELECTION_NAMESPACES,
-
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/Cache.java b/src/main/java/com/gargoylesoftware/htmlunit/Cache.java
index 717c748c62d..32f955de295 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/Cache.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/Cache.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,13 +19,14 @@
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.client.utils.DateUtils;
-import org.w3c.dom.css.CSSStyleSheet;
+import com.gargoylesoftware.css.dom.CSSStyleSheetImpl;
import com.gargoylesoftware.htmlunit.util.HeaderUtils;
import com.gargoylesoftware.htmlunit.util.UrlUtils;
@@ -38,6 +39,7 @@
* @author Daniel Gredler
* @author Ahmed Ashour
* @author Anton Demydenko
+ * @author Ronald Brill
*/
public class Cache implements Serializable {
@@ -45,7 +47,8 @@ public class Cache implements Serializable {
private int maxSize_ = 40;
private static final Pattern DATE_HEADER_PATTERN = Pattern.compile("-?\\d+");
- private static final long DELAY = 10 * org.apache.commons.lang3.time.DateUtils.MILLIS_PER_MINUTE;
+ static final long DELAY = 10 * org.apache.commons.lang3.time.DateUtils.MILLIS_PER_MINUTE;
+
/**
* The map which holds the cached responses. Note that when keying on URLs, we key on the string version
* of the URLs, rather than on the URLs themselves. This is done for performance, because a) the
@@ -109,6 +112,42 @@ public int hashCode() {
public void touch() {
lastAccess_ = System.currentTimeMillis();
}
+
+ /**
+ * Check freshness return value if
+ * a) s-maxage specified
+ * b) max-age specified
+ * c) expired specified
+ * otherwise return {@code null}
+ *
+ * @see RFC 7234
+ *
+ * @param response
+ * @param createdAt
+ * @return freshnessLifetime
+ */
+ private boolean isStillFresh(final long now) {
+ long freshnessLifetime = 0;
+ if (!HeaderUtils.containsPrivate(response_) && HeaderUtils.containsSMaxage(response_)) {
+ // check s-maxage
+ freshnessLifetime = HeaderUtils.sMaxage(response_);
+ }
+ else if (HeaderUtils.containsMaxAge(response_)) {
+ // check max-age
+ freshnessLifetime = HeaderUtils.maxAge(response_);
+ }
+ else if (response_.getResponseHeaderValue(HttpHeader.EXPIRES) != null) {
+ final Date expires = parseDateHeader(response_, HttpHeader.EXPIRES);
+ if (expires != null) {
+ // use the same logic as in isCacheableContent()
+ return expires.getTime() - now > DELAY;
+ }
+ }
+ else {
+ return true;
+ }
+ return now - createdAt_ < freshnessLifetime * org.apache.commons.lang3.time.DateUtils.MILLIS_PER_SECOND;
+ }
}
/**
@@ -123,7 +162,7 @@ public void touch() {
*/
public boolean cacheIfPossible(final WebRequest request, final WebResponse response, final Object toCache) {
if (isCacheable(request, response)) {
- final URL url = response.getWebRequest().getUrl();
+ final URL url = request.getUrl();
if (url == null) {
return false;
}
@@ -142,13 +181,13 @@ public boolean cacheIfPossible(final WebRequest request, final WebResponse respo
* than requests and responses as is done above) because a) this allows us to cache inline CSS, b) CSS is
* extremely expensive to parse, so we want to avoid it as much as possible, c) CSS files aren't usually
* nearly as large as JavaScript files, so memory bloat won't be too bad, and d) caching on requests and
- * responses requires checking dynamicity (see {@link #isCacheableContent(WebResponse)}), and headers often
+ * responses requires checking dynamically (see {@link #isCacheableContent(WebResponse)}), and headers often
* aren't set up correctly, disallowing caching when in fact it should be allowed.
*
* @param css the CSS snippet from which styleSheet is derived
* @param styleSheet the parsed version of css
*/
- public void cache(final String css, final CSSStyleSheet styleSheet) {
+ public void cache(final String css, final CSSStyleSheetImpl styleSheet) {
final Entry entry = new Entry(css, null, styleSheet);
entries_.put(entry.key_, entry);
deleteOverflow();
@@ -205,7 +244,14 @@ protected boolean isCacheableContent(final WebResponse response) {
}
final Date lastModified = parseDateHeader(response, HttpHeader.LAST_MODIFIED);
- final Date expires = parseDateHeader(response, HttpHeader.EXPIRES);
+
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires
+ // If there is a Cache-Control header with the max-age or s-maxage directive
+ // in the response, the Expires header is ignored.
+ Date expires = null;
+ if (!HeaderUtils.containsMaxAgeOrSMaxage(response)) {
+ expires = parseDateHeader(response, HttpHeader.EXPIRES);
+ }
final long now = getCurrentTimestamp();
@@ -229,7 +275,7 @@ protected long getCurrentTimestamp() {
* @param headerName the header name
* @return the specified date header of the specified response
*/
- protected Date parseDateHeader(final WebResponse response, final String headerName) {
+ protected static Date parseDateHeader(final WebResponse response, final String headerName) {
final String value = response.getResponseHeaderValue(headerName);
if (value == null) {
return null;
@@ -286,61 +332,23 @@ private Entry getCacheEntry(final WebRequest request) {
if (url == null) {
return null;
}
- final Entry cachedEntry = entries_.get(UrlUtils.normalize(url));
+
+ final String normalizedUrl = UrlUtils.normalize(url);
+ final Entry cachedEntry = entries_.get(normalizedUrl);
if (cachedEntry == null) {
return null;
}
- // check if object still fresh
- if (checkFreshness(cachedEntry.response_, cachedEntry.createdAt_)) {
+ if (cachedEntry.isStillFresh(getCurrentTimestamp())) {
synchronized (entries_) {
cachedEntry.touch();
}
return cachedEntry;
}
- else {
- entries_.remove(UrlUtils.normalize(url));
- }
+ entries_.remove(UrlUtils.normalize(url));
return null;
}
- /**
- * Check freshness return value if
- * a) s-maxage specified
- * b) max-age specified
- * c) expired specified
- * otherwise return {@code null}
- *
- * @see RFC 7234
- *
- * @param response
- * @param createdAt
- * @return freshnessLifetime
- */
- private boolean checkFreshness(final WebResponse response, final long createdAt) {
- final long now = getCurrentTimestamp();
- long freshnessLifetime = 0;
- if (!HeaderUtils.containsPrivate(response) && HeaderUtils.containsSMaxage(response)) {
- // check s-maxage
- freshnessLifetime = HeaderUtils.sMaxage(response);
- }
- else if (HeaderUtils.containsMaxAge(response)) {
- // check max-age
- freshnessLifetime = HeaderUtils.maxAge(response);
- }
- else if (response.getResponseHeaderValue(HttpHeader.EXPIRES) != null) {
- final Date expires = parseDateHeader(response, HttpHeader.EXPIRES);
- if (expires != null) {
- // use the same logic as in isCacheableContent()
- return expires.getTime() - now > DELAY;
- }
- }
- else {
- return true;
- }
- return now - createdAt < freshnessLifetime * org.apache.commons.lang3.time.DateUtils.MILLIS_PER_SECOND;
- }
-
/**
* Returns the cached parsed version of the specified CSS snippet. If there is no
* corresponding cached stylesheet, this method returns {@code null}.
@@ -348,7 +356,7 @@ else if (response.getResponseHeaderValue(HttpHeader.EXPIRES) != null) {
* @param css the CSS snippet whose cached stylesheet is sought
* @return the cached stylesheet corresponding to the specified CSS snippet
*/
- public CSSStyleSheet getCachedStyleSheet(final String css) {
+ public CSSStyleSheetImpl getCachedStyleSheet(final String css) {
final Entry cachedEntry = entries_.get(css);
if (cachedEntry == null) {
return null;
@@ -356,7 +364,7 @@ public CSSStyleSheet getCachedStyleSheet(final String css) {
synchronized (entries_) {
cachedEntry.touch();
}
- return (CSSStyleSheet) cachedEntry.value_;
+ return (CSSStyleSheetImpl) cachedEntry.value_;
}
/**
@@ -405,4 +413,22 @@ public void clear() {
entries_.clear();
}
}
+
+ /**
+ * Removes outdated entries from the cache.
+ */
+ public void clearOutdated() {
+ synchronized (entries_) {
+ final long now = getCurrentTimestamp();
+
+ final Iterator> iter = entries_.entrySet().iterator();
+ while (iter.hasNext()) {
+ final Map.Entry entry = iter.next();
+ if (entry.getValue().response_ == null
+ || !entry.getValue().isStillFresh(now)) {
+ iter.remove();
+ }
+ }
+ }
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/CollectingAlertHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/CollectingAlertHandler.java
index fe8e024f9f9..20b33fe4e5e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/CollectingAlertHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/CollectingAlertHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/ConfirmHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/ConfirmHandler.java
index f6578091941..ba7fe0319df 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/ConfirmHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/ConfirmHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,13 +14,15 @@
*/
package com.gargoylesoftware.htmlunit;
+import java.io.Serializable;
+
/**
* A handler for the JavaScript function window.confirm() . Confirms
* are triggered when the JavaScript function window.confirm() is invoked.
*
* @author Mike Bowler
*/
-public interface ConfirmHandler {
+public interface ConfirmHandler extends Serializable {
/**
* Handles a confirm for the specified page.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/CookieManager.java b/src/main/java/com/gargoylesoftware/htmlunit/CookieManager.java
index 42c70977341..b7abd377d3b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/CookieManager.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/CookieManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/DefaultCredentialsProvider.java b/src/main/java/com/gargoylesoftware/htmlunit/DefaultCredentialsProvider.java
index f253a7995fe..12686ed440d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/DefaultCredentialsProvider.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/DefaultCredentialsProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@
*/
public class DefaultCredentialsProvider implements CredentialsProvider, Serializable {
- private final Map credentialsMap_ = new HashMap<>();
+ private final Map credentialsMap_ = new HashMap<>();
/**
* Adds credentials for the specified username/password for any host/port/realm combination.
@@ -98,21 +98,13 @@ public synchronized void setCredentials(final AuthScope authscope, final Credent
if (authscope == null) {
throw new IllegalArgumentException("Authentication scope may not be null");
}
- final CredentialsFactory factory;
- if (credentials instanceof UsernamePasswordCredentials) {
- final UsernamePasswordCredentials userCredentials = (UsernamePasswordCredentials) credentials;
- factory = new UsernamePasswordCredentialsFactory(userCredentials.getUserName(),
- userCredentials.getPassword());
- }
- else if (credentials instanceof NTCredentials) {
- final NTCredentials ntCredentials = (NTCredentials) credentials;
- factory = new NTCredentialsFactory(ntCredentials.getUserName(), ntCredentials.getPassword(),
- ntCredentials.getWorkstation(), ntCredentials.getDomain());
- }
- else {
- throw new IllegalArgumentException("Unsupported Credential type: " + credentials.getClass().getName());
+
+ if ((credentials instanceof UsernamePasswordCredentials) || (credentials instanceof NTCredentials)) {
+ credentialsMap_.put(new AuthScopeProxy(authscope), credentials);
+ return;
}
- credentialsMap_.put(new AuthScopeProxy(authscope), factory);
+
+ throw new IllegalArgumentException("Unsupported Credential type: " + credentials.getClass().getName());
}
/**
@@ -122,28 +114,23 @@ else if (credentials instanceof NTCredentials) {
* @param authscope the {@link AuthScope authentication scope}
* @return the credentials
*/
- private static Credentials matchCredentials(final Map map,
- final AuthScope authscope) {
- final CredentialsFactory factory = map.get(new AuthScopeProxy(authscope));
- Credentials creds = null;
- if (factory == null) {
+ private static Credentials matchCredentials(final Map map, final AuthScope authscope) {
+ Credentials creds = map.get(new AuthScopeProxy(authscope));
+ if (creds == null) {
int bestMatchFactor = -1;
- AuthScope bestMatch = null;
+ AuthScopeProxy bestMatch = null;
for (final AuthScopeProxy proxy : map.keySet()) {
final AuthScope current = proxy.getAuthScope();
final int factor = authscope.match(current);
if (factor > bestMatchFactor) {
bestMatchFactor = factor;
- bestMatch = current;
+ bestMatch = proxy;
}
}
if (bestMatch != null) {
- creds = map.get(new AuthScopeProxy(bestMatch)).getInstance();
+ creds = map.get(bestMatch);
}
}
- else {
- creds = factory.getInstance();
- }
return creds;
}
@@ -202,18 +189,22 @@ public synchronized void clear() {
*/
private static class AuthScopeProxy implements Serializable {
private AuthScope authScope_;
+
AuthScopeProxy(final AuthScope authScope) {
authScope_ = authScope;
}
+
public AuthScope getAuthScope() {
return authScope_;
}
+
private void writeObject(final ObjectOutputStream stream) throws IOException {
stream.writeObject(authScope_.getHost());
stream.writeInt(authScope_.getPort());
stream.writeObject(authScope_.getRealm());
stream.writeObject(authScope_.getScheme());
}
+
private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException {
final String host = (String) stream.readObject();
final int port = stream.readInt();
@@ -221,72 +212,15 @@ private void readObject(final ObjectInputStream stream) throws IOException, Clas
final String scheme = (String) stream.readObject();
authScope_ = new AuthScope(host, port, realm, scheme);
}
+
@Override
public int hashCode() {
return authScope_.hashCode();
}
+
@Override
public boolean equals(final Object obj) {
return obj instanceof AuthScopeProxy && authScope_.equals(((AuthScopeProxy) obj).getAuthScope());
}
}
-
- /**
- * We have to create a factory class, so that credentials can be serialized correctly.
- */
- private static class UsernamePasswordCredentialsFactory implements CredentialsFactory, Serializable {
- private String username_;
- private String password_;
-
- UsernamePasswordCredentialsFactory(final String username, final String password) {
- username_ = username;
- password_ = password;
- }
-
- @Override
- public Credentials getInstance() {
- return new UsernamePasswordCredentials(username_, password_);
- }
-
- @Override
- public String toString() {
- return getInstance().toString();
- }
- }
-
- /**
- * We have to create a factory class, so that credentials can be serialized correctly.
- */
- private static class NTCredentialsFactory implements CredentialsFactory, Serializable {
- private String username_;
- private String password_;
- private String workstation_;
- private String domain_;
-
- NTCredentialsFactory(final String username, final String password, final String workstation,
- final String domain) {
- username_ = username;
- password_ = password;
- workstation_ = workstation;
- domain_ = domain;
- }
-
- @Override
- public Credentials getInstance() {
- return new NTCredentials(username_, password_, workstation_, domain_);
- }
-
- @Override
- public String toString() {
- return getInstance().toString();
- }
- }
-
- /**
- * Factory class interface
- */
- private interface CredentialsFactory {
- Credentials getInstance();
- }
-
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/DefaultCssErrorHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/DefaultCssErrorHandler.java
index ecc3bc8b02e..444a13efbb8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/DefaultCssErrorHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/DefaultCssErrorHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,9 @@ public class DefaultCssErrorHandler implements CSSErrorHandler, Serializable {
*/
@Override
public void error(final CSSParseException exception) {
- LOG.warn("CSS error: " + buildMessage(exception));
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("CSS error: " + buildMessage(exception));
+ }
}
/**
@@ -46,7 +48,9 @@ public void error(final CSSParseException exception) {
*/
@Override
public void fatalError(final CSSParseException exception) {
- LOG.warn("CSS fatal error: " + buildMessage(exception));
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("CSS fatal error: " + buildMessage(exception));
+ }
}
/**
@@ -54,7 +58,9 @@ public void fatalError(final CSSParseException exception) {
*/
@Override
public void warning(final CSSParseException exception) {
- LOG.warn("CSS warning: " + buildMessage(exception));
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("CSS warning: " + buildMessage(exception));
+ }
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/DefaultPageCreator.java b/src/main/java/com/gargoylesoftware/htmlunit/DefaultPageCreator.java
index 9568ba8e03b..dfbb73aaf4c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/DefaultPageCreator.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/DefaultPageCreator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,9 +23,12 @@
import org.apache.commons.lang3.StringUtils;
import com.gargoylesoftware.htmlunit.html.DomElement;
-import com.gargoylesoftware.htmlunit.html.HTMLParser;
+import com.gargoylesoftware.htmlunit.html.Html;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.XHtmlPage;
+import com.gargoylesoftware.htmlunit.html.parser.HTMLParser;
+import com.gargoylesoftware.htmlunit.html.parser.neko.HtmlUnitNekoHtmlParser;
+import com.gargoylesoftware.htmlunit.util.MimeType;
import com.gargoylesoftware.htmlunit.xml.XmlPage;
/**
@@ -79,6 +82,8 @@ public class DefaultPageCreator implements PageCreator, Serializable {
private static final byte[] markerUTF16BE_ = {(byte) 0xfe, (byte) 0xff};
private static final byte[] markerUTF16LE_ = {(byte) 0xff, (byte) 0xfe};
+ private static final HTMLParser htmlParser_ = new HtmlUnitNekoHtmlParser();
+
/**
* The different supported page types.
*/
@@ -106,16 +111,16 @@ public static PageType determinePageType(final String contentType) {
}
switch (contentType) {
- case "text/html":
+ case MimeType.TEXT_HTML:
case "image/svg+xml":
return PageType.HTML;
case "text/javascript":
case "application/x-javascript":
- case "application/javascript":
+ case MimeType.APPLICATION_JAVASCRIPT:
return PageType.JAVASCRIPT;
- case "text/xml":
+ case MimeType.TEXT_XML:
case "application/xml":
case "text/vnd.wap.wml":
return PageType.XML;
@@ -163,7 +168,7 @@ public Page createPage(final WebResponse webResponse, final WebWindow webWindow)
case XML:
final SgmlPage sgmlPage = createXmlPage(webResponse, webWindow);
final DomElement doc = sgmlPage.getDocumentElement();
- if (doc != null && HTMLParser.XHTML_NAMESPACE.equals(doc.getNamespaceURI())) {
+ if (doc != null && Html.XHTML_NAMESPACE.equals(doc.getNamespaceURI())) {
return createXHtmlPage(webResponse, webWindow);
}
return sgmlPage;
@@ -195,25 +200,33 @@ private String determineContentType(final WebResponse webResponse)
try (InputStream contentAsStream = webResponse.getContentAsStream()) {
final byte[] bytes = read(contentAsStream, 500);
if (bytes.length == 0) {
- return "text/plain";
+ return MimeType.TEXT_PLAIN;
}
final String asAsciiString = new String(bytes, "ASCII").toUpperCase(Locale.ROOT);
if (asAsciiString.contains("")) {
- return "application/javascript";
+ return MimeType.APPLICATION_JAVASCRIPT;
}
else if (isBinary(bytes)) {
- return "application/octet-stream";
+ return MimeType.APPLICATION_OCTET_STREAM;
}
}
- return "text/plain";
+ return MimeType.TEXT_PLAIN;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public HTMLParser getHtmlParser() {
+ return htmlParser_;
}
/**
@@ -264,7 +277,7 @@ private static byte[] read(final InputStream stream, final int maxNb) throws IOE
* @throws IOException if the page could not be created
*/
protected HtmlPage createHtmlPage(final WebResponse webResponse, final WebWindow webWindow) throws IOException {
- return HTMLParser.parseHtml(webResponse, webWindow);
+ return htmlParser_.parseHtml(webResponse, webWindow);
}
/**
@@ -276,7 +289,7 @@ protected HtmlPage createHtmlPage(final WebResponse webResponse, final WebWindow
* @throws IOException if the page could not be created
*/
protected XHtmlPage createXHtmlPage(final WebResponse webResponse, final WebWindow webWindow) throws IOException {
- return HTMLParser.parseXHtml(webResponse, webWindow);
+ return htmlParser_.parseXHtml(webResponse, webWindow);
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/DialogWindow.java b/src/main/java/com/gargoylesoftware/htmlunit/DialogWindow.java
index c7b7c9a3300..ecf1d56f95f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/DialogWindow.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/DialogWindow.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/DownloadedContent.java b/src/main/java/com/gargoylesoftware/htmlunit/DownloadedContent.java
index 7b73c467ada..b8d6b42b3cf 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/DownloadedContent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/DownloadedContent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,10 @@
import java.io.ByteArrayInputStream;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
+import java.nio.file.Files;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
@@ -86,8 +85,8 @@ class OnFile implements DownloadedContent {
}
@Override
- public InputStream getInputStream() throws FileNotFoundException {
- return new FileInputStream(file_);
+ public InputStream getInputStream() throws IOException {
+ return Files.newInputStream(file_.toPath());
}
@Override
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/ElementNotFoundException.java b/src/main/java/com/gargoylesoftware/htmlunit/ElementNotFoundException.java
index 10decfe40fe..564c580e35e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/ElementNotFoundException.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/ElementNotFoundException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/FailingHttpStatusCodeException.java b/src/main/java/com/gargoylesoftware/htmlunit/FailingHttpStatusCodeException.java
index e6dada07614..60513d9b9b3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/FailingHttpStatusCodeException.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/FailingHttpStatusCodeException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/FormEncodingType.java b/src/main/java/com/gargoylesoftware/htmlunit/FormEncodingType.java
index 9825e2e4021..2020e235180 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/FormEncodingType.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/FormEncodingType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/History.java b/src/main/java/com/gargoylesoftware/htmlunit/History.java
index e66f77df625..13f3799cad6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/History.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/History.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,24 @@
*/
public class History implements Serializable {
+ /** The window to which this navigation history belongs. */
+ private final WebWindow window_;
+
+ /**
+ * Whether or not to ignore calls to {@link #addPage(Page)}; this is a bit hackish (we should probably be using
+ * explicit boolean parameters in the various methods that load new pages), but it does the job for now -- without
+ * any new API cruft.
+ */
+ private transient ThreadLocal ignoreNewPages_;
+
+ /**
+ * The {@link History.HistoryEntry}s in this navigation history.
+ */
+ private final List entries_ = new ArrayList<>();
+
+ /** The current index within the list of pages which make up this navigation history. */
+ private int index_ = -1;
+
/**
* The single entry in the history.
*/
@@ -107,24 +125,6 @@ private void setState(final Object state) {
}
}
- /** The window to which this navigation history belongs. */
- private final WebWindow window_;
-
- /**
- * Whether or not to ignore calls to {@link #addPage(Page)}; this is a bit hackish (we should probably be using
- * explicit boolean parameters in the various methods that load new pages), but it does the job for now -- without
- * any new API cruft.
- */
- private transient ThreadLocal ignoreNewPages_;
-
- /**
- * The {@link History.HistoryEntry}s in this navigation history.
- */
- private final List entries_ = new ArrayList<>();
-
- /** The current index within the list of pages which make up this navigation history. */
- private int index_ = -1;
-
/**
* Creates a new navigation history for the specified window.
* @param window the window which owns the new navigation history
@@ -289,8 +289,8 @@ private void goToUrlAtCurrentIndex() throws IOException {
page.getWebResponse().getWebRequest().setUrl(entry.getUrl());
}
- final Window jsWindow = (Window) window_.getScriptableObject();
- if (jsWindow.hasEventHandlers("onpopstate")) {
+ final Window jsWindow = window_.getScriptableObject();
+ if (jsWindow != null && jsWindow.hasEventHandlers("onpopstate")) {
final Event event = new PopStateEvent(jsWindow, Event.TYPE_POPSTATE, entry.getState());
jsWindow.executeEventLocally(event);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/HttpHeader.java b/src/main/java/com/gargoylesoftware/htmlunit/HttpHeader.java
index c2fb88c293b..e3a884d8da6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/HttpHeader.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/HttpHeader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@ public final class HttpHeader {
/** Accept. */
public static final String ACCEPT = "Accept";
- /** accept. */
+ /** Accept-LC. */
public static final String ACCEPT_LC = "accept";
/** Accept-Language. */
@@ -89,12 +89,24 @@ public final class HttpHeader {
/** connection. */
public static final String CONNECTION_LC = "connection";
+ /** Connection. */
+ public static final String CONTENT_DISPOSITION = "Content-Disposition";
+
/** DNT. */
public static final String DNT = "DNT";
/** Upgrade-Insecure-Requests. */
public static final String UPGRADE_INSECURE_REQUESTS = "Upgrade-Insecure-Requests";
+ /** Sec-Fetch-Mode. */
+ public static final String SEC_FETCH_MODE = "Sec-Fetch-Mode";
+
+ /** Sec-Fetch-Site. */
+ public static final String SEC_FETCH_SITE = "Sec-Fetch-Site";
+
+ /** Sec-Fetch-User. */
+ public static final String SEC_FETCH_USER = "Sec-Fetch-User";
+
/** Access-Control-Request-Method. */
public static final String ACCESS_CONTROL_REQUEST_METHOD = "Access-Control-Request-Method";
/** Access-Control-Request-Headers. */
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/HttpMethod.java b/src/main/java/com/gargoylesoftware/htmlunit/HttpMethod.java
index 689581d3e5e..7d5aec83ac5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/HttpMethod.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/HttpMethod.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/HttpWebConnection.java b/src/main/java/com/gargoylesoftware/htmlunit/HttpWebConnection.java
index 18c682f81c3..6b6e865367a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/HttpWebConnection.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/HttpWebConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,14 +20,15 @@
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
+import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -96,6 +97,7 @@
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
@@ -111,6 +113,7 @@
import com.gargoylesoftware.htmlunit.httpclient.HtmlUnitSSLConnectionSocketFactory;
import com.gargoylesoftware.htmlunit.httpclient.SocksConnectionSocketFactory;
import com.gargoylesoftware.htmlunit.util.KeyDataPair;
+import com.gargoylesoftware.htmlunit.util.MimeType;
import com.gargoylesoftware.htmlunit.util.NameValuePair;
import com.gargoylesoftware.htmlunit.util.UrlUtils;
@@ -166,14 +169,7 @@ public HttpWebConnection(final WebClient webClient) {
*/
@Override
public WebResponse getResponse(final WebRequest request) throws IOException {
- final URL url = request.getUrl();
final HttpClientBuilder builder = reconfigureHttpClientIfNeeded(getHttpClientBuilder());
- final HttpContext httpContext = getHttpContext();
-
- if (connectionManager_ == null) {
- connectionManager_ = createConnectionManager(builder);
- }
- builder.setConnectionManager(connectionManager_);
HttpUriRequest httpMethod = null;
try {
@@ -181,21 +177,26 @@ public WebResponse getResponse(final WebRequest request) throws IOException {
httpMethod = makeHttpMethod(request, builder);
}
catch (final URISyntaxException e) {
- throw new IOException("Unable to create URI from URL: " + url.toExternalForm()
+ throw new IOException("Unable to create URI from URL: " + request.getUrl().toExternalForm()
+ " (reason: " + e.getMessage() + ")", e);
}
final HttpHost hostConfiguration = getHostConfiguration(request);
final long startTime = System.currentTimeMillis();
+ final HttpContext httpContext = getHttpContext();
HttpResponse httpResponse = null;
try {
- httpResponse = builder.build().execute(hostConfiguration, httpMethod, httpContext);
+ try (CloseableHttpClient closeableHttpClient = builder.build()) {
+ httpResponse = closeableHttpClient.execute(hostConfiguration, httpMethod, httpContext);
+ }
}
catch (final SSLPeerUnverifiedException s) {
// Try to use only SSLv3 instead
if (webClient_.getOptions().isUseInsecureSSL()) {
HtmlUnitSSLConnectionSocketFactory.setUseSSL3Only(httpContext, true);
- httpResponse = builder.build().execute(hostConfiguration, httpMethod, httpContext);
+ try (CloseableHttpClient closeableHttpClient = builder.build()) {
+ httpResponse = closeableHttpClient.execute(hostConfiguration, httpMethod, httpContext);
+ }
}
else {
throw s;
@@ -286,8 +287,8 @@ private void setProxy(final HttpRequestBase httpRequest, final WebRequest webReq
private HttpUriRequest makeHttpMethod(final WebRequest webRequest, final HttpClientBuilder httpClientBuilder)
throws URISyntaxException {
- final Charset charset = webRequest.getCharset();
final HttpContext httpContext = getHttpContext();
+ final Charset charset = webRequest.getCharset();
// Make sure that the URL is fully encoded. IE actually sends some Unicode chars in request
// URLs; because of this we allow some Unicode chars in URLs. However, at this point we're
// handing things over the HttpClient, and HttpClient will blow up if we leave these Unicode
@@ -300,6 +301,7 @@ private HttpUriRequest makeHttpMethod(final WebRequest webRequest, final HttpCli
}
final HttpRequestBase httpMethod = buildHttpMethod(webRequest.getHttpMethod(), uri);
setProxy(httpMethod, webRequest);
+
if (!(httpMethod instanceof HttpEntityEnclosingRequest)) {
// this is the case for GET as well as TRACE, DELETE, OPTIONS and HEAD
if (!webRequest.getRequestParameters().isEmpty()) {
@@ -341,7 +343,7 @@ else if (FormEncodingType.MULTIPART == webRequest.getEncodingType()) {
}
else {
builder.addTextBody(pair.getName(), pair.getValue(),
- ContentType.create("text/plain", charset));
+ ContentType.create(MimeType.TEXT_PLAIN, charset));
}
}
method.setEntity(builder.build());
@@ -381,7 +383,6 @@ else if (FormEncodingType.MULTIPART == webRequest.getEncodingType()) {
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
httpContext.removeAttribute(HttpClientContext.CREDS_PROVIDER);
httpContext.removeAttribute(HttpClientContext.TARGET_AUTH_STATE);
-
return httpMethod;
}
@@ -412,7 +413,7 @@ private static Charset getCharset(final Charset charset, final ListHttpClientBuilder that will be used by this WebConnection
*/
- protected HttpClientBuilder createHttpClient() {
+ protected HttpClientBuilder createHttpClientBuilder() {
final HttpClientBuilder builder = HttpClientBuilder.create();
builder.setRedirectStrategy(new HtmlUnitRedirectStrategie());
configureTimeout(builder, getTimeout());
configureHttpsScheme(builder);
builder.setMaxConnPerRoute(6);
+
+ builder.setConnectionManagerShared(true);
return builder;
}
@@ -605,6 +609,7 @@ private HttpClientBuilder reconfigureHttpClientIfNeeded(final HttpClientBuilder
|| options.getSSLClientProtocols() != usedOptions_.getSSLClientProtocols()
|| options.getProxyConfig() != usedOptions_.getProxyConfig()) {
configureHttpsScheme(httpClientBuilder);
+
if (connectionManager_ != null) {
connectionManager_.shutdown();
connectionManager_ = null;
@@ -615,6 +620,12 @@ private HttpClientBuilder reconfigureHttpClientIfNeeded(final HttpClientBuilder
if (timeout != usedOptions_.getTimeout()) {
configureTimeout(httpClientBuilder, timeout);
}
+
+ if (connectionManager_ == null) {
+ connectionManager_ = createConnectionManager(httpClientBuilder);
+ }
+ httpClientBuilder.setConnectionManager(connectionManager_);
+
return httpClientBuilder;
}
@@ -726,7 +737,7 @@ public static DownloadedContent downloadContent(final InputStream is, final int
// we have exceeded the max for memory, let's write everything to a temporary file
final File file = File.createTempFile("htmlunit", ".tmp");
file.deleteOnExit();
- try (FileOutputStream fos = new FileOutputStream(file)) {
+ try (OutputStream fos = Files.newOutputStream(file.toPath())) {
bos.writeTo(fos); // what we have already read
IOUtils.copyLarge(is, fos); // what remains from the server response
}
@@ -775,6 +786,7 @@ private List getHttpRequestInterceptors(final WebRequest
host.append(Integer.toString(port));
}
+ // make sure the headers are added in the right order
final String userAgent = webClient_.getBrowserVersion().getUserAgent();
final String[] headerNames = webClient_.getBrowserVersion().getHeaderNamesOrdered();
if (headerNames != null) {
@@ -785,20 +797,53 @@ private List getHttpRequestInterceptors(final WebRequest
else if (HttpHeader.USER_AGENT.equals(header)) {
list.add(new UserAgentHeaderHttpRequestInterceptor(userAgent));
}
- else if (HttpHeader.ACCEPT.equals(header) && requestHeaders.get(header) != null) {
- list.add(new AcceptHeaderHttpRequestInterceptor(requestHeaders.get(header)));
+ else if (HttpHeader.ACCEPT.equals(header)) {
+ final String headerValue = webRequest.getAdditionalHeader(header);
+ if (headerValue != null) {
+ list.add(new AcceptHeaderHttpRequestInterceptor(headerValue));
+ }
+ }
+ else if (HttpHeader.ACCEPT_LANGUAGE.equals(header)) {
+ final String headerValue = webRequest.getAdditionalHeader(header);
+ if (headerValue != null) {
+ list.add(new AcceptLanguageHeaderHttpRequestInterceptor(headerValue));
+ }
}
- else if (HttpHeader.ACCEPT_LANGUAGE.equals(header) && requestHeaders.get(header) != null) {
- list.add(new AcceptLanguageHeaderHttpRequestInterceptor(requestHeaders.get(header)));
+ else if (HttpHeader.ACCEPT_ENCODING.equals(header)) {
+ final String headerValue = webRequest.getAdditionalHeader(header);
+ if (headerValue != null) {
+ list.add(new AcceptEncodingHeaderHttpRequestInterceptor(headerValue));
+ }
}
- else if (HttpHeader.ACCEPT_ENCODING.equals(header) && requestHeaders.get(header) != null) {
- list.add(new AcceptEncodingHeaderHttpRequestInterceptor(requestHeaders.get(header)));
+ else if (HttpHeader.SEC_FETCH_MODE.equals(header)) {
+ final String headerValue = webRequest.getAdditionalHeader(header);
+ if (headerValue != null) {
+ list.add(new SecFetchModeHeaderHttpRequestInterceptor(headerValue));
+ }
}
- else if (HttpHeader.UPGRADE_INSECURE_REQUESTS.equals(header) && requestHeaders.get(header) != null) {
- list.add(new UpgradeInsecureRequestHeaderHttpRequestInterceptor(requestHeaders.get(header)));
+ else if (HttpHeader.SEC_FETCH_SITE.equals(header)) {
+ final String headerValue = webRequest.getAdditionalHeader(header);
+ if (headerValue != null) {
+ list.add(new SecFetchSiteHeaderHttpRequestInterceptor(headerValue));
+ }
}
- else if (HttpHeader.REFERER.equals(header) && requestHeaders.get(header) != null) {
- list.add(new RefererHeaderHttpRequestInterceptor(requestHeaders.get(header)));
+ else if (HttpHeader.SEC_FETCH_USER.equals(header)) {
+ final String headerValue = webRequest.getAdditionalHeader(header);
+ if (headerValue != null) {
+ list.add(new SecFetchUserHeaderHttpRequestInterceptor(headerValue));
+ }
+ }
+ else if (HttpHeader.UPGRADE_INSECURE_REQUESTS.equals(header)) {
+ final String headerValue = webRequest.getAdditionalHeader(header);
+ if (headerValue != null) {
+ list.add(new UpgradeInsecureRequestHeaderHttpRequestInterceptor(headerValue));
+ }
+ }
+ else if (HttpHeader.REFERER.equals(header)) {
+ final String headerValue = webRequest.getAdditionalHeader(header);
+ if (headerValue != null) {
+ list.add(new RefererHeaderHttpRequestInterceptor(headerValue));
+ }
}
else if (HttpHeader.CONNECTION.equals(header)) {
list.add(new RequestClientConnControl());
@@ -934,6 +979,45 @@ public void process(final HttpRequest request, final HttpContext context) throws
}
}
+ private static final class SecFetchModeHeaderHttpRequestInterceptor implements HttpRequestInterceptor {
+ private String value_;
+
+ SecFetchModeHeaderHttpRequestInterceptor(final String value) {
+ value_ = value;
+ }
+
+ @Override
+ public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
+ request.setHeader(HttpHeader.SEC_FETCH_MODE, value_);
+ }
+ }
+
+ private static final class SecFetchSiteHeaderHttpRequestInterceptor implements HttpRequestInterceptor {
+ private String value_;
+
+ SecFetchSiteHeaderHttpRequestInterceptor(final String value) {
+ value_ = value;
+ }
+
+ @Override
+ public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
+ request.setHeader(HttpHeader.SEC_FETCH_SITE, value_);
+ }
+ }
+
+ private static final class SecFetchUserHeaderHttpRequestInterceptor implements HttpRequestInterceptor {
+ private String value_;
+
+ SecFetchUserHeaderHttpRequestInterceptor(final String value) {
+ value_ = value;
+ }
+
+ @Override
+ public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
+ request.setHeader(HttpHeader.SEC_FETCH_USER, value_);
+ }
+ }
+
private static class MultiHttpRequestInterceptor implements HttpRequestInterceptor {
private final Map map_;
@@ -986,10 +1070,8 @@ public synchronized String toString() {
*/
@Override
public void close() {
- final Thread current = Thread.currentThread();
- if (httpClientBuilder_.get(current) != null) {
- httpClientBuilder_.remove(current);
- }
+ httpClientBuilder_.clear();
+
if (connectionManager_ != null) {
connectionManager_.shutdown();
connectionManager_ = null;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/ImmediateRefreshHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/ImmediateRefreshHandler.java
index 8a4085c7dbe..54e72e1837e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/ImmediateRefreshHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/ImmediateRefreshHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/IncorrectnessListener.java b/src/main/java/com/gargoylesoftware/htmlunit/IncorrectnessListener.java
index cb56db914a9..06639f0a2d4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/IncorrectnessListener.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/IncorrectnessListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/IncorrectnessListenerImpl.java b/src/main/java/com/gargoylesoftware/htmlunit/IncorrectnessListenerImpl.java
index 06c45fa2c05..ec1742c8559 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/IncorrectnessListenerImpl.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/IncorrectnessListenerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/MockWebConnection.java b/src/main/java/com/gargoylesoftware/htmlunit/MockWebConnection.java
index ff1754ef976..64db6e22700 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/MockWebConnection.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/MockWebConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,9 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import com.gargoylesoftware.htmlunit.util.MimeType;
import com.gargoylesoftware.htmlunit.util.NameValuePair;
+import com.gargoylesoftware.htmlunit.util.TextUtils;
/**
* A fake {@link WebConnection} designed to mock out the actual HTTP connections.
@@ -44,6 +46,13 @@ public class MockWebConnection implements WebConnection {
private static final Log LOG = LogFactory.getLog(MockWebConnection.class);
+ private final Map throwableMap_ = new HashMap<>();
+ private final Map responseMap_ = new HashMap<>();
+ private RawResponseData defaultResponse_;
+ private WebRequest lastRequest_;
+ private int requestCount_;
+ private final List requestedUrls_ = Collections.synchronizedList(new ArrayList());
+
/**
* Contains the raw data configured for a response.
*/
@@ -94,7 +103,7 @@ else if (stringContent_ == null) {
content = new byte[] {};
}
else {
- content = TextUtil.stringToByteArray(stringContent_, charset_);
+ content = TextUtils.stringToByteArray(stringContent_, charset_);
}
return new WebResponseData(content, statusCode_, statusMessage_, headers_);
}
@@ -148,12 +157,6 @@ public Charset getCharset() {
}
}
- private final Map responseMap_ = new HashMap<>(10);
- private RawResponseData defaultResponse_;
- private WebRequest lastRequest_;
- private int requestCount_ = 0;
- private final List requestedUrls_ = Collections.synchronizedList(new ArrayList());
-
/**
* {@inheritDoc}
*/
@@ -167,8 +170,9 @@ public WebResponse getResponse(final WebRequest request) throws IOException {
* Gets the raw response configured for the request.
* @param request the request
* @return the raw response
+ * @throws IOException if defined
*/
- public RawResponseData getRawResponse(final WebRequest request) {
+ public RawResponseData getRawResponse(final WebRequest request) throws IOException {
final URL url = request.getUrl();
if (LOG.isDebugEnabled()) {
@@ -180,6 +184,11 @@ public RawResponseData getRawResponse(final WebRequest request) {
requestedUrls_.add(url);
String urlString = url.toExternalForm();
+ final IOException throwable = throwableMap_.get(urlString);
+ if (throwable != null) {
+ throw throwable;
+ }
+
RawResponseData rawResponse = responseMap_.get(urlString);
if (rawResponse == null) {
// try to find without query params
@@ -203,6 +212,14 @@ public RawResponseData getRawResponse(final WebRequest request) {
return rawResponse;
}
+ /**
+ * Gets the list of requested URLs.
+ * @return the list of relative URLs
+ */
+ public List getRequestedUrls() {
+ return Collections.unmodifiableList(requestedUrls_);
+ }
+
/**
* Gets the list of requested URLs relative to the provided URL.
* @param relativeTo what should be removed from the requested URLs.
@@ -219,7 +236,7 @@ public List getRequestedUrls(final URL relativeTo) {
response.add(s);
}
- return response;
+ return Collections.unmodifiableList(response);
}
/**
@@ -282,6 +299,15 @@ public void setResponse(final URL url, final String content, final int statusCod
responseMap_.put(url.toExternalForm(), responseEntry);
}
+ /**
+ * Sets the exception that will be thrown when the specified URL is requested.
+ * @param url the URL that will force the exception
+ * @param throwable the Throwable
+ */
+ public void setThrowable(final URL url, final IOException throwable) {
+ throwableMap_.put(url.toExternalForm(), throwable);
+ }
+
/**
* Sets the response that will be returned when the specified URL is requested.
* @param url the URL that will return the given response
@@ -323,7 +349,7 @@ private static RawResponseData buildRawResponseData(final String content, Charse
* @param content the content to return
*/
public void setResponse(final URL url, final String content) {
- setResponse(url, content, 200, "OK", "text/html", null);
+ setResponse(url, content, 200, "OK", MimeType.TEXT_HTML, null);
}
/**
@@ -403,7 +429,7 @@ public void setDefaultResponse(final byte[] content, final int statusCode,
* @param content the content to return
*/
public void setDefaultResponse(final String content) {
- setDefaultResponse(content, 200, "OK", "text/html");
+ setDefaultResponse(content, 200, "OK", MimeType.TEXT_HTML);
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/NiceRefreshHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/NiceRefreshHandler.java
index 2aa1ef377cc..d167a3df928 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/NiceRefreshHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/NiceRefreshHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/NicelyResynchronizingAjaxController.java b/src/main/java/com/gargoylesoftware/htmlunit/NicelyResynchronizingAjaxController.java
index 5c3dc068d26..34ffcfee814 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/NicelyResynchronizingAjaxController.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/NicelyResynchronizingAjaxController.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/test/java/com/gargoylesoftware/htmlunit/annotations/BuildServerDiscrepancy.java b/src/main/java/com/gargoylesoftware/htmlunit/NotYetImplementedException.java
similarity index 53%
rename from src/test/java/com/gargoylesoftware/htmlunit/annotations/BuildServerDiscrepancy.java
rename to src/main/java/com/gargoylesoftware/htmlunit/NotYetImplementedException.java
index 18734bda4a3..90436117b1f 100644
--- a/src/test/java/com/gargoylesoftware/htmlunit/annotations/BuildServerDiscrepancy.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/NotYetImplementedException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -12,20 +12,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.gargoylesoftware.htmlunit.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
+package com.gargoylesoftware.htmlunit;
/**
- * An annotation to denote a test which behaves on the build server different than locally.
+ * Thrown if a method is not yet implemented for some reason
+ * but at least available from js.
*
- * @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@Retention(RetentionPolicy.SOURCE)
-@Target(ElementType.METHOD)
-public @interface BuildServerDiscrepancy {
+public class NotYetImplementedException extends RuntimeException {
+ /**
+ * Creates a new instance.
+ * @param method the not yet implemented method
+ */
+ public NotYetImplementedException(final String method) {
+ super("Method '" + method + "' is not yet implemented.");
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/ObjectInstantiationException.java b/src/main/java/com/gargoylesoftware/htmlunit/ObjectInstantiationException.java
index a2e0da5e52b..58ea1c56560 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/ObjectInstantiationException.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/ObjectInstantiationException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/OnbeforeunloadHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/OnbeforeunloadHandler.java
index db1b25bd5d2..a843772c39f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/OnbeforeunloadHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/OnbeforeunloadHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,12 +14,15 @@
*/
package com.gargoylesoftware.htmlunit;
+import java.io.Serializable;
+
/**
* A handler for onbeforeunload events.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-public interface OnbeforeunloadHandler {
+public interface OnbeforeunloadHandler extends Serializable {
/**
* Handles an onbeforeunload event for the specified page.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/Page.java b/src/main/java/com/gargoylesoftware/htmlunit/Page.java
index 03ffd01962e..af6ae51eb00 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/Page.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/Page.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/PageCreator.java b/src/main/java/com/gargoylesoftware/htmlunit/PageCreator.java
index 9900f77ab19..a9d40001d47 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/PageCreator.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/PageCreator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
import java.io.IOException;
+import com.gargoylesoftware.htmlunit.html.parser.HTMLParser;
+
/**
* Something that knows how to create a page object. It is also the responsibility
* of the page creator to establish the relationship between the webWindow
@@ -35,7 +37,13 @@ public interface PageCreator {
* @exception IOException If an io problem occurs
* @return the new page
*/
- Page createPage(WebResponse webResponse, WebWindow webWindow)
- throws IOException;
+ Page createPage(WebResponse webResponse, WebWindow webWindow) throws IOException;
+
+ /**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
+ * @return the HTMLParser in use
+ */
+ HTMLParser getHtmlParser();
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/PluginConfiguration.java b/src/main/java/com/gargoylesoftware/htmlunit/PluginConfiguration.java
index 818157709a9..08e0d5a258c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/PluginConfiguration.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/PluginConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/PromptHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/PromptHandler.java
index d69f43a16bf..28879de3710 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/PromptHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/PromptHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,14 +14,17 @@
*/
package com.gargoylesoftware.htmlunit;
+import java.io.Serializable;
+
/**
* A handler for JavaScript window.prompt(). Prompts are triggered when the JavaScript
* method Window.prompt() is called.
*
* @author Mike Bowler
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-public interface PromptHandler {
+public interface PromptHandler extends Serializable {
/**
* Handle a call to Window.prompt() for the given page.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/ProxyAutoConfig.java b/src/main/java/com/gargoylesoftware/htmlunit/ProxyAutoConfig.java
index 2c7e06341b9..28a8c02494f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/ProxyAutoConfig.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/ProxyAutoConfig.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,8 +37,10 @@
* @see PAC file format
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
public final class ProxyAutoConfig {
+ private static final String TIMEZONE_GMT = "GMT";
private ProxyAutoConfig() {
}
@@ -53,7 +55,7 @@ public static String evaluate(final String content, final URL url) {
final Context cx = Context.enter();
try {
final ProxyAutoConfig config = new ProxyAutoConfig();
- final Scriptable scope = cx.initStandardObjects();
+ final Scriptable scope = cx.initSafeStandardObjects();
config.defineMethod("isPlainHostName", scope);
config.defineMethod("dnsDomainIs", scope);
@@ -212,10 +214,11 @@ public static boolean shExpMatch(final String str, final String shexp) {
*/
public static boolean weekdayRange(final String wd1, Object wd2, final Object gmt) {
TimeZone timezone = TimeZone.getDefault();
- if ("GMT".equals(Context.toString(gmt)) || "GMT".equals(Context.toString(wd2))) {
- timezone = TimeZone.getTimeZone("GMT");
+ if (TIMEZONE_GMT.equals(Context.toString(gmt))
+ || TIMEZONE_GMT.equals(Context.toString(wd2))) {
+ timezone = TimeZone.getTimeZone(TIMEZONE_GMT);
}
- if (wd2 == Undefined.instance || "GMT".equals(Context.toString(wd2))) {
+ if (Undefined.isUndefined(wd2) || TIMEZONE_GMT.equals(Context.toString(wd2))) {
wd2 = wd1;
}
final Calendar calendar = Calendar.getInstance(timezone);
@@ -252,17 +255,22 @@ public static boolean dateRange(final String value1, final Object value2, final
//actual values length
int length;
for (length = values.length - 1; length >= 0; length--) {
- if ("GMT".equals(Context.toString(values[length]))) {
- timezone = TimeZone.getTimeZone("GMT");
+ if (TIMEZONE_GMT.equals(Context.toString(values[length]))) {
+ timezone = TimeZone.getTimeZone(TIMEZONE_GMT);
break;
}
- else if (values[length] != Undefined.instance) {
+ else if (!Undefined.isUndefined(values[length])) {
length++;
break;
}
}
- final int day1, day2, month1, month2, year1, year2;
+ final int day1;
+ final int day2;
+ final int month1;
+ final int month2;
+ final int year1;
+ final int year2;
final Calendar cal1;
final Calendar cal2;
switch (length) {
@@ -397,17 +405,22 @@ public static boolean timeRange(final String value1, final Object value2, final
//actual values length
int length;
for (length = values.length - 1; length >= 0; length--) {
- if ("GMT".equals(Context.toString(values[length]))) {
- timezone = TimeZone.getTimeZone("GMT");
+ if (TIMEZONE_GMT.equals(Context.toString(values[length]))) {
+ timezone = TimeZone.getTimeZone(TIMEZONE_GMT);
break;
}
- else if (values[length] != Undefined.instance) {
+ else if (!Undefined.isUndefined(values[length])) {
length++;
break;
}
}
- final int hour1, hour2, min1, min2, second1, second2;
+ final int hour1;
+ final int hour2;
+ final int min1;
+ final int min2;
+ final int second1;
+ final int second2;
final Calendar cal1;
final Calendar cal2;
switch (length) {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/ProxyConfig.java b/src/main/java/com/gargoylesoftware/htmlunit/ProxyConfig.java
index 779c871fa40..a53ecf38d64 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/ProxyConfig.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/ProxyConfig.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/RefreshHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/RefreshHandler.java
index ab173824d7d..90dc3867003 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/RefreshHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/RefreshHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/ScriptException.java b/src/main/java/com/gargoylesoftware/htmlunit/ScriptException.java
index 0b5a9f328ed..662a74e2f5c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/ScriptException.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/ScriptException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/ScriptPreProcessor.java b/src/main/java/com/gargoylesoftware/htmlunit/ScriptPreProcessor.java
index bb91a1018df..af04cf1c72f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/ScriptPreProcessor.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/ScriptPreProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/ScriptResult.java b/src/main/java/com/gargoylesoftware/htmlunit/ScriptResult.java
index ada80d54073..1a1f8d3c4e0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/ScriptResult.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/ScriptResult.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,18 +27,13 @@ public final class ScriptResult {
/** The object that was returned from the script engine. */
private final Object javaScriptResult_;
- /** The page that is currently loaded at the end of the script execution. */
- private final Page newPage_;
-
/**
* Creates a new instance.
*
* @param javaScriptResult the object that was returned from the script engine
- * @param newPage the page that is currently loaded at the end of the script execution
*/
- public ScriptResult(final Object javaScriptResult, final Page newPage) {
+ public ScriptResult(final Object javaScriptResult) {
javaScriptResult_ = javaScriptResult;
- newPage_ = newPage;
}
/**
@@ -49,20 +44,12 @@ public Object getJavaScriptResult() {
return javaScriptResult_;
}
- /**
- * Returns the page that is loaded at the end of the script execution.
- * @return the new page
- */
- public Page getNewPage() {
- return newPage_;
- }
-
/**
* {@inheritDoc}
*/
@Override
public String toString() {
- return "ScriptResult[result=" + javaScriptResult_ + " page=" + newPage_ + "]";
+ return "ScriptResult[result=" + javaScriptResult_ + "]";
}
/**
@@ -80,73 +67,6 @@ public static boolean isFalse(final ScriptResult scriptResult) {
* @return {@code true} if scriptResult is undefined (there was no return value)
*/
public static boolean isUndefined(final ScriptResult scriptResult) {
- return scriptResult != null && scriptResult.getJavaScriptResult() instanceof Undefined;
+ return scriptResult != null && Undefined.isUndefined(scriptResult.getJavaScriptResult());
}
-
- /**
- * Creates and returns a composite {@link ScriptResult} based on the two input {@link ScriptResult}s. This
- * method defines how the return values for multiple event handlers are combined during event capturing and
- * bubbling. The behavior of this method varies based on whether or not we are emulating IE.
- *
- * @param newResult the new {@link ScriptResult} (may be {@code null})
- * @param originalResult the original {@link ScriptResult} (may be {@code null})
- * @param ie whether or not we are emulating IE
- * @return a composite {@link ScriptResult}, based on the two input {@link ScriptResult}s
- */
- public static ScriptResult combine(final ScriptResult newResult, final ScriptResult originalResult,
- final boolean ie) {
-
- final Object jsResult;
- final Page page;
-
- // If we're emulating IE, the overall JavaScript return value is the last return value.
- // If we're emulating FF, the overall JavaScript return value is false if the return value
- // was false at any level.
- if (ie) {
- if (newResult != null && !ScriptResult.isUndefined(newResult)) {
- jsResult = newResult.getJavaScriptResult();
- }
- else if (originalResult != null) {
- jsResult = originalResult.getJavaScriptResult();
- }
- else if (newResult != null) {
- jsResult = newResult.getJavaScriptResult();
- }
- else {
- jsResult = null;
- }
- }
- else {
- if (ScriptResult.isFalse(newResult)) {
- jsResult = newResult.getJavaScriptResult();
- }
- else if (originalResult != null) {
- jsResult = originalResult.getJavaScriptResult();
- }
- else if (newResult != null) {
- jsResult = newResult.getJavaScriptResult();
- }
- else {
- jsResult = null;
- }
- }
-
- // The new page is always the newest page.
- if (newResult != null) {
- page = newResult.getNewPage();
- }
- else if (originalResult != null) {
- page = originalResult.getNewPage();
- }
- else {
- page = null;
- }
-
- // Build and return the composite script result.
- if (jsResult == null && page == null) {
- return null;
- }
- return new ScriptResult(jsResult, page);
- }
-
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/SgmlPage.java b/src/main/java/com/gargoylesoftware/htmlunit/SgmlPage.java
index 190f566f94c..0e3aa04a934 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/SgmlPage.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/SgmlPage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
*/
package com.gargoylesoftware.htmlunit;
-import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Comparator;
@@ -88,14 +87,6 @@ public WebResponse getWebResponse() {
return webResponse_;
}
- /**
- * {@inheritDoc}
- */
- @Override
- public void initialize() throws IOException {
- // nothing to do here
- }
-
/**
* Gets the name for the current node.
* @return the node name
@@ -111,7 +102,7 @@ public String getNodeName() {
*/
@Override
public short getNodeType() {
- return org.w3c.dom.Node.DOCUMENT_NODE;
+ return DOCUMENT_NODE;
}
/**
@@ -277,6 +268,10 @@ public DomAttr createAttribute(final String name) {
*/
@Override
public URL getUrl() {
+ final WebResponse wr = getWebResponse();
+ if (null == wr) {
+ return WebClient.URL_ABOUT_BLANK;
+ }
return getWebResponse().getWebRequest().getUrl();
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/SilentCssErrorHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/SilentCssErrorHandler.java
index 4c6a8e6dc5e..e279d79e136 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/SilentCssErrorHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/SilentCssErrorHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/StatusHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/StatusHandler.java
index c52666ba59c..e24e6ee53da 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/StatusHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/StatusHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,12 +14,15 @@
*/
package com.gargoylesoftware.htmlunit;
+import java.io.Serializable;
+
/**
* A handler for changes to window.status .
*
* @author Mike Bowler
+ * @author Ronald Brill
*/
-public interface StatusHandler {
+public interface StatusHandler extends Serializable {
/**
* Handles a change to window.status .
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/StorageHolder.java b/src/main/java/com/gargoylesoftware/htmlunit/StorageHolder.java
index ee8385d17cf..e730f3a0ccd 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/StorageHolder.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/StorageHolder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/StringWebResponse.java b/src/main/java/com/gargoylesoftware/htmlunit/StringWebResponse.java
index 1892446c15e..79133cdf7fe 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/StringWebResponse.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/StringWebResponse.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
import org.apache.http.HttpStatus;
import com.gargoylesoftware.htmlunit.util.NameValuePair;
+import com.gargoylesoftware.htmlunit.util.TextUtils;
/**
* A simple WebResponse created from a string. Content is assumed to be of type text/html .
@@ -67,7 +68,7 @@ public StringWebResponse(final String content, final Charset charset, final URL
* @return a simple WebResponseData with defaults specified
*/
private static WebResponseData getWebResponseData(final String contentString, final Charset charset) {
- final byte[] content = TextUtil.stringToByteArray(contentString, charset);
+ final byte[] content = TextUtils.stringToByteArray(contentString, charset);
final List compiledHeaders = new ArrayList<>();
compiledHeaders.add(new NameValuePair(HttpHeader.CONTENT_TYPE, "text/html; charset=" + charset));
return new WebResponseData(content, HttpStatus.SC_OK, "OK", compiledHeaders);
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/TextPage.java b/src/main/java/com/gargoylesoftware/htmlunit/TextPage.java
index 19b44bf1932..57884c11049 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/TextPage.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/TextPage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,12 @@
*/
package com.gargoylesoftware.htmlunit;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
/**
* A generic page that will be returned for any text related content.
* Specifically any content types that start with {@code text/}
@@ -43,4 +49,17 @@ public TextPage(final WebResponse webResponse, final WebWindow enclosingWindow)
public String getContent() {
return getWebResponse().getContentAsString();
}
+
+ /**
+ * Saves the content of this page to a text file.
+ *
+ * @param file file to write this page into
+ * @throws IOException If an error occurs
+ */
+ public void save(final File file) throws IOException {
+ final Path savePath = file.toPath();
+ final String text = getContent();
+ final Charset charset = getWebResponse().getContentCharset();
+ Files.write(savePath, text.getBytes(charset));
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/ThreadedRefreshHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/ThreadedRefreshHandler.java
index 281a6a8c9f3..cc68fd169b6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/ThreadedRefreshHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/ThreadedRefreshHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/TopLevelWindow.java b/src/main/java/com/gargoylesoftware/htmlunit/TopLevelWindow.java
index 52c95f59d6b..3b3e1a1d94b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/TopLevelWindow.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/TopLevelWindow.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/UnexpectedPage.java b/src/main/java/com/gargoylesoftware/htmlunit/UnexpectedPage.java
index bad12e4bf43..8e4fcc41e4e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/UnexpectedPage.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/UnexpectedPage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/Version.java b/src/main/java/com/gargoylesoftware/htmlunit/Version.java
index 26eabcfc2e6..fc352c28c81 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/Version.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/Version.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -78,6 +78,6 @@ public static String getProductVersion() {
* @return the copyright notice
*/
public static String getCopyright() {
- return "Copyright (c) 2002-2018 Gargoyle Software Inc. All rights reserved.";
+ return "Copyright (c) 2002-2020 Gargoyle Software Inc. All rights reserved.";
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WaitingRefreshHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/WaitingRefreshHandler.java
index ec099b9e864..a672d3ac385 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WaitingRefreshHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WaitingRefreshHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebAssert.java b/src/main/java/com/gargoylesoftware/htmlunit/WebAssert.java
index ae3a2bc2fa4..a76e04c6592 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebAssert.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebAssert.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java b/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java
index 8d1e1c7f350..e390e66f1b2 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebClient.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.DIALOGWINDOW_REFERER;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTTP_HEADER_SEC_FETCH;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTTP_HEADER_UPGRADE_INSECURE_REQUEST;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTTP_REDIRECT_308;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_XML_SUPPORT_VIA_ACTIVEXOBJECT;
@@ -25,7 +26,6 @@
import java.io.BufferedInputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
@@ -36,12 +36,11 @@
import java.net.URLConnection;
import java.net.URLDecoder;
import java.nio.charset.Charset;
-import java.util.ArrayDeque;
+import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Date;
-import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -68,15 +67,14 @@
import com.gargoylesoftware.css.parser.CSSErrorHandler;
import com.gargoylesoftware.htmlunit.activex.javascript.msxml.MSXMLActiveXObjectFactory;
-import com.gargoylesoftware.htmlunit.attachment.Attachment;
import com.gargoylesoftware.htmlunit.attachment.AttachmentHandler;
import com.gargoylesoftware.htmlunit.html.BaseFrameElement;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.FrameWindow;
-import com.gargoylesoftware.htmlunit.html.HTMLParserListener;
import com.gargoylesoftware.htmlunit.html.HtmlInlineFrame;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import com.gargoylesoftware.htmlunit.html.parser.HTMLParserListener;
import com.gargoylesoftware.htmlunit.httpclient.HtmlUnitBrowserCompatCookieSpec;
import com.gargoylesoftware.htmlunit.javascript.AbstractJavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.DefaultJavaScriptErrorListener;
@@ -93,7 +91,9 @@
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLIFrameElement;
import com.gargoylesoftware.htmlunit.protocol.data.DataURLConnection;
import com.gargoylesoftware.htmlunit.util.Cookie;
+import com.gargoylesoftware.htmlunit.util.MimeType;
import com.gargoylesoftware.htmlunit.util.NameValuePair;
+import com.gargoylesoftware.htmlunit.util.TextUtils;
import com.gargoylesoftware.htmlunit.util.UrlUtils;
import com.gargoylesoftware.htmlunit.webstart.WebStartHandler;
@@ -170,7 +170,8 @@ public class WebClient implements Serializable, AutoCloseable {
private PageCreator pageCreator_ = new DefaultPageCreator();
private final Set webWindowListeners_ = new HashSet<>(5);
- private final Deque topLevelWindows_ = new ArrayDeque<>(); // top-level windows
+ private final List topLevelWindows_ =
+ Collections.synchronizedList(new ArrayList()); // top-level windows
private final List windows_ = Collections.synchronizedList(new ArrayList()); // all windows
private transient List> jobManagers_ =
Collections.synchronizedList(new ArrayList>());
@@ -205,7 +206,8 @@ public class WebClient implements Serializable, AutoCloseable {
private JavaScriptErrorListener javaScriptErrorListener_ = new DefaultJavaScriptErrorListener();
private WebClientOptions options_ = new WebClientOptions();
- private WebClientInternals internals_ = new WebClientInternals(this);
+ private final boolean javaScriptEngineEnabled_;
+ private WebClientInternals internals_ = new WebClientInternals();
private final StorageHolder storageHolder_ = new StorageHolder();
private static final WebResponseData responseDataNoHttpResponse_ = new WebResponseData(
@@ -234,9 +236,23 @@ public WebClient(final BrowserVersion browserVersion) {
* @param proxyPort the port to use on the proxy server
*/
public WebClient(final BrowserVersion browserVersion, final String proxyHost, final int proxyPort) {
+ this(browserVersion, true, proxyHost, proxyPort);
+ }
+
+ /**
+ * Creates an instance that will use the specified {@link BrowserVersion} and proxy server.
+ * @param browserVersion the browser version to simulate
+ * @param javaScriptEngineEnabled set to false if the simulated browser should not support javaScript
+ * @param proxyHost the server that will act as proxy or null for no proxy
+ * @param proxyPort the port to use on the proxy server
+ */
+ public WebClient(final BrowserVersion browserVersion, final boolean javaScriptEngineEnabled,
+ final String proxyHost, final int proxyPort) {
WebAssert.notNull("browserVersion", browserVersion);
browserVersion_ = browserVersion;
+ javaScriptEngineEnabled_ = javaScriptEngineEnabled;
+
if (proxyHost == null) {
getOptions().setProxyConfig(new ProxyConfig());
}
@@ -245,16 +261,21 @@ public WebClient(final BrowserVersion browserVersion, final String proxyHost, fi
}
webConnection_ = new HttpWebConnection(this); // this has to be done after the browser version was set
- scriptEngine_ = new JavaScriptEngine(this);
+ if (javaScriptEngineEnabled_) {
+ scriptEngine_ = new JavaScriptEngine(this);
+ }
loadQueue_ = new ArrayList<>();
// The window must be constructed AFTER the script engine.
addWebWindowListener(new CurrentWindowTracker(this));
currentWindow_ = new TopLevelWindow("", this);
- fireWindowOpened(new WebWindowEvent(currentWindow_, WebWindowEvent.OPEN, null, null));
- if (getBrowserVersion().hasFeature(JS_XML_SUPPORT_VIA_ACTIVEXOBJECT)) {
- initMSXMLActiveX();
+ if (isJavaScriptEnabled()) {
+ fireWindowOpened(new WebWindowEvent(currentWindow_, WebWindowEvent.OPEN, null, null));
+
+ if (getBrowserVersion().hasFeature(JS_XML_SUPPORT_VIA_ACTIVEXOBJECT)) {
+ initMSXMLActiveX();
+ }
}
}
@@ -358,7 +379,7 @@ P getPage(final WebWindow webWindow, final WebRequest webReques
webWindow.getHistory().addPage(page);
}
- final Window window = (Window) webWindow.getScriptableObject();
+ final Window window = webWindow.getScriptableObject();
if (window != null) { // js enabled
window.getLocation().setHash(current.getRef());
window.clearComputedStyles();
@@ -460,8 +481,11 @@ public
P getPage(final String url) throws IOException, FailingH
*/
@SuppressWarnings("unchecked")
public
P getPage(final URL url) throws IOException, FailingHttpStatusCodeException {
- return (P) getPage(getCurrentWindow().getTopWindow(),
- new WebRequest(url, getBrowserVersion().getHtmlAcceptHeader()));
+ final WebRequest request = new WebRequest(url, getBrowserVersion().getHtmlAcceptHeader(),
+ getBrowserVersion().getAcceptEncodingHeader());
+ request.setCharset(UTF_8);
+
+ return (P) getPage(getCurrentWindow().getTopWindow(), request);
}
/**
@@ -512,7 +536,7 @@ public Page loadWebResponseInto(final WebResponse webResponse, final WebWindow w
return webWindow.getEnclosedPage();
}
- if (attachmentHandler_ != null && Attachment.isAttachment(webResponse)) {
+ if (attachmentHandler_ != null && attachmentHandler_.isAttachment(webResponse)) {
final WebWindow w = openWindow(null, null, webWindow);
final Page page = pageCreator_.createPage(webResponse, w);
attachmentHandler_.handleAttachment(page);
@@ -536,7 +560,8 @@ public Page loadWebResponseInto(final WebResponse webResponse, final WebWindow w
newPage.initialize();
// hack: onload should be fired the same way for all type of pages
// here is a hack to handle non HTML pages
- if (webWindow instanceof FrameWindow && !newPage.isHtmlPage()) {
+ if (isJavaScriptEnabled()
+ && webWindow instanceof FrameWindow && !newPage.isHtmlPage()) {
final FrameWindow fw = (FrameWindow) webWindow;
final BaseFrameElement frame = fw.getFrameElement();
if (frame.hasEventHandlers("onload")) {
@@ -565,7 +590,7 @@ public void printContentIfNecessary(final WebResponse webResponse) {
if (getOptions().isPrintContentOnFailingStatusCode()) {
final int statusCode = webResponse.getStatusCode();
final boolean successful = statusCode >= HttpStatus.SC_OK && statusCode < HttpStatus.SC_MULTIPLE_CHOICES;
- if (!successful) {
+ if (!successful && LOG.isInfoEnabled()) {
final String contentType = webResponse.getContentType();
LOG.info("statusCode=[" + statusCode + "] contentType=[" + contentType + "]");
LOG.info(webResponse.getContentAsString());
@@ -804,10 +829,10 @@ public void setCurrentWindow(final WebWindow window) {
//2. onFocus event is triggered for focusedElement of new current window
final Page enclosedPage = currentWindow_.getEnclosedPage();
if (enclosedPage != null && enclosedPage.isHtmlPage()) {
- final Object jsWindow = currentWindow_.getScriptableObject();
- if (jsWindow instanceof Window) {
+ final Window jsWindow = currentWindow_.getScriptableObject();
+ if (jsWindow != null) {
final HTMLElement activeElement =
- ((HTMLDocument) ((Window) jsWindow).getDocument()).getActiveElement();
+ ((HTMLDocument) jsWindow.getDocument()).getActiveElement();
if (activeElement != null) {
((HtmlPage) enclosedPage).setFocusedElement(activeElement.getDomNodeOrDie(), true);
}
@@ -877,12 +902,16 @@ public WebWindow openWindow(final URL url, final String windowName) {
*/
public WebWindow openWindow(final URL url, final String windowName, final WebWindow opener) {
final WebWindow window = openTargetWindow(opener, windowName, TARGET_BLANK);
- final HtmlPage openerPage = (HtmlPage) opener.getEnclosedPage();
if (url != null) {
try {
- final WebRequest request = new WebRequest(url, getBrowserVersion().getHtmlAcceptHeader());
+ final WebRequest request = new WebRequest(url, getBrowserVersion().getHtmlAcceptHeader(),
+ getBrowserVersion().getAcceptEncodingHeader());
+ request.setCharset(UTF_8);
+
+ final Page openerPage = opener.getEnclosedPage();
if (getBrowserVersion().hasFeature(DIALOGWINDOW_REFERER)
- && openerPage != null) {
+ && openerPage != null
+ && openerPage.getUrl() != null) {
final String referer = openerPage.getUrl().toExternalForm();
request.setAdditionalHeader(HttpHeader.REFERER, referer);
}
@@ -1010,7 +1039,10 @@ public DialogWindow openDialogWindow(final URL url, final WebWindow opener, fina
fireWindowOpened(new WebWindowEvent(window, WebWindowEvent.OPEN, null, null));
final HtmlPage openerPage = (HtmlPage) opener.getEnclosedPage();
- final WebRequest request = new WebRequest(url, getBrowserVersion().getHtmlAcceptHeader());
+ final WebRequest request = new WebRequest(url, getBrowserVersion().getHtmlAcceptHeader(),
+ getBrowserVersion().getAcceptEncodingHeader());
+ request.setCharset(UTF_8);
+
if (getBrowserVersion().hasFeature(DIALOGWINDOW_REFERER) && openerPage != null) {
final String referer = openerPage.getUrl().toExternalForm();
request.setAdditionalHeader(HttpHeader.REFERER, referer);
@@ -1070,7 +1102,10 @@ public WebWindow getWebWindowByName(final String name) throws WebWindowNotFoundE
*/
public void initialize(final WebWindow webWindow) {
WebAssert.notNull("webWindow", webWindow);
- scriptEngine_.initialize(webWindow);
+
+ if (isJavaScriptEngineEnabled()) {
+ scriptEngine_.initialize(webWindow);
+ }
}
/**
@@ -1081,9 +1116,10 @@ public void initialize(final WebWindow webWindow) {
*/
public void initialize(final Page newPage) {
WebAssert.notNull("newPage", newPage);
- final WebWindow webWindow = newPage.getEnclosingWindow();
- if (webWindow.getScriptableObject() instanceof Window) {
- ((Window) webWindow.getScriptableObject()).initialize(newPage);
+
+ if (isJavaScriptEngineEnabled()) {
+ final Window window = newPage.getEnclosingWindow().getScriptableObject();
+ window.initialize(newPage);
}
}
@@ -1096,8 +1132,11 @@ public void initialize(final Page newPage) {
*/
public void initializeEmptyWindow(final WebWindow webWindow) {
WebAssert.notNull("webWindow", webWindow);
- initialize(webWindow);
- ((Window) webWindow.getScriptableObject()).initialize();
+
+ if (isJavaScriptEngineEnabled()) {
+ initialize(webWindow);
+ ((Window) webWindow.getScriptableObject()).initialize();
+ }
}
/**
@@ -1166,10 +1205,11 @@ private WebResponse makeWebResponseForDataUrl(final WebRequest webRequest) throw
}
}
- private static WebResponse makeWebResponseForAboutUrl(final URL url) {
+ private static WebResponse makeWebResponseForAboutUrl(final WebRequest webRequest) throws MalformedURLException {
+ final URL url = webRequest.getUrl();
final String urlWithoutQuery = StringUtils.substringBefore(url.toExternalForm(), "?");
if (!"blank".equalsIgnoreCase(StringUtils.substringAfter(urlWithoutQuery, WebClient.ABOUT_SCHEME))) {
- throw new IllegalArgumentException(url + " is not supported, only about:blank is supported now.");
+ throw new MalformedURLException(url + " is not supported, only about:blank is supported now.");
}
return new StringWebResponse("", URL_ABOUT_BLANK);
}
@@ -1205,10 +1245,10 @@ private WebResponse makeWebResponseForFileUrl(final WebRequest webRequest) throw
if (!file.exists()) {
// construct 404
final List compiledHeaders = new ArrayList<>();
- compiledHeaders.add(new NameValuePair(HttpHeader.CONTENT_TYPE, "text/html"));
+ compiledHeaders.add(new NameValuePair(HttpHeader.CONTENT_TYPE, MimeType.TEXT_HTML));
final WebResponseData responseData =
new WebResponseData(
- TextUtil.stringToByteArray("File: " + file.getAbsolutePath(), UTF_8),
+ TextUtils.stringToByteArray("File: " + file.getAbsolutePath(), UTF_8),
404, "Not Found", compiledHeaders);
return new WebResponse(responseData, webRequest, 0);
}
@@ -1238,20 +1278,20 @@ public String guessContentType(final File file) {
final String fileName = file.getName();
if (fileName.endsWith(".xhtml")) {
// Java's mime type map returns application/xml in JDK8.
- return "application/xhtml+xml";
+ return MimeType.APPLICATION_XHTML;
}
// Java's mime type map does not know these in JDK8.
if (fileName.endsWith(".js")) {
- return "application/javascript";
+ return MimeType.APPLICATION_JAVASCRIPT;
}
if (fileName.toLowerCase(Locale.ROOT).endsWith(".css")) {
- return "text/css";
+ return MimeType.TEXT_CSS;
}
String contentType = URLConnection.guessContentTypeFromName(fileName);
if (contentType == null) {
- try (InputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
+ try (InputStream inputStream = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
contentType = URLConnection.guessContentTypeFromStream(inputStream);
}
catch (final IOException e) {
@@ -1259,7 +1299,7 @@ public String guessContentType(final File file) {
}
}
if (contentType == null) {
- contentType = "application/octet-stream";
+ contentType = MimeType.APPLICATION_OCTET_STREAM;
}
return contentType;
}
@@ -1280,7 +1320,7 @@ private WebResponse makeWebResponseForJavaScriptUrl(final WebWindow webWindow, f
}
if (page == null) {
- page = getPage(webWindow, new WebRequest(WebClient.URL_ABOUT_BLANK));
+ page = getPage(webWindow, WebRequest.newAboutBlankRequest());
}
final ScriptResult r = page.executeJavaScript(url.toExternalForm(), "JavaScript URL", 1);
if (r.getJavaScriptResult() == null || ScriptResult.isUndefined(r)) {
@@ -1303,7 +1343,7 @@ private WebResponse makeWebResponseForJavaScriptUrl(final WebWindow webWindow, f
public WebResponse loadWebResponse(final WebRequest webRequest) throws IOException {
switch (webRequest.getUrl().getProtocol()) {
case "about":
- return makeWebResponseForAboutUrl(webRequest.getUrl());
+ return makeWebResponseForAboutUrl(webRequest);
case "file":
return makeWebResponseForFileUrl(webRequest);
@@ -1312,8 +1352,7 @@ public WebResponse loadWebResponse(final WebRequest webRequest) throws IOExcepti
return makeWebResponseForDataUrl(webRequest);
default:
- return loadWebResponseFromWebConnection(webRequest, ALLOWED_REDIRECTIONS_SAME_URL,
- webRequest.getCharset());
+ return loadWebResponseFromWebConnection(webRequest, ALLOWED_REDIRECTIONS_SAME_URL);
}
}
@@ -1321,12 +1360,11 @@ public WebResponse loadWebResponse(final WebRequest webRequest) throws IOExcepti
* Loads a {@link WebResponse} from the server through the WebConnection.
* @param webRequest the request
* @param allowedRedirects the number of allowed redirects remaining
- * @param charset the charset to use
* @throws IOException if an IO problem occurs
* @return the resultant {@link WebResponse}
*/
private WebResponse loadWebResponseFromWebConnection(final WebRequest webRequest,
- final int allowedRedirects, final Charset charset) throws IOException {
+ final int allowedRedirects) throws IOException {
URL url = webRequest.getUrl();
final HttpMethod method = webRequest.getHttpMethod();
@@ -1336,7 +1374,8 @@ private WebResponse loadWebResponseFromWebConnection(final WebRequest webRequest
WebAssert.notNull("method", method);
WebAssert.notNull("parameters", parameters);
- url = UrlUtils.encodeUrl(url, getBrowserVersion().hasFeature(URL_MINIMAL_QUERY_ENCODING), charset);
+ url = UrlUtils.encodeUrl(url, getBrowserVersion().hasFeature(URL_MINIMAL_QUERY_ENCODING),
+ webRequest.getCharset());
webRequest.setUrl(url);
if (LOG.isDebugEnabled()) {
@@ -1399,7 +1438,6 @@ else if (!proxyConfig.shouldBypassProxy(webRequest.getUrl().getHost())) {
catch (final NoHttpResponseException e) {
return new WebResponse(responseDataNoHttpResponse_, webRequest, 0);
}
- getCache().cacheIfPossible(webRequest, webResponse, null);
}
// Continue according to the HTTP status code.
@@ -1445,25 +1483,32 @@ && getOptions().isRedirectEnabled()) {
|| status == HttpStatus.SC_MOVED_TEMPORARILY
|| status == HttpStatus.SC_SEE_OTHER) {
final WebRequest wrs = new WebRequest(newUrl, HttpMethod.GET);
+ wrs.setCharset(webRequest.getCharset());
+
if (HttpMethod.HEAD == webRequest.getHttpMethod()) {
wrs.setHttpMethod(HttpMethod.HEAD);
}
for (final Map.Entry entry : webRequest.getAdditionalHeaders().entrySet()) {
wrs.setAdditionalHeader(entry.getKey(), entry.getValue());
}
- return loadWebResponseFromWebConnection(wrs, allowedRedirects - 1, UTF_8);
+ return loadWebResponseFromWebConnection(wrs, allowedRedirects - 1);
}
else if (status == HttpStatus.SC_TEMPORARY_REDIRECT
|| status == 308) {
final WebRequest wrs = new WebRequest(newUrl, webRequest.getHttpMethod());
+ wrs.setCharset(webRequest.getCharset());
+
wrs.setRequestParameters(parameters);
for (final Map.Entry entry : webRequest.getAdditionalHeaders().entrySet()) {
wrs.setAdditionalHeader(entry.getKey(), entry.getValue());
}
- return loadWebResponseFromWebConnection(wrs, allowedRedirects - 1, UTF_8);
+ return loadWebResponseFromWebConnection(wrs, allowedRedirects - 1);
}
}
+ if (fromCache == null) {
+ getCache().cacheIfPossible(webRequest, webResponse, null);
+ }
return webResponse;
}
@@ -1472,21 +1517,42 @@ else if (status == HttpStatus.SC_TEMPORARY_REDIRECT
* @param wrs the WebRequestSettings instance to modify
*/
private void addDefaultHeaders(final WebRequest wrs) {
- // Add standard HtmlUnit headers.
+ // Add user-specified headers to the web request if not present there yet.
+ requestHeaders_.forEach((name, value) -> {
+ if (!wrs.isAdditionalHeader(name)) {
+ wrs.setAdditionalHeader(name, value);
+ }
+ });
+
+ // Add standard HtmlUnit headers to the web request if still not present there yet.
if (!wrs.isAdditionalHeader(HttpHeader.ACCEPT_LANGUAGE)) {
wrs.setAdditionalHeader(HttpHeader.ACCEPT_LANGUAGE, getBrowserVersion().getBrowserLanguage());
}
+
+ if (getBrowserVersion().hasFeature(HTTP_HEADER_SEC_FETCH)
+ && !wrs.isAdditionalHeader(HttpHeader.SEC_FETCH_MODE)) {
+ wrs.setAdditionalHeader(HttpHeader.SEC_FETCH_MODE, "navigate");
+ }
+ if (getBrowserVersion().hasFeature(HTTP_HEADER_SEC_FETCH)
+ && !wrs.isAdditionalHeader(HttpHeader.SEC_FETCH_SITE)) {
+ wrs.setAdditionalHeader(HttpHeader.SEC_FETCH_SITE, "same-origin");
+ }
+ if (getBrowserVersion().hasFeature(HTTP_HEADER_SEC_FETCH)
+ && !wrs.isAdditionalHeader(HttpHeader.SEC_FETCH_USER)) {
+ wrs.setAdditionalHeader(HttpHeader.SEC_FETCH_USER, "?1");
+ }
+
if (getBrowserVersion().hasFeature(HTTP_HEADER_UPGRADE_INSECURE_REQUEST)
&& !wrs.isAdditionalHeader(HttpHeader.UPGRADE_INSECURE_REQUESTS)) {
wrs.setAdditionalHeader(HttpHeader.UPGRADE_INSECURE_REQUESTS, "1");
}
- // Add user-specified headers last so that they can override HtmlUnit defaults.
- wrs.getAdditionalHeaders().putAll(requestHeaders_);
}
/**
* Returns an immutable list of open web windows (whether they are top level windows or not).
* This is a snapshot; future changes are not reflected by this list.
+ *
+ * The list is ordered by age, the oldest one first.
*
* @return an immutable list of open web windows (whether they are top level windows or not)
* @see #getWebWindowByName(String)
@@ -1513,6 +1579,8 @@ public boolean containsWebWindow(final WebWindow webWindow) {
/**
* Returns an immutable list of open top level windows.
* This is a snapshot; future changes are not reflected by this list.
+ *
+ * The list is ordered by age, the oldest one first.
*
* @return an immutable list of open top level windows
* @see #getWebWindowByName(String)
@@ -1661,7 +1729,7 @@ public IncorrectnessListener getIncorrectnessListener() {
*/
public void setIncorrectnessListener(final IncorrectnessListener listener) {
if (listener == null) {
- throw new NullPointerException("Null incorrectness listener.");
+ throw new IllegalArgumentException("Null is not a valid IncorrectnessListener");
}
incorrectnessListener_ = listener;
}
@@ -1691,7 +1759,7 @@ public AjaxController getAjaxController() {
*/
public void setAjaxController(final AjaxController newValue) {
if (newValue == null) {
- throw new NullPointerException();
+ throw new IllegalArgumentException("Null is not a valid AjaxController");
}
ajaxController_ = newValue;
}
@@ -1801,18 +1869,25 @@ public void webWindowClosed(final WebWindowEvent event) {
if (webClient_.topLevelWindows_.isEmpty()) {
// Must always have at least window, and there are no top-level windows left; must create one.
final TopLevelWindow newWindow = new TopLevelWindow("", webClient_);
- webClient_.topLevelWindows_.push(newWindow);
+ webClient_.topLevelWindows_.add(newWindow);
webClient_.setCurrentWindow(newWindow);
}
else {
// The current window is now the previous top-level window.
- webClient_.setCurrentWindow(webClient_.topLevelWindows_.peek());
+ webClient_.setCurrentWindow(
+ webClient_.topLevelWindows_.get(webClient_.topLevelWindows_.size() - 1));
}
}
}
else if (window == webClient_.getCurrentWindow()) {
// The current window is now the last top-level window.
- webClient_.setCurrentWindow(webClient_.topLevelWindows_.peek());
+ if (webClient_.topLevelWindows_.isEmpty()) {
+ webClient_.setCurrentWindow(null);
+ }
+ else {
+ webClient_.setCurrentWindow(
+ webClient_.topLevelWindows_.get(webClient_.topLevelWindows_.size() - 1));
+ }
}
}
@@ -1839,7 +1914,7 @@ else if (window instanceof FrameWindow) {
// now looks at the visibility of the frame window
final BaseFrameElement frameElement = fw.getFrameElement();
- if (frameElement.isDisplayed()) {
+ if (webClient_.isJavaScriptEnabled() && frameElement.isDisplayed()) {
final Object element = frameElement.getScriptableObject();
final HTMLElement htmlElement = (HTMLElement) element;
final ComputedCSSStyleDeclaration style =
@@ -1861,7 +1936,7 @@ public void webWindowOpened(final WebWindowEvent event) {
final WebWindow window = event.getWebWindow();
if (window instanceof TopLevelWindow) {
final TopLevelWindow tlw = (TopLevelWindow) window;
- webClient_.topLevelWindows_.push(tlw);
+ webClient_.topLevelWindows_.add(tlw);
}
// Page is not loaded yet, don't set it now as current window.
}
@@ -2201,7 +2276,9 @@ public void loadDownloadedResponses() throws FailingHttpStatusCodeException, IOE
for (int i = queue.size() - 1; i >= 0; --i) {
final LoadJob loadJob = queue.get(i);
if (loadJob.isOutdated()) {
- LOG.info("No usage of download: " + loadJob);
+ if (LOG.isInfoEnabled()) {
+ LOG.info("No usage of download: " + loadJob);
+ }
continue;
}
@@ -2217,7 +2294,7 @@ public void loadDownloadedResponses() throws FailingHttpStatusCodeException, IOE
req.setUrl(loadJob.urlWithOnlyHashChange_);
// update location.hash
- final Window jsWindow = (Window) win.getScriptableObject();
+ final Window jsWindow = win.getScriptableObject();
if (null != jsWindow) {
final Location location = jsWindow.getLocation();
location.setHash(oldURL, loadJob.urlWithOnlyHashChange_.getRef());
@@ -2244,7 +2321,9 @@ public void loadDownloadedResponses() throws FailingHttpStatusCodeException, IOE
}
}
else {
- LOG.info("No usage of download: " + loadJob);
+ if (LOG.isInfoEnabled()) {
+ LOG.info("No usage of download: " + loadJob);
+ }
}
}
}
@@ -2363,4 +2442,25 @@ else if (LOG.isDebugEnabled()) {
LOG.debug("Skipped adding cookie: '" + cookieString + "'");
}
}
+
+ /**
+ * Returns true if the javaScript support is enabled.
+ * To disable the javascript support (eg. temporary)
+ * you have to use the {@link WebClientOptions#setJavaScriptEnabled(boolean)} setter.
+ * @see #isJavaScriptEngineEnabled()
+ * @return true if the javaScript engine and the javaScript support is enabled.
+ */
+ public boolean isJavaScriptEnabled() {
+ return javaScriptEngineEnabled_ && getOptions().isJavaScriptEnabled();
+ }
+
+ /**
+ * Returns true if the javaScript engine is enabled.
+ * To disable the javascript engine you have to use the
+ * {@link WebClient#WebClient(BrowserVersion, boolean, String, int)} constructor.
+ * @return true if the javaScript engine is enabled.
+ */
+ public boolean isJavaScriptEngineEnabled() {
+ return javaScriptEngineEnabled_;
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebClientInternals.java b/src/main/java/com/gargoylesoftware/htmlunit/WebClientInternals.java
index 601e396bfcc..34d7fe19fb5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebClientInternals.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebClientInternals.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,14 +27,13 @@
* Represents a ways to get notified about internal objects.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
public class WebClientInternals implements Serializable {
- private final WebClient webClient_;
private Collection listeners_;
- WebClientInternals(final WebClient webClient) {
- webClient_ = webClient;
+ WebClientInternals() {
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebClientOptions.java b/src/main/java/com/gargoylesoftware/htmlunit/WebClientOptions.java
index b9642d7d285..bd14811a7f7 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebClientOptions.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebClientOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -335,20 +335,6 @@ public void setPrintContentOnFailingStatusCode(final boolean enabled) {
printContentOnFailingStatusCode_ = enabled;
}
- /**
- * Returns {@code true} if the content of the resulting document will be printed to
- * the console in the event of a failing response code.
- *
- * @return {@code true} if the content of the resulting document will be printed to
- * the console in the event of a failing response code
- * @see #setPrintContentOnFailingStatusCode
- * @deprecated as of 2.27, please use {@link #isPrintContentOnFailingStatusCode()}
- */
- @Deprecated
- public boolean getPrintContentOnFailingStatusCode() {
- return printContentOnFailingStatusCode_;
- }
-
/**
* Returns {@code true} if the content of the resulting document will be printed to
* the console in the event of a failing response code.
@@ -562,7 +548,7 @@ public int getHistorySizeLimit() {
/**
* Sets the History size limit. HtmlUnit uses SoftReferences<Page> for
* storing the pages that are part of the history. If you like to fine tune this
- * you can use {@link #getHistoryPageCacheLimit()} to limit the number of page references
+ * you can use {@link #setHistoryPageCacheLimit(int)} to limit the number of page references
* stored by the history.
* @param historySizeLimit maximum number of pages in history
*/
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebConnection.java b/src/main/java/com/gargoylesoftware/htmlunit/WebConnection.java
index ce1887b2d8c..bfc1cb73fa4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebConnection.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,4 +34,6 @@ public interface WebConnection extends AutoCloseable {
*/
WebResponse getResponse(WebRequest request) throws IOException;
+ @Override
+ void close() throws IOException;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebConsole.java b/src/main/java/com/gargoylesoftware/htmlunit/WebConsole.java
index f16cb905770..e751d6fcf05 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebConsole.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebConsole.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,9 @@
*/
public class WebConsole implements Serializable {
+ private Formatter formatter_ = new DefaultFormatter();
+ private Logger logger_ = new DefaultLogger();
+
/**
* A simple logging interface abstracting logging APIs.
*/
@@ -167,9 +170,6 @@ public interface Formatter {
String parameterAsFloat(Object o);
}
- private Formatter formatter_ = new DefaultFormatter();
- private Logger logger_ = new DefaultLogger();
-
/**
* Sets the Formatter.
* @param formatter the formatter
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebRequest.java b/src/main/java/com/gargoylesoftware/htmlunit/WebRequest.java
index 2e65ae17f77..a10517a562d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebRequest.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebRequest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -72,11 +72,34 @@ public class WebRequest implements Serializable {
* Instantiates a {@link WebRequest} for the specified URL.
* @param url the target URL
* @param acceptHeader the accept header to use
+ * @param acceptEncodingHeader the accept encoding header to use
*/
- public WebRequest(final URL url, final String acceptHeader) {
+ public WebRequest(final URL url, final String acceptHeader, final String acceptEncodingHeader) {
setUrl(url);
- setAdditionalHeader(HttpHeader.ACCEPT, acceptHeader);
- setAdditionalHeader(HttpHeader.ACCEPT_ENCODING, "gzip, deflate");
+ if (acceptHeader != null) {
+ setAdditionalHeader(HttpHeader.ACCEPT, acceptHeader);
+ }
+ if (acceptEncodingHeader != null) {
+ setAdditionalHeader(HttpHeader.ACCEPT_ENCODING, acceptEncodingHeader);
+ }
+ }
+
+ /**
+ * Instantiates a {@link WebRequest} for the specified URL.
+ * @param url the target URL
+ * @param acceptHeader the accept header to use
+ * @deprecated as of 2.36.0, use {@link #WebRequest(URL, String, String)} instead
+ */
+ @Deprecated
+ public WebRequest(final URL url, final String acceptHeader) {
+ this(url, acceptHeader, "gzip, deflate");
+ }
+
+ /**
+ * @return a new request for about:blank
+ */
+ public static WebRequest newAboutBlankRequest() {
+ return new WebRequest(WebClient.URL_ABOUT_BLANK, "*/*", "gzip, deflate");
}
/**
@@ -84,7 +107,7 @@ public WebRequest(final URL url, final String acceptHeader) {
* @param url the target URL
*/
public WebRequest(final URL url) {
- this(url, "*/*");
+ this(url, "*/*", "gzip, deflate");
}
/**
@@ -359,19 +382,36 @@ public boolean isAdditionalHeader(final String name) {
return false;
}
+ /**
+ * Returns the header value associated with this name.
+ * @param name the name of the additional HTTP header
+ * @return the value or null
+ */
+ public String getAdditionalHeader(final String name) {
+ String newKey = name;
+ for (final String key : additionalHeaders_.keySet()) {
+ if (name.equalsIgnoreCase(key)) {
+ newKey = key;
+ break;
+ }
+ }
+ return additionalHeaders_.get(newKey);
+ }
+
/**
* Sets the specified name/value pair in the additional HTTP headers.
* @param name the name of the additional HTTP header
* @param value the value of the additional HTTP header
*/
- public void setAdditionalHeader(String name, final String value) {
+ public void setAdditionalHeader(final String name, final String value) {
+ String newKey = name;
for (final String key : additionalHeaders_.keySet()) {
if (name.equalsIgnoreCase(key)) {
- name = key;
+ newKey = key;
break;
}
}
- additionalHeaders_.put(name, value);
+ additionalHeaders_.put(newKey, value);
}
/**
@@ -435,16 +475,15 @@ public void setCharset(final Charset charset) {
*/
@Override
public String toString() {
- final StringBuilder builder = new StringBuilder();
+ final StringBuilder builder = new StringBuilder(100);
builder.append(getClass().getSimpleName());
- builder.append("[<");
- builder.append("url=\"" + url_ + '"');
- builder.append(", " + httpMethod_);
- builder.append(", " + encodingType_);
- builder.append(", " + requestParameters_);
- builder.append(", " + additionalHeaders_);
- builder.append(", " + credentials_);
- builder.append(">]");
+ builder.append("[]");
return builder.toString();
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebResponse.java b/src/main/java/com/gargoylesoftware/htmlunit/WebResponse.java
index 43002178b38..ca6dd2d2735 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebResponse.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebResponse.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -57,6 +57,7 @@ public class WebResponse implements Serializable {
private long loadTime_;
private WebResponseData responseData_;
private WebRequest request_;
+ private boolean defaultCharsetUtf8_;
/**
* Constructs with all data.
@@ -180,12 +181,12 @@ public Charset getContentCharset() {
// xml pages are using a different content type
if (null != contentType
- && PageType.XML == DefaultPageCreator.determinePageType(contentType)) {
+ && (defaultCharsetUtf8_
+ || PageType.XML == DefaultPageCreator.determinePageType(contentType))) {
return UTF_8;
}
-
- charset = getWebRequest().getCharset();
}
+
if (charset == null) {
charset = ISO_8859_1;
}
@@ -245,7 +246,7 @@ public String getContentAsString(final Charset encoding, final boolean ignoreUtf
}
}
catch (final IOException e) {
- LOG.warn(e);
+ LOG.warn(e.getMessage(), e);
}
}
return null;
@@ -287,4 +288,11 @@ public void cleanUp() {
responseData_.cleanUp();
}
}
+
+ /**
+ * Mark this response for using UTF-8 as default charset.
+ */
+ public void defaultCharsetUtf8() {
+ defaultCharsetUtf8_ = true;
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebResponseData.java b/src/main/java/com/gargoylesoftware/htmlunit/WebResponseData.java
index 00daa588e94..cc31d30e63a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebResponseData.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebResponseData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,9 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.brotli.dec.BrotliInputStream;
+import com.gargoylesoftware.htmlunit.util.MimeType;
import com.gargoylesoftware.htmlunit.util.NameValuePair;
/**
@@ -91,7 +93,6 @@ public WebResponseData(final DownloadedContent downloadedContent, final int stat
private InputStream getStream(final DownloadedContent downloadedContent,
final List headers) throws IOException {
-
InputStream stream = downloadedContent_.getInputStream();
if (downloadedContent.isEmpty()) {
return stream;
@@ -99,7 +100,11 @@ private InputStream getStream(final DownloadedContent downloadedContent,
final String encoding = getHeader(headers, "content-encoding");
if (encoding != null) {
- if (StringUtils.contains(encoding, "gzip")) {
+ boolean isGzip = StringUtils.contains(encoding, "gzip") && !"no-gzip".equals(encoding);
+ if ("gzip-only-text/html".equals(encoding)) {
+ isGzip = MimeType.TEXT_HTML.equals(getHeader(headers, "content-type"));
+ }
+ if (isGzip) {
try {
stream = new GZIPInputStream(stream);
}
@@ -117,6 +122,24 @@ private InputStream getStream(final DownloadedContent downloadedContent,
+ "", ISO_8859_1);
}
}
+ else if ("br".equals(encoding)) {
+ try {
+ stream = new BrotliInputStream(stream);
+ }
+ catch (final IOException e) {
+ LOG.error("Reading Brotli encodec content failed.", e);
+ stream.close();
+ stream = IOUtils.toInputStream(
+ "\n"
+ + "Problem loading page \n"
+ + "\n"
+ + "Content Encoding Error \n"
+ + "The page you are trying to view cannot be shown because"
+ + " it uses an invalid or unsupported form of compression.
\n"
+ + "\n"
+ + "", ISO_8859_1);
+ }
+ }
else if (StringUtils.contains(encoding, "deflate")) {
boolean zlibHeader = false;
if (stream.markSupported()) { // should be always the case as the content is in a byte[] or in a file
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebResponseFromCache.java b/src/main/java/com/gargoylesoftware/htmlunit/WebResponseFromCache.java
index 62e0dc59010..12aafefa49c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebResponseFromCache.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebResponseFromCache.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebWindow.java b/src/main/java/com/gargoylesoftware/htmlunit/WebWindow.java
index e99ed6d4689..1de1a6a76c3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebWindow.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebWindow.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,6 @@
import java.io.Serializable;
-import javax.script.ScriptContext;
-
import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJobManager;
/**
@@ -179,34 +177,4 @@ public interface WebWindow extends Serializable {
* @param outerHeight the outer height
*/
void setOuterHeight(int outerHeight);
-
- /**
- * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
- *
- * Returns the {@link ScriptContext}
- *
- * @return the {@link ScriptContext}
- */
- ScriptContext getScriptContext();
-
- /**
- * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
- *
- * Returns a thread local object.
- *
- * @param key the object key
- *
- * @return the thread local object
- */
- Object getThreadLocal(Object key);
-
- /**
- * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
- *
- * Puts a thread local object by {@code key}.
- *
- * @param key the object key
- * @param value the object value
- */
- void putThreadLocal(Object key, Object value);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebWindowAdapter.java b/src/main/java/com/gargoylesoftware/htmlunit/WebWindowAdapter.java
index 9d15623bb18..80e4fcfdc3e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebWindowAdapter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebWindowAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebWindowEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/WebWindowEvent.java
index 4f77b5ad3df..21088270c94 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebWindowEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebWindowEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebWindowImpl.java b/src/main/java/com/gargoylesoftware/htmlunit/WebWindowImpl.java
index 275870aa887..7f993e3729e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebWindowImpl.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebWindowImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,19 +15,14 @@
package com.gargoylesoftware.htmlunit;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_63;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_132;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_94;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_86;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_92;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-
-import javax.script.ScriptContext;
-import javax.script.SimpleScriptContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -57,13 +52,11 @@ public abstract class WebWindowImpl implements WebWindow {
private WebClient webClient_;
private Page enclosedPage_;
private transient Object scriptObject_;
- private transient ScriptContext scriptContext_ = new SimpleScriptContext();
private JavaScriptJobManager jobManager_;
private final List childWindows_ = new ArrayList<>();
private String name_ = "";
private final History history_ = new History(this);
private boolean closed_;
- private Map threadLocalMap_;
private int innerHeight_;
private int outerHeight_;
@@ -80,27 +73,22 @@ public WebWindowImpl(final WebClient webClient) {
webClient_ = webClient;
jobManager_ = BackgroundJavaScriptFactory.theFactory().createJavaScriptJobManager(this);
- boolean plus16 = false;
innerHeight_ = 605;
+ innerWidth_ = 1256;
if (webClient.getBrowserVersion().hasFeature(JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_63)) {
outerHeight_ = innerHeight_ + 63;
- plus16 = true;
- }
- else if (webClient.getBrowserVersion().hasFeature(JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_94)) {
- outerHeight_ = innerHeight_ + 94;
- }
- else if (webClient.getBrowserVersion().hasFeature(JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_132)) {
- outerHeight_ = innerHeight_ + 132;
- plus16 = true;
+ outerWidth_ = innerWidth_ + 16;
}
- else {
- outerHeight_ = innerHeight_ + 115;
+ else if (webClient.getBrowserVersion().hasFeature(JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_86)) {
+ outerHeight_ = innerHeight_ + 86;
+ outerWidth_ = innerWidth_ + 14;
}
- innerWidth_ = 1256;
- if (plus16) {
+ else if (webClient.getBrowserVersion().hasFeature(JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_92)) {
+ outerHeight_ = innerHeight_ + 92;
outerWidth_ = innerWidth_ + 16;
}
else {
+ outerHeight_ = innerHeight_ + 115;
outerWidth_ = innerWidth_ + 14;
}
}
@@ -346,30 +334,6 @@ public void setOuterHeight(final int outerHeight) {
outerHeight_ = outerHeight;
}
- /**
- * {@inheritDoc}
- */
- @Override
- public ScriptContext getScriptContext() {
- return scriptContext_;
- }
-
- @Override
- public final Object getThreadLocal(final Object key) {
- if (threadLocalMap_ == null) {
- return null;
- }
- return threadLocalMap_.get(key);
- }
-
- @Override
- public final synchronized void putThreadLocal(final Object key, final Object value) {
- if (threadLocalMap_ == null) {
- threadLocalMap_ = new HashMap<>();
- }
- threadLocalMap_.put(key, value);
- }
-
private void writeObject(final ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(scriptObject_ instanceof Scriptable ? scriptObject_ : null);
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebWindowListener.java b/src/main/java/com/gargoylesoftware/htmlunit/WebWindowListener.java
index de2aa274d40..c17dce2f995 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebWindowListener.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebWindowListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/WebWindowNotFoundException.java b/src/main/java/com/gargoylesoftware/htmlunit/WebWindowNotFoundException.java
index 64a29678fea..52332ba1fd9 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/WebWindowNotFoundException.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/WebWindowNotFoundException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLActiveXObjectFactory.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLActiveXObjectFactory.java
index 0d8041d790a..69c120ee014 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLActiveXObjectFactory.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLActiveXObjectFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLConfiguration.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLConfiguration.java
index 06dc346a674..49e0b6f3927 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLConfiguration.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLJavaScriptEnvironment.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLJavaScriptEnvironment.java
index 7c880fb213a..fe7aba798d5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLJavaScriptEnvironment.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLJavaScriptEnvironment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -78,10 +78,6 @@ public MSXMLJavaScriptEnvironment(final BrowserVersion browserVersion) throws Ex
final Scriptable parentPrototype = prototypesPerJSName.get(config.getExtendedClassName());
prototype.setPrototype(parentPrototype);
}
- else {
-// prototype.setPrototype(objectPrototype);
-// prototype.setPrototype(fallbackCaller);
- }
}
prototypes_ = prototypes;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLScriptable.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLScriptable.java
index dc367c8f788..b1ffa52ef19 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLScriptable.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/MSXMLScriptable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMAttribute.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMAttribute.java
index 502279cdd01..caa25e6fdbb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMAttribute.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMAttribute.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,7 +44,8 @@ public class XMLDOMAttribute extends XMLDOMNode {
/**
* Creates an instance.
*/
- public XMLDOMAttribute() { }
+ public XMLDOMAttribute() {
+ }
/**
* Returns a node list containing the child nodes.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCDATASection.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCDATASection.java
index 9e402187d86..30152e51bbd 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCDATASection.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCDATASection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCharacterData.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCharacterData.java
index 262d2751b74..cb1acb17df1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCharacterData.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMCharacterData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMComment.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMComment.java
index d2d92d8453f..7636b39aee8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMComment.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMComment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocument.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocument.java
index 94188e9602b..f6bca1efa46 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocument.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocument.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.DomProcessingInstruction;
import com.gargoylesoftware.htmlunit.html.DomText;
-import com.gargoylesoftware.htmlunit.html.HTMLParser;
+import com.gargoylesoftware.htmlunit.html.Html;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -439,8 +439,8 @@ private Object createElementNS(final String namespaceURI, final String qualified
if ("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul".equals(namespaceURI)) {
throw Context.reportRuntimeError("XUL not available");
}
- else if (HTMLParser.XHTML_NAMESPACE.equals(namespaceURI)
- || HTMLParser.SVG_NAMESPACE.equals(namespaceURI)) {
+ else if (Html.XHTML_NAMESPACE.equals(namespaceURI)
+ || Html.SVG_NAMESPACE.equals(namespaceURI)) {
element = getPage().createElementNS(namespaceURI, qualifiedName);
}
else {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocumentFragment.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocumentFragment.java
index 652607ff035..5e44c50abcf 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocumentFragment.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocumentFragment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocumentType.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocumentType.java
index 66f4ff94a05..7ff9bd69a54 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocumentType.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMDocumentType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMElement.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMElement.java
index dcc77e9b091..b426043d34d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMElement.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMImplementation.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMImplementation.java
index fa2889be83f..d9ca5dd3498 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMImplementation.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMImplementation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNamedNodeMap.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNamedNodeMap.java
index b55f912baaa..9348a80e3fb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNamedNodeMap.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNamedNodeMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@ public class XMLDOMNamedNodeMap extends MSXMLScriptable {
private final org.w3c.dom.NamedNodeMap attributes_;
- private int currentIndex_ = 0;
+ private int currentIndex_;
/**
* Creates an instance.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNode.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNode.java
index bf26fa91da8..274dc19dd22 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNode.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -443,7 +443,7 @@ protected Object insertBeforeImpl(final Object[] args) {
}
final DomNode refChildNode;
// IE accepts non standard calls with only one arg
- if (refChildObject == Undefined.instance) {
+ if (Undefined.isUndefined(refChildObject)) {
if (args.length > 1) {
throw Context.reportRuntimeError("Invalid argument.");
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNodeList.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNodeList.java
index bb329f3211e..5f5381f16a9 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNodeList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMNodeList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -78,7 +78,7 @@ protected enum EffectOnCache {
/**
* IE provides a way of enumerating through some element collections; this counter supports that functionality.
*/
- private int currentIndex_ = 0;
+ private int currentIndex_;
/**
* Creates an instance.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMParseError.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMParseError.java
index c5a002ae8f6..32f1692d1ec 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMParseError.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMParseError.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMProcessingInstruction.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMProcessingInstruction.java
index 9700aae700c..df62d321067 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMProcessingInstruction.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMProcessingInstruction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMSelection.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMSelection.java
index ecc1c031228..e93ca20c6f8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMSelection.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMSelection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMText.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMText.java
index 496833b5a06..dd93a8c3596 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMText.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLDOMText.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLHTTPRequest.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLHTTPRequest.java
index 20123dad499..60e75821def 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLHTTPRequest.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLHTTPRequest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -55,6 +55,7 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter;
import com.gargoylesoftware.htmlunit.javascript.host.Window;
import com.gargoylesoftware.htmlunit.javascript.host.xml.FormData;
+import com.gargoylesoftware.htmlunit.util.MimeType;
import com.gargoylesoftware.htmlunit.util.NameValuePair;
import com.gargoylesoftware.htmlunit.xml.XmlPage;
@@ -246,8 +247,10 @@ public Object getResponseXML() {
return doc;
}
catch (final IOException e) {
- LOG.warn("Failed parsing XML document " + webResponse_.getWebRequest().getUrl() + ": "
- + e.getMessage());
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Failed parsing XML document " + webResponse_.getWebRequest().getUrl() + ": "
+ + e.getMessage());
+ }
return null;
}
}
@@ -271,8 +274,10 @@ public int getStatus() {
return webResponse_.getStatusCode();
}
- LOG.error("XMLHTTPRequest.status was retrieved without a response available (readyState: "
- + state_ + ").");
+ if (LOG.isErrorEnabled()) {
+ LOG.error("XMLHTTPRequest.status was retrieved without a response available (readyState: "
+ + state_ + ").");
+ }
return 0;
}
@@ -289,8 +294,10 @@ public String getStatusText() {
return webResponse_.getStatusMessage();
}
- LOG.error("XMLHTTPRequest.statusText was retrieved without a response available (readyState: "
- + state_ + ").");
+ if (LOG.isErrorEnabled()) {
+ LOG.error("XMLHTTPRequest.statusText was retrieved without a response available (readyState: "
+ + state_ + ").");
+ }
return null;
}
@@ -320,8 +327,10 @@ public String getAllResponseHeaders() {
return builder.append("\r\n").toString();
}
- LOG.error("XMLHTTPRequest.getAllResponseHeaders() was called without a response available (readyState: "
- + state_ + ").");
+ if (LOG.isErrorEnabled()) {
+ LOG.error("XMLHTTPRequest.getAllResponseHeaders() was called without a response available (readyState: "
+ + state_ + ").");
+ }
return null;
}
@@ -349,8 +358,10 @@ public String getResponseHeader(final String header) {
return value;
}
- LOG.error("XMLHTTPRequest.getResponseHeader(..) was called without a response available (readyState: "
- + state_ + ").");
+ if (LOG.isErrorEnabled()) {
+ LOG.error("XMLHTTPRequest.getResponseHeader(..) was called without a response available (readyState: "
+ + state_ + ").");
+ }
return null;
}
@@ -388,7 +399,7 @@ public void open(final String method, final Object url, final Object asyncParam,
// defaults to true if not specified
boolean async = true;
- if (asyncParam != Undefined.instance) {
+ if (!Undefined.isUndefined(asyncParam)) {
async = ScriptRuntime.toBoolean(asyncParam);
}
@@ -407,11 +418,11 @@ public void open(final String method, final Object url, final Object asyncParam,
request.setHttpMethod(HttpMethod.valueOf(method.toUpperCase(Locale.ROOT)));
// password is ignored if no user defined
- if (user != null && user != Undefined.instance) {
+ if (user != null && !Undefined.isUndefined(user)) {
final String userCred = user.toString();
String passwordCred = "";
- if (password != null && password != Undefined.instance) {
+ if (password != null && !Undefined.isUndefined(password)) {
passwordCred = password.toString();
}
@@ -420,11 +431,15 @@ public void open(final String method, final Object url, final Object asyncParam,
webRequest_ = request;
}
catch (final MalformedURLException e) {
- LOG.error("Unable to initialize XMLHTTPRequest using malformed URL '" + urlAsString + "'.");
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Unable to initialize XMLHTTPRequest using malformed URL '" + urlAsString + "'.");
+ }
return;
}
catch (final IllegalArgumentException e) {
- LOG.error("Unable to initialize XMLHTTPRequest using illegal argument '" + e.getMessage() + "'.");
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Unable to initialize XMLHTTPRequest using illegal argument '" + e.getMessage() + "'.");
+ }
webRequest_ = null;
}
// Async stays a boolean.
@@ -465,7 +480,7 @@ public void send(final Object body) {
// Create and start a thread in which to execute the request.
final Scriptable startingScope = w;
final ContextFactory cf = ((JavaScriptEngine) client.getJavaScriptEngine()).getContextFactory();
- final ContextAction action = new ContextAction() {
+ final ContextAction action = new ContextAction() {
@Override
public Object run(final Context cx) {
// KEY_STARTING_SCOPE maintains a stack of scopes
@@ -501,7 +516,7 @@ public Object run(final Context cx) {
* @param content the content to send
*/
private void prepareRequest(final Object content) {
- if (content != null && content != Undefined.instance) {
+ if (content != null && !Undefined.isUndefined(content)) {
if (!"".equals(content) && HttpMethod.GET == webRequest_.getHttpMethod()) {
webRequest_.setHttpMethod(HttpMethod.POST);
}
@@ -574,6 +589,9 @@ private void doSend(final Context context) {
if (LOG.isDebugEnabled()) {
LOG.debug("Web response loaded successfully.");
}
+ // this kind of web responses using UTF-8 as default encoding
+ webResponse.defaultCharsetUtf8();
+
boolean allowOriginResponse = true;
if (originHeaderValue != null) {
final String value = webResponse.getResponseHeaderValue(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN);
@@ -654,7 +672,7 @@ private static boolean isPreflightHeader(final String name, final String value)
final String lcValue = value.toLowerCase(Locale.ROOT);
return !(lcValue.startsWith(FormEncodingType.URL_ENCODED.getName())
|| lcValue.startsWith(FormEncodingType.MULTIPART.getName())
- || lcValue.startsWith("text/plain"));
+ || lcValue.startsWith(MimeType.TEXT_PLAIN));
}
return !(HttpHeader.ACCEPT_LC.equals(name)
@@ -686,8 +704,10 @@ public void setRequestHeader(final String name, final String value) {
return;
}
if (!isAuthorizedHeader(name)) {
- LOG.warn("Ignoring XMLHTTPRequest.setRequestHeader for " + name
- + ": it is a restricted header");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Ignoring XMLHTTPRequest.setRequestHeader for " + name
+ + ": it is a restricted header");
+ }
return;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLSerializer.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLSerializer.java
index 9b718429125..75d5d835d1b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLSerializer.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XMLSerializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XSLProcessor.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XSLProcessor.java
index 785fe3dfe47..869a0a3a635 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XSLProcessor.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XSLProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,7 +41,7 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter;
import com.gargoylesoftware.htmlunit.javascript.host.dom.Node;
-import com.gargoylesoftware.htmlunit.xml.XmlUtil;
+import com.gargoylesoftware.htmlunit.util.XmlUtils;
import net.sourceforge.htmlunit.corejs.javascript.Context;
@@ -210,7 +210,7 @@ private void transform(final XMLDOMNode source, final DomNode parent) {
final SgmlPage parentPage = parent.getPage();
final NodeList children = ((org.w3c.dom.Node) result).getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
- XmlUtil.appendChild(parentPage, parent, children.item(i), false);
+ XmlUtils.appendChild(parentPage, parent, children.item(i), false);
}
}
else {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XSLTemplate.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XSLTemplate.java
index 7e0c923a8e3..455d7dd81e3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XSLTemplate.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/XSLTemplate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/package-info.java
index 0b12177168f..856787efb8f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/activex/javascript/msxml/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/attachment/Attachment.java b/src/main/java/com/gargoylesoftware/htmlunit/attachment/Attachment.java
index c0f45434245..174105dd4b8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/attachment/Attachment.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/attachment/Attachment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
*/
package com.gargoylesoftware.htmlunit.attachment;
+import com.gargoylesoftware.htmlunit.HttpHeader;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.WebResponse;
@@ -24,6 +25,7 @@
* @author Bruce Chapman
* @author Sudhan Moghe
* @author Daniel Gredler
+ * @author Ronald Brill
*/
public class Attachment {
@@ -53,7 +55,7 @@ public Page getPage() {
*/
public String getSuggestedFilename() {
final WebResponse response = page_.getWebResponse();
- final String disp = response.getResponseHeaderValue("Content-Disposition");
+ final String disp = response.getResponseHeaderValue(HttpHeader.CONTENT_DISPOSITION);
int start = disp.indexOf("filename=");
if (start == -1) {
return null;
@@ -73,19 +75,4 @@ public String getSuggestedFilename() {
}
return disp.substring(start, end);
}
-
- /**
- * Returns {@code true} if the specified response represents an attachment.
- * @param response the response to check
- * @return {@code true} if the specified response represents an attachment, {@code false} otherwise
- * @see RFC 2183
- */
- public static boolean isAttachment(final WebResponse response) {
- final String disp = response.getResponseHeaderValue("Content-Disposition");
- if (disp == null) {
- return false;
- }
- return disp.startsWith("attachment");
- }
-
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.java
index afb43ecb36e..7bee2836225 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,11 @@
*/
package com.gargoylesoftware.htmlunit.attachment;
+import java.io.Serializable;
+
+import com.gargoylesoftware.htmlunit.HttpHeader;
import com.gargoylesoftware.htmlunit.Page;
+import com.gargoylesoftware.htmlunit.WebResponse;
/**
* A handler for attachments, which represent pages received from the server which contain
@@ -34,11 +38,12 @@
* @author Bruce Chapman
* @author Sudhan Moghe
* @author Daniel Gredler
+ * @author Ronald Brill
* @see com.gargoylesoftware.htmlunit.WebClient#setAttachmentHandler(AttachmentHandler)
* @see com.gargoylesoftware.htmlunit.WebClient#getAttachmentHandler()
* @see RFC 2183
*/
-public interface AttachmentHandler {
+public interface AttachmentHandler extends Serializable {
/**
* Handles the specified attached page.
@@ -46,4 +51,17 @@ public interface AttachmentHandler {
*/
void handleAttachment(Page page);
+ /**
+ * Returns {@code true} if the specified response represents an attachment.
+ * @param response the response to check
+ * @return {@code true} if the specified response represents an attachment, {@code false} otherwise
+ * @see RFC 2183
+ */
+ default boolean isAttachment(final WebResponse response) {
+ final String disp = response.getResponseHeaderValue(HttpHeader.CONTENT_DISPOSITION);
+ if (disp == null) {
+ return false;
+ }
+ return disp.startsWith("attachment");
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/attachment/CollectingAttachmentHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/attachment/CollectingAttachmentHandler.java
index 50d262a19be..060521acadd 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/attachment/CollectingAttachmentHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/attachment/CollectingAttachmentHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
* @author Bruce Chapman
* @author Sudhan Moghe
* @author Daniel Gredler
+ * @author Ronald Brill
*/
public class CollectingAttachmentHandler implements AttachmentHandler {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/attachment/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/attachment/package-info.java
index 15635131495..24d47dcf139 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/attachment/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/attachment/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/css/StyleElement.java b/src/main/java/com/gargoylesoftware/htmlunit/css/StyleElement.java
index efe41f4e0bd..5900dcdc2fa 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/css/StyleElement.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/css/StyleElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.css;
import java.io.Serializable;
+import java.util.concurrent.atomic.AtomicLong;
import com.gargoylesoftware.css.parser.selector.SelectorSpecificity;
@@ -39,7 +40,7 @@ public class StyleElement implements Comparable, Serializable {
public static final String PRIORITY_IMPORTANT = "important";
/** The current style element index. */
- private static long ElementIndex_ = 0;
+ private static final AtomicLong ElementIndex_ = new AtomicLong();
private final String name_;
private final String value_;
@@ -73,7 +74,7 @@ public StyleElement(final String name, final String value, final String priority
*/
public StyleElement(final String name, final String value, final String priority,
final SelectorSpecificity specificity) {
- this(name, value, priority, specificity, ElementIndex_++);
+ this(name, value, priority, specificity, StyleElement.ElementIndex_.incrementAndGet());
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/css/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/css/package-info.java
index b4e06fee490..f3c6c080095 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/css/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/css/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/AbstractDomNodeList.java b/src/main/java/com/gargoylesoftware/htmlunit/html/AbstractDomNodeList.java
index e885711b39e..ba6b6acb374 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/AbstractDomNodeList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/AbstractDomNodeList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/BaseFrameElement.java b/src/main/java/com/gargoylesoftware/htmlunit/html/BaseFrameElement.java
index 5e71fedc24c..5b81e4bf8a6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/BaseFrameElement.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/BaseFrameElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,9 +14,12 @@
*/
package com.gargoylesoftware.htmlunit.html;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.URL_MINIMAL_QUERY_ENCODING;
+
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
+import java.nio.charset.Charset;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
@@ -55,9 +58,9 @@ public abstract class BaseFrameElement extends HtmlElement {
private static final Log LOG = LogFactory.getLog(BaseFrameElement.class);
private FrameWindow enclosedWindow_;
- private boolean contentLoaded_ = false;
- private boolean createdByJavascript_ = false;
- private boolean loadSrcWhenAddedToPage_ = false;
+ private boolean contentLoaded_;
+ private boolean createdByJavascript_;
+ private boolean loadSrcWhenAddedToPage_;
/**
* Creates an instance of BaseFrame.
@@ -91,8 +94,7 @@ private void init() {
// put about:blank in the window to allow JS to run on this frame before the
// real content is loaded
final WebClient webClient = htmlPage.getWebClient();
- final HtmlPage temporaryPage = webClient.getPage(enclosedWindow,
- new WebRequest(WebClient.URL_ABOUT_BLANK));
+ final HtmlPage temporaryPage = webClient.getPage(enclosedWindow, WebRequest.newAboutBlankRequest());
temporaryPage.setReadyState(READY_STATE_LOADING);
}
}
@@ -123,8 +125,9 @@ public void loadInnerPage() throws FailingHttpStatusCodeException {
final Page enclosedPage = getEnclosedPage();
if (enclosedPage != null && enclosedPage.isHtmlPage()) {
final HtmlPage htmlPage = (HtmlPage) enclosedPage;
+
final AbstractJavaScriptEngine> jsEngine = getPage().getWebClient().getJavaScriptEngine();
- if (jsEngine.isScriptRunning()) {
+ if (jsEngine != null && jsEngine.isScriptRunning()) {
final PostponedAction action = new PostponedAction(getPage()) {
@Override
public void execute() throws Exception {
@@ -173,17 +176,22 @@ private void loadInnerPageIfPossible(final String src) throws FailingHttpStatusC
notifyIncorrectness("Invalid src attribute of " + getTagName() + ": url=[" + src + "]. Ignored.");
return;
}
- if (isAlreadyLoadedByAncestor(url)) {
+
+ final WebRequest request = new WebRequest(url);
+ request.setCharset(getPage().getCharset());
+ request.setAdditionalHeader(HttpHeader.REFERER, getPage().getUrl().toExternalForm());
+
+ if (isAlreadyLoadedByAncestor(url, request.getCharset())) {
notifyIncorrectness("Recursive src attribute of " + getTagName() + ": url=[" + src + "]. Ignored.");
return;
}
try {
- final WebRequest request = new WebRequest(url);
- request.setAdditionalHeader(HttpHeader.REFERER, getPage().getUrl().toExternalForm());
getPage().getEnclosingWindow().getWebClient().getPage(enclosedWindow_, request);
}
catch (final IOException e) {
- LOG.error("IOException when getting content for " + getTagName() + ": url=[" + url + "]", e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("IOException when getting content for " + getTagName() + ": url=[" + url + "]", e);
+ }
}
}
}
@@ -191,14 +199,19 @@ private void loadInnerPageIfPossible(final String src) throws FailingHttpStatusC
/**
* Test if the provided URL is the one of one of the parents which would cause an infinite loop.
* @param url the URL to test
+ * @param charset the request charset
* @return {@code false} if no parent has already this URL
*/
- private boolean isAlreadyLoadedByAncestor(final URL url) {
+ private boolean isAlreadyLoadedByAncestor(final URL url, final Charset charset) {
WebWindow window = getPage().getEnclosingWindow();
while (window != null) {
- if (UrlUtils.sameFile(url, window.getEnclosedPage().getUrl())) {
+ final URL encUrl = UrlUtils.encodeUrl(url,
+ window.getWebClient().getBrowserVersion().hasFeature(URL_MINIMAL_QUERY_ENCODING),
+ charset);
+ if (UrlUtils.sameFile(encUrl, window.getEnclosedPage().getUrl())) {
return true;
}
+
if (window == window.getParentWindow()) {
// TODO: should getParentWindow() return null on top windows?
window = null;
@@ -341,7 +354,7 @@ public FrameWindow getEnclosedWindow() {
* @param attribute the new value of the {@code src} attribute
*/
public final void setSrcAttribute(final String attribute) {
- setAttribute("src", attribute);
+ setAttribute(SRC_ATTRIBUTE, attribute);
}
/**
@@ -350,14 +363,14 @@ public final void setSrcAttribute(final String attribute) {
@Override
protected void setAttributeNS(final String namespaceURI, final String qualifiedName, String attributeValue,
final boolean notifyAttributeChangeListeners, final boolean notifyMutationObserver) {
- if (null != attributeValue && "src".equals(qualifiedName)) {
+ if (null != attributeValue && SRC_ATTRIBUTE.equals(qualifiedName)) {
attributeValue = attributeValue.trim();
}
super.setAttributeNS(namespaceURI, qualifiedName, attributeValue, notifyAttributeChangeListeners,
notifyMutationObserver);
- if ("src".equals(qualifiedName) && WebClient.ABOUT_BLANK != attributeValue) {
+ if (SRC_ATTRIBUTE.equals(qualifiedName) && WebClient.ABOUT_BLANK != attributeValue) {
if (isAttachedToPage()) {
loadSrc();
}
@@ -374,13 +387,13 @@ protected void setAttributeNS(final String namespaceURI, final String qualifiedN
public Attr setAttributeNode(final Attr attribute) {
final String qualifiedName = attribute.getName();
String attributeValue = null;
- if ("src".equals(qualifiedName)) {
+ if (SRC_ATTRIBUTE.equals(qualifiedName)) {
attributeValue = attribute.getValue().trim();
}
final Attr result = super.setAttributeNode(attribute);
- if ("src".equals(qualifiedName) && !WebClient.ABOUT_BLANK.equals(attributeValue)) {
+ if (SRC_ATTRIBUTE.equals(qualifiedName) && !WebClient.ABOUT_BLANK.equals(attributeValue)) {
if (isAttachedToPage()) {
loadSrc();
}
@@ -400,7 +413,8 @@ private void loadSrc() {
// When src is set from a script, loading is postponed until script finishes
// in fact this implementation is probably wrong: JavaScript URL should be
// first evaluated and only loading, when any, should be postponed.
- if (!jsEngine.isScriptRunning() || src.startsWith(JavaScriptURLConnection.JAVASCRIPT_PREFIX)) {
+ if (jsEngine == null || !jsEngine.isScriptRunning()
+ || src.startsWith(JavaScriptURLConnection.JAVASCRIPT_PREFIX)) {
loadInnerPageIfPossible(src);
}
else {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/CharacterDataChangeEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/html/CharacterDataChangeEvent.java
index 55b5a088bc1..7cf4d0acd57 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/CharacterDataChangeEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/CharacterDataChangeEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/CharacterDataChangeListener.java b/src/main/java/com/gargoylesoftware/htmlunit/html/CharacterDataChangeListener.java
index 1fa405ed221..a816be51a73 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/CharacterDataChangeListener.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/CharacterDataChangeListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DefaultElementFactory.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DefaultElementFactory.java
index 32a3ea24ee4..1f8eba84a60 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DefaultElementFactory.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DefaultElementFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,8 @@
import java.util.Locale;
import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;
import com.gargoylesoftware.htmlunit.BrowserVersion;
@@ -30,6 +32,8 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JavaScriptConfiguration;
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Element factory which creates elements by calling the constructor on a
* given {@link HtmlElement} subclass.
* The constructor is expected to take 2 arguments of type
@@ -38,19 +42,25 @@
* holding the initial attributes for the element.
*
* @author Christian Sell
+ * @author Marc Guillemot
* @author Ahmed Ashour
* @author David K. Taylor
+ * @author Dmitri Zoubkov
* @author Ronald Brill
* @author Frank Danek
*/
-class DefaultElementFactory implements ElementFactory {
+public class DefaultElementFactory implements ElementFactory {
+
+ /** Logging support. */
+ private static final Log LOG = LogFactory.getLog(DefaultElementFactory.class);
private static final String KEYGEN_ = "keygen";
- /*
- * You can generate your own test cases by looking into ElementTestSource.generateTestForHtmlElements
+ /**
+ * You can generate your own test cases by looking into ElementTestSource.generateTestForHtmlElements.
*/
- static final List SUPPORTED_TAGS_ = Arrays.asList(KEYGEN_, HtmlAbbreviated.TAG_NAME, HtmlAcronym.TAG_NAME,
+ public static final List SUPPORTED_TAGS_ = Arrays.asList(
+ KEYGEN_, HtmlAbbreviated.TAG_NAME, HtmlAcronym.TAG_NAME,
HtmlAnchor.TAG_NAME, HtmlAddress.TAG_NAME, HtmlApplet.TAG_NAME, HtmlArea.TAG_NAME,
HtmlArticle.TAG_NAME, HtmlAside.TAG_NAME, HtmlAudio.TAG_NAME,
HtmlBackgroundSound.TAG_NAME, HtmlBase.TAG_NAME, HtmlBaseFont.TAG_NAME,
@@ -72,7 +82,9 @@ class DefaultElementFactory implements ElementFactory {
HtmlHeading4.TAG_NAME, HtmlHeading5.TAG_NAME, HtmlHeading6.TAG_NAME,
HtmlHorizontalRule.TAG_NAME, HtmlHtml.TAG_NAME, HtmlInlineFrame.TAG_NAME,
HtmlInlineQuotation.TAG_NAME,
- HtmlImage.TAG_NAME, HtmlImage.TAG_NAME2, HtmlInsertedText.TAG_NAME, HtmlIsIndex.TAG_NAME,
+ HtmlImage.TAG_NAME, HtmlImage.TAG_NAME2,
+ HtmlInput.TAG_NAME,
+ HtmlInsertedText.TAG_NAME, HtmlIsIndex.TAG_NAME,
HtmlItalic.TAG_NAME,
HtmlKeyboard.TAG_NAME, HtmlLabel.TAG_NAME, HtmlLayer.TAG_NAME,
HtmlLegend.TAG_NAME, HtmlListing.TAG_NAME, HtmlListItem.TAG_NAME,
@@ -148,6 +160,7 @@ public HtmlElement createElementNS(final SgmlPage page, final String namespaceUR
tagName = qualifiedName.substring(colonIndex + 1).toLowerCase(Locale.ROOT);
}
+ boolean doBrowserCompatibilityCheck = checkBrowserCompatibility;
switch (tagName) {
case KEYGEN_:
final BrowserVersion browserVersion = page.getWebClient().getBrowserVersion();
@@ -232,6 +245,12 @@ else if (browserVersion.hasFeature(KEYGEN_AS_SELECT)) {
case HtmlBody.TAG_NAME:
element = new HtmlBody(qualifiedName, page, attributeMap, false);
+ // Force script object creation now to forward onXXX handlers to window.
+ if (page instanceof HtmlPage) {
+ if (page.getWebClient().isJavaScriptEngineEnabled()) {
+ element.getScriptableObject();
+ }
+ }
break;
case HtmlBold.TAG_NAME:
@@ -356,7 +375,7 @@ else if (browserVersion.hasFeature(KEYGEN_AS_SELECT)) {
case HtmlFrame.TAG_NAME:
if (attributeMap != null) {
- final DomAttr srcAttribute = attributeMap.get("src");
+ final DomAttr srcAttribute = attributeMap.get(DomElement.SRC_ATTRIBUTE);
if (srcAttribute != null) {
srcAttribute.setValue(srcAttribute.getValue().trim());
}
@@ -415,7 +434,7 @@ else if (browserVersion.hasFeature(KEYGEN_AS_SELECT)) {
case HtmlInlineFrame.TAG_NAME:
if (attributeMap != null) {
- final DomAttr srcAttribute = attributeMap.get("src");
+ final DomAttr srcAttribute = attributeMap.get(DomElement.SRC_ATTRIBUTE);
if (srcAttribute != null) {
srcAttribute.setValue(srcAttribute.getValue().trim());
}
@@ -427,6 +446,11 @@ else if (browserVersion.hasFeature(KEYGEN_AS_SELECT)) {
element = new HtmlInlineQuotation(qualifiedName, page, attributeMap);
break;
+ case HtmlInput.TAG_NAME:
+ element = createInputElement(qualifiedName, page, attributeMap);
+ doBrowserCompatibilityCheck = false;
+ break;
+
case HtmlInsertedText.TAG_NAME:
element = new HtmlInsertedText(qualifiedName, page, attributeMap);
break;
@@ -669,6 +693,7 @@ else if (browserVersion.hasFeature(KEYGEN_AS_SELECT)) {
case HtmlTableDataCell.TAG_NAME:
element = new HtmlTableDataCell(qualifiedName, page, attributeMap);
+ doBrowserCompatibilityCheck = false;
break;
case HtmlTableFooter.TAG_NAME:
@@ -681,6 +706,7 @@ else if (browserVersion.hasFeature(KEYGEN_AS_SELECT)) {
case HtmlTableHeaderCell.TAG_NAME:
element = new HtmlTableHeaderCell(qualifiedName, page, attributeMap);
+ doBrowserCompatibilityCheck = false;
break;
case HtmlTableRow.TAG_NAME:
@@ -735,10 +761,12 @@ else if (browserVersion.hasFeature(KEYGEN_AS_SELECT)) {
throw new IllegalStateException("Cannot find HtmlElement for " + qualifiedName);
}
- final JavaScriptConfiguration config = page.getWebClient().getJavaScriptEngine().getJavaScriptConfiguration();
- if (config != null && !"td".equals(tagName) && !"th".equals(tagName)
- && checkBrowserCompatibility && config.getDomJavaScriptMapping().get(element.getClass()) == null) {
- return UnknownElementFactory.instance.createElementNS(page, namespaceURI, qualifiedName, attributes);
+ if (doBrowserCompatibilityCheck) {
+ final JavaScriptConfiguration config =
+ JavaScriptConfiguration.getInstance(page.getWebClient().getBrowserVersion());
+ if (config != null && config.getDomJavaScriptMapping().get(element.getClass()) == null) {
+ return UnknownElementFactory.instance.createElementNS(page, namespaceURI, qualifiedName, attributes);
+ }
}
return element;
}
@@ -751,22 +779,138 @@ else if (browserVersion.hasFeature(KEYGEN_AS_SELECT)) {
* @return the map of attribute values for {@link HtmlElement}s
*/
static Map toMap(final SgmlPage page, final Attributes attributes) {
- Map attributeMap = null;
- if (attributes != null) {
- attributeMap = new LinkedHashMap<>(attributes.getLength());
- for (int i = 0; i < attributes.getLength(); i++) {
- final String qName = attributes.getQName(i);
- // browsers consider only first attribute (ex: ...
)
- if (!attributeMap.containsKey(qName)) {
- String namespaceURI = attributes.getURI(i);
- if (namespaceURI != null && namespaceURI.isEmpty()) {
- namespaceURI = null;
- }
- final DomAttr newAttr = new DomAttr(page, namespaceURI, qName, attributes.getValue(i), true);
- attributeMap.put(qName, newAttr);
+ if (attributes == null) {
+ return null;
+ }
+
+ final Map attributeMap = new LinkedHashMap<>(attributes.getLength());
+ for (int i = 0; i < attributes.getLength(); i++) {
+ final String qName = attributes.getQName(i);
+ // browsers consider only first attribute (ex: ...
)
+ if (!attributeMap.containsKey(qName)) {
+ String namespaceURI = attributes.getURI(i);
+ if (namespaceURI != null && namespaceURI.isEmpty()) {
+ namespaceURI = null;
}
+ final DomAttr newAttr = new DomAttr(page, namespaceURI, qName, attributes.getValue(i), true);
+ attributeMap.put(qName, newAttr);
}
}
return attributeMap;
}
+
+ private HtmlElement createInputElement(final String qualifiedName, final SgmlPage page,
+ final Map attributeMap) {
+ String type = "";
+ if (attributeMap != null) {
+ for (final Map.Entry entry : attributeMap.entrySet()) {
+ if ("type".equalsIgnoreCase(entry.getKey())) {
+ type = entry.getValue().getValue();
+ }
+ }
+ }
+
+ final HtmlInput result;
+ switch (type.toLowerCase(Locale.ROOT)) {
+ case "":
+ // This not an illegal value, as it defaults to "text"
+ // cf http://www.w3.org/TR/REC-html40/interact/forms.html#adef-type-INPUT
+ // and the common browsers seem to treat it as a "text" input so we will as well.
+ case "text":
+ result = new HtmlTextInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "submit":
+ result = new HtmlSubmitInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "checkbox":
+ result = new HtmlCheckBoxInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "radio":
+ result = new HtmlRadioButtonInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "hidden":
+ result = new HtmlHiddenInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "password":
+ result = new HtmlPasswordInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "image":
+ result = new HtmlImageInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "reset":
+ result = new HtmlResetInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "button":
+ result = new HtmlButtonInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "file":
+ result = new HtmlFileInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "color":
+ result = new HtmlColorInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "date":
+ result = new HtmlDateInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "datetime-local":
+ result = new HtmlDateTimeLocalInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "email":
+ result = new HtmlEmailInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "month":
+ result = new HtmlMonthInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "number":
+ result = new HtmlNumberInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "range":
+ result = new HtmlRangeInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "search":
+ result = new HtmlSearchInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "tel":
+ result = new HtmlTelInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "time":
+ result = new HtmlTimeInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "url":
+ result = new HtmlUrlInput(qualifiedName, page, attributeMap);
+ break;
+
+ case "week":
+ result = new HtmlWeekInput(qualifiedName, page, attributeMap);
+ break;
+
+ default:
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Bad input type: \"" + type + "\", creating a text input");
+ }
+ result = new HtmlTextInput(qualifiedName, page, attributeMap);
+ break;
+ }
+ return result;
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DisabledElement.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DisabledElement.java
index e76b6780eee..f713804063c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DisabledElement.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DisabledElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DoTypeProcessor.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DoTypeProcessor.java
index bd7fe93e86d..71985f6e6f7 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DoTypeProcessor.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DoTypeProcessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,7 +47,8 @@
import com.gargoylesoftware.htmlunit.html.impl.SelectionDelegate;
/**
- * The process for {@link HtmlElement#doType(char, boolean, boolean)}.
+ * The processor for {@link HtmlElement#doType(char, boolean)}
+ * and {@link HtmlElement#doType(int, boolean)}.
*
* @author Marc Guillemot
* @author Ronald Brill
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomAttr.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomAttr.java
index 569e169f14a..cb8f0e67b2d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomAttr.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomAttr.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomCDataSection.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomCDataSection.java
index 83083ec23e9..2f1800a5e4e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomCDataSection.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomCDataSection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomChangeEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomChangeEvent.java
index 269ae705480..42d3278469c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomChangeEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomChangeEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomChangeListener.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomChangeListener.java
index 160803d0c38..a4b0e8e4c6c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomChangeListener.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomChangeListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomCharacterData.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomCharacterData.java
index 63e153be965..ac85484bc62 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomCharacterData.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomCharacterData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomComment.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomComment.java
index 36afa0ce995..7e0ba394b92 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomComment.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomComment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -81,4 +81,12 @@ protected void printXml(final String indent, final PrintWriter printWriter) {
public String toString() {
return asXml();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPrefix(final String prefix) {
+ // Empty.
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomDocumentFragment.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomDocumentFragment.java
index 2c6ebc66e2f..65fe789c2a5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomDocumentFragment.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomDocumentFragment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,4 +75,20 @@ public String asXml() {
public boolean isAttachedToPage() {
return false;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setNodeValue(final String value) {
+ // Default behavior is to do nothing, overridden in some subclasses
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPrefix(final String prefix) {
+ // Empty.
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomDocumentType.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomDocumentType.java
index 9416865ffe7..3508fb33a04 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomDocumentType.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomDocumentType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -107,4 +107,20 @@ public String getPublicId() {
public String getSystemId() {
return systemId_;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setNodeValue(final String value) {
+ // Default behavior is to do nothing, overridden in some subclasses
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPrefix(final String prefix) {
+ // Empty.
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomElement.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomElement.java
index 177a5f96e05..e630aaa5a92 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomElement.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
@@ -54,6 +53,7 @@
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.css.StyleElement;
import com.gargoylesoftware.htmlunit.javascript.AbstractJavaScriptEngine;
+import com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory;
import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.host.css.CSSStyleSheet;
@@ -64,10 +64,6 @@
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLElement;
import com.gargoylesoftware.htmlunit.util.StringUtils;
-import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
-import net.sourceforge.htmlunit.corejs.javascript.ContextFactory;
-
/**
* @author Ahmed Ashour
* @author Marc Guillemot
@@ -78,6 +74,9 @@ public class DomElement extends DomNamespaceNode implements Element {
private static final Log LOG = LogFactory.getLog(DomElement.class);
+ /** src. */
+ public static final String SRC_ATTRIBUTE = "src";
+
/** Constant meaning that the specified attribute was not defined. */
public static final String ATTRIBUTE_NOT_DEFINED = new String("");
@@ -569,7 +568,7 @@ public void writeStyleToElement(final Map styleMap) {
final SortedSet sortedValues = new TreeSet<>(styleMap.values());
for (final StyleElement e : sortedValues) {
if (builder.length() != 0) {
- builder.append(" ");
+ builder.append(' ');
}
builder.append(e.getName());
builder.append(": ");
@@ -580,7 +579,7 @@ public void writeStyleToElement(final Map styleMap) {
builder.append(" !");
builder.append(prio);
}
- builder.append(";");
+ builder.append(';');
}
final String value = builder.toString();
setAttribute("style", value);
@@ -596,7 +595,7 @@ public DomNodeList getElementsByTagName(final String tagName) {
/**
* This should be {@link #getElementsByTagName(String)}, but is separate because of the type erasure in Java.
- * @param name The name of the tag to match on
+ * @param tagName The name of the tag to match on
* @return A list of matching elements.
*/
DomNodeList getElementsByTagNameImpl(final String tagName) {
@@ -897,6 +896,13 @@ public P click(final boolean shiftKey, final boolean ctrlKey, f
return click(shiftKey, ctrlKey, altKey, triggerMouseEvents, false, false);
}
+ /**
+ * @return true if this is an {@link DisabledElement} and disabled
+ */
+ protected boolean isDisabledElementAndDisabled() {
+ return this instanceof DisabledElement && ((DisabledElement) this).isDisabled();
+ }
+
/**
* INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
*
@@ -924,10 +930,25 @@ public
P click(final boolean shiftKey, final boolean ctrlKey, f
final SgmlPage page = getPage();
page.getWebClient().setCurrentWindow(page.getEnclosingWindow());
- if ((!ignoreVisibility && !isDisplayed())
- || !(page instanceof HtmlPage)
- || this instanceof DisabledElement && ((DisabledElement) this).isDisabled()) {
- return (P) page;
+ if (!ignoreVisibility) {
+ if (!(page instanceof HtmlPage)) {
+ return (P) page;
+ }
+
+ if (!isDisplayed()) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Calling click() ignored because the target element '" + toString()
+ + "' is not displayed.");
+ }
+ return (P) page;
+ }
+
+ if (isDisabledElementAndDisabled()) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Calling click() ignored because the target element '" + toString() + "' is disabled.");
+ }
+ return (P) page;
+ }
}
synchronized (page) {
@@ -951,20 +972,22 @@ else if (this instanceof HtmlOption) {
mouseUp(shiftKey, ctrlKey, altKey, MouseEvent.BUTTON_LEFT);
}
- final MouseEvent event;
- if (getPage().getWebClient().getBrowserVersion().hasFeature(EVENT_ONCLICK_USES_POINTEREVENT)) {
- event = new PointerEvent(getEventTargetElement(), MouseEvent.TYPE_CLICK, shiftKey,
- ctrlKey, altKey, MouseEvent.BUTTON_LEFT);
- }
- else {
- event = new MouseEvent(getEventTargetElement(), MouseEvent.TYPE_CLICK, shiftKey,
- ctrlKey, altKey, MouseEvent.BUTTON_LEFT);
- }
+ MouseEvent event = null;
+ if (page.getWebClient().isJavaScriptEnabled()) {
+ if (page.getWebClient().getBrowserVersion().hasFeature(EVENT_ONCLICK_USES_POINTEREVENT)) {
+ event = new PointerEvent(getEventTargetElement(), MouseEvent.TYPE_CLICK, shiftKey,
+ ctrlKey, altKey, MouseEvent.BUTTON_LEFT);
+ }
+ else {
+ event = new MouseEvent(getEventTargetElement(), MouseEvent.TYPE_CLICK, shiftKey,
+ ctrlKey, altKey, MouseEvent.BUTTON_LEFT);
+ }
- if (disableProcessLabelAfterBubbling) {
- event.disableProcessLabelAfterBubbling();
+ if (disableProcessLabelAfterBubbling) {
+ event.disableProcessLabelAfterBubbling();
+ }
}
- return click(event, ignoreVisibility);
+ return click(event, shiftKey, ctrlKey, altKey, ignoreVisibility);
}
}
@@ -986,20 +1009,30 @@ protected DomNode getEventTargetElement() {
* action listeners, etc.
*
* @param event the click event used
+ * @param shiftKey {@code true} if SHIFT is pressed during the click
+ * @param ctrlKey {@code true} if CTRL is pressed during the click
+ * @param altKey {@code true} if ALT is pressed during the click
* @param ignoreVisibility whether to ignore visibility or not
* @param
the page type
* @return the page contained in the current window as returned by {@link WebClient#getCurrentWindow()}
* @exception IOException if an IO error occurs
*/
@SuppressWarnings("unchecked")
- public
P click(final Event event, final boolean ignoreVisibility) throws IOException {
+ public
P click(final Event event,
+ final boolean shiftKey, final boolean ctrlKey, final boolean altKey,
+ final boolean ignoreVisibility) throws IOException {
final SgmlPage page = getPage();
- if ((!ignoreVisibility && !isDisplayed())
- || (this instanceof DisabledElement && ((DisabledElement) this).isDisabled())) {
+ if ((!ignoreVisibility && !isDisplayed()) || isDisabledElementAndDisabled()) {
return (P) page;
}
+ if (!page.getWebClient().isJavaScriptEnabled()) {
+ doClickStateUpdate(shiftKey, ctrlKey);
+ page.getWebClient().loadDownloadedResponses();
+ return (P) getPage().getWebClient().getCurrentWindow().getEnclosedPage();
+ }
+
// may be different from page when working with "orphaned pages"
// (ex: clicking a link in a page that is not active anymore)
final Page contentPage = page.getEnclosingWindow().getEnclosedPage();
@@ -1007,7 +1040,7 @@ public
P click(final Event event, final boolean ignoreVisibilit
boolean stateUpdated = false;
boolean changed = false;
if (isStateUpdateFirst()) {
- changed = doClickStateUpdate(event.isShiftKey(), event.isCtrlKey());
+ changed = doClickStateUpdate(shiftKey, ctrlKey);
stateUpdated = true;
}
@@ -1019,7 +1052,7 @@ public
P click(final Event event, final boolean ignoreVisibilit
final boolean pageAlreadyChanged = contentPage != page.getEnclosingWindow().getEnclosedPage();
if (!pageAlreadyChanged && !stateUpdated && !eventIsAborted) {
- changed = doClickStateUpdate(event.isShiftKey(), event.isCtrlKey());
+ changed = doClickStateUpdate(shiftKey, ctrlKey);
}
}
finally {
@@ -1117,7 +1150,7 @@ public
P dblClick() throws IOException {
@SuppressWarnings("unchecked")
public
P dblClick(final boolean shiftKey, final boolean ctrlKey, final boolean altKey)
throws IOException {
- if (this instanceof DisabledElement && ((DisabledElement) this).isDisabled()) {
+ if (isDisabledElementAndDisabled()) {
return (P) getPage();
}
@@ -1152,7 +1185,7 @@ public
P dblClick(final boolean shiftKey, final boolean ctrlKey
if (scriptResult == null) {
return clickPage;
}
- return (P) scriptResult.getNewPage();
+ return (P) getPage().getWebClient().getCurrentWindow().getEnclosedPage();
}
/**
@@ -1344,6 +1377,9 @@ public Page rightClick(final boolean shiftKey, final boolean ctrlKey, final bool
private Page doMouseEvent(final String eventType, final boolean shiftKey, final boolean ctrlKey,
final boolean altKey, final int button) {
final SgmlPage page = getPage();
+ if (!page.getWebClient().isJavaScriptEnabled()) {
+ return page;
+ }
final ScriptResult scriptResult;
final Event event;
@@ -1361,7 +1397,7 @@ && getPage().getWebClient().getBrowserVersion().hasFeature(EVENT_ONCLICK_USES_PO
currentPage = page;
}
else {
- currentPage = scriptResult.getNewPage();
+ currentPage = page.getWebClient().getCurrentWindow().getEnclosedPage();
}
final boolean mouseOver = !MouseEvent.TYPE_MOUSE_OUT.equals(eventType);
@@ -1383,7 +1419,10 @@ && getPage().getWebClient().getBrowserVersion().hasFeature(EVENT_ONCLICK_USES_PO
* @return the execution result, or {@code null} if nothing is executed
*/
public ScriptResult fireEvent(final String eventType) {
- return fireEvent(new Event(this, eventType));
+ if (getPage().getWebClient().isJavaScriptEnabled()) {
+ return fireEvent(new Event(this, eventType));
+ }
+ return null;
}
/**
@@ -1395,7 +1434,7 @@ public ScriptResult fireEvent(final String eventType) {
*/
public ScriptResult fireEvent(final Event event) {
final WebClient client = getPage().getWebClient();
- if (!client.getOptions().isJavaScriptEnabled()) {
+ if (!client.isJavaScriptEnabled()) {
return null;
}
@@ -1406,16 +1445,10 @@ public ScriptResult fireEvent(final Event event) {
if (LOG.isDebugEnabled()) {
LOG.debug("Firing " + event);
}
- final EventTarget jsElt = getScriptableObject();
- final ContextAction action = new ContextAction() {
- @Override
- public Object run(final Context cx) {
- return jsElt.fireEvent(event);
- }
- };
- final ContextFactory cf = ((JavaScriptEngine) client.getJavaScriptEngine()).getContextFactory();
- final ScriptResult result = (ScriptResult) cf.call(action);
+ final EventTarget jsElt = getScriptableObject();
+ final HtmlUnitContextFactory cf = ((JavaScriptEngine) client.getJavaScriptEngine()).getContextFactory();
+ final ScriptResult result = cf.callSecured(cx -> jsElt.fireEvent(event), getHtmlPageOrNull());
if (event.isAborted(result)) {
preventDefault();
}
@@ -1438,9 +1471,12 @@ protected void preventDefault() {
public void focus() {
final HtmlPage page = (HtmlPage) getPage();
page.setFocusedElement(this);
- final Object o = getScriptableObject();
- if (o instanceof HTMLElement) {
- ((HTMLElement) o).setActive();
+
+ if (page.getWebClient().isJavaScriptEnabled()) {
+ final Object o = getScriptableObject();
+ if (o instanceof HTMLElement) {
+ ((HTMLElement) o).setActive();
+ }
}
}
@@ -1509,6 +1545,14 @@ public boolean matches(final String selectorString) {
throw new CSSException("Error parsing CSS selectors from '" + selectorString + "': " + e.getMessage());
}
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setNodeValue(final String value) {
+ // Default behavior is to do nothing, overridden in some subclasses
+ }
}
/**
@@ -1516,9 +1560,11 @@ public boolean matches(final String selectorString) {
*/
class NamedAttrNodeMapImpl implements Map, NamedNodeMap, Serializable {
protected static final NamedAttrNodeMapImpl EMPTY_MAP = new NamedAttrNodeMapImpl();
+ private static final DomAttr[] EMPTY_ARRAY = new DomAttr[0];
private final Map map_ = new LinkedHashMap<>();
- private final List attrPositions_ = new ArrayList<>();
+ private boolean dirty_ = false;
+ private DomAttr[] attrPositions_ = EMPTY_ARRAY;
private final DomElement domNode_;
private final boolean caseSensitive_;
@@ -1582,10 +1628,14 @@ public Node getNamedItemNS(final String namespaceURI, final String localName) {
*/
@Override
public Node item(final int index) {
- if (index < 0 || index >= attrPositions_.size()) {
+ if (index < 0 || index >= map_.size()) {
return null;
}
- return map_.get(attrPositions_.get(index));
+ if (dirty_) {
+ attrPositions_ = map_.values().toArray(attrPositions_);
+ dirty_ = false;
+ }
+ return attrPositions_[index];
}
/**
@@ -1629,11 +1679,8 @@ public Node setNamedItemNS(final Node node) throws DOMException {
@Override
public DomAttr put(final String key, final DomAttr value) {
final String name = fixName(key);
- final DomAttr previous = map_.put(name, value);
- if (null == previous) {
- attrPositions_.add(name);
- }
- return previous;
+ dirty_ = true;
+ return map_.put(name, value);
}
/**
@@ -1643,7 +1690,7 @@ public DomAttr put(final String key, final DomAttr value) {
public DomAttr remove(final Object key) {
if (key instanceof String) {
final String name = fixName((String) key);
- attrPositions_.remove(name);
+ dirty_ = true;
return map_.remove(name);
}
return null;
@@ -1654,7 +1701,7 @@ public DomAttr remove(final Object key) {
*/
@Override
public void clear() {
- attrPositions_.clear();
+ dirty_ = true;
map_.clear();
}
@@ -1695,7 +1742,7 @@ public DomAttr get(final Object key) {
/**
* Fast access.
- * @param the key
+ * @param key the key
*/
protected DomAttr getDirect(final String key) {
return map_.get(key);
@@ -1713,7 +1760,7 @@ public boolean containsValue(final Object value) {
* {@inheritDoc}
*/
@Override
- public Set> entrySet() {
+ public Set> entrySet() {
return map_.entrySet();
}
@@ -1748,5 +1795,4 @@ public int size() {
public Collection values() {
return map_.values();
}
-
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomNamespaceNode.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomNamespaceNode.java
index fa428070224..9985a960b97 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomNamespaceNode.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomNamespaceNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.WebAssert;
-import com.gargoylesoftware.htmlunit.html.xpath.XPathUtils;
+import com.gargoylesoftware.htmlunit.html.xpath.XPathHelper;
import com.gargoylesoftware.htmlunit.javascript.host.dom.Document;
/**
@@ -70,8 +70,8 @@ protected DomNamespaceNode(final String namespaceURI, final String qualifiedName
@Override
public String getNamespaceURI() {
if (getPage().isHtmlPage() && !(getPage() instanceof XHtmlPage)
- && HTMLParser.XHTML_NAMESPACE.equals(namespaceURI_)
- && XPathUtils.isProcessingXPath()) {
+ && Html.XHTML_NAMESPACE.equals(namespaceURI_)
+ && XPathHelper.isProcessingXPath()) {
// for Xalan processing we have to strip the 'default' XHTML namespace for HTML pages to be able to find
// the elements by XPath without needing to add the namespace to it
return null;
@@ -85,7 +85,7 @@ public String getNamespaceURI() {
@Override
public String getLocalName() {
final boolean caseSensitive = getPage().hasCaseSensitiveTagNames();
- if (!caseSensitive && XPathUtils.isProcessingXPath()) { // and this method was called from Xalan
+ if (!caseSensitive && XPathHelper.isProcessingXPath()) { // and this method was called from Xalan
return localNameLC_;
}
return localName_;
@@ -137,7 +137,7 @@ public void processImportNode(final Document doc) {
// we have to drop the XHtmlNamespace because we did this already
// for the HTML document itself
final SgmlPage page = (SgmlPage) doc.getDomNodeOrDie();
- if (page.isHtmlPage() && !(page instanceof XHtmlPage) && HTMLParser.XHTML_NAMESPACE.equals(namespaceURI_)) {
+ if (page.isHtmlPage() && !(page instanceof XHtmlPage) && Html.XHTML_NAMESPACE.equals(namespaceURI_)) {
namespaceURI_ = null;
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomNode.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomNode.java
index 418f050476c..a6b47662bbc 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomNode.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,12 +16,13 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.DOM_NORMALIZE_REMOVE_CHILDREN;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.QUERYSELECTORALL_NOT_IN_QUIRKS;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.XPATH_ATTRIBUTE_CASE_SENSITIVE;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.XPATH_SELECTION_NAMESPACES;
import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.io.Serializable;
-import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
@@ -44,7 +45,6 @@
import com.gargoylesoftware.css.parser.CSSException;
import com.gargoylesoftware.css.parser.CSSOMParser;
import com.gargoylesoftware.css.parser.CSSParseException;
-import com.gargoylesoftware.css.parser.InputSource;
import com.gargoylesoftware.css.parser.javacc.CSS3Parser;
import com.gargoylesoftware.css.parser.selector.Selector;
import com.gargoylesoftware.css.parser.selector.SelectorList;
@@ -56,7 +56,7 @@
import com.gargoylesoftware.htmlunit.WebAssert;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlElement.DisplayStyle;
-import com.gargoylesoftware.htmlunit.html.xpath.XPathUtils;
+import com.gargoylesoftware.htmlunit.html.xpath.XPathHelper;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.host.css.CSSStyleDeclaration;
import com.gargoylesoftware.htmlunit.javascript.host.css.CSSStyleSheet;
@@ -170,7 +170,7 @@ public abstract class DomNode implements Cloneable, Serializable, Node {
private boolean attachedToPage_;
- private final Object listeners_lock_ = new Serializable() { };
+ private transient Object listeners_lock_ = new Object();
/** The listeners which are to be notified of characterData change. */
private Collection characterDataListeners_;
@@ -195,7 +195,7 @@ protected DomNode(final SgmlPage page) {
* @param startLineNumber the line number where the DOM node starts
* @param startColumnNumber the column number where the DOM node starts
*/
- void setStartLocation(final int startLineNumber, final int startColumnNumber) {
+ public void setStartLocation(final int startLineNumber, final int startColumnNumber) {
startLineNumber_ = startLineNumber;
startColumnNumber_ = startColumnNumber;
}
@@ -206,7 +206,7 @@ void setStartLocation(final int startLineNumber, final int startColumnNumber) {
* @param endLineNumber the line number where the DOM node ends
* @param endColumnNumber the column number where the DOM node ends
*/
- void setEndLocation(final int endLineNumber, final int endColumnNumber) {
+ public void setEndLocation(final int endLineNumber, final int endColumnNumber) {
endLineNumber_ = endLineNumber;
endColumnNumber_ = endColumnNumber;
}
@@ -388,8 +388,12 @@ protected void setPreviousSibling(final DomNode previous) {
previousSibling_ = previous;
}
- /** @param next set the nextSibling field value */
- protected void setNextSibling(final DomNode next) {
+ /**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
+ * @param next set the nextSibling field value
+ */
+ public void setNextSibling(final DomNode next) {
nextSibling_ = next;
}
@@ -431,14 +435,6 @@ public String getPrefix() {
return null;
}
- /**
- * {@inheritDoc}
- */
- @Override
- public void setPrefix(final String prefix) {
- // Empty.
- }
-
/**
* {@inheritDoc}
*/
@@ -559,10 +555,12 @@ public short compareDocumentPosition(final Node other) {
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Gets the ancestors of the node.
* @return a list of the ancestors with the root at the first position
*/
- protected List getAncestors() {
+ public List getAncestors() {
final List list = new ArrayList<>();
list.add(this);
@@ -739,20 +737,22 @@ public boolean isDisplayed() {
return false;
}
- final HtmlPage htmlPage = getHtmlPageOrNull();
- if (htmlPage != null && htmlPage.getEnclosingWindow().getWebClient().getOptions().isCssEnabled()) {
+ final Page page = getPage();
+ final WebClient webClient = page.getEnclosingWindow().getWebClient();
+ if (webClient.getOptions().isCssEnabled() && webClient.isJavaScriptEnabled()) {
// 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();
final ArrayList styles = new ArrayList<>(ancestors.size());
for (final Node node : ancestors) {
+ if (node instanceof HtmlElement && ((HtmlElement) node).isHidden()) {
+ return false;
+ }
+
final Object scriptableObject = ((DomNode) node).getScriptableObject();
if (scriptableObject instanceof HTMLElement) {
final HTMLElement elem = (HTMLElement) scriptableObject;
- if (elem.isHidden()) {
- return false;
- }
final CSSStyleDeclaration style = elem.getWindow().getComputedStyle(elem, null);
if (DisplayStyle.NONE.value().equals(style.getDisplay())) {
return false;
@@ -808,6 +808,21 @@ public String asText() {
return ser.asText(this);
}
+ /**
+ * Returns a textual representation of this element in the same way as
+ * the selenium/WebDriver WebElement#getText() property does.
+ * see https://w3c.github.io/webdriver/#get-element-text and
+ * https://w3c.github.io/webdriver/#dfn-bot-dom-getvisibletext
+ * Note: this is different from asText
+ *
+ * @return a textual representation of this element that represents what would
+ * be visible to the user if this page was shown in a web browser
+ */
+ public String getVisibleText() {
+ final HtmlSerializerVisibleText ser = new HtmlSerializerVisibleText();
+ return ser.asText(this);
+ }
+
/**
* Returns a string representation of the XML document from this element and all it's children (recursively).
* The charset used is the current page encoding.
@@ -867,14 +882,6 @@ public String getNodeValue() {
return null;
}
- /**
- * {@inheritDoc}
- */
- @Override
- public void setNodeValue(final String value) {
- // Default behavior is to do nothing, overridden in some subclasses
- }
-
/**
* {@inheritDoc}
*/
@@ -925,7 +932,7 @@ public T getScriptableObject() {
// because this is a strange case we like to provide as many info as possible
msg.append(" class: '");
msg.append(page.getClass().getName());
- msg.append("'");
+ msg.append('\'');
try {
msg.append(" url: '").append(page.getUrl()).append('\'');
msg.append(" content: ");
@@ -1185,6 +1192,10 @@ else if (previousSibling_ != null && previousSibling_.nextSibling_ == this) {
nextSibling_ = null;
previousSibling_ = null;
parent_ = null;
+ attachedToPage_ = false;
+ for (DomNode descendant : getDescendants()) {
+ descendant.attachedToPage_ = false;
+ }
}
private void fireRemoval(final DomNode exParent) {
@@ -1234,13 +1245,15 @@ public void replace(final DomNode newNode) {
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Quietly removes this node and moves its children to the specified destination. "Quietly" means
* that no node events are fired. This method is not appropriate for most use cases. It should
* only be used in specific cases for HTML parsing hackery.
*
* @param destination the node to which this node's children should be moved before this node is removed
*/
- void quietlyRemoveAndMoveChildrenTo(final DomNode destination) {
+ public void quietlyRemoveAndMoveChildrenTo(final DomNode destination) {
if (destination.getPage() != getPage()) {
throw new RuntimeException("Cannot perform quiet move on nodes from different pages.");
}
@@ -1301,7 +1314,7 @@ protected void onAddedToPage() {
* super.onAllChildrenAddedToPage() if you implement this method.
* @param postponed whether to use {@link com.gargoylesoftware.htmlunit.javascript.PostponedAction} or no
*/
- protected void onAllChildrenAddedToPage(final boolean postponed) {
+ public void onAllChildrenAddedToPage(final boolean postponed) {
// Empty by default.
}
@@ -1332,7 +1345,7 @@ public final Iterable getChildren() {
protected class ChildIterator implements Iterator {
private DomNode nextNode_ = firstChild_;
- private DomNode currentNode_ = null;
+ private DomNode currentNode_;
/** {@inheritDoc} */
@Override
@@ -1543,6 +1556,11 @@ else if (tok.startsWith("xmlns:")) {
/**
* Evaluates the specified XPath expression from this node, returning the matching elements.
+ *
+ * Note: This implies that the ',' point to this node but the general axis like '//' are still
+ * looking at the whole document. E.g. if you like to get all child h1 nodes from the current one
+ * you have to use './/h1' instead of '//h1' because the later matches all h1 nodes of the#
+ * whole document.
*
* @param the expected type
* @param xpathExpr the XPath expression to evaluate
@@ -1592,7 +1610,7 @@ public boolean handlesNullPrefixes() {
}
}
}
- return XPathUtils.getByXPath(this, xpathExpr, prefixResolver);
+ return XPathHelper.getByXPath(this, xpathExpr, prefixResolver, hasFeature(XPATH_ATTRIBUTE_CASE_SENSITIVE));
}
/**
@@ -1605,7 +1623,7 @@ public boolean handlesNullPrefixes() {
* @see #getCanonicalXPath()
*/
public List> getByXPath(final String xpathExpr, final PrefixResolver resolver) {
- return XPathUtils.getByXPath(this, xpathExpr, resolver);
+ return XPathHelper.getByXPath(this, xpathExpr, resolver, hasFeature(XPATH_ATTRIBUTE_CASE_SENSITIVE));
}
/**
@@ -1866,7 +1884,7 @@ protected SelectorList getSelectorList(final String selectors, final BrowserVers
final CheckErrorHandler errorHandler = new CheckErrorHandler();
parser.setErrorHandler(errorHandler);
- final SelectorList selectorList = parser.parseSelectors(new InputSource(new StringReader(selectors)));
+ final SelectorList selectorList = parser.parseSelectors(selectors);
// in case of error parseSelectors returns null
if (errorHandler.errorDetected()) {
throw new CSSException("Invalid selectors: " + selectors);
@@ -1921,7 +1939,7 @@ public boolean isAttachedToPage() {
* @see HtmlScript#processImportNode(com.gargoylesoftware.htmlunit.javascript.host.dom.Document)
*/
public void processImportNode(final com.gargoylesoftware.htmlunit.javascript.host.dom.Document doc) {
- // empty default impl
+ page_ = (SgmlPage) doc.getDomNodeOrDie();
}
/**
@@ -2000,4 +2018,8 @@ public DomElement getNextElementSibling() {
return (DomElement) node;
}
+ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ listeners_lock_ = new Object();
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomNodeIterator.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomNodeIterator.java
index a0b70063076..2ea9385b6c4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomNodeIterator.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomNodeIterator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -191,12 +191,12 @@ private boolean isAccepted(final Node node) {
* traversal) from the given node.
*/
private DomNode getFirstUncleNode(final DomNode node) {
- if (node == root_ || node == null) {
+ if (node == null || node == root_) {
return null;
}
final DomNode parent = node.getParentNode();
- if (parent == null) {
+ if (parent == null || parent == root_) {
return null;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomNodeList.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomNodeList.java
index baee57ba2fd..bd29e5a11be 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomNodeList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomNodeList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomProcessingInstruction.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomProcessingInstruction.java
index b1bc57a1947..bca4d2c3452 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomProcessingInstruction.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomProcessingInstruction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -121,4 +121,11 @@ protected void printXml(final String indent, final PrintWriter printWriter) {
printWriter.print("?>");
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPrefix(final String prefix) {
+ // Empty.
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomText.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomText.java
index 308f0dbc3b0..f1ba47b7a9e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomText.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomText.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -168,16 +168,11 @@ protected boolean isTrimmedText() {
/**
* Performs the effective type action, called after the keyPress event and before the keyUp event.
* @param c the character you with to simulate typing
- * @param startAtEnd whether typing should start at the text end or not
* @param htmlElement the element in which typing occurs
* @param lastType is this the last character to type
*/
- protected void doType(final char c, final boolean startAtEnd, final HtmlElement htmlElement,
- final boolean lastType) {
+ protected void doType(final char c, final HtmlElement htmlElement, final boolean lastType) {
initDoTypeProcessor();
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getData().length());
- }
doTypeProcessor_.doType(getData(), selectionDelegate_, c, htmlElement, lastType);
}
@@ -185,16 +180,11 @@ protected void doType(final char c, final boolean startAtEnd, final HtmlElement
* Performs the effective type action, called after the keyPress event and before the keyUp event.
*
* @param keyCode the key code wish to simulate typing
- * @param startAtEnd whether typing should start at the text end or not
* @param htmlElement the element in which typing occurs
* @param lastType is this the last character to type
*/
- protected void doType(final int keyCode, final boolean startAtEnd, final HtmlElement htmlElement,
- final boolean lastType) {
+ protected void doType(final int keyCode, final HtmlElement htmlElement, final boolean lastType) {
initDoTypeProcessor();
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getData().length());
- }
doTypeProcessor_.doType(getData(), selectionDelegate_, keyCode, htmlElement, lastType);
}
@@ -227,4 +217,20 @@ public DomNode cloneNode(final boolean deep) {
return newnode;
}
+
+ /**
+ * Moves the selection to the end.
+ */
+ public void moveSelectionToEnd() {
+ initDoTypeProcessor();
+ selectionDelegate_.setSelectionStart(getData().length());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPrefix(final String prefix) {
+ // Empty.
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/DomTreeWalker.java b/src/main/java/com/gargoylesoftware/htmlunit/html/DomTreeWalker.java
index 55e463eaecb..04c097f2713 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/DomTreeWalker.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/DomTreeWalker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/ElementFactory.java b/src/main/java/com/gargoylesoftware/htmlunit/html/ElementFactory.java
index cbbbc775f21..b66689b1b60 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/ElementFactory.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/ElementFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/ElementFromPointHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/html/ElementFromPointHandler.java
index 9b433213d06..d09c5f46fcf 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/ElementFromPointHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/ElementFromPointHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/FormFieldWithNameHistory.java b/src/main/java/com/gargoylesoftware/htmlunit/html/FormFieldWithNameHistory.java
index 15c6c0b3a3b..dad9b4487b0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/FormFieldWithNameHistory.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/FormFieldWithNameHistory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/FrameWindow.java b/src/main/java/com/gargoylesoftware/htmlunit/html/FrameWindow.java
index 33d04398041..4fca6e1d724 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/FrameWindow.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/FrameWindow.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,8 +37,9 @@ public class FrameWindow extends WebWindowImpl {
FrameWindow(final BaseFrameElement frame) {
super(frame.getPage().getWebClient());
frame_ = frame;
- final WebWindowImpl parent = (WebWindowImpl) getParentWindow();
performRegistration();
+
+ final WebWindowImpl parent = (WebWindowImpl) frame_.getPage().getEnclosingWindow();
parent.addChildWindow(this);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HTMLParser.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HTMLParser.java
deleted file mode 100644
index 422fdb872fa..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HTMLParser.java
+++ /dev/null
@@ -1,1058 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.html;
-
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTML_ATTRIBUTE_LOWER_CASE;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTML_COMMAND_TAG;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTML_ISINDEX_TAG;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTML_MAIN_TAG;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.KEYGEN_AS_SELECT;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.META_X_UA_COMPATIBLE;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.PAGE_WAIT_LOAD_BEFORE_BODY;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringReader;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URL;
-import java.nio.charset.Charset;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.xerces.parsers.AbstractSAXParser;
-import org.apache.xerces.util.DefaultErrorHandler;
-import org.apache.xerces.xni.Augmentations;
-import org.apache.xerces.xni.QName;
-import org.apache.xerces.xni.XMLAttributes;
-import org.apache.xerces.xni.XNIException;
-import org.apache.xerces.xni.parser.XMLInputSource;
-import org.apache.xerces.xni.parser.XMLParseException;
-import org.apache.xerces.xni.parser.XMLParserConfiguration;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.ext.LexicalHandler;
-
-import com.gargoylesoftware.htmlunit.BrowserVersion;
-import com.gargoylesoftware.htmlunit.ObjectInstantiationException;
-import com.gargoylesoftware.htmlunit.Page;
-import com.gargoylesoftware.htmlunit.SgmlPage;
-import com.gargoylesoftware.htmlunit.WebAssert;
-import com.gargoylesoftware.htmlunit.WebClient;
-import com.gargoylesoftware.htmlunit.WebResponse;
-import com.gargoylesoftware.htmlunit.WebWindow;
-import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLBodyElement;
-import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument;
-import com.gargoylesoftware.htmlunit.svg.SvgElementFactory;
-
-import net.sourceforge.htmlunit.cyberneko.HTMLConfiguration;
-import net.sourceforge.htmlunit.cyberneko.HTMLElements;
-import net.sourceforge.htmlunit.cyberneko.HTMLEventInfo;
-import net.sourceforge.htmlunit.cyberneko.HTMLScanner;
-import net.sourceforge.htmlunit.cyberneko.HTMLTagBalancer;
-import net.sourceforge.htmlunit.cyberneko.HTMLTagBalancingListener;
-
-/**
- * SAX parser implementation that uses the NekoHTML {@link net.sourceforge.htmlunit.cyberneko.HTMLConfiguration}
- * to parse HTML into a HtmlUnit-specific DOM (HU-DOM) tree.
- *
- * @author Christian Sell
- * @author David K. Taylor
- * @author Chris Erskine
- * @author Ahmed Ashour
- * @author Marc Guillemot
- * @author Ethan Glasser-Camp
- * @author Sudhan Moghe
- * @author Ronald Brill
- * @author Frank Danek
- * @author Carsten Steul
- */
-public final class HTMLParser {
-
- /** XHTML namespace. */
- public static final String XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
-
- /** SVG namespace. */
- public static final String SVG_NAMESPACE = "http://www.w3.org/2000/svg";
-
- /**
- * The SVG factory.
- */
- public static final SvgElementFactory SVG_FACTORY = new SvgElementFactory();
-
- private static final Map ELEMENT_FACTORIES = new HashMap<>();
-
- static {
- ELEMENT_FACTORIES.put(HtmlInput.TAG_NAME, InputElementFactory.instance);
-
- final DefaultElementFactory defaultElementFactory = new DefaultElementFactory();
- for (final String tagName : DefaultElementFactory.SUPPORTED_TAGS_) {
- ELEMENT_FACTORIES.put(tagName, defaultElementFactory);
- }
- }
-
- /**
- * You should never need to create one of these!
- */
- private HTMLParser() {
- // Empty.
- }
-
- /**
- * Parses the HTML content from the given string into an object tree representation.
- *
- * @param parent the parent for the new nodes
- * @param source the (X)HTML to be parsed
- * @throws SAXException if a SAX error occurs
- * @throws IOException if an IO error occurs
- */
- public static void parseFragment(final DomNode parent, final String source) throws SAXException, IOException {
- parseFragment(parent, parent, source);
- }
-
- /**
- * Parses the HTML content from the given string into an object tree representation.
- *
- * @param parent where the new parsed nodes will be added to
- * @param context the context to build the fragment context stack
- * @param source the (X)HTML to be parsed
- * @throws SAXException if a SAX error occurs
- * @throws IOException if an IO error occurs
- */
- public static void parseFragment(final DomNode parent, final DomNode context, final String source)
- throws SAXException, IOException {
- final Page page = parent.getPage();
- if (!(page instanceof HtmlPage)) {
- return;
- }
- final HtmlPage htmlPage = (HtmlPage) page;
- final URL url = htmlPage.getUrl();
-
- final HtmlUnitDOMBuilder domBuilder = new HtmlUnitDOMBuilder(parent, url, source);
- domBuilder.setFeature("http://cyberneko.org/html/features/balance-tags/document-fragment", true);
- // build fragment context stack
- DomNode node = context;
- final List ancestors = new ArrayList<>();
- while (node != null && node.getNodeType() != Node.DOCUMENT_NODE) {
- ancestors.add(0, new QName(null, node.getNodeName(), null, null));
- node = node.getParentNode();
- }
- if (ancestors.isEmpty() || !"html".equals(ancestors.get(0).localpart)) {
- ancestors.add(0, new QName(null, "html", null, null));
- }
- if (ancestors.size() == 1 || !"body".equals(ancestors.get(1).localpart)) {
- ancestors.add(1, new QName(null, "body", null, null));
- }
-
- domBuilder.setFeature(HTMLScanner.ALLOW_SELFCLOSING_TAGS, true);
- domBuilder.setProperty(HTMLTagBalancer.FRAGMENT_CONTEXT_STACK, ancestors.toArray(new QName[] {}));
-
- final XMLInputSource in = new XMLInputSource(null, url.toString(), null, new StringReader(source), null);
-
- htmlPage.registerParsingStart();
- htmlPage.registerSnippetParsingStart();
- try {
- domBuilder.parse(in);
- }
- finally {
- htmlPage.registerParsingEnd();
- htmlPage.registerSnippetParsingEnd();
- }
- }
-
- /**
- * Parses the HTML content from the specified WebResponse into an object tree representation.
- *
- * @param webResponse the response data
- * @param webWindow the web window into which the page is to be loaded
- * @return the page object which is the root of the DOM tree
- * @throws IOException if there is an IO error
- */
- public static HtmlPage parseHtml(final WebResponse webResponse, final WebWindow webWindow) throws IOException {
- final HtmlPage page = new HtmlPage(webResponse, webWindow);
- parse(webResponse, webWindow, page, false);
- return page;
- }
-
- /**
- * Parses the XHTML content from the specified WebResponse into an object tree representation.
- *
- * @param webResponse the response data
- * @param webWindow the web window into which the page is to be loaded
- * @return the page object which is the root of the DOM tree
- * @throws IOException if there is an IO error
- */
- public static XHtmlPage parseXHtml(final WebResponse webResponse, final WebWindow webWindow) throws IOException {
- final XHtmlPage page = new XHtmlPage(webResponse, webWindow);
- parse(webResponse, webWindow, page, true);
- return page;
- }
-
- private static void parse(final WebResponse webResponse, final WebWindow webWindow, final HtmlPage page,
- final boolean xhtml)
- throws IOException {
-
- webWindow.setEnclosedPage(page);
-
- final URL url = webResponse.getWebRequest().getUrl();
- final HtmlUnitDOMBuilder domBuilder = new HtmlUnitDOMBuilder(page, url, null);
-
- Charset charset = webResponse.getContentCharsetOrNull();
- try {
- // handle charset
- if (charset == null) {
- final Charset specifiedCharset = webResponse.getWebRequest().getCharset();
- if (specifiedCharset != null) {
- charset = specifiedCharset;
- }
- }
- else {
- domBuilder.setFeature(HTMLScanner.IGNORE_SPECIFIED_CHARSET, true);
- }
-
- // xml content is different
- if (xhtml) {
- domBuilder.setFeature(HTMLScanner.ALLOW_SELFCLOSING_TAGS, true);
- }
- }
- catch (final Exception e) {
- throw new ObjectInstantiationException("Error setting HTML parser feature", e);
- }
-
- try (InputStream content = webResponse.getContentAsStream()) {
- String encoding = null;
- if (charset != null) {
- encoding = charset.name();
- }
- final XMLInputSource in = new XMLInputSource(null, url.toString(), null, content, encoding);
-
- page.registerParsingStart();
- try {
- domBuilder.parse(in);
- }
- catch (final XNIException e) {
- // extract enclosed exception
- final Throwable origin = extractNestedException(e);
- throw new RuntimeException("Failed parsing content from " + url, origin);
- }
- }
- finally {
- page.registerParsingEnd();
- }
-
- addBodyToPageIfNecessary(page, true, domBuilder.body_ != null);
- }
-
- /**
- * Adds a body element to the current page, if necessary. Strictly speaking, this should
- * probably be done by NekoHTML. See the bug linked below. If and when that bug is fixed,
- * we may be able to get rid of this code.
- *
- * http://sourceforge.net/p/nekohtml/bugs/15/
- * @param page
- * @param originalCall
- * @param checkInsideFrameOnly true if the original page had body that was removed by JavaScript
- */
- private static void addBodyToPageIfNecessary(
- final HtmlPage page, final boolean originalCall, final boolean checkInsideFrameOnly) {
- // IE waits for the whole page to load before initializing bodies for frames.
- final boolean waitToLoad = page.hasFeature(PAGE_WAIT_LOAD_BEFORE_BODY);
- if (page.getEnclosingWindow() instanceof FrameWindow && originalCall && waitToLoad) {
- return;
- }
-
- // Find out if the document already has a body element (or frameset).
- final Element doc = page.getDocumentElement();
- boolean hasBody = false;
- for (Node child = doc.getFirstChild(); child != null; child = child.getNextSibling()) {
- if (child instanceof HtmlBody || child instanceof HtmlFrameSet) {
- hasBody = true;
- break;
- }
- }
-
- // If the document does not have a body, add it.
- if (!hasBody && !checkInsideFrameOnly) {
- final HtmlBody body = new HtmlBody("body", page, null, false);
- doc.appendChild(body);
- }
-
- // If this is IE, we need to initialize the bodies of any frames, as well.
- // This will already have been done when emulating FF (see above).
- if (waitToLoad) {
- for (final FrameWindow frame : page.getFrames()) {
- final Page containedPage = frame.getEnclosedPage();
- if (containedPage != null && containedPage.isHtmlPage()) {
- addBodyToPageIfNecessary((HtmlPage) containedPage, false, false);
- }
- }
- }
- }
-
- /**
- * Extract nested exception within an XNIException (Nekohtml uses reflection and generated
- * exceptions are wrapped many times within XNIException and InvocationTargetException)
- *
- * @param e the original XNIException
- * @return the cause exception
- */
- static Throwable extractNestedException(final Throwable e) {
- Throwable originalException = e;
- Throwable cause = ((XNIException) e).getException();
- while (cause != null) {
- originalException = cause;
- if (cause instanceof XNIException) {
- cause = ((XNIException) cause).getException();
- }
- else if (cause instanceof InvocationTargetException) {
- cause = cause.getCause();
- }
- else {
- cause = null;
- }
- }
- return originalException;
- }
-
- /**
- * @param tagName an HTML element tag name
- * @return a factory for creating HtmlElements representing the given tag
- */
- public static ElementFactory getFactory(final String tagName) {
- final ElementFactory result = ELEMENT_FACTORIES.get(tagName);
-
- if (result != null) {
- return result;
- }
- return UnknownElementFactory.instance;
- }
-
- /**
- * Returns the pre-registered element factory corresponding to the specified tag, or an UnknownElementFactory.
- * @param page the page
- * @param namespaceURI the namespace URI
- * @param qualifiedName the qualified name
- * @param insideSvg is the node inside an SVG node or not
- * @param svgSupport true if called from javascript createElementNS
- * @return the pre-registered element factory corresponding to the specified tag, or an UnknownElementFactory
- */
- static ElementFactory getElementFactory(final SgmlPage page, final String namespaceURI,
- final String qualifiedName, final boolean insideSvg, final boolean svgSupport) {
- if (insideSvg) {
- return SVG_FACTORY;
- }
-
- if (namespaceURI == null || namespaceURI.isEmpty()
- || XHTML_NAMESPACE.equals(namespaceURI)
- || SVG_NAMESPACE.equals(namespaceURI)
- || !qualifiedName.contains(":")) {
-
- String tagName = qualifiedName;
- final int index = tagName.indexOf(':');
- if (index == -1) {
- tagName = tagName.toLowerCase(Locale.ROOT);
- }
- else {
- tagName = tagName.substring(index + 1);
- }
- final ElementFactory factory;
- if (svgSupport && !"svg".equals(tagName) && SVG_NAMESPACE.equals(namespaceURI)) {
- factory = SVG_FACTORY;
- }
- else {
- factory = ELEMENT_FACTORIES.get(tagName);
- }
-
- if (factory != null) {
- return factory;
- }
- }
- return UnknownElementFactory.instance;
- }
-
- /**
- * The parser and DOM builder. This class subclasses Xerces's AbstractSAXParser and implements
- * the ContentHandler interface. Thus all parser APIs are kept private. The ContentHandler methods
- * consume SAX events to build the page DOM
- */
- static final class HtmlUnitDOMBuilder extends AbstractSAXParser
- implements ContentHandler, LexicalHandler, HTMLTagBalancingListener {
-
- private enum HeadParsed { YES, SYNTHESIZED, NO }
-
- private final HtmlPage page_;
-
- private Locator locator_;
- private final Deque stack_ = new ArrayDeque<>();
-
- /** Did the snippet tried to overwrite the start node? */
- private boolean snippetStartNodeOverwritten_;
- private final int initialSize_;
- private DomNode currentNode_;
- private StringBuilder characters_;
- private HeadParsed headParsed_ = HeadParsed.NO;
- private HtmlElement body_;
- private boolean lastTagWasSynthesized_;
- private HtmlForm formWaitingForLostChildren_;
- private boolean insideSvg_;
-
- private static final String FEATURE_AUGMENTATIONS = "http://cyberneko.org/html/features/augmentations";
- private static final String FEATURE_PARSE_NOSCRIPT
- = "http://cyberneko.org/html/features/parse-noscript-content";
-
- /**
- * Parses and then inserts the specified HTML content into the HTML content currently being parsed.
- * @param html the HTML content to push
- */
- public void pushInputString(final String html) {
- page_.registerParsingStart();
- page_.registerInlineSnippetParsingStart();
- try {
- final WebResponse webResponse = page_.getWebResponse();
- final Charset charset = webResponse.getContentCharset();
- final String url = webResponse.getWebRequest().getUrl().toString();
- final XMLInputSource in = new XMLInputSource(null, url, null, new StringReader(html), charset.name());
- ((HTMLConfiguration) fConfiguration).evaluateInputSource(in);
- }
- finally {
- page_.registerParsingEnd();
- page_.registerInlineSnippetParsingEnd();
- }
- }
-
- /**
- * Creates a new builder for parsing the specified response contents.
- * @param node the location at which to insert the new content
- * @param url the page's URL
- */
- private HtmlUnitDOMBuilder(final DomNode node, final URL url, final String htmlContent) {
- super(createConfiguration(node.getPage().getWebClient().getBrowserVersion()));
-
- page_ = (HtmlPage) node.getPage();
-
- currentNode_ = node;
- for (final Node ancestor : currentNode_.getAncestors()) {
- stack_.push((DomNode) ancestor);
- }
-
- final WebClient webClient = page_.getWebClient();
- final HTMLParserListener listener = webClient.getHTMLParserListener();
- final boolean reportErrors = listener != null;
- if (reportErrors) {
- fConfiguration.setErrorHandler(new HTMLErrorHandler(listener, url, htmlContent));
- }
-
- try {
- setFeature(FEATURE_AUGMENTATIONS, true);
- setProperty("http://cyberneko.org/html/properties/names/elems", "default");
- if (!webClient.getBrowserVersion().hasFeature(HTML_ATTRIBUTE_LOWER_CASE)) {
- setProperty("http://cyberneko.org/html/properties/names/attrs", "no-change");
- }
- setFeature("http://cyberneko.org/html/features/report-errors", reportErrors);
- setFeature(FEATURE_PARSE_NOSCRIPT, !webClient.getOptions().isJavaScriptEnabled());
- setFeature(HTMLScanner.ALLOW_SELFCLOSING_IFRAME, false);
-
- setContentHandler(this);
- setLexicalHandler(this); //comments and CDATA
- }
- catch (final SAXException e) {
- throw new ObjectInstantiationException("unable to create HTML parser", e);
- }
- initialSize_ = stack_.size();
- }
-
- /**
- * Create the configuration depending on the simulated browser
- * @param webClient the current WebClient
- * @return the configuration
- */
- private static XMLParserConfiguration createConfiguration(final BrowserVersion browserVersion) {
- final HTMLConfiguration configuration = new HTMLConfiguration();
- if (browserVersion.hasFeature(HTML_COMMAND_TAG)) {
- configuration.htmlElements_.setElement(new HTMLElements.Element(HTMLElements.COMMAND, "COMMAND",
- HTMLElements.Element.EMPTY, HTMLElements.BODY, null));
- }
- if (browserVersion.hasFeature(HTML_ISINDEX_TAG)) {
- configuration.htmlElements_.setElement(new HTMLElements.Element(HTMLElements.ISINDEX, "ISINDEX",
- HTMLElements.Element.INLINE, HTMLElements.BODY, null));
- }
- if (browserVersion.hasFeature(HTML_MAIN_TAG)) {
- configuration.htmlElements_.setElement(new HTMLElements.Element(HTMLElements.MAIN, "MAIN",
- HTMLElements.Element.INLINE, HTMLElements.BODY, null));
- }
-
- return configuration;
- }
-
- /**
- * @return the document locator
- */
- public Locator getLocator() {
- return locator_;
- }
-
- /** {@inheritDoc ContentHandler#setDocumentLocator} */
- @Override
- public void setDocumentLocator(final Locator locator) {
- locator_ = locator;
- }
-
- /** {@inheritDoc ContentHandler#startDocument()} */
- @Override
- public void startDocument() throws SAXException {
- }
-
- /** {@inheritDoc} */
- @Override
- public void startElement(final QName element, final XMLAttributes attributes, final Augmentations augs)
- throws XNIException {
- // augs might change so we store only the interesting part
- lastTagWasSynthesized_ = isSynthesized(augs);
- super.startElement(element, attributes, augs);
- }
-
- /** {@inheritDoc ContentHandler#startElement(String,String,String,Attributes)} */
- @Override
- public void startElement(String namespaceURI, final String localName, String qName, final Attributes atts)
- throws SAXException {
-
- if (snippetStartNodeOverwritten_) {
- snippetStartNodeOverwritten_ = false;
- return;
- }
- handleCharacters();
-
- String tagLower = localName.toLowerCase(Locale.ROOT);
- if (page_.isParsingHtmlSnippet() && ("html".equals(tagLower) || "body".equals(tagLower))) {
- return;
- }
-
- if ("head".equals(tagLower)) {
- if (headParsed_ == HeadParsed.YES || page_.isParsingHtmlSnippet()) {
- return;
- }
-
- headParsed_ = lastTagWasSynthesized_ ? HeadParsed.SYNTHESIZED : HeadParsed.YES;
- }
-
- if (namespaceURI != null) {
- namespaceURI = namespaceURI.trim();
- }
-
- // add a head if none was there
- else if (headParsed_ == HeadParsed.NO && ("body".equals(tagLower) || "frameset".equals(tagLower))) {
- final ElementFactory factory = getElementFactory(page_, namespaceURI, "head", insideSvg_, false);
- final DomElement newElement = factory.createElement(page_, "head", null);
- currentNode_.appendChild(newElement);
- headParsed_ = HeadParsed.SYNTHESIZED;
- }
-
- // If we're adding a body element, keep track of any temporary synthetic ones
- // that we may have had to create earlier (for document.write(), for example).
- HtmlBody oldBody = null;
- if ("body".equals(qName) && page_.getBody() instanceof HtmlBody) {
- oldBody = (HtmlBody) page_.getBody();
- }
-
- // Need to reset this at each starting form tag because it could be set from a synthesized
- // end tag.
- if ("form".equals(tagLower)) {
- formWaitingForLostChildren_ = null;
- }
-
- // Add the new node.
- if (!(page_ instanceof XHtmlPage) && XHTML_NAMESPACE.equals(namespaceURI)) {
- namespaceURI = null;
- }
-
- final boolean keyGenAsSelect = "keygen".equals(tagLower) && page_.hasFeature(KEYGEN_AS_SELECT);
- if (keyGenAsSelect) {
- tagLower = "select";
- qName = "select";
- }
-
- final ElementFactory factory = getElementFactory(page_, namespaceURI, qName, insideSvg_, false);
- if (factory == SVG_FACTORY) {
- namespaceURI = SVG_NAMESPACE;
- }
- final DomElement newElement = factory.createElementNS(page_, namespaceURI, qName, atts, true);
- newElement.setStartLocation(locator_.getLineNumber(), locator_.getColumnNumber());
-
- // parse can't replace everything as it does not buffer elements while parsing
- addNodeToRightParent(currentNode_, newElement);
-
- if ("svg".equals(tagLower)) {
- insideSvg_ = true;
- }
-
- // If we had an old synthetic body and we just added a real body element, quietly
- // remove the old body and move its children to the real body element we just added.
- if (oldBody != null) {
- oldBody.quietlyRemoveAndMoveChildrenTo(newElement);
- }
-
- if ("body".equals(tagLower)) {
- body_ = (HtmlElement) newElement;
- }
- else if ("meta".equals(tagLower) && page_.hasFeature(META_X_UA_COMPATIBLE)) {
- final HtmlMeta meta = (HtmlMeta) newElement;
- if ("X-UA-Compatible".equals(meta.getHttpEquivAttribute())) {
- final String content = meta.getContentAttribute();
- if (content.startsWith("IE=")) {
- final String mode = content.substring(3).trim();
- final int version = page_.getWebClient().getBrowserVersion().getBrowserVersionNumeric();
- if ("edge".equals(mode)) {
- ((HTMLDocument) page_.getScriptableObject()).forceDocumentMode(version);
- }
- else {
- try {
- int value = Integer.parseInt(mode);
- if (value > version) {
- value = version;
- }
- ((HTMLDocument) page_.getScriptableObject()).forceDocumentMode(value);
- }
- catch (final Exception e) {
- // ignore
- }
- }
- }
- }
- }
- if (keyGenAsSelect) {
- DomElement option = factory.createElementNS(page_, namespaceURI, "option", null, true);
- option.appendChild(new DomText(page_, "High Grade"));
- newElement.appendChild(option);
-
- option = factory.createElementNS(page_, namespaceURI, "option", null, true);
- option.appendChild(new DomText(page_, "Medium Grade"));
- newElement.appendChild(option);
- }
- currentNode_ = newElement;
- stack_.push(currentNode_);
- }
-
- /**
- * Adds the new node to the right parent that is not necessary the currentNode in case of
- * malformed HTML code. The method tries to emulate the behavior of Firefox.
- */
- private void addNodeToRightParent(final DomNode currentNode, final DomElement newElement) {
- final String currentNodeName = currentNode.getNodeName();
- final String newNodeName = newElement.getNodeName();
-
- DomNode parent = currentNode;
-
- // If the new node is a table element and the current node isn't one search the stack for the
- // correct parent.
- if ("tr".equals(newNodeName) && !isTableChild(currentNodeName)) {
- parent = findElementOnStack("tbody", "thead", "tfoot");
- }
- else if (isTableChild(newNodeName) && !"table".equals(currentNodeName)) {
- parent = findElementOnStack("table");
- }
- else if (isTableCell(newNodeName) && !"tr".equals(currentNodeName)) {
- parent = findElementOnStack("tr");
- }
-
- // If the parent changed and the old parent was a form it is now waiting for lost children.
- if (parent != currentNode && "form".equals(currentNodeName)) {
- formWaitingForLostChildren_ = (HtmlForm) currentNode;
- }
-
- final String parentNodeName = parent.getNodeName();
-
- if (("table".equals(parentNodeName) && !isTableChild(newNodeName))
- || (isTableChild(parentNodeName) && !"caption".equals(parentNodeName)
- && !"colgroup".equals(parentNodeName) && !"tr".equals(newNodeName))
- || ("colgroup".equals(parentNodeName) && !"col".equals(newNodeName))
- || ("tr".equals(parentNodeName) && !isTableCell(newNodeName))) {
- // If its a form or submittable just add it even though the resulting DOM is incorrect.
- // Otherwise insert the element before the table.
- if ("form".equals(newNodeName)) {
- formWaitingForLostChildren_ = (HtmlForm) newElement;
- parent.appendChild(newElement);
- }
- else if (newElement instanceof SubmittableElement) {
- if (formWaitingForLostChildren_ != null) {
- formWaitingForLostChildren_.addLostChild((HtmlElement) newElement);
- }
- parent.appendChild(newElement);
- }
- else {
- parent = findElementOnStack("table");
- parent.insertBefore(newElement);
- }
- }
- else if (formWaitingForLostChildren_ != null && "form".equals(parentNodeName)) {
- // Do not append any children to invalid form. Submittable are inserted after the form,
- // everything else before the table.
- if (newElement instanceof SubmittableElement) {
- formWaitingForLostChildren_.addLostChild((HtmlElement) newElement);
- parent.getParentNode().appendChild(newElement);
- }
- else {
- parent = findElementOnStack("table");
- parent.insertBefore(newElement);
- }
- }
- else if (formWaitingForLostChildren_ != null && newElement instanceof SubmittableElement) {
- formWaitingForLostChildren_.addLostChild((HtmlElement) newElement);
- parent.appendChild(newElement);
- }
- else {
- parent.appendChild(newElement);
- }
- }
-
- private DomNode findElementOnStack(final String... searchedElementNames) {
- DomNode searchedNode = null;
- for (final DomNode node : stack_) {
- if (ArrayUtils.contains(searchedElementNames, node.getNodeName())) {
- searchedNode = node;
- break;
- }
- }
-
- if (searchedNode == null) {
- searchedNode = stack_.peek(); // this is surely wrong but at least it won't throw a NPE
- }
-
- return searchedNode;
- }
-
- private static boolean isTableChild(final String nodeName) {
- return "thead".equals(nodeName) || "tbody".equals(nodeName)
- || "tfoot".equals(nodeName) || "caption".equals(nodeName)
- || "colgroup".equals(nodeName);
- }
-
- private static boolean isTableCell(final String nodeName) {
- return "td".equals(nodeName) || "th".equals(nodeName);
- }
-
- /** {@inheritDoc} */
- @Override
- public void endElement(final QName element, final Augmentations augs)
- throws XNIException {
- // augs might change so we store only the interesting part
- lastTagWasSynthesized_ = isSynthesized(augs);
- super.endElement(element, augs);
- }
-
- /** {@inheritDoc ContentHandler@endElement(String,String,String)} */
- @Override
- public void endElement(final String namespaceURI, final String localName, final String qName)
- throws SAXException {
-
- handleCharacters();
-
- final String tagLower = localName.toLowerCase(Locale.ROOT);
-
- if (page_.isParsingHtmlSnippet()) {
- if ("html".equals(tagLower) || "body".equals(tagLower)) {
- return;
- }
- if (stack_.size() == initialSize_) {
- snippetStartNodeOverwritten_ = true;
- return;
- }
- }
-
- if ("svg".equals(tagLower)) {
- insideSvg_ = false;
- }
-
- // Need to reset this at each closing form tag because a valid form could start afterwards.
- if ("form".equals(tagLower)) {
- formWaitingForLostChildren_ = null;
- }
-
- final DomNode previousNode = stack_.pop(); //remove currentElement from stack
- previousNode.setEndLocation(locator_.getLineNumber(), locator_.getColumnNumber());
-
- // special handling for form lost children (malformed HTML code where is synthesized)
- if (previousNode instanceof HtmlForm && lastTagWasSynthesized_) {
- formWaitingForLostChildren_ = (HtmlForm) previousNode;
- }
-
- if (!stack_.isEmpty()) {
- currentNode_ = stack_.peek();
- }
-
- final boolean postponed = page_.isParsingInlineHtmlSnippet();
- previousNode.onAllChildrenAddedToPage(postponed);
- }
-
- /** {@inheritDoc} */
- @Override
- public void characters(final char[] ch, final int start, final int length) throws SAXException {
- if (characters_ == null) {
- characters_ = new StringBuilder();
- }
- characters_.append(ch, start, length);
- }
-
- /** {@inheritDoc} */
- @Override
- public void ignorableWhitespace(final char[] ch, final int start, final int length) throws SAXException {
- if (characters_ == null) {
- characters_ = new StringBuilder();
- }
- characters_.append(ch, start, length);
- }
-
- /**
- * Picks up the character data accumulated so far and add it to the current element as a text node.
- */
- private void handleCharacters() {
- if (characters_ != null && characters_.length() != 0) {
- if (currentNode_ instanceof HtmlHtml) {
- // In HTML, the node only has two possible children:
- // the and the ; any text is ignored.
- characters_.setLength(0);
- }
- else {
- // Use the normal behavior: append a text node for the accumulated text.
- final String textValue = characters_.toString();
- final DomText text = new DomText(page_, textValue);
- characters_.setLength(0);
-
- if (StringUtils.isNotBlank(textValue)) {
- // malformed HTML: some text => text comes before the table
- if (currentNode_ instanceof HtmlTableRow) {
- final HtmlTableRow row = (HtmlTableRow) currentNode_;
- final HtmlTable enclosingTable = row.getEnclosingTable();
- if (enclosingTable != null) { // may be null when called from Range.createContextualFragment
- if (enclosingTable.getPreviousSibling() instanceof DomText) {
- final DomText domText = (DomText) enclosingTable.getPreviousSibling();
- domText.setTextContent(domText + textValue);
- }
- else {
- enclosingTable.insertBefore(text);
- }
- }
- }
- else if (currentNode_ instanceof HtmlTable) {
- final HtmlTable enclosingTable = (HtmlTable) currentNode_;
- if (enclosingTable.getPreviousSibling() instanceof DomText) {
- final DomText domText = (DomText) enclosingTable.getPreviousSibling();
- domText.setTextContent(domText + textValue);
- }
- else {
- enclosingTable.insertBefore(text);
- }
- }
- else if (currentNode_ instanceof HtmlImage) {
- currentNode_.setNextSibling(text);
- }
- else {
- currentNode_.appendChild(text);
- }
- }
- else {
- currentNode_.appendChild(text);
- }
- }
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public void endDocument() throws SAXException {
- handleCharacters();
- final DomNode currentPage = page_;
- currentPage.setEndLocation(locator_.getLineNumber(), locator_.getColumnNumber());
- }
-
- /** {@inheritDoc} */
- @Override
- public void startPrefixMapping(final String prefix, final String uri) throws SAXException {
- }
-
- /** {@inheritDoc} */
- @Override
- public void endPrefixMapping(final String prefix) throws SAXException {
- }
-
- /** {@inheritDoc} */
- @Override
- public void processingInstruction(final String target, final String data) throws SAXException {
- }
-
- /** {@inheritDoc} */
- @Override
- public void skippedEntity(final String name) throws SAXException {
- }
-
- // LexicalHandler methods
-
- /** {@inheritDoc} */
- @Override
- public void comment(final char[] ch, final int start, final int length) {
- handleCharacters();
- final String data = new String(ch, start, length);
- final DomComment comment = new DomComment(page_, data);
- currentNode_.appendChild(comment);
- }
-
- /** {@inheritDoc} */
- @Override
- public void endCDATA() {
- }
-
- /** {@inheritDoc} */
- @Override
- public void endDTD() {
- }
-
- /** {@inheritDoc} */
- @Override
- public void endEntity(final String name) {
- }
-
- /** {@inheritDoc} */
- @Override
- public void startCDATA() {
- }
-
- /** {@inheritDoc} */
- @Override
- public void startDTD(final String name, final String publicId, final String systemId) {
- final DomDocumentType type = new DomDocumentType(page_, name, publicId, systemId);
- page_.setDocumentType(type);
-
- final Node child;
- child = type;
- page_.appendChild(child);
- }
-
- /** {@inheritDoc} */
- @Override
- public void startEntity(final String name) {
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void ignoredEndElement(final QName element, final Augmentations augs) {
- // if real is reached, don't accept fields anymore as lost children
- if ("form".equals(element.localpart)) {
- formWaitingForLostChildren_ = null;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void ignoredStartElement(final QName elem, final XMLAttributes attrs, final Augmentations augs) {
- // when multiple body elements are encountered, the attributes of the discarded
- // elements are used when not previously defined
- if (body_ != null && "body".equalsIgnoreCase(elem.localpart) && attrs != null) {
- copyAttributes(body_, attrs);
- }
- if (body_ != null && "html".equalsIgnoreCase(elem.localpart) && attrs != null) {
- copyAttributes((DomElement) body_.getParentNode(), attrs);
- }
- }
-
- private static void copyAttributes(final DomElement to, final XMLAttributes attrs) {
- final int length = attrs.getLength();
- for (int i = 0; i < length; i++) {
- final String attrName = attrs.getLocalName(i).toLowerCase(Locale.ROOT);
- if (to.getAttributes().getNamedItem(attrName) == null) {
- to.setAttribute(attrName, attrs.getValue(i));
- if (attrName.startsWith("on") && to.getScriptableObject() instanceof HTMLBodyElement) {
- final HTMLBodyElement jsBody = to.getScriptableObject();
- jsBody.createEventHandlerFromAttribute(attrName, attrs.getValue(i));
- }
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void parse(final XMLInputSource inputSource) throws XNIException, IOException {
- final HtmlUnitDOMBuilder oldBuilder = page_.getBuilder();
- page_.setBuilder(this);
- try {
- super.parse(inputSource);
- }
- finally {
- page_.setBuilder(oldBuilder);
- }
- }
-
- private static boolean isSynthesized(final Augmentations augs) {
- final HTMLEventInfo info = (augs == null) ? null
- : (HTMLEventInfo) augs.getItem(FEATURE_AUGMENTATIONS);
- return info != null && info.isSynthesized();
- }
- }
-}
-
-/**
- * Utility to transmit parsing errors to a {@link HTMLParserListener}.
- */
-class HTMLErrorHandler extends DefaultErrorHandler {
- private final HTMLParserListener listener_;
- private final URL url_;
- private String html_;
-
- HTMLErrorHandler(final HTMLParserListener listener, final URL url, final String htmlContent) {
- WebAssert.notNull("listener", listener);
- WebAssert.notNull("url", url);
- listener_ = listener;
- url_ = url;
- html_ = htmlContent;
- }
-
- /** @see DefaultErrorHandler#error(String,String,XMLParseException) */
- @Override
- public void error(final String domain, final String key,
- final XMLParseException exception) throws XNIException {
- listener_.error(exception.getMessage(),
- url_,
- html_,
- exception.getLineNumber(),
- exception.getColumnNumber(),
- key);
- }
-
- /** @see DefaultErrorHandler#warning(String,String,XMLParseException) */
- @Override
- public void warning(final String domain, final String key,
- final XMLParseException exception) throws XNIException {
- listener_.warning(exception.getMessage(),
- url_,
- html_,
- exception.getLineNumber(),
- exception.getColumnNumber(),
- key);
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/MozCSSKeyframesRule.java b/src/main/java/com/gargoylesoftware/htmlunit/html/Html.java
similarity index 57%
rename from src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/MozCSSKeyframesRule.java
rename to src/main/java/com/gargoylesoftware/htmlunit/html/Html.java
index 4b60b44f9b4..b4d9ba8f432 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/MozCSSKeyframesRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/Html.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -12,17 +12,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.gargoylesoftware.htmlunit.javascript.host.css;
-
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
+package com.gargoylesoftware.htmlunit.html;
/**
- * A JavaScript object for {@code MozCSSKeyframesRule}.
+ * Html constants.
*
- * @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(FF45)
-public class MozCSSKeyframesRule extends CSSRule {
+public final class Html {
+
+ /** XHTML namespace. */
+ public static final String XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
+
+ /** SVG namespace. */
+ public static final String SVG_NAMESPACE = "http://www.w3.org/2000/svg";
+
+ private Html() {
+ }
+
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAbbreviated.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAbbreviated.java
index 475ba50fc82..87f65f4adb6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAbbreviated.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAbbreviated.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAcronym.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAcronym.java
index a749f9c3fc6..4ef26f6dfc0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAcronym.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAcronym.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAddress.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAddress.java
index 07b0715d93b..4c8836e03f6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAddress.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAddress.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAnchor.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAnchor.java
index 239f992b30c..86e2a6c6dbc 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAnchor.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAnchor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.html;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.ANCHOR_EMPTY_HREF_NO_FILENAME;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.ANCHOR_IGNORE_TARGET_FOR_JS_HREF;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.ANCHOR_SEND_PING_REQUEST;
import java.io.IOException;
import java.net.MalformedURLException;
@@ -31,7 +31,6 @@
import com.gargoylesoftware.htmlunit.HttpMethod;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.SgmlPage;
-import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
@@ -74,17 +73,18 @@ public class HtmlAnchor extends HtmlElement {
*/
@Override
@SuppressWarnings("unchecked")
- public P click(final Event event, final boolean ignoreVisibility) throws IOException {
- final boolean ctrl = event.isCtrlKey();
+ public
P click(final Event event,
+ final boolean shiftKey, final boolean ctrlKey, final boolean altKey,
+ final boolean ignoreVisibility) throws IOException {
WebWindow oldWebWindow = null;
- if (ctrl) {
+ if (ctrlKey) {
oldWebWindow = ((HTMLElement) event.getSrcElement()).getDomNodeOrDie()
.getPage().getWebClient().getCurrentWindow();
}
- P page = super.click(event, ignoreVisibility);
+ P page = super.click(event, shiftKey, ctrlKey, altKey, ignoreVisibility);
- if (ctrl) {
+ if (ctrlKey) {
page.getEnclosingWindow().getWebClient().setCurrentWindow(oldWebWindow);
page = (P) oldWebWindow.getEnclosedPage();
}
@@ -131,27 +131,22 @@ protected void doClickStateUpdate(final boolean shiftKey, final boolean ctrlKey,
builder.append(ch);
}
- if (hasFeature(ANCHOR_IGNORE_TARGET_FOR_JS_HREF) && !shiftKey && !ctrlKey) {
- page.executeJavaScript(builder.toString(), "javascript url", getStartLineNumber());
+ final String target;
+ if (shiftKey || ctrlKey) {
+ target = "_blank";
}
else {
- final String target;
- if (shiftKey || ctrlKey) {
- target = "_blank";
- }
- else {
- target = page.getResolvedTarget(getTargetAttribute());
- }
- final WebWindow win = page.getWebClient().openTargetWindow(page.getEnclosingWindow(), target, "_self");
- Page enclosedPage = win.getEnclosedPage();
- if (enclosedPage == null) {
- win.getWebClient().getPage(win, new WebRequest(WebClient.URL_ABOUT_BLANK));
- enclosedPage = win.getEnclosedPage();
- }
- if (enclosedPage != null && enclosedPage.isHtmlPage()) {
- page = (HtmlPage) enclosedPage;
- page.executeJavaScript(builder.toString(), "javascript url", getStartLineNumber());
- }
+ target = page.getResolvedTarget(getTargetAttribute());
+ }
+ final WebWindow win = page.getWebClient().openTargetWindow(page.getEnclosingWindow(), target, "_self");
+ Page enclosedPage = win.getEnclosedPage();
+ if (enclosedPage == null) {
+ win.getWebClient().getPage(win, WebRequest.newAboutBlankRequest());
+ enclosedPage = win.getEnclosedPage();
+ }
+ if (enclosedPage != null && enclosedPage.isHtmlPage()) {
+ page = (HtmlPage) enclosedPage;
+ page.executeJavaScript(builder.toString(), "javascript url", getStartLineNumber());
}
return;
}
@@ -159,7 +154,7 @@ protected void doClickStateUpdate(final boolean shiftKey, final boolean ctrlKey,
final URL url = getTargetUrl(href, page);
final BrowserVersion browser = page.getWebClient().getBrowserVersion();
- if (ATTRIBUTE_NOT_DEFINED != getPingAttribute() && browser.hasFeature(ANCHOR_IGNORE_TARGET_FOR_JS_HREF)) {
+ if (ATTRIBUTE_NOT_DEFINED != getPingAttribute() && browser.hasFeature(ANCHOR_SEND_PING_REQUEST)) {
final URL pingUrl = getTargetUrl(getPingAttribute(), page);
final WebRequest pingRequest = new WebRequest(pingUrl, HttpMethod.POST);
pingRequest.setAdditionalHeader(HttpHeader.PING_FROM, page.getUrl().toExternalForm());
@@ -168,8 +163,11 @@ protected void doClickStateUpdate(final boolean shiftKey, final boolean ctrlKey,
page.getWebClient().loadWebResponse(pingRequest);
}
- final WebRequest webRequest = new WebRequest(url, browser.getHtmlAcceptHeader());
+ final WebRequest webRequest = new WebRequest(url, browser.getHtmlAcceptHeader(),
+ browser.getAcceptEncodingHeader());
+ // use the page encoding even if this is a GET requests
webRequest.setCharset(page.getCharset());
+
webRequest.setAdditionalHeader(HttpHeader.REFERER, page.getUrl().toExternalForm());
if (LOG.isDebugEnabled()) {
LOG.debug(
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlApplet.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlApplet.java
index 981a6517279..dfd2eee87be 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlApplet.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlApplet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
*/
package com.gargoylesoftware.htmlunit.html;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.APPLET_INLINE_BLOCK;
-
import java.applet.Applet;
import java.io.IOException;
import java.net.URL;
@@ -63,7 +61,6 @@ public class HtmlApplet extends HtmlElement {
public static final String TAG_NAME = "applet";
private Applet applet_;
- private AppletClassLoader appletClassLoader_;
private List archiveUrls_;
/**
@@ -261,76 +258,78 @@ private synchronized void setupAppletIfNeeded() throws IOException {
appletClassName = appletClassName.substring(0, appletClassName.length() - 6);
}
- appletClassLoader_ = new AppletClassLoader((Window) getPage().getEnclosingWindow().getScriptableObject(),
- Thread.currentThread().getContextClassLoader());
-
- final String documentUrl = page.getUrl().toExternalForm();
- String baseUrl = UrlUtils.resolveUrl(documentUrl, ".");
- if (StringUtils.isNotEmpty(codebaseProperty)) {
- // codebase can be relative to the page
- baseUrl = UrlUtils.resolveUrl(baseUrl, codebaseProperty);
- }
- if (!baseUrl.endsWith("/")) {
- baseUrl = baseUrl + "/";
- }
+ try (AppletClassLoader appletClassLoader =
+ new AppletClassLoader((Window) getPage().getEnclosingWindow().getScriptableObject(),
+ Thread.currentThread().getContextClassLoader())) {
- // check archive
- final List archiveUrls = new LinkedList<>();
- String[] archives = StringUtils.split(params.get(ARCHIVE), ',');
- if (null != archives) {
- for (int i = 0; i < archives.length; i++) {
- final String tmpArchive = archives[i].trim();
- final String tempUrl = UrlUtils.resolveUrl(baseUrl, tmpArchive);
- final URL archiveUrl = UrlUtils.toUrlUnsafe(tempUrl);
-
- appletClassLoader_.addArchiveToClassPath(archiveUrl);
- archiveUrls.add(archiveUrl);
+ final String documentUrl = page.getUrl().toExternalForm();
+ String baseUrl = UrlUtils.resolveUrl(documentUrl, ".");
+ if (StringUtils.isNotEmpty(codebaseProperty)) {
+ // codebase can be relative to the page
+ baseUrl = UrlUtils.resolveUrl(baseUrl, codebaseProperty);
}
- }
- archives = StringUtils.split(params.get(CACHE_ARCHIVE), ',');
- if (null != archives) {
- for (int i = 0; i < archives.length; i++) {
- final String tmpArchive = archives[i].trim();
- final String tempUrl = UrlUtils.resolveUrl(baseUrl, tmpArchive);
- final URL archiveUrl = UrlUtils.toUrlUnsafe(tempUrl);
-
- appletClassLoader_.addArchiveToClassPath(archiveUrl);
- archiveUrls.add(archiveUrl);
+ if (!baseUrl.endsWith("/")) {
+ baseUrl = baseUrl + "/";
}
- }
- archiveUrls_ = Collections.unmodifiableList(archiveUrls);
- // no archive attribute, single class
- if (archiveUrls_.isEmpty()) {
- final String tempUrl = UrlUtils.resolveUrl(baseUrl, getCodeAttribute());
- final URL classUrl = UrlUtils.toUrlUnsafe(tempUrl);
+ // check archive
+ final List archiveUrls = new LinkedList<>();
+ String[] archives = StringUtils.split(params.get(ARCHIVE), ',');
+ if (null != archives) {
+ for (String tmpArchive : archives) {
+ final String tempUrl = UrlUtils.resolveUrl(baseUrl, tmpArchive.trim());
+ final URL archiveUrl = UrlUtils.toUrlUnsafe(tempUrl);
+
+ appletClassLoader.addArchiveToClassPath(archiveUrl);
+ archiveUrls.add(archiveUrl);
+ }
+ }
+ archives = StringUtils.split(params.get(CACHE_ARCHIVE), ',');
+ if (null != archives) {
+ for (String tmpArchive : archives) {
+ final String tempUrl = UrlUtils.resolveUrl(baseUrl, tmpArchive.trim());
+ final URL archiveUrl = UrlUtils.toUrlUnsafe(tempUrl);
+
+ appletClassLoader.addArchiveToClassPath(archiveUrl);
+ archiveUrls.add(archiveUrl);
+ }
+ }
+ archiveUrls_ = Collections.unmodifiableList(archiveUrls);
+
+ // no archive attribute, single class
+ if (archiveUrls_.isEmpty()) {
+ final String tempUrl = UrlUtils.resolveUrl(baseUrl, getCodeAttribute());
+ final URL classUrl = UrlUtils.toUrlUnsafe(tempUrl);
+
+ final WebResponse response = webclient.loadWebResponse(new WebRequest(classUrl));
+ try {
+ webclient.throwFailingHttpStatusCodeExceptionIfNecessary(response);
+ appletClassLoader.addClassToClassPath(appletClassName, response);
+ }
+ catch (final FailingHttpStatusCodeException e) {
+ // that is what the browser does, the applet only fails, if
+ // the main class is not loadable
+ LOG.error(e.getMessage(), e);
+ }
+ }
- final WebResponse response = webclient.loadWebResponse(new WebRequest(classUrl));
try {
- webclient.throwFailingHttpStatusCodeExceptionIfNecessary(response);
- appletClassLoader_.addClassToClassPath(appletClassName, response);
+ final Class appletClass = (Class) appletClassLoader.loadClass(appletClassName);
+ applet_ = appletClass.newInstance();
+ applet_.setStub(new AppletStubImpl(getHtmlPageOrNull(), params,
+ UrlUtils.toUrlUnsafe(baseUrl), UrlUtils.toUrlUnsafe(documentUrl)));
+ applet_.init();
+ applet_.start();
}
- catch (final FailingHttpStatusCodeException e) {
- // that is what the browser does, the applet only fails, if
- // the main class is not loadable
- LOG.error(e.getMessage(), e);
+ catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Loading applet '" + appletClassName + "' failed\n"
+ + " " + e.toString()
+ + "\n Classpath:\n" + appletClassLoader.info());
+ }
+ throw new RuntimeException(e);
}
}
-
- try {
- final Class appletClass = (Class) appletClassLoader_.loadClass(appletClassName);
- applet_ = appletClass.newInstance();
- applet_.setStub(new AppletStubImpl(getHtmlPageOrNull(), params,
- UrlUtils.toUrlUnsafe(baseUrl), UrlUtils.toUrlUnsafe(documentUrl)));
- applet_.init();
- applet_.start();
- }
- catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
- LOG.error("Loading applet '" + appletClassName + "' failed\n"
- + " " + e.toString()
- + "\n Classpath:\n" + appletClassLoader_.info());
- throw new RuntimeException(e);
- }
}
/**
@@ -348,9 +347,6 @@ public List getArchiveUrls() {
*/
@Override
public DisplayStyle getDefaultStyleDisplay() {
- if (getPage().getWebClient().getBrowserVersion().hasFeature(APPLET_INLINE_BLOCK)) {
- return DisplayStyle.INLINE_BLOCK;
- }
return DisplayStyle.INLINE;
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlArea.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlArea.java
index 9001a30691b..7d0df825d55 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlArea.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlArea.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,6 +47,7 @@
* @author Marc Guillemot
* @author Ahmed Ashour
* @author Frank Danek
+ * @author Ronald Brill
*/
public class HtmlArea extends HtmlElement {
private static final Log LOG = LogFactory.getLog(HtmlArea.class);
@@ -54,6 +55,10 @@ public class HtmlArea extends HtmlElement {
/** The HTML tag represented by this element. */
public static final String TAG_NAME = "area";
+ private static final String SHAPE_RECT = "rect";
+ private static final String SHAPE_CIRCLE = "circle";
+ private static final String SHAPE_POLY = "poly";
+
/**
* Creates a new instance.
*
@@ -91,6 +96,7 @@ protected boolean doClickStateUpdate(final boolean shiftKey, final boolean ctrlK
"Not a valid url: " + getHrefAttribute());
}
final WebRequest request = new WebRequest(url);
+ request.setCharset(page.getCharset());
request.setAdditionalHeader(HttpHeader.REFERER, page.getUrl().toExternalForm());
final WebWindow webWindow = enclosingPage.getEnclosingWindow();
webClient.getPage(
@@ -218,23 +224,23 @@ public final String getTargetAttribute() {
* @return {@code true} if the point is contained in this area
*/
boolean containsPoint(final int x, final int y) {
- final String shape = StringUtils.defaultIfEmpty(getShapeAttribute(), "rect").toLowerCase(Locale.ROOT);
+ final String shape = StringUtils.defaultIfEmpty(getShapeAttribute(), SHAPE_RECT).toLowerCase(Locale.ROOT);
if ("default".equals(shape) && getCoordsAttribute() != null) {
return true;
}
- if ("rect".equals(shape) && getCoordsAttribute() != null) {
+ if (SHAPE_RECT.equals(shape) && getCoordsAttribute() != null) {
final Rectangle2D rectangle = parseRect();
return rectangle.contains(x, y);
}
- if ("circle".equals(shape) && getCoordsAttribute() != null) {
+ if (SHAPE_CIRCLE.equals(shape) && getCoordsAttribute() != null) {
final Ellipse2D ellipse = parseCircle();
return ellipse.contains(x, y);
}
- if ("poly".equals(shape) && getCoordsAttribute() != null) {
+ if (SHAPE_POLY.equals(shape) && getCoordsAttribute() != null) {
final GeneralPath path = parsePoly();
return path.contains(x, y);
}
@@ -289,7 +295,9 @@ private Rectangle2D parseRect() {
}
}
catch (final NumberFormatException e) {
- LOG.warn("Invalid rect coords '" + Arrays.toString(coords) + "'", e);
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Invalid rect coords '" + Arrays.toString(coords) + "'", e);
+ }
}
final Rectangle2D rectangle = new Rectangle2D.Double(leftX, topY,
@@ -333,7 +341,9 @@ private GeneralPath parsePoly() {
}
}
catch (final NumberFormatException e) {
- LOG.warn("Invalid poly coords '" + Arrays.toString(coords) + "'", e);
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Invalid poly coords '" + Arrays.toString(coords) + "'", e);
+ }
}
path.closePath();
@@ -341,23 +351,23 @@ private GeneralPath parsePoly() {
}
private boolean isEmpty() {
- final String shape = StringUtils.defaultIfEmpty(getShapeAttribute(), "rect").toLowerCase(Locale.ROOT);
+ final String shape = StringUtils.defaultIfEmpty(getShapeAttribute(), SHAPE_RECT).toLowerCase(Locale.ROOT);
if ("default".equals(shape) && getCoordsAttribute() != null) {
return false;
}
- if ("rect".equals(shape) && getCoordsAttribute() != null) {
+ if (SHAPE_RECT.equals(shape) && getCoordsAttribute() != null) {
final Rectangle2D rectangle = parseRect();
return rectangle.isEmpty();
}
- if ("circle".equals(shape) && getCoordsAttribute() != null) {
+ if (SHAPE_CIRCLE.equals(shape) && getCoordsAttribute() != null) {
final Ellipse2D ellipse = parseCircle();
return ellipse.isEmpty();
}
- if ("poly".equals(shape) && getCoordsAttribute() != null) {
+ if (SHAPE_POLY.equals(shape) && getCoordsAttribute() != null) {
return false;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlArticle.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlArticle.java
index 64ee79c8794..fb183174071 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlArticle.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlArticle.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAside.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAside.java
index eb7881be78b..930ccc7a4c8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAside.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAside.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAttributeChangeEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAttributeChangeEvent.java
index fcae6772e7f..f82c14cc06a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAttributeChangeEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAttributeChangeEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAttributeChangeListener.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAttributeChangeListener.java
index aaeace1d3b9..245afd1ca8a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAttributeChangeListener.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAttributeChangeListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAudio.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAudio.java
index 9edbbd11151..b37ea946288 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAudio.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlAudio.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,10 +19,11 @@
import com.gargoylesoftware.htmlunit.SgmlPage;
/**
- * Wrapper for the HTML element "audio".
+ * Wrapper for the HTML element "Audio".
*
* @author Ahmed Ashour
* @author Frank Danek
+ * @author Ronald Brill
*/
public class HtmlAudio extends HtmlMedia {
@@ -30,7 +31,7 @@ public class HtmlAudio extends HtmlMedia {
public static final String TAG_NAME = "audio";
/**
- * Creates an instance of HtmlAudio
+ * Creates an instance of HtmlAudio.
*
* @param qualifiedName the qualified name of the element type to instantiate
* @param page the HtmlPage that contains this element
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBackgroundSound.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBackgroundSound.java
index 8152b91860d..24fcdb97753 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBackgroundSound.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBackgroundSound.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBase.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBase.java
index 598ca9a2d8d..1a0b4e73a4b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBase.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBaseFont.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBaseFont.java
index 3ab9db8c325..b80b707a2f6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBaseFont.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBaseFont.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBidirectionalIsolation.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBidirectionalIsolation.java
index 7f71dfbd2ef..ddf5b4f6e0c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBidirectionalIsolation.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBidirectionalIsolation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBidirectionalOverride.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBidirectionalOverride.java
index 7e651e0c8e8..c74166ca9ad 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBidirectionalOverride.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBidirectionalOverride.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBig.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBig.java
index 30a8a02a490..a6bbc145b41 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBig.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBig.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBlink.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBlink.java
index 81c3ff7b9c2..d1ccaf3ca01 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBlink.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBlink.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBlockQuote.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBlockQuote.java
index 1bb3c7ac6d3..791def6b331 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBlockQuote.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBlockQuote.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBody.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBody.java
index d6009464839..832c288aa08 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBody.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBody.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,11 +50,6 @@ public HtmlBody(final String qualifiedName, final SgmlPage page,
super(qualifiedName, page, attributes);
temporary_ = temporary;
-
- // Force script object creation now to forward onXXX handlers to window.
- if (getOwnerDocument() instanceof HtmlPage) {
- getScriptableObject();
- }
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBold.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBold.java
index f82ff707e34..e5d13a87c2a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBold.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBold.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBreak.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBreak.java
index 137b602e716..52ba9f521b9 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBreak.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlBreak.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlButton.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlButton.java
index 3a4e5d7b963..fdb83485455 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlButton.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlButton.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -85,15 +85,13 @@ protected boolean doClickStateUpdate(final boolean shiftKey, final boolean ctrlK
HtmlForm form = null;
final String formId = getAttributeDirect("form");
- if (DomElement.ATTRIBUTE_NOT_DEFINED == formId) {
+ if (DomElement.ATTRIBUTE_NOT_DEFINED == formId || !hasFeature(FORM_FORM_ATTRIBUTE_SUPPORTED)) {
form = getEnclosingForm();
}
else {
- if (hasFeature(FORM_FORM_ATTRIBUTE_SUPPORTED)) {
- final DomElement elem = getHtmlPageOrNull().getElementById(formId);
- if (elem instanceof HtmlForm) {
- form = (HtmlForm) elem;
- }
+ final DomElement elem = getHtmlPageOrNull().getElementById(formId);
+ if (elem instanceof HtmlForm) {
+ form = (HtmlForm) elem;
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlButtonInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlButtonInput.java
index 81904e5a01c..8df4cab2215 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlButtonInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlButtonInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,6 +51,14 @@ public void reset() {
// Empty.
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCanvas.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCanvas.java
index 02ebe35726e..3b65c9eaa2a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCanvas.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCanvas.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCaption.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCaption.java
index a7a4dc2c7f8..afe79fef619 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCaption.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCaption.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCenter.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCenter.java
index a63db1e38e6..d9132970795 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCenter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCenter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCheckBoxInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCheckBoxInput.java
index 53ca2784efd..3726e718425 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCheckBoxInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCheckBoxInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCitation.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCitation.java
index e21506e1db2..f82587c8b69 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCitation.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCitation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCode.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCode.java
index 972ef6a34ff..9d6288af16b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCode.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlColorInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlColorInput.java
index 9176cc24be7..cd74ec41dbe 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlColorInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlColorInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,11 +14,14 @@
*/
package com.gargoylesoftware.htmlunit.html;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLINPUT_TYPE_COLOR_NOT_SUPPORTED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INPUT_SET_VALUE_MOVE_SELECTION_TO_START;
import java.awt.Color;
import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+
import com.gargoylesoftware.htmlunit.SgmlPage;
/**
@@ -39,17 +42,36 @@ public class HtmlColorInput extends HtmlInput {
HtmlColorInput(final String qualifiedName, final SgmlPage page,
final Map attributes) {
super(qualifiedName, page, attributes);
- if (getValueAttribute() == ATTRIBUTE_NOT_DEFINED && !hasFeature(JS_INPUT_SET_VALUE_MOVE_SELECTION_TO_START)) {
+ if (getValueAttribute() == ATTRIBUTE_NOT_DEFINED
+ && !hasFeature(JS_INPUT_SET_VALUE_MOVE_SELECTION_TO_START)) {
setValueAttribute("#" + Integer.toHexString(Color.black.getRGB()).substring(2));
}
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
@Override
public void setValueAttribute(final String newValue) {
- if (hasFeature(JS_INPUT_SET_VALUE_MOVE_SELECTION_TO_START) || isValid(newValue)) {
+ if (hasFeature(HTMLINPUT_TYPE_COLOR_NOT_SUPPORTED)) {
+ super.setValueAttribute(newValue);
+ return;
+ }
+
+ if (StringUtils.isEmpty(newValue)) {
+ super.setValueAttribute("#000000");
+ return;
+ }
+
+ if (isValid(newValue)) {
super.setValueAttribute(newValue);
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCommand.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCommand.java
index 0696bd52d90..5aaa26d6a31 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCommand.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlCommand.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlContent.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlContent.java
index 42a2eee17de..4f0f38a28b3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlContent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlContent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlData.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlData.java
index 2a4984be432..963603f3f8b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlData.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDataList.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDataList.java
index c1447f268ed..557d8c70553 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDataList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDataList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDateInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDateInput.java
index 712450ade06..7b437c60cc8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDateInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDateInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,22 +15,30 @@
package com.gargoylesoftware.htmlunit.html;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INPUT_SET_VALUE_DATE_SUPPORTED;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INPUT_SET_VALUE_MOVE_SELECTION_TO_START;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Map;
import com.gargoylesoftware.htmlunit.SgmlPage;
+import com.gargoylesoftware.htmlunit.html.impl.SelectableTextInput;
+import com.gargoylesoftware.htmlunit.html.impl.SelectableTextSelectionDelegate;
+import org.apache.commons.lang3.StringUtils;
/**
* Wrapper for the HTML element "input" where type is "date".
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-public class HtmlDateInput extends HtmlInput {
+public class HtmlDateInput extends HtmlInput implements SelectableTextInput {
private static DateTimeFormatter FORMATTER_ = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+ private SelectableTextSelectionDelegate selectionDelegate_ = new SelectableTextSelectionDelegate(this);
+ private DoTypeProcessor doTypeProcessor_ = new DoTypeProcessor(this);
+
/**
* Creates an instance.
*
@@ -43,13 +51,149 @@ public class HtmlDateInput extends HtmlInput {
super(qualifiedName, page, attributes);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doType(final char c, final boolean lastType) {
+ doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, c, this, lastType);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doType(final int keyCode, final boolean lastType) {
+ doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, keyCode, this, lastType);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void typeDone(final String newValue, final boolean notifyAttributeChangeListeners) {
+ if (newValue.length() <= getMaxLength()) {
+ setAttributeNS(null, "value", newValue, notifyAttributeChangeListeners, false);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isSubmittableByEnter() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void select() {
+ selectionDelegate_.select();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getSelectedText() {
+ return selectionDelegate_.getSelectedText();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getText() {
+ return getValueAttribute();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setText(final String text) {
+ setValueAttribute(text);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getSelectionStart() {
+ return selectionDelegate_.getSelectionStart();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setSelectionStart(final int selectionStart) {
+ selectionDelegate_.setSelectionStart(selectionStart);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getSelectionEnd() {
+ return selectionDelegate_.getSelectionEnd();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setSelectionEnd(final int selectionEnd) {
+ selectionDelegate_.setSelectionEnd(selectionEnd);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void setAttributeNS(final String namespaceURI, final String qualifiedName, final String attributeValue,
+ final boolean notifyAttributeChangeListeners, final boolean notifyMutationObservers) {
+ super.setAttributeNS(namespaceURI, qualifiedName, attributeValue, notifyAttributeChangeListeners,
+ notifyMutationObservers);
+ if ("value".equals(qualifiedName)) {
+ final SgmlPage page = getPage();
+ if (page != null && page.isHtmlPage()) {
+ int pos = 0;
+ if (!hasFeature(JS_INPUT_SET_VALUE_MOVE_SELECTION_TO_START)) {
+ pos = attributeValue.length();
+ }
+ setSelectionStart(pos);
+ setSelectionEnd(pos);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultValue(final String defaultValue) {
+ final boolean modifyValue = getValueAttribute().equals(getDefaultValue());
+ setDefaultValue(defaultValue, modifyValue);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
@Override
public void setValueAttribute(final String newValue) {
try {
- if (hasFeature(JS_INPUT_SET_VALUE_DATE_SUPPORTED)) {
+ if (hasFeature(JS_INPUT_SET_VALUE_DATE_SUPPORTED) && StringUtils.isNotEmpty(newValue)) {
FORMATTER_.parse(newValue);
}
super.setValueAttribute(newValue);
@@ -58,4 +202,26 @@ public void setValueAttribute(final String newValue) {
// ignore
}
}
+
+ /**
+ * {@inheritDoc}
+ * @see HtmlInput#reset()
+ */
+ @Override
+ public void reset() {
+ super.reset();
+ setSelectionEnd(0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public DomNode cloneNode(final boolean deep) {
+ final HtmlDateInput newnode = (HtmlDateInput) super.cloneNode(deep);
+ newnode.selectionDelegate_ = new SelectableTextSelectionDelegate(newnode);
+ newnode.doTypeProcessor_ = new DoTypeProcessor(newnode);
+
+ return newnode;
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDateTimeLocalInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDateTimeLocalInput.java
index fbbf85c7550..5538ef6daf1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDateTimeLocalInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDateTimeLocalInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,13 +14,15 @@
*/
package com.gargoylesoftware.htmlunit.html;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INPUT_SET_VALUE_DATE_SUPPORTED;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLINPUT_TYPE_DATETIME_SUPPORTED;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLINPUT_TYPE_MONTH_NOT_SUPPORTED;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Map;
import com.gargoylesoftware.htmlunit.SgmlPage;
+import org.apache.commons.lang3.StringUtils;
/**
* Wrapper for the HTML element "input" where type is "datetime-local".
@@ -43,13 +45,23 @@ public class HtmlDateTimeLocalInput extends HtmlInput {
super(qualifiedName, page, attributes);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
@Override
public void setValueAttribute(final String newValue) {
try {
- if (hasFeature(JS_INPUT_SET_VALUE_DATE_SUPPORTED)) {
+ if (hasFeature(HTMLINPUT_TYPE_DATETIME_SUPPORTED)
+ && !hasFeature(HTMLINPUT_TYPE_MONTH_NOT_SUPPORTED)
+ && StringUtils.isNotEmpty(newValue)) {
FORMATTER_.parse(newValue);
}
super.setValueAttribute(newValue);
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinition.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinition.java
index 03dfed49381..e255ea47618 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinition.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinition.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionDescription.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionDescription.java
index 68bc64a712c..e4563a71d69 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionDescription.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionDescription.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionList.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionList.java
index d78e045322d..670104a3c16 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionTerm.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionTerm.java
index 4c930f9f00f..b2d15b53b31 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionTerm.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDefinitionTerm.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDeletedText.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDeletedText.java
index 173ef01a01f..e462ac71e60 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDeletedText.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDeletedText.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDetails.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDetails.java
index 21a164b70ac..f38a947d5a7 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDetails.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDetails.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDialog.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDialog.java
index 3ff920db1f7..1f81f78cab8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDialog.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDialog.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDirectory.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDirectory.java
index ee2b91b3e46..d3cc7c005fe 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDirectory.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDirectory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDivision.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDivision.java
index d3530e45d16..f17e7a26b41 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDivision.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlDivision.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlElement.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlElement.java
index aac5dd2771b..b07fb1eb5a3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlElement.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
*/
package com.gargoylesoftware.htmlunit.html;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLELEMENT_DETACH_ACTIVE_TRIGGERS_NO_KEYUP_EVENT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLELEMENT_REMOVE_ACTIVE_TRIGGERS_BLUR_EVENT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.KEYBOARD_EVENT_SPECIAL_KEYPRESS;
@@ -43,6 +44,7 @@
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.WebAssert;
import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.html.impl.SelectableTextInput;
import com.gargoylesoftware.htmlunit.javascript.host.dom.Document;
import com.gargoylesoftware.htmlunit.javascript.host.dom.MutationObserver;
import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
@@ -154,7 +156,7 @@ public String value() {
*/
protected HtmlElement(final String qualifiedName, final SgmlPage page,
final Map attributes) {
- this(HTMLParser.XHTML_NAMESPACE, qualifiedName, page, attributes);
+ this(Html.XHTML_NAMESPACE, qualifiedName, page, attributes);
}
/**
@@ -211,7 +213,7 @@ protected void setAttributeNS(final String namespaceURI, final String qualifiedN
notifyAttributeChangeListeners(event, this, oldAttributeValue, notifyMutationObservers);
}
- fireAttributeChangeImpl(event, htmlPage, mappedElement, qualifiedName, attributeValue, oldAttributeValue);
+ fireAttributeChangeImpl(event, htmlPage, mappedElement, oldAttributeValue);
}
/**
@@ -249,8 +251,7 @@ protected static void notifyAttributeChangeListeners(final HtmlAttributeChangeEv
}
private void fireAttributeChangeImpl(final HtmlAttributeChangeEvent event,
- final HtmlPage htmlPage, final boolean mappedElement,
- final String qualifiedName, final String attributeValue, final String oldAttributeValue) {
+ final HtmlPage htmlPage, final boolean mappedElement, final String oldAttributeValue) {
if (mappedElement) {
htmlPage.addMappedElement(this);
}
@@ -297,7 +298,7 @@ public Attr setAttributeNode(final Attr attribute) {
final Attr result = super.setAttributeNode(attribute);
- fireAttributeChangeImpl(event, htmlPage, mappedElement, qualifiedName, attribute.getValue(), oldAttributeValue);
+ fireAttributeChangeImpl(event, htmlPage, mappedElement, oldAttributeValue);
return result;
}
@@ -494,7 +495,7 @@ public void type(final String text) throws IOException {
* @exception IOException if an IO error occurs
*/
public Page type(final char c) throws IOException {
- return type(c, false, true);
+ return type(c, true);
}
/**
@@ -509,9 +510,9 @@ public Page type(final char c) throws IOException {
* @return the page contained in the current window as returned by {@link WebClient#getCurrentWindow()}
* @exception IOException if an IO error occurs
*/
- private Page type(final char c, final boolean startAtEnd, final boolean lastType)
+ private Page type(final char c, final boolean lastType)
throws IOException {
- if (this instanceof DisabledElement && ((DisabledElement) this).isDisabled()) {
+ if (isDisabledElementAndDisabled()) {
return getPage();
}
@@ -537,7 +538,7 @@ private Page type(final char c, final boolean startAtEnd, final boolean lastType
}
final Event keyDown = new KeyboardEvent(this, Event.TYPE_KEY_DOWN, c,
- shiftPressed_ || isShiftNeeded, ctrlPressed_, altPressed_);
+ shiftPressed_ || isShiftNeeded, ctrlPressed_, altPressed_);
final ScriptResult keyDownResult = fireEvent(keyDown);
if (!keyDown.isAborted(keyDownResult)) {
@@ -547,23 +548,43 @@ private Page type(final char c, final boolean startAtEnd, final boolean lastType
if ((shiftDown == null || !shiftDown.isAborted(shiftDownResult))
&& !keyPress.isAborted(keyPressResult)) {
- doType(c, startAtEnd, lastType);
+ doType(c, lastType);
}
}
final WebClient webClient = page.getWebClient();
if (this instanceof HtmlTextInput
|| this instanceof HtmlTextArea
+ || this instanceof HtmlTelInput
+ || this instanceof HtmlNumberInput
+ || this instanceof HtmlSearchInput
|| this instanceof HtmlPasswordInput) {
- fireKeyboardEvent(Event.TYPE_INPUT, c, shiftPressed_ || isShiftNeeded);
+ fireEvent(new KeyboardEvent(this, Event.TYPE_INPUT, c,
+ shiftPressed_ || isShiftNeeded, ctrlPressed_, altPressed_));
}
- fireKeyboardEvent(Event.TYPE_KEY_UP, c, shiftPressed_ || isShiftNeeded);
+ HtmlElement eventSource = this;
+ if (!isAttachedToPage()) {
+ final BrowserVersion browserVersion = page.getWebClient().getBrowserVersion();
+ if (browserVersion.hasFeature(HTMLELEMENT_DETACH_ACTIVE_TRIGGERS_NO_KEYUP_EVENT)) {
+ eventSource = null;
+ }
+ else {
+ eventSource = page.getBody();
+ }
+ }
- if (isShiftNeeded) {
- final Event shiftUp = new KeyboardEvent(this, Event.TYPE_KEY_UP, KeyboardEvent.DOM_VK_SHIFT,
- false, ctrlPressed_, altPressed_);
- fireEvent(shiftUp);
+ if (eventSource != null) {
+ final Event keyUp = new KeyboardEvent(this, Event.TYPE_KEY_UP, c,
+ shiftPressed_ || isShiftNeeded, ctrlPressed_, altPressed_);
+ eventSource.fireEvent(keyUp);
+
+ if (isShiftNeeded) {
+ final Event shiftUp = new KeyboardEvent(this, Event.TYPE_KEY_UP,
+ KeyboardEvent.DOM_VK_SHIFT,
+ false, ctrlPressed_, altPressed_);
+ eventSource.fireEvent(shiftUp);
+ }
}
final HtmlForm form = getEnclosingForm();
@@ -578,10 +599,6 @@ private Page type(final char c, final boolean startAtEnd, final boolean lastType
return webClient.getCurrentWindow().getEnclosedPage();
}
- private void fireKeyboardEvent(final String eventType, final char c, final boolean shift) {
- fireEvent(new KeyboardEvent(this, eventType, c, shift, ctrlPressed_, altPressed_));
- }
-
/**
* Simulates typing the specified key code while this element has focus, returning the page contained
* by this element's window after typing. Note that it may or may not be the same as the original page,
@@ -594,7 +611,7 @@ private void fireKeyboardEvent(final String eventType, final char c, final boole
* @return the page that occupies this window after typing
*/
public Page type(final int keyCode) {
- return type(keyCode, false, true, true, true, true);
+ return type(keyCode, true, true, true, true);
}
/**
@@ -611,11 +628,24 @@ public Page type(final Keyboard keyboard) throws IOException {
Page page = null;
final List keys = keyboard.getKeys();
+
+ if (keyboard.isStartAtEnd()) {
+ if (this instanceof SelectableTextInput) {
+ final SelectableTextInput textInput = (SelectableTextInput) this;
+ textInput.setSelectionStart(textInput.getText().length());
+ }
+ else {
+ final DomText domText = getDoTypeNode();
+ if (domText != null) {
+ domText.moveSelectionToEnd();
+ }
+ }
+ }
+
for (int i = 0; i < keys.size(); i++) {
final Object[] entry = keys.get(i);
- final boolean startAtEnd = i == 0 && keyboard.isStartAtEnd();
if (entry.length == 1) {
- type((char) entry[0], startAtEnd, i == keys.size() - 1);
+ type((char) entry[0], i == keys.size() - 1);
}
else {
final int key = (int) entry[0];
@@ -648,10 +678,10 @@ public Page type(final Keyboard keyboard) throws IOException {
default:
}
- page = type(key, startAtEnd, true, keyPress, keyUp, i == keys.size() - 1);
+ page = type(key, true, keyPress, keyUp, i == keys.size() - 1);
}
else {
- page = type(key, startAtEnd, false, false, true, i == keys.size() - 1);
+ page = type(key, false, false, true, i == keys.size() - 1);
}
}
}
@@ -659,10 +689,10 @@ public Page type(final Keyboard keyboard) throws IOException {
return page;
}
- private Page type(final int keyCode, final boolean startAtEnd,
+ private Page type(final int keyCode,
final boolean fireKeyDown, final boolean fireKeyPress, final boolean fireKeyUp,
final boolean lastType) {
- if (this instanceof DisabledElement && ((DisabledElement) this).isDisabled()) {
+ if (isDisabledElementAndDisabled()) {
return getPage();
}
@@ -699,11 +729,14 @@ private Page type(final int keyCode, final boolean startAtEnd,
if (keyDown != null && !keyDown.isAborted(keyDownResult)
&& (keyPress == null || !keyPress.isAborted(keyPressResult))) {
- doType(keyCode, startAtEnd, lastType);
+ doType(keyCode, lastType);
}
if (this instanceof HtmlTextInput
|| this instanceof HtmlTextArea
+ || this instanceof HtmlTelInput
+ || this instanceof HtmlNumberInput
+ || this instanceof HtmlSearchInput
|| this instanceof HtmlPasswordInput) {
final Event input = new KeyboardEvent(this, Event.TYPE_INPUT, keyCode,
shiftPressed_, ctrlPressed_, altPressed_);
@@ -734,21 +767,12 @@ private Page type(final int keyCode, final boolean startAtEnd,
/**
* Performs the effective type action, called after the keyPress event and before the keyUp event.
* @param c the character you with to simulate typing
- * @param startAtEnd whether typing should start at the text end or not
* @param lastType is this the last character to type
*/
- protected void doType(final char c, final boolean startAtEnd, final boolean lastType) {
- final DomNode domNode = getDoTypeNode();
- if (domNode instanceof DomText) {
- ((DomText) domNode).doType(c, startAtEnd, this, lastType);
- }
- else if (domNode instanceof HtmlElement) {
- try {
- ((HtmlElement) domNode).type(c, startAtEnd, lastType);
- }
- catch (final IOException e) {
- throw new RuntimeException(e);
- }
+ protected void doType(final char c, final boolean lastType) {
+ final DomText domText = getDoTypeNode();
+ if (domText != null) {
+ domText.doType(c, this, lastType);
}
}
@@ -758,16 +782,12 @@ else if (domNode instanceof HtmlElement) {
* An example of predefined values is {@link KeyboardEvent#DOM_VK_PAGE_DOWN}.
*
* @param keyCode the key code wish to simulate typing
- * @param startAtEnd whether typing should start at the text end or not
* @param lastType is this the last to type
*/
- protected void doType(final int keyCode, final boolean startAtEnd, final boolean lastType) {
- final DomNode domNode = getDoTypeNode();
- if (domNode instanceof DomText) {
- ((DomText) domNode).doType(keyCode, startAtEnd, this, lastType);
- }
- else if (domNode instanceof HtmlElement) {
- ((HtmlElement) domNode).type(keyCode, startAtEnd, true, true, true, lastType);
+ protected void doType(final int keyCode, final boolean lastType) {
+ final DomText domText = getDoTypeNode();
+ if (domText != null) {
+ domText.doType(keyCode, this, lastType);
}
}
@@ -775,29 +795,25 @@ else if (domNode instanceof HtmlElement) {
* Returns the node to type into.
* @return the node
*/
- private DomNode getDoTypeNode() {
- DomNode node = null;
+ private DomText getDoTypeNode() {
final HTMLElement scriptElement = getScriptableObject();
if (scriptElement.isIsContentEditable()
|| "on".equals(((Document) scriptElement.getOwnerDocument()).getDesignMode())) {
- final DomNodeList children = getChildNodes();
- if (!children.isEmpty()) {
+
+ DomNodeList children = getChildNodes();
+ while (!children.isEmpty()) {
final DomNode lastChild = children.get(children.size() - 1);
if (lastChild instanceof DomText) {
- node = lastChild;
- }
- else if (lastChild instanceof HtmlElement) {
- node = lastChild;
+ return (DomText) lastChild;
}
+ children = lastChild.getChildNodes();
}
- if (node == null) {
- final DomText domText = new DomText(getPage(), "");
- appendChild(domText);
- node = domText;
- }
+ final DomText domText = new DomText(getPage(), "");
+ appendChild(domText);
+ return domText;
}
- return node;
+ return null;
}
/**
@@ -1171,13 +1187,20 @@ private String getXPathToken() {
return getNodeName() + '[' + nodeIndex + ']';
}
+ /**
+ * @return true if the hidden attribute is set.
+ */
+ public boolean isHidden() {
+ return ATTRIBUTE_NOT_DEFINED != getAttributeDirect("hidden");
+ }
+
/**
* {@inheritDoc}
* Overwritten to support the hidden attribute (html5).
*/
@Override
public boolean isDisplayed() {
- if (ATTRIBUTE_NOT_DEFINED != getAttributeDirect("hidden")) {
+ if (isHidden()) {
return false;
}
return super.isDisplayed();
@@ -1204,7 +1227,7 @@ protected final String getSrcAttributeNormalized() {
// at the moment StringUtils.replaceChars returns the org string
// if nothing to replace was found but the doc implies, that we
// can't trust on this in the future
- final String attrib = getAttributeDirect("src");
+ final String attrib = getAttributeDirect(SRC_ATTRIBUTE);
if (ATTRIBUTE_NOT_DEFINED == attrib) {
return attrib;
}
@@ -1220,7 +1243,13 @@ protected final String getSrcAttributeNormalized() {
*/
@Override
protected void detach() {
- final Object document = getPage().getScriptableObject();
+ final SgmlPage page = getPage();
+ if (!page.getWebClient().isJavaScriptEngineEnabled()) {
+ super.detach();
+ return;
+ }
+
+ final Object document = page.getScriptableObject();
if (document instanceof HTMLDocument) {
final HTMLDocument doc = (HTMLDocument) document;
@@ -1229,10 +1258,10 @@ protected void detach() {
if (activeElement == getScriptableObject()) {
doc.setActiveElement(null);
if (hasFeature(HTMLELEMENT_REMOVE_ACTIVE_TRIGGERS_BLUR_EVENT)) {
- ((HtmlPage) getPage()).setFocusedElement(null);
+ ((HtmlPage) page).setFocusedElement(null);
}
else {
- ((HtmlPage) getPage()).setElementWithFocus(null);
+ ((HtmlPage) page).setElementWithFocus(null);
}
}
else {
@@ -1240,10 +1269,10 @@ protected void detach() {
if (activeElement == child.getScriptableObject()) {
doc.setActiveElement(null);
if (hasFeature(HTMLELEMENT_REMOVE_ACTIVE_TRIGGERS_BLUR_EVENT)) {
- ((HtmlPage) getPage()).setFocusedElement(null);
+ ((HtmlPage) page).setFocusedElement(null);
}
else {
- ((HtmlPage) getPage()).setElementWithFocus(null);
+ ((HtmlPage) page).setElementWithFocus(null);
}
break;
@@ -1263,7 +1292,7 @@ public boolean handles(final Event event) {
return this instanceof SubmittableElement || getTabIndex() != null;
}
- if (this instanceof DisabledElement && ((DisabledElement) this).isDisabled()) {
+ if (isDisabledElementAndDisabled()) {
return false;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmailInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmailInput.java
index 4baf2a5f7af..6abae420868 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmailInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmailInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,6 +47,14 @@ public class HtmlEmailInput extends HtmlInput implements SelectableTextInput {
super(qualifiedName, page, attributes);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
@@ -126,10 +134,7 @@ public String getText() {
* {@inheritDoc}
*/
@Override
- protected void doType(final char c, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final char c, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, c, this, lastType);
}
@@ -137,10 +142,7 @@ protected void doType(final char c, final boolean startAtEnd, final boolean last
* {@inheritDoc}
*/
@Override
- protected void doType(final int keyCode, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final int keyCode, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, keyCode, this, lastType);
}
@@ -154,6 +156,16 @@ protected void typeDone(final String newValue, final boolean notifyAttributeChan
}
}
+ /**
+ * {@inheritDoc}
+ * @see HtmlInput#reset()
+ */
+ @Override
+ public void reset() {
+ super.reset();
+ setSelectionEnd(0);
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmbed.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmbed.java
index 330a5ad7576..d3fdb325ac4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmbed.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmbed.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,10 +15,11 @@
package com.gargoylesoftware.htmlunit.html;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.net.URL;
+import java.nio.file.Files;
import java.util.Map;
import org.apache.commons.io.IOUtils;
@@ -62,12 +63,13 @@ public void saveAs(final File file) throws IOException {
final HtmlPage page = (HtmlPage) getPage();
final WebClient webclient = page.getWebClient();
- final URL url = page.getFullyQualifiedUrl(getAttributeDirect("src"));
+ final URL url = page.getFullyQualifiedUrl(getAttributeDirect(SRC_ATTRIBUTE));
final WebRequest request = new WebRequest(url);
+ request.setCharset(page.getCharset());
request.setAdditionalHeader(HttpHeader.REFERER, page.getUrl().toExternalForm());
final WebResponse webResponse = webclient.loadWebResponse(request);
- try (FileOutputStream fos = new FileOutputStream(file);
+ try (OutputStream fos = Files.newOutputStream(file.toPath());
InputStream content = webResponse.getContentAsStream()) {
IOUtils.copy(content, fos);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmphasis.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmphasis.java
index d4c42810b1a..6f48be5e9b3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmphasis.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlEmphasis.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlExample.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlExample.java
index 94fbb5d5309..a7cf4da0706 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlExample.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlExample.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFieldSet.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFieldSet.java
index 741968a221b..5d989ca542f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFieldSet.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFieldSet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFigure.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFigure.java
index ad610719bdb..180989145d4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFigure.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFigure.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFigureCaption.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFigureCaption.java
index 6763215ff7c..e7ea6abd8c1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFigureCaption.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFigureCaption.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFileInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFileInput.java
index a51a5ea2076..1f30cf49ba4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFileInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFileInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
import com.gargoylesoftware.htmlunit.util.KeyDataPair;
+import com.gargoylesoftware.htmlunit.util.MimeType;
import com.gargoylesoftware.htmlunit.util.NameValuePair;
/**
@@ -85,6 +86,14 @@ public final void setData(final byte[] data) {
data_ = data;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
@@ -100,7 +109,7 @@ public NameValuePair[] getSubmitNameValuePairs() {
if (contentType_ == null) {
contentType = getPage().getWebClient().getBrowserVersion().getUploadMimeType(file);
if (StringUtils.isEmpty(contentType)) {
- contentType = "application/octet-stream";
+ contentType = MimeType.APPLICATION_OCTET_STREAM;
}
}
else {
@@ -111,7 +120,7 @@ public NameValuePair[] getSubmitNameValuePairs() {
keyDataPair.setData(data_);
list.add(keyDataPair);
}
- return list.toArray(new NameValuePair[list.size()]);
+ return list.toArray(new NameValuePair[0]);
}
/**
@@ -196,4 +205,14 @@ private static File normalizeFile(final File file) {
public File[] getFiles() {
return files_;
}
+
+ /**
+ * Returns whether this element satisfies all form validation constraints set.
+ * @return whether this element satisfies all form validation constraints set
+ */
+ @Override
+ public boolean isValid() {
+ return !isRequiredSupported() || getAttributeDirect("required") == ATTRIBUTE_NOT_DEFINED
+ || files_.length > 0;
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFont.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFont.java
index 051b0c69da7..b2671263576 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFont.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFont.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFooter.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFooter.java
index 6bf18609763..1c2e9fb061f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFooter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFooter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlForm.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlForm.java
index 7cac8d5373f..69a3e0bc0d5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlForm.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlForm.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +34,8 @@
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.http.client.utils.URLEncodedUtils;
import com.gargoylesoftware.htmlunit.BrowserVersion;
@@ -71,6 +73,7 @@
* @author Anton Demydenko
*/
public class HtmlForm extends HtmlElement {
+ private static final Log LOG = LogFactory.getLog(HtmlForm.class);
/** The HTML tag represented by this element. */
public static final String TAG_NAME = "form";
@@ -113,10 +116,11 @@ public class HtmlForm extends HtmlElement {
Page submit(final SubmittableElement submitElement) {
final HtmlPage htmlPage = (HtmlPage) getPage();
final WebClient webClient = htmlPage.getWebClient();
- if (webClient.getOptions().isJavaScriptEnabled()) {
+ if (webClient.isJavaScriptEnabled()) {
if (submitElement != null) {
isPreventDefault_ = false;
- if (!areChildrenValid()) {
+ if (getAttributeDirect("novalidate") == ATTRIBUTE_NOT_DEFINED
+ && !areChildrenValid()) {
return htmlPage;
}
final ScriptResult scriptResult = fireEvent(Event.TYPE_SUBMIT);
@@ -125,13 +129,14 @@ Page submit(final SubmittableElement submitElement) {
if (scriptResult == null) {
return htmlPage;
}
- return scriptResult.getNewPage();
+ return htmlPage.getWebClient().getCurrentWindow().getEnclosedPage();
}
}
final String action = getActionAttribute().trim();
if (StringUtils.startsWithIgnoreCase(action, JavaScriptURLConnection.JAVASCRIPT_PREFIX)) {
- return htmlPage.executeJavaScript(action, "Form action", getStartLineNumber()).getNewPage();
+ htmlPage.executeJavaScript(action, "Form action", getStartLineNumber());
+ return htmlPage.getWebClient().getCurrentWindow().getEnclosedPage();
}
}
else {
@@ -217,6 +222,9 @@ private boolean areChildrenValid() {
boolean valid = true;
for (HtmlElement element : getFormHtmlElementDescendants()) {
if (element instanceof HtmlInput && !((HtmlInput) element).isValid()) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Form validation failed; element '" + element + "' was not valid. Submit cancelled.");
+ }
valid = false;
break;
}
@@ -249,13 +257,14 @@ public WebRequest getWebRequest(final SubmittableElement submitElement) {
final BrowserVersion browser = getPage().getWebClient().getBrowserVersion();
String actionUrl = getActionAttribute();
String anchor = null;
- String queryFromFields = "";
+ String queryFormFields = "";
+ final Charset enc = getSubmitCharset();
+
if (HttpMethod.GET == method) {
if (actionUrl.contains("#")) {
anchor = StringUtils.substringAfter(actionUrl, "#");
}
- final Charset enc = getPage().getCharset();
- queryFromFields =
+ queryFormFields =
URLEncodedUtils.format(Arrays.asList(NameValuePair.toHttpClient(parameters)), enc);
// action may already contain some query parameters: they have to be removed
@@ -263,6 +272,7 @@ public WebRequest getWebRequest(final SubmittableElement submitElement) {
actionUrl = StringUtils.substringBefore(actionUrl, "?");
parameters.clear(); // parameters have been added to query
}
+
URL url;
try {
if (actionUrl.isEmpty()) {
@@ -272,8 +282,8 @@ public WebRequest getWebRequest(final SubmittableElement submitElement) {
url = htmlPage.getFullyQualifiedUrl(actionUrl);
}
- if (!queryFromFields.isEmpty()) {
- url = UrlUtils.getUrlWithNewQuery(url, queryFromFields);
+ if (!queryFormFields.isEmpty()) {
+ url = UrlUtils.getUrlWithNewQuery(url, queryFormFields);
}
if (HttpMethod.GET == method && browser.hasFeature(FORM_SUBMISSION_URL_WITHOUT_HASH)
@@ -295,22 +305,28 @@ else if (anchor != null
throw new IllegalArgumentException("Not a valid url: " + actionUrl);
}
- final WebRequest request = new WebRequest(url, method);
- request.setAdditionalHeader(HttpHeader.ACCEPT, browser.getHtmlAcceptHeader());
- request.setAdditionalHeader(HttpHeader.ACCEPT_ENCODING, "gzip, deflate");
+ final WebRequest request = new WebRequest(url, browser.getHtmlAcceptHeader(),
+ browser.getAcceptEncodingHeader());
+ request.setHttpMethod(method);
request.setRequestParameters(parameters);
if (HttpMethod.POST == method) {
request.setEncodingType(FormEncodingType.getInstance(getEnctypeAttribute()));
}
- request.setCharset(getSubmitCharset());
+ request.setCharset(enc);
- String referer = htmlPage.getUrl().toExternalForm();
- request.setAdditionalHeader(HttpHeader.REFERER, referer);
+ request.setAdditionalHeader(HttpHeader.REFERER, htmlPage.getUrl().toExternalForm());
if (HttpMethod.POST == method
&& browser.hasFeature(FORM_SUBMISSION_HEADER_ORIGIN)) {
- referer = StringUtils.stripEnd(referer, "/");
- request.setAdditionalHeader(HttpHeader.ORIGIN, referer);
+ try {
+ request.setAdditionalHeader(HttpHeader.ORIGIN,
+ UrlUtils.getUrlWithProtocolAndAuthority(htmlPage.getUrl()).toExternalForm());
+ }
+ catch (final MalformedURLException e) {
+ if (LOG.isWarnEnabled()) {
+ LOG.info("Invalid origin url '" + htmlPage.getUrl() + "'");
+ }
+ }
}
if (HttpMethod.POST == method
&& browser.hasFeature(FORM_SUBMISSION_HEADER_CACHE_CONTROL_MAX_AGE)) {
@@ -375,7 +391,7 @@ public Page reset() {
final SgmlPage htmlPage = getPage();
final ScriptResult scriptResult = fireEvent(Event.TYPE_RESET);
if (ScriptResult.isFalse(scriptResult)) {
- return scriptResult.getNewPage();
+ return htmlPage.getWebClient().getCurrentWindow().getEnclosedPage();
}
for (final HtmlElement next : getHtmlElementDescendants()) {
@@ -472,11 +488,8 @@ private static boolean isSubmittable(final HtmlElement element, final Submittabl
return false;
}
}
- if (HtmlButton.TAG_NAME.equals(tagName)) {
- return false;
- }
- return true;
+ return !HtmlButton.TAG_NAME.equals(tagName);
}
/**
@@ -916,11 +929,13 @@ public List getInputsByValue(final String value) {
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Allows the parser to notify the form of a field that doesn't belong to its DOM children
* due to malformed HTML code
- * @param element the form field
+ * @param field the form field
*/
- void addLostChild(final HtmlElement field) {
+ public void addLostChild(final HtmlElement field) {
lostChildren_.add(field);
field.setOwningForm(this);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFrame.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFrame.java
index e9ed3453f1d..7990892e300 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFrame.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFrame.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFrameSet.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFrameSet.java
index 3826cbfdb67..5c010fdd620 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFrameSet.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlFrameSet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHead.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHead.java
index ca9bcd2f46f..a226e3f21cf 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHead.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHead.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeader.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeader.java
index 41eb80b0433..9e1dd635578 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeader.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading1.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading1.java
index efea330234c..fadcb24b0e6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading1.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading1.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading2.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading2.java
index 03d72458b3a..258fdd2d507 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading2.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading3.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading3.java
index 5adf0e0d701..8321d2ccff5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading3.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading3.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading4.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading4.java
index be5e29662f4..198f1084be3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading4.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading4.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading5.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading5.java
index d0c461b17c6..f1bb23801e9 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading5.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading5.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading6.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading6.java
index cd4bc03c931..e150266d63c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading6.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHeading6.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHiddenInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHiddenInput.java
index fbc3ab3bb9b..73acfb313c9 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHiddenInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHiddenInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -67,6 +67,14 @@ public String asText() {
return "";
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHorizontalRule.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHorizontalRule.java
index 1ca68404569..676e82c92f8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHorizontalRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHorizontalRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHtml.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHtml.java
index 26fb9dc7710..9d490b76121 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHtml.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlHtml.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlImage.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlImage.java
index 26c9d660f37..df066023ca3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlImage.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlImage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,10 +22,12 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_IMAGE_COMPLETE_RETURNS_TRUE_FOR_NO_REQUEST;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
import java.net.URL;
+import java.nio.file.Files;
import java.util.Iterator;
import java.util.Map;
@@ -39,6 +41,7 @@
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpStatus;
+import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.HttpHeader;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.SgmlPage;
@@ -46,8 +49,9 @@
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.javascript.PostponedAction;
-import com.gargoylesoftware.htmlunit.javascript.host.dom.Node;
+import com.gargoylesoftware.htmlunit.javascript.host.dom.Document;
import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
+import com.gargoylesoftware.htmlunit.util.UrlUtils;
/**
* Wrapper for the HTML element "img".
@@ -80,7 +84,7 @@ public class HtmlImage extends HtmlElement {
private int height_ = -1;
private boolean downloaded_;
private boolean isComplete_;
- private boolean onloadInvoked_;
+ private boolean onloadProcessed_;
private boolean createdByJavascript_;
/**
@@ -130,14 +134,14 @@ protected void setAttributeNS(final String namespaceURI, final String qualifiedN
final boolean notifyAttributeChangeListeners, final boolean notifyMutationObservers) {
final HtmlPage htmlPage = getHtmlPageOrNull();
- if ("src".equals(qualifiedName) && value != ATTRIBUTE_NOT_DEFINED && htmlPage != null) {
+ if (SRC_ATTRIBUTE.equals(qualifiedName) && value != ATTRIBUTE_NOT_DEFINED && htmlPage != null) {
final String oldValue = getAttributeNS(namespaceURI, qualifiedName);
if (!oldValue.equals(value)) {
super.setAttributeNS(namespaceURI, qualifiedName, value, notifyAttributeChangeListeners,
notifyMutationObservers);
// onload handlers may need to be invoked again, and a new image may need to be downloaded
- onloadInvoked_ = false;
+ onloadProcessed_ = false;
downloaded_ = false;
isComplete_ = false;
width_ = -1;
@@ -167,23 +171,83 @@ public void execute() throws Exception {
notifyMutationObservers);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void processImportNode(final Document doc) {
+ URL oldUrl = null;
+ final String src = getSrcAttribute();
+ HtmlPage htmlPage = getHtmlPageOrNull();
+ try {
+ if (htmlPage != null) {
+ oldUrl = htmlPage.getFullyQualifiedUrl(src);
+ }
+ }
+ catch (final MalformedURLException e) {
+ // ignore
+ }
+
+ super.processImportNode(doc);
+
+ URL url = null;
+ htmlPage = getHtmlPageOrNull();
+ try {
+ if (htmlPage != null) {
+ url = htmlPage.getFullyQualifiedUrl(src);
+ }
+ }
+ catch (final MalformedURLException e) {
+ // ignore
+ }
+
+ if (oldUrl == null || !UrlUtils.sameFile(oldUrl, url)) {
+ // image has to be reloaded
+ lastClickX_ = 0;
+ lastClickY_ = 0;
+ imageWebResponse_ = null;
+ imageData_ = null;
+ width_ = -1;
+ height_ = -1;
+ downloaded_ = false;
+ isComplete_ = false;
+ onloadProcessed_ = false;
+ createdByJavascript_ = true;
+ }
+
+ if (htmlPage == null) {
+ return; // nothing to do if embedded in XML code
+ }
+
+ if (htmlPage.getWebClient().getOptions().isDownloadImages()) {
+ try {
+ downloadImageIfNeeded();
+ }
+ catch (final IOException e) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Unable to download image for element " + this);
+ }
+ }
+ }
+ }
+
/**
* INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
*
- * Executes this element's onload handler if it has one. This method also downloads the image
- * if this element has an onload handler (prior to invoking said handler), because applications
- * sometimes use images to send information to the server and use the onload handler to get notified
- * when the information has been received by the server.
+ * Executes this element's onload or onerror handler. This method downloads the image
+ * if either of these handlers are present (prior to invoking the resulting handler), because applications
+ * sometimes use images to send information to the server and use these handlers to get notified when the
+ * information has been received by the server.
*
* See here and
* here for the discussion which
* lead up to this method.
*
- * This method may be called multiple times, but will only attempt to execute the onload
- * handler the first time it is invoked.
+ * This method may be called multiple times, but will only attempt to execute the onload or
+ * onerror handler the first time it is invoked.
*/
public void doOnLoad() {
- if (onloadInvoked_) {
+ if (onloadProcessed_) {
return;
}
@@ -193,47 +257,48 @@ public void doOnLoad() {
}
final WebClient client = htmlPage.getWebClient();
- if (!client.getOptions().isJavaScriptEnabled()) {
- onloadInvoked_ = true;
+ if (!client.isJavaScriptEnabled()) {
+ onloadProcessed_ = true;
return;
}
- if (hasEventHandlers("onload") && !getSrcAttribute().isEmpty()) {
- // An onload handler and source are defined; we need to download the image and then call the onload handler.
- onloadInvoked_ = true;
- try {
- downloadImageIfNeeded();
- final int i = imageWebResponse_.getStatusCode();
- if ((i >= HttpStatus.SC_OK && i < HttpStatus.SC_MULTIPLE_CHOICES)
- || i == HttpStatus.SC_USE_PROXY) {
-
- // If the download was a success, trigger the onload handler.
- final Event event = new Event(this, Event.TYPE_LOAD);
- final Node scriptObject = getScriptableObject();
-
- final String readyState = htmlPage.getReadyState();
- if (READY_STATE_LOADING.equals(readyState)) {
- final PostponedAction action = new PostponedAction(getPage()) {
- @Override
- public void execute() throws Exception {
- scriptObject.executeEventLocally(event);
- }
- };
- htmlPage.addAfterLoadAction(action);
- }
- else {
- scriptObject.executeEventLocally(event);
+ if ((hasEventHandlers("onload") || hasEventHandlers("onerror")) && hasAttribute(SRC_ATTRIBUTE)) {
+ onloadProcessed_ = true;
+ boolean loadSuccessful = false;
+ if (!getSrcAttribute().isEmpty()) {
+ // We need to download the image and then call the resulting handler.
+ try {
+ downloadImageIfNeeded();
+ final int i = imageWebResponse_.getStatusCode();
+ // if the download was a success
+ if ((i >= HttpStatus.SC_OK && i < HttpStatus.SC_MULTIPLE_CHOICES)
+ || i == HttpStatus.SC_USE_PROXY) {
+ loadSuccessful = true; // Trigger the onload handler
}
}
- return;
- }
- catch (final IOException e) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("IOException while downloading image for '" + this + "' : " + e.getMessage());
+ catch (final IOException e) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("IOException while downloading image for '" + this + "' : " + e.getMessage());
+ }
}
}
+
+ final Event event = new Event(this, loadSuccessful ? Event.TYPE_LOAD : Event.TYPE_ERROR);
if (LOG.isDebugEnabled()) {
- LOG.debug("Unable to download image for '" + this + "'; not firing onload event.");
+ LOG.debug("Firing the " + event.getType() + " event for '" + this + "'.");
+ }
+
+ if (READY_STATE_LOADING.equals(htmlPage.getReadyState())) {
+ final PostponedAction action = new PostponedAction(getPage()) {
+ @Override
+ public void execute() throws Exception {
+ HtmlImage.this.fireEvent(event);
+ }
+ };
+ htmlPage.addAfterLoadAction(action);
+ }
+ else {
+ fireEvent(event);
}
}
}
@@ -455,16 +520,21 @@ private void downloadImageIfNeeded() throws IOException {
if (!downloaded_) {
// HTMLIMAGE_BLANK_SRC_AS_EMPTY
final String src = getSrcAttribute();
- if (!"".equals(src)
- && !(hasFeature(HTMLIMAGE_BLANK_SRC_AS_EMPTY) && StringUtils.isBlank(src))) {
- final HtmlPage page = (HtmlPage) getPage();
- final WebClient webclient = page.getWebClient();
- final URL url = page.getFullyQualifiedUrl(src);
- final String accept = webclient.getBrowserVersion().getImgAcceptHeader();
- final WebRequest request = new WebRequest(url, accept);
- request.setAdditionalHeader(HttpHeader.REFERER, page.getUrl().toExternalForm());
- imageWebResponse_ = webclient.loadWebResponse(request);
+ if (!"".equals(src)) {
+ final HtmlPage page = (HtmlPage) getPage();
+ final WebClient webClient = page.getWebClient();
+ final BrowserVersion browser = webClient.getBrowserVersion();
+
+ if (!(browser.hasFeature(HTMLIMAGE_BLANK_SRC_AS_EMPTY)
+ && StringUtils.isBlank(src))) {
+ final URL url = page.getFullyQualifiedUrl(src);
+ final WebRequest request = new WebRequest(url, browser.getImgAcceptHeader(),
+ browser.getAcceptEncodingHeader());
+ request.setCharset(page.getCharset());
+ request.setAdditionalHeader(HttpHeader.REFERER, page.getUrl().toExternalForm());
+ imageWebResponse_ = webClient.loadWebResponse(request);
+ }
}
if (imageData_ != null) {
@@ -484,7 +554,7 @@ private void readImageIfNeeded() throws IOException {
downloadImageIfNeeded();
if (imageData_ == null) {
if (null == imageWebResponse_) {
- throw new IOException("No image response available (src=" + getSrcAttribute() + ")");
+ throw new IOException("No image response available (src='" + getSrcAttribute() + "')");
}
@SuppressWarnings("resource")
final ImageInputStream iis = ImageIO.createImageInputStream(imageWebResponse_.getContentAsStream());
@@ -578,9 +648,9 @@ protected boolean doClickStateUpdate(final boolean shiftKey, final boolean ctrlK
public void saveAs(final File file) throws IOException {
downloadImageIfNeeded();
if (null != imageWebResponse_) {
- try (FileOutputStream fileOut = new FileOutputStream(file);
+ try (OutputStream fos = Files.newOutputStream(file.toPath());
InputStream inputStream = imageWebResponse_.getContentAsStream()) {
- IOUtils.copy(inputStream, fileOut);
+ IOUtils.copy(inputStream, fos);
}
}
}
@@ -649,15 +719,6 @@ public boolean isComplete() {
: imageData_ != null);
}
- /**
- * @return true if the image was successfully downloaded
- * @deprecated as of 2.26, please use {@link #isComplete()} instead
- */
- @Deprecated
- public boolean getComplete() {
- return isComplete();
- }
-
/**
* {@inheritDoc}
*/
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlImageInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlImageInput.java
index 1c2dc54781a..0fecd24efdb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlImageInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlImageInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,15 +19,17 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_IMAGE_COMPLETE_RETURNS_TRUE_FOR_NO_REQUEST;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.net.URL;
+import java.nio.file.Files;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
+import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.ElementNotFoundException;
import com.gargoylesoftware.htmlunit.HttpHeader;
import com.gargoylesoftware.htmlunit.Page;
@@ -161,9 +163,19 @@ public P click(final int x, final int y) throws IOException, El
* @exception IOException if an IO error occurs
*/
@Override
- public
P click(final Event event, final boolean ignoreVisibility) throws IOException {
+ public
P click(final Event event,
+ final boolean shiftKey, final boolean ctrlKey, final boolean altKey,
+ final boolean ignoreVisibility) throws IOException {
wasPositionSpecified_ = true;
- return super.click(event, ignoreVisibility);
+ return super.click(event, shiftKey, ctrlKey, altKey, ignoreVisibility);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
}
/**
@@ -211,13 +223,15 @@ private void downloadImageIfNeeded() throws IOException {
if (!"".equals(src)
&& !(hasFeature(HTMLIMAGE_BLANK_SRC_AS_EMPTY) && StringUtils.isBlank(src))) {
final HtmlPage page = (HtmlPage) getPage();
- final WebClient webclient = page.getWebClient();
+ final WebClient webClient = page.getWebClient();
final URL url = page.getFullyQualifiedUrl(src);
- final String accept = webclient.getBrowserVersion().getImgAcceptHeader();
- final WebRequest request = new WebRequest(url, accept);
+ final BrowserVersion browser = webClient.getBrowserVersion();
+ final WebRequest request = new WebRequest(url, browser.getImgAcceptHeader(),
+ browser.getAcceptEncodingHeader());
+ request.setCharset(page.getCharset());
request.setAdditionalHeader(HttpHeader.REFERER, page.getUrl().toExternalForm());
- imageWebResponse_ = webclient.loadWebResponse(request);
+ imageWebResponse_ = webClient.loadWebResponse(request);
}
if (imageData_ != null) {
@@ -237,9 +251,9 @@ private void downloadImageIfNeeded() throws IOException {
public void saveAs(final File file) throws IOException {
downloadImageIfNeeded();
if (null != imageWebResponse_) {
- try (FileOutputStream fileOut = new FileOutputStream(file);
+ try (OutputStream fos = Files.newOutputStream(file.toPath());
InputStream inputStream = imageWebResponse_.getContentAsStream()) {
- IOUtils.copy(inputStream, fileOut);
+ IOUtils.copy(inputStream, fos);
}
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInlineFrame.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInlineFrame.java
index c23d0cadcc2..8504181fbdf 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInlineFrame.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInlineFrame.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInlineQuotation.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInlineQuotation.java
index 83cc946d5e3..6945e585672 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInlineQuotation.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInlineQuotation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInput.java
index 7f7eb209b6c..fa63fdf0126 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.html;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_INPUT_DISPLAY_INLINE_BLOCK;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_INPUT_DISPLAY_RADIO_CHECKBOX_INLINE_BLOCK;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_MOUSE_ON_DISABLED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLINPUT_DOES_NOT_CLICK_SURROUNDING_ANCHOR;
@@ -417,18 +418,6 @@ public String getDefaultValue() {
return defaultValue_;
}
- /**
- * {@inheritDoc} The default implementation is empty; only checkboxes and radio buttons
- * really care what the default checked value is.
- * @see SubmittableElement#setDefaultChecked(boolean)
- * @see HtmlRadioButtonInput#setDefaultChecked(boolean)
- * @see HtmlCheckBoxInput#setDefaultChecked(boolean)
- */
- @Override
- public void setDefaultChecked(final boolean defaultChecked) {
- // Empty.
- }
-
/**
* {@inheritDoc} The default implementation returns {@code false}; only checkboxes and
* radio buttons really care what the default checked value is.
@@ -529,7 +518,7 @@ static Page executeOnChangeHandlerIfAppropriate(final HtmlElement htmlElement) {
if (scriptResult != null) {
// current window doesn't exist anymore
- return scriptResult.getNewPage();
+ return page.getWebClient().getCurrentWindow().getEnclosedPage();
}
return page;
@@ -627,6 +616,15 @@ public DisplayStyle getDefaultStyleDisplay() {
if (hasFeature(CSS_INPUT_DISPLAY_INLINE_BLOCK)) {
return DisplayStyle.INLINE_BLOCK;
}
+
+ if (hasFeature(CSS_INPUT_DISPLAY_RADIO_CHECKBOX_INLINE_BLOCK)) {
+ final String type = getTypeAttribute();
+ if ("radio".equals(type)
+ || "checkbox".equals(type)) {
+ return DisplayStyle.INLINE_BLOCK;
+ }
+ }
+
return DisplayStyle.INLINE;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInsertedText.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInsertedText.java
index dc4bd73d4f5..4138ea056c1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInsertedText.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlInsertedText.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlIsIndex.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlIsIndex.java
index 2167390bb57..680c3b1c21b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlIsIndex.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlIsIndex.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlItalic.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlItalic.java
index 3fd8b5864bc..5b6dbddce48 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlItalic.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlItalic.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlKeyboard.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlKeyboard.java
index a86dab7b27c..45cefaf9830 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlKeyboard.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlKeyboard.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLabel.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLabel.java
index f1932bb2a34..3b714ba5a0d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLabel.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLabel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -148,23 +148,20 @@ public HtmlElement getReferencedElement() {
* {@inheritDoc}
*/
@Override
- public
P click(final Event event, final boolean ignoreVisibility) throws IOException {
+ public
P click(final Event event,
+ final boolean shiftKey, final boolean ctrlKey, final boolean altKey,
+ final boolean ignoreVisibility) throws IOException {
// first the click on the label
- final P page = super.click(event, ignoreVisibility);
-
- // not sure which page we should return
- final P response;
+ final P page = super.click(event, shiftKey, ctrlKey, altKey, ignoreVisibility);
// then the click on the referenced element
final HtmlElement element = getReferencedElement();
- if (element != null) {
- response = element.click(false, false, false, false, true, true);
- }
- else {
- response = page;
+ if (element == null || element.isDisabledElementAndDisabled()) {
+ return page;
}
- return response;
+ // not sure which page we should return
+ return element.click(false, false, false, false, true, true);
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLayer.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLayer.java
index 80561e45734..76ecda765a6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLayer.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLayer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLegend.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLegend.java
index 5130080c869..00b688c7331 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLegend.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLegend.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLink.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLink.java
index 879b2343492..24c88b5cc01 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLink.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlLink.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpStatus;
+import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.HttpHeader;
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.WebClient;
@@ -226,13 +227,13 @@ public WebRequest getWebRequest() throws MalformedURLException {
final HtmlPage page = (HtmlPage) getPage();
final URL url = page.getFullyQualifiedUrl(getHrefAttribute());
- final WebRequest request = new WebRequest(url);
+ final BrowserVersion browser = page.getWebClient().getBrowserVersion();
+ final WebRequest request = new WebRequest(url, browser.getCssAcceptHeader(), browser.getAcceptEncodingHeader());
+ // use the page encoding even if this is a GET requests
+ request.setCharset(page.getCharset());
request.setAdditionalHeader(HttpHeader.REFERER, page.getUrl().toExternalForm());
- final String accept = page.getWebClient().getBrowserVersion().getCssAcceptHeader();
- request.setAdditionalHeader(HttpHeader.ACCEPT, accept);
-
return request;
}
@@ -266,7 +267,7 @@ private void executeEvent(final String type) {
* {@inheritDoc}
*/
@Override
- protected void onAllChildrenAddedToPage(final boolean postponed) {
+ public void onAllChildrenAddedToPage(final boolean postponed) {
if (getOwnerDocument() instanceof XmlPage) {
return;
}
@@ -274,8 +275,29 @@ protected void onAllChildrenAddedToPage(final boolean postponed) {
LOG.debug("Link node added: " + asXml());
}
- if (!getPage().getWebClient().getOptions().isCssEnabled()
- || !StyleSheetList.isStyleSheetLink(this)) {
+ final WebClient webClient = getPage().getWebClient();
+ if (!StyleSheetList.isStyleSheetLink(this)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Link type '" + getRelAttribute() + "' not supported ("
+ + asXml().replaceAll("\\r|\\n", "") + ").");
+ }
+
+ return;
+ }
+
+ if (!webClient.getOptions().isCssEnabled()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Stylesheet Link found but ignored because css support is disabled ("
+ + asXml().replaceAll("\\r|\\n", "") + ").");
+ }
+ return;
+ }
+
+ if (!webClient.isJavaScriptEngineEnabled()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Stylesheet Link found but ignored because javascript engine is disabled ("
+ + asXml().replaceAll("\\r|\\n", "") + ").");
+ }
return;
}
@@ -287,7 +309,7 @@ public void execute() {
}
};
- final AbstractJavaScriptEngine> engine = getPage().getWebClient().getJavaScriptEngine();
+ final AbstractJavaScriptEngine> engine = webClient.getJavaScriptEngine();
if (postponed) {
engine.addPostponedAction(action);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlListItem.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlListItem.java
index eca5d33dbcf..ccc2b96010e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlListItem.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlListItem.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlListing.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlListing.java
index 71780c517be..dced694c98f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlListing.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlListing.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMain.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMain.java
index d6cf026e4f5..ea4bc39174c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMain.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMain.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMap.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMap.java
index c88e6329979..7b4910ded1c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMap.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMark.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMark.java
index 2ec87ffb3cb..4cb68d89eeb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMark.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMark.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMarquee.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMarquee.java
index b6eed2a40e8..94e55fbf354 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMarquee.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMarquee.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMedia.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMedia.java
index fb644298bb9..113a6652ca1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMedia.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMedia.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMenu.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMenu.java
index 3c9bf24a9c4..b1264f57efb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMenu.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMenu.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMenuItem.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMenuItem.java
index f75596f29cb..e0d0e43ffce 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMenuItem.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMenuItem.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMeta.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMeta.java
index 8969b33adf3..2c6161b69d8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMeta.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMeta.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,22 +45,15 @@ public class HtmlMeta extends HtmlElement {
final Map attributes) {
super(qualifiedName, page, attributes);
+ // Handles the cookies specified in meta tags,
+ // like <meta http-equiv='set-cookie' content='webm=none; path=/;'> .
if ("set-cookie".equalsIgnoreCase(getHttpEquivAttribute())) {
- performSetCookie();
+ final WebClient client = page.getWebClient();
+ final URL url = page.getUrl();
+ client.addCookie(getContentAttribute(), url, this);
}
}
- /**
- * Handles the cookies specified in meta tags,
- * like <meta http-equiv='set-cookie' content='webm=none; path=/;'> .
- */
- protected void performSetCookie() {
- final SgmlPage page = getPage();
- final WebClient client = page.getWebClient();
- final URL url = page.getUrl();
- client.addCookie(getContentAttribute(), url, this);
- }
-
/**
* {@inheritDoc}
*/
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMeter.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMeter.java
index 30357cb075d..f994f734050 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMeter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMeter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMonthInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMonthInput.java
index 017fbe95194..147b99b35bb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMonthInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMonthInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,13 +14,15 @@
*/
package com.gargoylesoftware.htmlunit.html;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INPUT_SET_VALUE_DATE_SUPPORTED;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLINPUT_TYPE_DATETIME_SUPPORTED;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLINPUT_TYPE_MONTH_NOT_SUPPORTED;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Map;
import com.gargoylesoftware.htmlunit.SgmlPage;
+import org.apache.commons.lang3.StringUtils;
/**
* Wrapper for the HTML element "input" where type is "month".
@@ -43,13 +45,23 @@ public class HtmlMonthInput extends HtmlInput {
super(qualifiedName, page, attributes);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
@Override
public void setValueAttribute(final String newValue) {
try {
- if (hasFeature(JS_INPUT_SET_VALUE_DATE_SUPPORTED)) {
+ if (hasFeature(HTMLINPUT_TYPE_DATETIME_SUPPORTED)
+ && !hasFeature(HTMLINPUT_TYPE_MONTH_NOT_SUPPORTED)
+ && StringUtils.isNotEmpty(newValue)) {
FORMATTER_.parse(newValue);
}
super.setValueAttribute(newValue);
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMultiColumn.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMultiColumn.java
index eb9c79fa83d..f93eb1d2762 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMultiColumn.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlMultiColumn.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNav.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNav.java
index 397636919e3..e245e3c30f0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNav.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNav.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNextId.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNextId.java
index 8af81ced4f6..47578e2db36 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNextId.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNextId.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoBreak.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoBreak.java
index 96fa2ca57b5..c6a87585952 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoBreak.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoBreak.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoEmbed.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoEmbed.java
index 52eab4668dd..818de9ff808 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoEmbed.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoEmbed.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoFrames.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoFrames.java
index 171e1b31dd8..bbfb67ea4d1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoFrames.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoFrames.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoLayer.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoLayer.java
index b7d50d0b3e7..e4d4d0130ae 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoLayer.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoLayer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoScript.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoScript.java
index 02492df2cdf..148f865ad44 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoScript.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNoScript.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -52,7 +52,7 @@ public class HtmlNoScript extends HtmlElement {
*/
@Override
public DisplayStyle getDefaultStyleDisplay() {
- if (!getPage().getWebClient().getOptions().isJavaScriptEnabled()) {
+ if (!getPage().getWebClient().isJavaScriptEnabled()) {
return DisplayStyle.BLOCK;
}
if (hasFeature(CSS_NOSCRIPT_DISPLAY_INLINE)) {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNumberInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNumberInput.java
index 6d5e3029f5d..9e814a7b91e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNumberInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlNumberInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -49,10 +49,7 @@ public class HtmlNumberInput extends HtmlInput implements SelectableTextInput {
* {@inheritDoc}
*/
@Override
- protected void doType(final char c, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final char c, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, c, this, lastType);
}
@@ -60,10 +57,7 @@ protected void doType(final char c, final boolean startAtEnd, final boolean last
* {@inheritDoc}
*/
@Override
- protected void doType(final int keyCode, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final int keyCode, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, keyCode, this, lastType);
}
@@ -174,17 +168,17 @@ protected void setAttributeNS(final String namespaceURI, final String qualifiedN
* {@inheritDoc}
*/
@Override
- protected Object clone() throws CloneNotSupportedException {
- return new HtmlNumberInput(getQualifiedName(), getPage(), getAttributesMap());
+ public void setDefaultValue(final String defaultValue) {
+ final boolean modifyValue = getValueAttribute().equals(getDefaultValue());
+ setDefaultValue(defaultValue, modifyValue);
}
/**
* {@inheritDoc}
*/
@Override
- public void setDefaultValue(final String defaultValue) {
- final boolean modifyValue = getValueAttribute().equals(getDefaultValue());
- setDefaultValue(defaultValue, modifyValue);
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
}
/**
@@ -203,6 +197,16 @@ public void setValueAttribute(final String newValue) {
}
}
+ /**
+ * {@inheritDoc}
+ * @see HtmlInput#reset()
+ */
+ @Override
+ public void reset() {
+ super.reset();
+ setSelectionEnd(0);
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlObject.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlObject.java
index 0954e79277e..ef0354563c6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlObject.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlObject.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -63,8 +63,6 @@ public class HtmlObject extends HtmlElement {
public static final String TAG_NAME = "object";
private Applet applet_;
- private AppletClassLoader appletClassLoader_;
- private List archiveUrls_;
/**
* Creates an instance of HtmlObject
@@ -287,7 +285,7 @@ public final String getVspaceAttribute() {
* {@inheritDoc}
*/
@Override
- protected void onAllChildrenAddedToPage(final boolean postponed) {
+ public void onAllChildrenAddedToPage(final boolean postponed) {
if (getOwnerDocument() instanceof XmlPage) {
return;
}
@@ -297,7 +295,7 @@ protected void onAllChildrenAddedToPage(final boolean postponed) {
}
final String clsId = getClassIdAttribute();
- if (ATTRIBUTE_NOT_DEFINED != clsId) {
+ if (ATTRIBUTE_NOT_DEFINED != clsId && getPage().getWebClient().isJavaScriptEngineEnabled()) {
((HTMLObjectElement) getScriptableObject()).setClassid(clsId);
}
}
@@ -374,75 +372,77 @@ private synchronized void setupAppletIfNeeded() throws IOException {
appletClassName = appletClassName.substring(0, appletClassName.length() - 6);
}
- appletClassLoader_ = new AppletClassLoader((Window) getPage().getEnclosingWindow().getScriptableObject(),
- Thread.currentThread().getContextClassLoader());
+ try (AppletClassLoader appletClassLoader =
+ new AppletClassLoader((Window) getPage().getEnclosingWindow().getScriptableObject(),
+ Thread.currentThread().getContextClassLoader())) {
- final String documentUrl = page.getUrl().toExternalForm();
- String baseUrl = UrlUtils.resolveUrl(documentUrl, ".");
- if (StringUtils.isNotEmpty(codebaseProperty)) {
- // codebase can be relative to the page
- baseUrl = UrlUtils.resolveUrl(baseUrl, codebaseProperty);
- }
- if (!baseUrl.endsWith("/")) {
- baseUrl = baseUrl + "/";
- }
-
- // check archive
- archiveUrls_ = new LinkedList<>();
- String[] archives = StringUtils.split(params.get(ARCHIVE), ',');
- if (null != archives) {
- for (int i = 0; i < archives.length; i++) {
- final String tmpArchive = archives[i].trim();
- final String tempUrl = UrlUtils.resolveUrl(baseUrl, tmpArchive);
- final URL archiveUrl = UrlUtils.toUrlUnsafe(tempUrl);
-
- appletClassLoader_.addArchiveToClassPath(archiveUrl);
- archiveUrls_.add(archiveUrl);
+ final String documentUrl = page.getUrl().toExternalForm();
+ String baseUrl = UrlUtils.resolveUrl(documentUrl, ".");
+ if (StringUtils.isNotEmpty(codebaseProperty)) {
+ // codebase can be relative to the page
+ baseUrl = UrlUtils.resolveUrl(baseUrl, codebaseProperty);
}
- }
- archives = StringUtils.split(params.get(CACHE_ARCHIVE), ',');
- if (null != archives) {
- for (int i = 0; i < archives.length; i++) {
- final String tmpArchive = archives[i].trim();
- final String tempUrl = UrlUtils.resolveUrl(baseUrl, tmpArchive);
- final URL archiveUrl = UrlUtils.toUrlUnsafe(tempUrl);
-
- appletClassLoader_.addArchiveToClassPath(archiveUrl);
- archiveUrls_.add(archiveUrl);
+ if (!baseUrl.endsWith("/")) {
+ baseUrl = baseUrl + "/";
}
- }
- archiveUrls_ = Collections.unmodifiableList(archiveUrls_);
- // no archive attribute, single class
- if (archiveUrls_.isEmpty()) {
- final String tempUrl = UrlUtils.resolveUrl(baseUrl, getAttributeDirect("code"));
- final URL classUrl = UrlUtils.toUrlUnsafe(tempUrl);
+ // check archive
+ List archiveUrls = new LinkedList<>();
+ String[] archives = StringUtils.split(params.get(ARCHIVE), ',');
+ if (null != archives) {
+ for (String tmpArchive : archives) {
+ final String tempUrl = UrlUtils.resolveUrl(baseUrl, tmpArchive.trim());
+ final URL archiveUrl = UrlUtils.toUrlUnsafe(tempUrl);
+
+ appletClassLoader.addArchiveToClassPath(archiveUrl);
+ archiveUrls.add(archiveUrl);
+ }
+ }
+ archives = StringUtils.split(params.get(CACHE_ARCHIVE), ',');
+ if (null != archives) {
+ for (String tmpArchive : archives) {
+ final String tempUrl = UrlUtils.resolveUrl(baseUrl, tmpArchive.trim());
+ final URL archiveUrl = UrlUtils.toUrlUnsafe(tempUrl);
+
+ appletClassLoader.addArchiveToClassPath(archiveUrl);
+ archiveUrls.add(archiveUrl);
+ }
+ }
+ archiveUrls = Collections.unmodifiableList(archiveUrls);
+
+ // no archive attribute, single class
+ if (archiveUrls.isEmpty()) {
+ final String tempUrl = UrlUtils.resolveUrl(baseUrl, getAttributeDirect("code"));
+ final URL classUrl = UrlUtils.toUrlUnsafe(tempUrl);
+
+ final WebResponse response = webclient.loadWebResponse(new WebRequest(classUrl));
+ try {
+ webclient.throwFailingHttpStatusCodeExceptionIfNecessary(response);
+ appletClassLoader.addClassToClassPath(appletClassName, response);
+ }
+ catch (final FailingHttpStatusCodeException e) {
+ // that is what the browser does, the applet only fails, if
+ // the main class is not loadable
+ LOG.error(e.getMessage(), e);
+ }
+ }
- final WebResponse response = webclient.loadWebResponse(new WebRequest(classUrl));
try {
- webclient.throwFailingHttpStatusCodeExceptionIfNecessary(response);
- appletClassLoader_.addClassToClassPath(appletClassName, response);
+ final Class appletClass = (Class) appletClassLoader.loadClass(appletClassName);
+ applet_ = appletClass.newInstance();
+ applet_.setStub(new AppletStubImpl(getHtmlPageOrNull(), params,
+ UrlUtils.toUrlUnsafe(baseUrl), UrlUtils.toUrlUnsafe(documentUrl)));
+ applet_.init();
+ applet_.start();
}
- catch (final FailingHttpStatusCodeException e) {
- // that is what the browser does, the applet only fails, if
- // the main class is not loadable
- LOG.error(e.getMessage(), e);
+ catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Loading applet '" + appletClassName + "' failed\n"
+ + " " + e.toString()
+ + "\n Classpath:\n" + appletClassLoader.info());
+ }
+ throw new RuntimeException(e);
}
}
-
- try {
- final Class appletClass = (Class) appletClassLoader_.loadClass(appletClassName);
- applet_ = appletClass.newInstance();
- applet_.setStub(new AppletStubImpl(getHtmlPageOrNull(), params,
- UrlUtils.toUrlUnsafe(baseUrl), UrlUtils.toUrlUnsafe(documentUrl)));
- applet_.init();
- applet_.start();
- }
- catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
- LOG.error("Loading applet '" + appletClassName + "' failed\n"
- + " " + e.toString()
- + "\n Classpath:\n" + appletClassLoader_.info());
- throw new RuntimeException(e);
- }
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOption.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOption.java
index e9682ce0a2d..f1257b668b5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOption.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOption.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_ONMOUSEOVER_NEVER_FOR_SELECT_OPTION;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_ONMOUSEUP_FOR_SELECT_OPTION_TRIGGERS_ADDITIONAL_UP_FOR_SELECT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_ONMOUSEUP_NOT_FOR_SELECT_OPTION;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLOPTION_EXACT_ONE_OPTION_GETS_NERVER_DESELECTED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLOPTION_PREVENT_DISABLED;
import java.io.IOException;
@@ -110,17 +109,13 @@ public void setSelectedFromJavaScript(final boolean selected) {
* @param shiftKey {@code true} if SHIFT is pressed
* @param ctrlKey {@code true} if CTRL is pressed
*/
- private void setSelected(boolean selected, final boolean invokeOnFocus, final boolean isClick,
+ private void setSelected(final boolean selected, final boolean invokeOnFocus, final boolean isClick,
final boolean shiftKey, final boolean ctrlKey) {
if (selected == isSelected()) {
return;
}
final HtmlSelect select = getEnclosingSelect();
if (select != null) {
- if (hasFeature(HTMLOPTION_EXACT_ONE_OPTION_GETS_NERVER_DESELECTED)
- && !select.isMultipleSelectEnabled() && select.getOptionSize() == 1) {
- selected = true;
- }
select.setSelectedAttribute(this, selected, invokeOnFocus, shiftKey, ctrlKey, isClick);
return;
}
@@ -291,7 +286,9 @@ public Page mouseUp(final boolean shiftKey, final boolean ctrlKey, final boolean
*/
@Override
@SuppressWarnings("unchecked")
- public P click(final Event event, final boolean ignoreVisibility) throws IOException {
+ public
P click(final Event event,
+ final boolean shiftKey, final boolean ctrlKey, final boolean altKey,
+ final boolean ignoreVisibility) throws IOException {
if (hasFeature(EVENT_ONCLICK_FOR_SELECT_ONLY)) {
final SgmlPage page = getPage();
@@ -303,9 +300,9 @@ public
P click(final Event event, final boolean ignoreVisibilit
doClickStateUpdate(event.isShiftKey(), event.isCtrlKey());
}
- return getEnclosingSelect().click(event, ignoreVisibility);
+ return getEnclosingSelect().click(event, shiftKey, ctrlKey, altKey, ignoreVisibility);
}
- return super.click(event, ignoreVisibility);
+ return super.click(event, shiftKey, ctrlKey, altKey, ignoreVisibility);
}
/**
@@ -423,6 +420,10 @@ public Page mouseOver(final boolean shiftKey, final boolean ctrlKey, final boole
if (page.getWebClient().getBrowserVersion().hasFeature(EVENT_ONMOUSEOVER_NEVER_FOR_SELECT_OPTION)) {
return page;
}
+
+ if (hasFeature(EVENT_ONMOUSEOVER_FOR_DISABLED_OPTION) && isDisabled()) {
+ getEnclosingSelect().mouseOver(shiftKey, ctrlKey, altKey, button);
+ }
return super.mouseOver(shiftKey, ctrlKey, altKey, button);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOptionGroup.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOptionGroup.java
index 2f541445f8b..3a2b9e62e60 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOptionGroup.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOptionGroup.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOrderedList.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOrderedList.java
index 9bf42ac568d..92a777e4c77 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOrderedList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOrderedList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOutput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOutput.java
index 4058750f47a..3c968355396 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOutput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlOutput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java
index 496025bbfe4..829e07be28f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_FOCUS_FOCUS_IN_BLUR_OUT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_FOCUS_IN_FOCUS_OUT_BLUR;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.FOCUS_BODY_ELEMENT_AT_START;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CALL_RESULT_IS_LAST_RETURN_VALUE;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DEFERRED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_IGNORES_UTF8_BOM_SOMETIMES;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.PAGE_SELECTION_RANGE_FROM_SELECTABLE_TEXT_INPUT;
@@ -61,7 +60,6 @@
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.ranges.Range;
-import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.Cache;
import com.gargoylesoftware.htmlunit.ElementNotFoundException;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
@@ -77,20 +75,22 @@
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.WebWindow;
-import com.gargoylesoftware.htmlunit.html.HTMLParser.HtmlUnitDOMBuilder;
import com.gargoylesoftware.htmlunit.html.impl.SelectableTextInput;
import com.gargoylesoftware.htmlunit.html.impl.SimpleRange;
+import com.gargoylesoftware.htmlunit.html.parser.HTMLParserDOMBuilder;
import com.gargoylesoftware.htmlunit.javascript.AbstractJavaScriptEngine;
+import com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory;
import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.PostponedAction;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.host.Window;
-import com.gargoylesoftware.htmlunit.javascript.host.dom.Node;
import com.gargoylesoftware.htmlunit.javascript.host.event.BeforeUnloadEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
+import com.gargoylesoftware.htmlunit.javascript.host.event.EventTarget;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument;
import com.gargoylesoftware.htmlunit.protocol.javascript.JavaScriptURLConnection;
import com.gargoylesoftware.htmlunit.util.EncodingSniffer;
+import com.gargoylesoftware.htmlunit.util.MimeType;
import com.gargoylesoftware.htmlunit.util.UrlUtils;
import net.sourceforge.htmlunit.corejs.javascript.Context;
@@ -140,6 +140,7 @@
* @author Ronald Brill
* @author Frank Danek
* @author Joerg Werner
+ * @author Atsushi Nakagawa
*/
public class HtmlPage extends SgmlPage {
@@ -147,7 +148,7 @@ public class HtmlPage extends SgmlPage {
private static final Comparator documentPositionComparator = new DocumentPositionComparator();
- private HtmlUnitDOMBuilder builder_;
+ private HTMLParserDOMBuilder domBuilder_;
private transient Charset originalCharset_;
private Map> idMap_
@@ -244,6 +245,9 @@ public void initialize() throws IOException, FailingHttpStatusCodeException {
}
}
}
+
+ executeEventHandlersIfNeeded(Event.TYPE_DOM_DOCUMENT_LOADED);
+
loadFrames();
// don't set the ready state if we really load the blank page into the window
@@ -256,7 +260,6 @@ public void initialize() throws IOException, FailingHttpStatusCodeException {
getDocumentElement().setReadyState(READY_STATE_COMPLETE);
}
- executeEventHandlersIfNeeded(Event.TYPE_DOM_DOCUMENT_LOADED);
executeDeferredScriptsIfNeeded();
setReadyStateOnDeferredScriptsIfNeeded();
@@ -550,7 +553,8 @@ public DomElement createElement(String tagName) {
if (tagName.indexOf(':') == -1) {
tagName = tagName.toLowerCase(Locale.ROOT);
}
- return HTMLParser.getFactory(tagName).createElementNS(this, null, tagName, null, true);
+ return getWebClient().getPageCreator().getHtmlParser().getFactory(tagName)
+ .createElementNS(this, null, tagName, null, true);
}
/**
@@ -558,8 +562,9 @@ public DomElement createElement(String tagName) {
*/
@Override
public DomElement createElementNS(final String namespaceURI, final String qualifiedName) {
- return HTMLParser.getElementFactory(this, namespaceURI, qualifiedName, false, true)
- .createElementNS(this, namespaceURI, qualifiedName, null, true);
+ return getWebClient().getPageCreator().getHtmlParser()
+ .getElementFactory(this, namespaceURI, qualifiedName, false, true)
+ .createElementNS(this, namespaceURI, qualifiedName, null, true);
}
/**
@@ -875,7 +880,7 @@ public List getHtmlElementsByAccessKey(final char accessKey) {
* be achieved to execute JavaScript in the current page by entering "javascript:...some JS code..."
* in the URL field of a native browser.
* Note: the provided code won't be executed if JavaScript has been disabled on the WebClient
- * (see {@link com.gargoylesoftware.htmlunit.WebClientOptions#isJavaScriptEnabled()}.
+ * (see {@link com.gargoylesoftware.htmlunit.WebClient#isJavaScriptEnabled()}.
* @param sourceCode the JavaScript code to execute
* @return a ScriptResult which will contain both the current page (which may be different than
* the previous page) and a JavaScript result object
@@ -905,8 +910,8 @@ public ScriptResult executeJavaScript(final String sourceCode) {
* the previous page and a JavaScript result object.
*/
public ScriptResult executeJavaScript(String sourceCode, final String sourceName, final int startLine) {
- if (!getWebClient().getOptions().isJavaScriptEnabled()) {
- return new ScriptResult(null, this);
+ if (!getWebClient().isJavaScriptEnabled()) {
+ return new ScriptResult(Undefined.instance);
}
if (StringUtils.startsWithIgnoreCase(sourceCode, JavaScriptURLConnection.JAVASCRIPT_PREFIX)) {
@@ -917,13 +922,15 @@ public ScriptResult executeJavaScript(String sourceCode, final String sourceName
}
final Object result = getWebClient().getJavaScriptEngine().execute(this, sourceCode, sourceName, startLine);
- return new ScriptResult(result, getWebClient().getCurrentWindow().getEnclosedPage());
+ return new ScriptResult(result);
}
/** Various possible external JavaScript file loading results. */
enum JavaScriptLoadResult {
/** The load was aborted and nothing was done. */
NOOP,
+ /** The load was aborted and nothing was done. */
+ NO_CONTENT,
/** The external JavaScript file was downloaded and compiled successfully. */
SUCCESS,
/** The external JavaScript file was not downloaded successfully. */
@@ -946,7 +953,7 @@ JavaScriptLoadResult loadExternalJavaScriptFile(final String srcAttribute, final
throws FailingHttpStatusCodeException {
final WebClient client = getWebClient();
- if (StringUtils.isBlank(srcAttribute) || !client.getOptions().isJavaScriptEnabled()) {
+ if (StringUtils.isBlank(srcAttribute) || !client.isJavaScriptEnabled()) {
return JavaScriptLoadResult.NOOP;
}
@@ -955,7 +962,9 @@ JavaScriptLoadResult loadExternalJavaScriptFile(final String srcAttribute, final
scriptURL = getFullyQualifiedUrl(srcAttribute);
final String protocol = scriptURL.getProtocol();
if ("javascript".equals(protocol)) {
- LOG.info("Ignoring script src [" + srcAttribute + "]");
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Ignoring script src [" + srcAttribute + "]");
+ }
return JavaScriptLoadResult.NOOP;
}
if (!"http".equals(protocol) && !"https".equals(protocol)
@@ -979,6 +988,9 @@ JavaScriptLoadResult loadExternalJavaScriptFile(final String srcAttribute, final
return JavaScriptLoadResult.DOWNLOAD_ERROR;
}
catch (final FailingHttpStatusCodeException e) {
+ if (e.getStatusCode() == HttpStatus.SC_NO_CONTENT) {
+ return JavaScriptLoadResult.NO_CONTENT;
+ }
client.getJavaScriptErrorListener().loadScriptError(this, scriptURL, e);
throw e;
}
@@ -1011,11 +1023,12 @@ private Object loadJavaScriptFromUrl(final URL url, final Charset scriptCharset)
final WebRequest referringRequest = getWebResponse().getWebRequest();
final WebClient client = getWebClient();
- final BrowserVersion browser = client.getBrowserVersion();
- final WebRequest request = new WebRequest(url, browser.getScriptAcceptHeader());
+ final WebRequest request = new WebRequest(url);
+ // copy all headers from the referring request
request.setAdditionalHeaders(new HashMap<>(referringRequest.getAdditionalHeaders()));
- request.setAdditionalHeader(HttpHeader.REFERER, referringRequest.getUrl().toString());
+ // at least overwrite this headers
request.setAdditionalHeader(HttpHeader.ACCEPT, client.getBrowserVersion().getScriptAcceptHeader());
+ request.setAdditionalHeader(HttpHeader.REFERER, referringRequest.getUrl().toString());
// our cache is a bit strange;
// loadWebResponse check the cache for the web response
@@ -1034,15 +1047,18 @@ private Object loadJavaScriptFromUrl(final URL url, final Charset scriptCharset)
client.throwFailingHttpStatusCodeExceptionIfNecessary(response);
final int statusCode = response.getStatusCode();
- final boolean successful = statusCode >= HttpStatus.SC_OK && statusCode < HttpStatus.SC_MULTIPLE_CHOICES;
- final boolean noContent = statusCode == HttpStatus.SC_NO_CONTENT;
- if (!successful || noContent) {
+ if (statusCode == HttpStatus.SC_NO_CONTENT) {
+ throw new FailingHttpStatusCodeException(response);
+ }
+
+ if (statusCode < HttpStatus.SC_OK
+ || statusCode >= HttpStatus.SC_MULTIPLE_CHOICES) {
throw new IOException("Unable to download JavaScript from '" + url + "' (status " + statusCode + ").");
}
//http://www.ietf.org/rfc/rfc4329.txt
final String contentType = response.getContentType();
- if (!"application/javascript".equalsIgnoreCase(contentType)
+ if (!MimeType.APPLICATION_JAVASCRIPT.equalsIgnoreCase(contentType)
&& !"application/ecmascript".equalsIgnoreCase(contentType)) {
// warn about obsolete or not supported content types
if ("text/javascript".equals(contentType)
@@ -1199,26 +1215,41 @@ private HtmlTitle getTitleElement() {
*/
private boolean executeEventHandlersIfNeeded(final String eventType) {
// If JavaScript isn't enabled, there's nothing for us to do.
- if (!getWebClient().getOptions().isJavaScriptEnabled()) {
+ if (!getWebClient().isJavaScriptEnabled()) {
return true;
}
// Execute the specified event on the document element.
final WebWindow window = getEnclosingWindow();
if (window.getScriptableObject() instanceof Window) {
- final DomElement element = getDocumentElement();
- if (element == null) { // happens for instance if document.documentElement has been removed from parent
- return true;
- }
final Event event;
if (eventType.equals(Event.TYPE_BEFORE_UNLOAD)) {
- event = new BeforeUnloadEvent(element, eventType);
+ event = new BeforeUnloadEvent(this, eventType);
+ }
+ else {
+ event = new Event(this, eventType);
+ }
+
+ // This is the same as DomElement.fireEvent() and was copied
+ // here so it could be used with HtmlPage.
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Firing " + event);
+ }
+
+ final EventTarget jsNode;
+ if (Event.TYPE_DOM_DOCUMENT_LOADED.equals(eventType)) {
+ jsNode = this.getScriptableObject();
}
else {
- event = new Event(element, eventType);
+ // The load/beforeunload/unload events target Document but paths Window only (tested in Chrome/FF)
+ jsNode = window.getScriptableObject();
}
- final ScriptResult result = element.fireEvent(event);
- if (!isOnbeforeunloadAccepted(this, event, result)) {
+
+ final HtmlUnitContextFactory cf = ((JavaScriptEngine) getWebClient().getJavaScriptEngine())
+ .getContextFactory();
+ cf.callSecured(cx -> jsNode.fireEvent(event), this);
+
+ if (!isOnbeforeunloadAccepted(this, event)) {
return false;
}
}
@@ -1245,8 +1276,13 @@ private boolean executeEventHandlersIfNeeded(final String eventType) {
else {
event = new Event(frame, eventType);
}
- final ScriptResult result = ((Node) frame.getScriptableObject()).executeEventLocally(event);
- if (!isOnbeforeunloadAccepted((HtmlPage) frame.getPage(), event, result)) {
+ // This fires the "load" event for the element which, like all non-window
+ // load events, propagates up to Document but not Window. The "load" event for
+ // on the other hand, like that of , is handled above where it is
+ // fired against Document and directed to Window.
+ frame.fireEvent(event);
+
+ if (!isOnbeforeunloadAccepted((HtmlPage) frame.getPage(), event)) {
return false;
}
}
@@ -1265,17 +1301,19 @@ public boolean isOnbeforeunloadAccepted() {
return executeEventHandlersIfNeeded(Event.TYPE_BEFORE_UNLOAD);
}
- private boolean isOnbeforeunloadAccepted(final HtmlPage page, final Event event, final ScriptResult result) {
- if (event.getType().equals(Event.TYPE_BEFORE_UNLOAD)) {
- final boolean ie = hasFeature(JS_CALL_RESULT_IS_LAST_RETURN_VALUE);
- final String message = getBeforeUnloadMessage(event, result, ie);
- if (message != null) {
+ private boolean isOnbeforeunloadAccepted(final HtmlPage page, final Event event) {
+ if (event instanceof BeforeUnloadEvent) {
+ final BeforeUnloadEvent beforeUnloadEvent = (BeforeUnloadEvent) event;
+ if (beforeUnloadEvent.isBeforeUnloadMessageSet()) {
final OnbeforeunloadHandler handler = getWebClient().getOnbeforeunloadHandler();
if (handler == null) {
- LOG.warn("document.onbeforeunload() returned a string in event.returnValue,"
- + " but no onbeforeunload handler installed.");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("document.onbeforeunload() returned a string in event.returnValue,"
+ + " but no onbeforeunload handler installed.");
+ }
}
else {
+ final String message = Context.toString(beforeUnloadEvent.getReturnValue());
return handler.handleEvent(page, message);
}
}
@@ -1283,30 +1321,6 @@ private boolean isOnbeforeunloadAccepted(final HtmlPage page, final Event event,
return true;
}
- private static String getBeforeUnloadMessage(final Event event, final ScriptResult result, final boolean ie) {
- String message = null;
- if (event.getReturnValue() != Undefined.instance) {
- if (!ie || event.getReturnValue() != null || result == null || result.getJavaScriptResult() == null
- || result.getJavaScriptResult() == Undefined.instance) {
- message = Context.toString(event.getReturnValue());
- }
- }
- else {
- if (result != null) {
- if (ie) {
- if (result.getJavaScriptResult() != Undefined.instance) {
- message = Context.toString(result.getJavaScriptResult());
- }
- }
- else if (result.getJavaScriptResult() != null
- && result.getJavaScriptResult() != Undefined.instance) {
- message = Context.toString(result.getJavaScriptResult());
- }
- }
- }
- return message;
- }
-
/**
* If a refresh has been specified either through a meta tag or an HTTP
* response header, then perform that refresh.
@@ -1338,7 +1352,9 @@ private void executeRefreshIfNeeded() throws IOException {
time = Double.parseDouble(refreshString);
}
catch (final NumberFormatException e) {
- LOG.error("Malformed refresh string (no ';' but not a number): " + refreshString, e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Malformed refresh string (no ';' but not a number): " + refreshString, e);
+ }
return;
}
url = getUrl();
@@ -1349,12 +1365,16 @@ private void executeRefreshIfNeeded() throws IOException {
time = Double.parseDouble(refreshString.substring(0, index).trim());
}
catch (final NumberFormatException e) {
- LOG.error("Malformed refresh string (no valid number before ';') " + refreshString, e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Malformed refresh string (no valid number before ';') " + refreshString, e);
+ }
return;
}
index = refreshString.toLowerCase(Locale.ROOT).indexOf("url=", index);
if (index == -1) {
- LOG.error("Malformed refresh string (found ';' but no 'url='): " + refreshString);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Malformed refresh string (found ';' but no 'url='): " + refreshString);
+ }
return;
}
final StringBuilder builder = new StringBuilder(refreshString.substring(index + 4));
@@ -1374,7 +1394,9 @@ private void executeRefreshIfNeeded() throws IOException {
url = getFullyQualifiedUrl(urlString);
}
catch (final MalformedURLException e) {
- LOG.error("Malformed URL in refresh string: " + refreshString, e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Malformed URL in refresh string: " + refreshString, e);
+ }
throw e;
}
}
@@ -1416,7 +1438,7 @@ private String getRefreshStringOrNull() {
* Executes any deferred scripts, if necessary.
*/
private void executeDeferredScriptsIfNeeded() {
- if (!getWebClient().getOptions().isJavaScriptEnabled()) {
+ if (!getWebClient().isJavaScriptEnabled()) {
return;
}
if (hasFeature(JS_DEFERRED)) {
@@ -1437,7 +1459,7 @@ private void executeDeferredScriptsIfNeeded() {
* Sets the ready state on any deferred scripts, if necessary.
*/
private void setReadyStateOnDeferredScriptsIfNeeded() {
- if (getWebClient().getOptions().isJavaScriptEnabled() && hasFeature(JS_DEFERRED)) {
+ if (getWebClient().isJavaScriptEnabled() && hasFeature(JS_DEFERRED)) {
final List elements = getDocumentElement().getElementsByTagName("script");
for (final HtmlElement e : elements) {
if (e instanceof HtmlScript) {
@@ -1786,11 +1808,12 @@ else if (!elements.contains(element)) {
}
}
- private static String getAttributeValue(final DomElement element, final String attribute) {
+ private String getAttributeValue(final DomElement element, final String attribute) {
// first try real attributes
String value = element.getAttribute(attribute);
if (DomElement.ATTRIBUTE_NOT_DEFINED == value
+ && getWebClient().isJavaScriptEngineEnabled()
&& !(element instanceof HtmlApplet)
&& !(element instanceof HtmlObject)) {
// second try are JavaScript attributes
@@ -1955,8 +1978,10 @@ protected HtmlPage clone() {
public HtmlPage cloneNode(final boolean deep) {
// we need the ScriptObject clone before cloning the kids.
final HtmlPage result = (HtmlPage) super.cloneNode(false);
- final SimpleScriptable jsObjClone = ((SimpleScriptable) getScriptableObject()).clone();
- jsObjClone.setDomNode(result);
+ if (getWebClient().isJavaScriptEnabled()) {
+ final SimpleScriptable jsObjClone = ((SimpleScriptable) getScriptableObject()).clone();
+ jsObjClone.setDomNode(result);
+ }
// if deep, clone the kids too, and re initialize parts of the clone
if (deep) {
@@ -2088,20 +2113,26 @@ public boolean isBeingParsed() {
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Called by the HTML parser to let the page know that it has started parsing some content for this page.
*/
- void registerParsingStart() {
+ public void registerParsingStart() {
parserCount_++;
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Called by the HTML parser to let the page know that it has finished parsing some content for this page.
*/
- void registerParsingEnd() {
+ public void registerParsingEnd() {
parserCount_--;
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Returns {@code true} if an HTML parser is parsing a non-inline HTML snippet to add content
* to this page. Non-inline content is content that is parsed for the page, but not in the
* same stream as the page itself -- basically anything other than document.write()
@@ -2111,25 +2142,31 @@ void registerParsingEnd() {
* @return {@code true} if an HTML parser is parsing a non-inline HTML snippet to add content
* to this page
*/
- boolean isParsingHtmlSnippet() {
+ public boolean isParsingHtmlSnippet() {
return snippetParserCount_ > 0;
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Called by the HTML parser to let the page know that it has started parsing a non-inline HTML snippet.
*/
- void registerSnippetParsingStart() {
+ public void registerSnippetParsingStart() {
snippetParserCount_++;
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Called by the HTML parser to let the page know that it has finished parsing a non-inline HTML snippet.
*/
- void registerSnippetParsingEnd() {
+ public void registerSnippetParsingEnd() {
snippetParserCount_--;
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Returns {@code true} if an HTML parser is parsing an inline HTML snippet to add content
* to this page. Inline content is content inserted into the parser stream dynamically
* while the page is being parsed (i.e. document.write() or document.writeln() ).
@@ -2137,21 +2174,25 @@ void registerSnippetParsingEnd() {
* @return {@code true} if an HTML parser is parsing an inline HTML snippet to add content
* to this page
*/
- boolean isParsingInlineHtmlSnippet() {
+ public boolean isParsingInlineHtmlSnippet() {
return inlineSnippetParserCount_ > 0;
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Called by the HTML parser to let the page know that it has started parsing an inline HTML snippet.
*/
- void registerInlineSnippetParsingStart() {
+ public void registerInlineSnippetParsingStart() {
inlineSnippetParserCount_++;
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Called by the HTML parser to let the page know that it has finished parsing an inline HTML snippet.
*/
- void registerInlineSnippetParsingEnd() {
+ public void registerInlineSnippetParsingEnd() {
inlineSnippetParserCount_--;
}
@@ -2173,23 +2214,27 @@ public Page refresh() throws IOException {
* @param string the HTML code to write in place
*/
public void writeInParsedStream(final String string) {
- builder_.pushInputString(string);
+ getDOMBuilder().pushInputString(string);
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Sets the builder to allow page to send content from document.write(ln) calls.
* @param htmlUnitDOMBuilder the builder
*/
- void setBuilder(final HtmlUnitDOMBuilder htmlUnitDOMBuilder) {
- builder_ = htmlUnitDOMBuilder;
+ public void setDOMBuilder(final HTMLParserDOMBuilder htmlUnitDOMBuilder) {
+ domBuilder_ = htmlUnitDOMBuilder;
}
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* Returns the current builder.
* @return the current builder
*/
- HtmlUnitDOMBuilder getBuilder() {
- return builder_;
+ public HTMLParserDOMBuilder getDOMBuilder() {
+ return domBuilder_;
}
/**
@@ -2219,7 +2264,7 @@ public Map getNamespaces() {
* {@inheritDoc}
*/
@Override
- protected void setDocumentType(final DocumentType type) {
+ public void setDocumentType(final DocumentType type) {
super.setDocumentType(type);
}
@@ -2268,7 +2313,7 @@ public URL getBaseURL() {
if (base_ == null) {
baseUrl = getUrl();
final WebWindow window = getEnclosingWindow();
- final boolean frame = window != window.getTopWindow();
+ final boolean frame = window != null && window != window.getTopWindow();
if (frame) {
final boolean frameSrcIsNotSet = baseUrl == WebClient.URL_ABOUT_BLANK;
final boolean frameSrcIsJs = "javascript".equals(baseUrl.getProtocol());
@@ -2295,7 +2340,7 @@ else if (baseUrl_ != null) {
else if (href.startsWith("//")) {
baseUrl = new URL(String.format("%s:%s", url.getProtocol(), href));
}
- else if (href.startsWith("/")) {
+ else if (href.length() > 0 && href.charAt(0) == '/') {
final int port = Window.getPort(url);
baseUrl = new URL(String.format("%s://%s:%d%s", url.getProtocol(), url.getHost(), port, href));
}
@@ -2363,7 +2408,9 @@ public void setElementFromPointHandler(final ElementFromPointHandler elementFrom
*/
public HtmlElement getElementFromPoint(final int x, final int y) {
if (elementFromPointHandler_ == null) {
- LOG.warn("ElementFromPointHandler was not specicifed for " + this);
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("ElementFromPointHandler was not specicifed for " + this);
+ }
if (x <= 0 || y <= 0) {
return null;
}
@@ -2506,8 +2553,8 @@ public void setSelectionRange(final Range selectionRange) {
*/
public ScriptResult executeJavaScriptFunction(final Object function, final Object thisObject,
final Object[] args, final DomNode htmlElementScope) {
- if (!getWebClient().getOptions().isJavaScriptEnabled()) {
- return new ScriptResult(null, this);
+ if (!getWebClient().isJavaScriptEnabled()) {
+ return new ScriptResult(null);
}
return executeJavaScriptFunction((Function) function, (Scriptable) thisObject, args, htmlElementScope);
@@ -2519,7 +2566,7 @@ private ScriptResult executeJavaScriptFunction(final Function function, final Sc
final JavaScriptEngine engine = (JavaScriptEngine) getWebClient().getJavaScriptEngine();
final Object result = engine.callFunction(this, function, thisObject, args, htmlElementScope);
- return new ScriptResult(result, getWebClient().getCurrentWindow().getEnclosedPage());
+ return new ScriptResult(result);
}
private void writeObject(final ObjectOutputStream oos) throws IOException {
@@ -2534,4 +2581,20 @@ private void readObject(final ObjectInputStream ois) throws ClassNotFoundExcepti
originalCharset_ = Charset.forName(charsetName);
}
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setNodeValue(final String value) {
+ // Default behavior is to do nothing, overridden in some subclasses
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPrefix(final String prefix) {
+ // Empty.
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlParagraph.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlParagraph.java
index 810ce67fe51..c63268a59c4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlParagraph.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlParagraph.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlParameter.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlParameter.java
index 9c0c63dfc01..3f3aff319a1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlParameter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlParameter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPasswordInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPasswordInput.java
index 2f881da69f9..44751ab749d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPasswordInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPasswordInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,6 +50,14 @@ public class HtmlPasswordInput extends HtmlInput implements SelectableTextInput
super(qualifiedName, page, attributes);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
@@ -126,10 +134,7 @@ public void setSelectionEnd(final int selectionEnd) {
* {@inheritDoc}
*/
@Override
- protected void doType(final char c, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final char c, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, c, this, lastType);
}
@@ -137,10 +142,7 @@ protected void doType(final char c, final boolean startAtEnd, final boolean last
* {@inheritDoc}
*/
@Override
- protected void doType(final int keyCode, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final int keyCode, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, keyCode, this, lastType);
}
@@ -154,14 +156,6 @@ protected void typeDone(final String newValue, final boolean notifyAttributeChan
}
}
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return new HtmlPasswordInput(getQualifiedName(), getPage(), getAttributesMap());
- }
-
/**
* {@inheritDoc}
*/
@@ -192,6 +186,16 @@ public void setDefaultValue(final String defaultValue) {
setDefaultValue(defaultValue, modifyValue);
}
+ /**
+ * {@inheritDoc}
+ * @see HtmlInput#reset()
+ */
+ @Override
+ public void reset() {
+ super.reset();
+ setSelectionEnd(0);
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPicture.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPicture.java
index 20d88d735d2..2e57cc1f770 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPicture.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPicture.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPlainText.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPlainText.java
index 580cf122c37..d3edd65da70 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPlainText.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPlainText.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPreformattedText.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPreformattedText.java
index b88b8b4e9ef..762ebc929ac 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPreformattedText.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlPreformattedText.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlProgress.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlProgress.java
index 718185d1a7f..5d85b65836b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlProgress.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlProgress.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput.java
index 321356e6e67..19728f3a137 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRadioButtonInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -143,7 +143,7 @@ else if (page != null && page.isHtmlPage()) {
if (changed) {
final ScriptResult scriptResult = fireEvent(Event.TYPE_CHANGE);
if (scriptResult != null) {
- page = scriptResult.getNewPage();
+ page = page.getEnclosingWindow().getWebClient().getCurrentWindow().getEnclosedPage();
}
}
return page;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRangeInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRangeInput.java
index 3b390461c2c..e577f06621b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRangeInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRangeInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,11 +17,13 @@
import java.util.Map;
import com.gargoylesoftware.htmlunit.SgmlPage;
+import org.apache.commons.lang3.StringUtils;
/**
* Wrapper for the HTML element "input" where type is "range".
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
public class HtmlRangeInput extends HtmlInput {
@@ -35,7 +37,87 @@ public class HtmlRangeInput extends HtmlInput {
HtmlRangeInput(final String qualifiedName, final SgmlPage page,
final Map attributes) {
super(qualifiedName, page, attributes);
- setValueAttribute("50");
+
+ final String value = getValueAttribute();
+ if (value == ATTRIBUTE_NOT_DEFINED) {
+ final double min = getMinNumeric();
+ final double max = getMaxNumeric();
+ if (max < min) {
+ setValueAttribute(min);
+ return;
+ }
+
+ final double val = min + ((max - min) / 2);
+ setValueAttribute(val);
+ }
+ else {
+ setValueAttribute(value);
+ }
+ }
+
+ /**
+ * @return the min as double
+ */
+ public double getMinNumeric() {
+ final String min = getAttributeDirect("min");
+ if (min == ATTRIBUTE_NOT_DEFINED) {
+ return 0;
+ }
+ try {
+ return Double.parseDouble(min);
+ }
+ catch (final NumberFormatException e) {
+ return 0;
+ }
+ }
+
+ /**
+ * @return the max as double
+ */
+ public double getMaxNumeric() {
+ final String max = getAttributeDirect("max");
+ if (max == ATTRIBUTE_NOT_DEFINED) {
+ return 100;
+ }
+ try {
+ return Double.parseDouble(max);
+ }
+ catch (final NumberFormatException e) {
+ return 100;
+ }
+ }
+
+ /**
+ * @return the max as double
+ */
+ public double getStepNumeric() {
+ final String step = getAttributeDirect("step");
+ if (step == ATTRIBUTE_NOT_DEFINED) {
+ return 1;
+ }
+ try {
+ return Double.parseDouble(step);
+ }
+ catch (final NumberFormatException e) {
+ return 1;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultValue(final String defaultValue) {
+ final boolean modifyValue = getValueAttribute().equals(getDefaultValue());
+ setDefaultValue(defaultValue, modifyValue);
}
/**
@@ -44,9 +126,15 @@ public class HtmlRangeInput extends HtmlInput {
@Override
public void setValueAttribute(final String newValue) {
try {
- final int value = Integer.parseInt(newValue);
- if (value >= 0 && value <= 100) {
- super.setValueAttribute(newValue);
+ if (StringUtils.isNotEmpty(newValue)) {
+ setValueAttribute(Double.parseDouble(newValue));
+ }
+ else {
+ final double min = getMinNumeric();
+ final double max = getMaxNumeric();
+
+ // place in the middle
+ setValueAttribute(min + ((max - min) / 2));
}
}
catch (final NumberFormatException e) {
@@ -54,6 +142,39 @@ public void setValueAttribute(final String newValue) {
}
}
+ private void setValueAttribute(final double newValue) {
+ double value = newValue;
+
+ final double min = getMinNumeric();
+ final double max = getMaxNumeric();
+
+ if (value > max) {
+ value = max;
+ }
+ else {
+ if (value < min) {
+ value = min;
+ }
+ }
+
+ final double step = getStepNumeric();
+ value = value - min;
+ int fact = (int) (value / step);
+ final double rest = value % step;
+ if (rest >= step / 2) {
+ fact++;
+ }
+ value = min + step * fact;
+
+ if (!Double.isInfinite(value) && (value == Math.floor(value))) {
+ super.setValueAttribute(Integer.toString((int) value));
+ }
+ else {
+ super.setValueAttribute(Double.toString(value));
+ }
+ return;
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlResetInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlResetInput.java
index a44329b6ffd..6bc826ca17c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlResetInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlResetInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -90,6 +90,14 @@ protected boolean doClickStateUpdate(final boolean shiftKey, final boolean ctrlK
return false;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc} This method does nothing for reset input elements.
* @see SubmittableElement#reset()
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRp.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRp.java
index 5ccbbe4b12e..eb0be40994b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRp.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,9 +79,6 @@ public DisplayStyle getDefaultStyleDisplay() {
return DisplayStyle.EMPTY;
}
}
- else {
- return DisplayStyle.NONE;
- }
- return DisplayStyle.INLINE;
+ return DisplayStyle.NONE;
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRt.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRt.java
index f7b4d084ada..eec57c4effe 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRt.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRt.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRuby.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRuby.java
index 814c29c1698..74363434335 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRuby.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlRuby.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlS.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlS.java
index 50859c8db82..5bebd0a2739 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlS.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlS.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSample.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSample.java
index 1e51cc2ca5a..c68a6a522d1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSample.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSample.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlScript.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlScript.java
index 1c3da56a7b1..c0bde91af43 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlScript.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlScript.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.html;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_ONLOAD_INTERNAL_JAVASCRIPT;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLSCRIPT_TRIM_TYPE;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_SCRIPT_HANDLE_204_AS_ERROR;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_SCRIPT_SUPPORTS_FOR_AND_EVENT_WINDOW;
import java.io.PrintWriter;
@@ -101,18 +101,6 @@ public final String getCharsetAttribute() {
return getAttributeDirect("charset");
}
- /**
- * {@inheritDoc}
- *
- * @deprecated as of 2.27, not used
- */
- @Override
- @Deprecated
- public final Charset getCharset() {
- final String charsetName = getCharsetAttribute();
- return EncodingSniffer.toCharset(charsetName);
- }
-
/**
* Returns the value of the attribute {@code type}. Refer to the
* HTML 4.01
@@ -197,7 +185,7 @@ public boolean mayBeDisplayed() {
protected void setAttributeNS(final String namespaceURI, final String qualifiedName, final String attributeValue,
final boolean notifyAttributeChangeListeners, final boolean notifyMutationObservers) {
// special additional processing for the 'src'
- if (namespaceURI != null || !"src".equals(qualifiedName)) {
+ if (namespaceURI != null || !SRC_ATTRIBUTE.equals(qualifiedName)) {
super.setAttributeNS(namespaceURI, qualifiedName, attributeValue, notifyAttributeChangeListeners,
notifyMutationObservers);
return;
@@ -224,7 +212,7 @@ public void execute() {
* the script itself, if necessary. {@inheritDoc}
*/
@Override
- protected void onAllChildrenAddedToPage(final boolean postponed) {
+ public void onAllChildrenAddedToPage(final boolean postponed) {
if (getOwnerDocument() instanceof XmlPage) {
return;
}
@@ -236,9 +224,9 @@ protected void onAllChildrenAddedToPage(final boolean postponed) {
@Override
public void execute() {
Object jsDoc = null;
- final Object window = getPage().getEnclosingWindow().getScriptableObject();
- if (window instanceof Window) {
- jsDoc = ((Window) window).getDocument();
+ final Window window = getPage().getEnclosingWindow().getScriptableObject();
+ if (window != null) {
+ jsDoc = window.getDocument();
((HTMLDocument) jsDoc).setExecutingDynamicExternalPosponed(getStartLineNumber() == -1
&& getSrcAttribute() != ATTRIBUTE_NOT_DEFINED);
}
@@ -254,12 +242,13 @@ public void execute() {
};
final AbstractJavaScriptEngine> engine = getPage().getWebClient().getJavaScriptEngine();
- if (hasAttribute("async") && !engine.isScriptRunning()) {
+ if (engine != null
+ && hasAttribute("async") && !engine.isScriptRunning()) {
final HtmlPage owningPage = getHtmlPageOrNull();
owningPage.addAfterLoadAction(action);
}
- else if (hasAttribute("async")
- || postponed && StringUtils.isBlank(getTextContent())) {
+ else if (engine != null && (hasAttribute("async")
+ || postponed && StringUtils.isBlank(getTextContent()))) {
engine.addPostponedAction(action);
}
else {
@@ -345,12 +334,13 @@ public void executeScriptIfNeeded() {
final HtmlPage page = (HtmlPage) getPage();
final String src = getSrcAttribute();
- if (src.equals(SLASH_SLASH_COLON)) {
- executeEvent(Event.TYPE_ERROR);
- return;
- }
if (src != ATTRIBUTE_NOT_DEFINED) {
+ if (src.equals(SLASH_SLASH_COLON)) {
+ executeEvent(Event.TYPE_ERROR);
+ return;
+ }
+
if (!src.startsWith(JavaScriptURLConnection.JAVASCRIPT_PREFIX)) {
//
if (LOG.isDebugEnabled()) {
@@ -380,6 +370,15 @@ public void executeScriptIfNeeded() {
else if (result == JavaScriptLoadResult.DOWNLOAD_ERROR) {
executeEvent(Event.TYPE_ERROR);
}
+ else if (result == JavaScriptLoadResult.NO_CONTENT) {
+ final BrowserVersion browserVersion = getPage().getWebClient().getBrowserVersion();
+ if (browserVersion.hasFeature(JS_SCRIPT_HANDLE_204_AS_ERROR)) {
+ executeEvent(Event.TYPE_ERROR);
+ }
+ else {
+ executeEvent(Event.TYPE_LOAD);
+ }
+ }
}
catch (final FailingHttpStatusCodeException e) {
executeEvent(Event.TYPE_ERROR);
@@ -428,7 +427,7 @@ private boolean isExecutionNeeded() {
// If JavaScript is disabled, we don't need to execute.
final SgmlPage page = getPage();
- if (!page.getWebClient().getOptions().isJavaScriptEnabled()) {
+ if (!page.getWebClient().isJavaScriptEnabled()) {
return false;
}
@@ -452,58 +451,17 @@ private boolean isExecutionNeeded() {
}
// If the script language is not JavaScript, we can't execute.
- if (!isJavaScript(getTypeAttribute(), getLanguageAttribute())) {
- final String t = getTypeAttribute();
- final String l = getLanguageAttribute();
- LOG.warn("Script is not JavaScript (type: " + t + ", language: " + l + "). Skipping execution.");
+ final String t = getTypeAttribute();
+ final String l = getLanguageAttribute();
+ if (!ScriptElementSupport.isJavaScript(this, t, l)) {
+ LOG.warn("Script is not JavaScript (type: '" + t + "', language: '" + l + "'). Skipping execution.");
return false;
}
// If the script's root ancestor node is not the page, then the script is not a part of the page.
// If it isn't yet part of the page, don't execute the script; it's probably just being cloned.
- if (!getPage().isAncestorOf(this)) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Returns true if a script with the specified type and language attributes is actually JavaScript.
- * According to W3C recommendation
- * are content types case insensitive.
- * IE supports only a limited number of values for the type attribute. For testing you can
- * use http://www.robinlionheart.com/stds/html4/scripts.
- * @param typeAttribute the type attribute specified in the script tag
- * @param languageAttribute the language attribute specified in the script tag
- * @return true if the script is JavaScript
- */
- boolean isJavaScript(String typeAttribute, final String languageAttribute) {
- final BrowserVersion browserVersion = getPage().getWebClient().getBrowserVersion();
-
- if (browserVersion.hasFeature(HTMLSCRIPT_TRIM_TYPE)) {
- typeAttribute = typeAttribute.trim();
- }
-
- if (StringUtils.isNotEmpty(typeAttribute)) {
- if ("text/javascript".equalsIgnoreCase(typeAttribute)
- || "text/ecmascript".equalsIgnoreCase(typeAttribute)) {
- return true;
- }
-
- if ("application/javascript".equalsIgnoreCase(typeAttribute)
- || "application/ecmascript".equalsIgnoreCase(typeAttribute)
- || "application/x-javascript".equalsIgnoreCase(typeAttribute)) {
- return true;
- }
- return false;
- }
-
- if (StringUtils.isNotEmpty(languageAttribute)) {
- return StringUtils.startsWithIgnoreCase(languageAttribute, "javascript");
- }
- return true;
+ return getPage().isAncestorOf(this);
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSearchInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSearchInput.java
index 3f0135102aa..ac10f7183c3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSearchInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSearchInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSection.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSection.java
index 4f9377c23ee..76db710ac9f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSection.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSelect.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSelect.java
index 247a0128aee..8ce3e598fd2 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSelect.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSelect.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_MOUSE_ON_DISABLED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_SELECT_SET_VALUES_CHECKS_ONLY_VALUE_ATTRIBUTE;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.SELECT_DESELECT_ALL_IF_SWITCHING_UNKNOWN;
import java.util.ArrayList;
import java.util.Collection;
@@ -80,7 +79,7 @@ public class HtmlSelect extends HtmlElement implements DisabledElement, Submitta
* @param postponed whether to use {@link com.gargoylesoftware.htmlunit.javascript.PostponedAction} or no
*/
@Override
- protected void onAllChildrenAddedToPage(final boolean postponed) {
+ public void onAllChildrenAddedToPage(final boolean postponed) {
// Fix the size if necessary.
int size;
try {
@@ -311,10 +310,8 @@ public P setSelectedAttribute(final String optionValue,
return setSelectedAttribute(selected, isSelected, invokeOnFocus, true, false, true);
}
catch (final ElementNotFoundException e) {
- if (hasFeature(SELECT_DESELECT_ALL_IF_SWITCHING_UNKNOWN)) {
- for (final HtmlOption o : getSelectedOptions()) {
- o.setSelected(false);
- }
+ for (final HtmlOption o : getSelectedOptions()) {
+ o.setSelected(false);
}
return (P) getPage();
}
@@ -575,7 +572,7 @@ public String asText() {
builder.append(currentOption.asText());
}
if (i.hasNext()) {
- builder.append("\n");
+ builder.append('\n');
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSerializer.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSerializer.java
index 6fa28a53bb1..79c3374b1be 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSerializer.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSerializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,12 +16,12 @@
import java.util.Iterator;
import java.util.List;
-import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.SgmlPage;
+import com.gargoylesoftware.htmlunit.html.HtmlSerializer.HtmlSerializerTextBuilder.Mode;
import com.gargoylesoftware.htmlunit.javascript.host.Element;
/**
@@ -33,20 +33,6 @@
* @author Rob Kodey
*/
public class HtmlSerializer {
- /** Indicates a block. Will be rendered as line separator (multiple block marks are ignored) */
- protected static final String AS_TEXT_BLOCK_SEPARATOR = "§bs§";
- private static final int AS_TEXT_BLOCK_SEPARATOR_LENGTH = AS_TEXT_BLOCK_SEPARATOR.length();
-
- /** Indicates a new line. Will be rendered as line separator. */
- protected static final String AS_TEXT_NEW_LINE = "§nl§";
- private static final int AS_TEXT_NEW_LINE_LENGTH = AS_TEXT_NEW_LINE.length();
-
- /** Indicates a non blank that can't be trimmed or reduced. */
- protected static final String AS_TEXT_BLANK = "§blank§";
- /** Indicates a tab. */
- protected static final String AS_TEXT_TAB = "§tab§";
-
- private static final Pattern TEXT_AREA_PATTERN = Pattern.compile("\r?\n");
private boolean ignoreMaskedElements_ = true;
@@ -56,145 +42,9 @@ public class HtmlSerializer {
* @return the text representation according to the setting of this serializer
*/
public String asText(final DomNode node) {
- final StringBuilder builder = new StringBuilder();
+ final HtmlSerializerTextBuilder builder = new HtmlSerializerTextBuilder();
appendNode(builder, node);
- final String response = builder.toString();
- return cleanUp(response);
- }
-
- /**
- * Reduce the whitespace and do some more cleanup.
- * @param text the text to clean up
- * @return the new text
- */
- protected String cleanUp(String text) {
- // ignore at the end of a block
- text = reduceWhitespace(text);
- text = StringUtils.replace(text, AS_TEXT_BLANK, " ");
- final String ls = System.lineSeparator();
- text = StringUtils.replace(text, AS_TEXT_NEW_LINE, ls);
- text = StringUtils.replace(text, AS_TEXT_BLOCK_SEPARATOR, ls);
- text = StringUtils.replace(text, AS_TEXT_TAB, "\t");
-
- return text;
- }
-
- private static String reduceWhitespace(String text) {
- text = trim(text);
-
- // remove white spaces before or after block separators
- text = reduceWhiteSpaceAroundBlockSeparator(text);
-
- // remove leading block separators
- while (text.startsWith(AS_TEXT_BLOCK_SEPARATOR)) {
- text = text.substring(AS_TEXT_BLOCK_SEPARATOR_LENGTH);
- }
-
- // remove trailing block separators
- while (text.endsWith(AS_TEXT_BLOCK_SEPARATOR)) {
- text = text.substring(0, text.length() - AS_TEXT_BLOCK_SEPARATOR_LENGTH);
- }
- text = trim(text);
-
- final StringBuilder builder = new StringBuilder(text.length());
-
- boolean whitespace = false;
- for (final char ch : text.toCharArray()) {
-
- // Translate non-breaking space to regular space.
- if (ch == (char) 160) {
- builder.append(' ');
- whitespace = false;
- }
- else {
- if (whitespace) {
- if (!isSpace(ch)) {
- builder.append(ch);
- whitespace = false;
- }
- }
- else {
- if (isSpace(ch)) {
- whitespace = true;
- builder.append(' ');
- }
- else {
- builder.append(ch);
- }
- }
- }
- }
- return builder.toString();
- }
-
- private static boolean isSpace(final char ch) {
- return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\f' || ch == '\r';
- }
-
- private static String trim(String string) {
- int length = string.length();
-
- int start = 0;
- while (start != length && isSpace(string.charAt(start))) {
- start++;
- }
- if (start != 0) {
- string = string.substring(start);
- length = string.length();
- }
-
- if (length != 0) {
- int end = length;
- while (end != 0 && isSpace(string.charAt(end - 1))) {
- end--;
- }
- if (end != length) {
- string = string.substring(0, end);
- }
- }
-
- return string;
- }
-
- private static String reduceWhiteSpaceAroundBlockSeparator(final String text) {
- int p0 = text.indexOf(AS_TEXT_BLOCK_SEPARATOR);
- if (p0 == -1) {
- return text;
- }
-
- final int length = text.length();
- if (length <= AS_TEXT_BLOCK_SEPARATOR_LENGTH) {
- return text;
- }
-
- final StringBuilder result = new StringBuilder(length);
- int start = 0;
- while (p0 != -1) {
- int p1 = p0 + AS_TEXT_BLOCK_SEPARATOR_LENGTH;
- while (p0 != start && isSpace(text.charAt(p0 - 1))) {
- p0--;
- }
- if (p0 >= AS_TEXT_NEW_LINE_LENGTH && text.startsWith(AS_TEXT_NEW_LINE, p0 - AS_TEXT_NEW_LINE_LENGTH)) {
- p0 = p0 - AS_TEXT_NEW_LINE_LENGTH;
- }
- result.append(text.substring(start, p0)).append(AS_TEXT_BLOCK_SEPARATOR);
-
- while (p1 < length && isSpace(text.charAt(p1))) {
- p1++;
- }
- start = p1;
-
- // ignore duplicates
- p0 = text.indexOf(AS_TEXT_BLOCK_SEPARATOR, start);
- while (p0 != -1 && p0 == start) {
- start += AS_TEXT_BLOCK_SEPARATOR_LENGTH;
- p0 = text.indexOf(AS_TEXT_BLOCK_SEPARATOR, start);
- }
- }
- if (start < length) {
- result.append(text.substring(start));
- }
- return result.toString();
+ return builder.getText();
}
/**
@@ -203,7 +53,7 @@ private static String reduceWhiteSpaceAroundBlockSeparator(final String text) {
* @param builder the StringBuilder to add to
* @param node the node to process
*/
- protected void appendChildren(final StringBuilder builder, final DomNode node) {
+ protected void appendChildren(final HtmlSerializerTextBuilder builder, final DomNode node) {
for (final DomNode child : node.getChildren()) {
appendNode(builder, child);
}
@@ -216,7 +66,7 @@ protected void appendChildren(final StringBuilder builder, final DomNode node) {
* @param builder the StringBuilder to add to
* @param node the node to process
*/
- protected void appendNode(final StringBuilder builder, final DomNode node) {
+ protected void appendNode(final HtmlSerializerTextBuilder builder, final DomNode node) {
if (node instanceof DomText) {
appendText(builder, (DomText) node);
}
@@ -284,7 +134,7 @@ else if (node instanceof HtmlPreformattedText) {
else if (node instanceof HtmlInlineFrame) {
appendInlineFrame(builder, (HtmlInlineFrame) node);
}
- else if (node instanceof HtmlNoScript && node.getPage().getWebClient().getOptions().isJavaScriptEnabled()) {
+ else if (node instanceof HtmlNoScript && node.getPage().getWebClient().isJavaScriptEnabled()) {
appendNoScript(builder, (HtmlNoScript) node);
}
else {
@@ -298,27 +148,26 @@ else if (node instanceof HtmlNoScript && node.getPage().getWebClient().getOption
* @param builder the StringBuilder to add to
* @param domNode the target to process
*/
- protected void appendDomNode(final StringBuilder builder, final DomNode domNode) {
- final boolean block;
- final Object scriptableObject = domNode.getScriptableObject();
- if (domNode instanceof HtmlBody) {
- block = false;
- }
- else if (scriptableObject instanceof Element) {
- final Element element = (Element) scriptableObject;
- final String display = element.getWindow().getComputedStyle(element, null).getDisplay(true);
- block = "block".equals(display);
- }
- else {
- block = false;
+ protected void appendDomNode(final HtmlSerializerTextBuilder builder, final DomNode domNode) {
+ boolean block = false;
+ if (!(domNode instanceof HtmlBody)) {
+ final SgmlPage page = domNode.getPage();
+ if (page != null && page.getWebClient().isJavaScriptEngineEnabled()) {
+ final Object scriptableObject = domNode.getScriptableObject();
+ if (scriptableObject instanceof Element) {
+ final Element element = (Element) scriptableObject;
+ final String display = element.getWindow().getComputedStyle(element, null).getDisplay(true);
+ block = "block".equals(display);
+ }
+ }
}
if (block) {
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
}
appendChildren(builder, domNode);
if (block) {
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
}
}
@@ -328,7 +177,7 @@ else if (scriptableObject instanceof Element) {
* @param builder the StringBuilder to add to
* @param htmlHiddenInput the target to process
*/
- protected void appendHiddenInput(final StringBuilder builder, final HtmlHiddenInput htmlHiddenInput) {
+ protected void appendHiddenInput(final HtmlSerializerTextBuilder builder, final HtmlHiddenInput htmlHiddenInput) {
// nothing to do
}
@@ -338,7 +187,7 @@ protected void appendHiddenInput(final StringBuilder builder, final HtmlHiddenIn
* @param builder the StringBuilder to add to
* @param htmlScript the target to process
*/
- protected void appendScript(final StringBuilder builder, final HtmlScript htmlScript) {
+ protected void appendScript(final HtmlSerializerTextBuilder builder, final HtmlScript htmlScript) {
// nothing to do
}
@@ -348,7 +197,7 @@ protected void appendScript(final StringBuilder builder, final HtmlScript htmlSc
* @param builder the StringBuilder to add to
* @param htmlStyle the target to process
*/
- protected void appendStyle(final StringBuilder builder, final HtmlStyle htmlStyle) {
+ protected void appendStyle(final HtmlSerializerTextBuilder builder, final HtmlStyle htmlStyle) {
// nothing to do
}
@@ -358,7 +207,7 @@ protected void appendStyle(final StringBuilder builder, final HtmlStyle htmlStyl
* @param builder the StringBuilder to add to
* @param htmlNoScript the target to process
*/
- protected void appendNoScript(final StringBuilder builder, final HtmlNoScript htmlNoScript) {
+ protected void appendNoScript(final HtmlSerializerTextBuilder builder, final HtmlNoScript htmlNoScript) {
// nothing to do
}
@@ -368,7 +217,7 @@ protected void appendNoScript(final StringBuilder builder, final HtmlNoScript ht
* @param builder the StringBuilder to add to
* @param htmlNoFrames the target to process
*/
- protected void appendNoFrames(final StringBuilder builder, final HtmlNoFrames htmlNoFrames) {
+ protected void appendNoFrames(final HtmlSerializerTextBuilder builder, final HtmlNoFrames htmlNoFrames) {
// nothing to do
}
@@ -378,8 +227,8 @@ protected void appendNoFrames(final StringBuilder builder, final HtmlNoFrames ht
* @param builder the StringBuilder to add to
* @param htmlSubmitInput the target to process
*/
- protected void appendSubmitInput(final StringBuilder builder, final HtmlSubmitInput htmlSubmitInput) {
- builder.append(htmlSubmitInput.asText());
+ protected void appendSubmitInput(final HtmlSerializerTextBuilder builder, final HtmlSubmitInput htmlSubmitInput) {
+ builder.append(htmlSubmitInput.asText(), Mode.NORMALIZE);
}
/**
@@ -388,8 +237,8 @@ protected void appendSubmitInput(final StringBuilder builder, final HtmlSubmitIn
* @param builder the StringBuilder to add to
* @param htmlInput the target to process
*/
- protected void appendInput(final StringBuilder builder, final HtmlInput htmlInput) {
- builder.append(htmlInput.getValueAttribute());
+ protected void appendInput(final HtmlSerializerTextBuilder builder, final HtmlInput htmlInput) {
+ builder.append(htmlInput.getValueAttribute(), Mode.NORMALIZE);
}
/**
@@ -398,8 +247,8 @@ protected void appendInput(final StringBuilder builder, final HtmlInput htmlInpu
* @param builder the StringBuilder to add to
* @param htmlResetInput the target to process
*/
- protected void appendResetInput(final StringBuilder builder, final HtmlResetInput htmlResetInput) {
- builder.append(htmlResetInput.asText());
+ protected void appendResetInput(final HtmlSerializerTextBuilder builder, final HtmlResetInput htmlResetInput) {
+ builder.append(htmlResetInput.asText(), Mode.NORMALIZE);
}
/**
@@ -407,17 +256,18 @@ protected void appendResetInput(final StringBuilder builder, final HtmlResetInpu
* @param builder the StringBuilder to add to
* @param htmlUnorderedList the target to process
*/
- protected void appendUnorderedList(final StringBuilder builder, final HtmlUnorderedList htmlUnorderedList) {
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ protected void appendUnorderedList(final HtmlSerializerTextBuilder builder,
+ final HtmlUnorderedList htmlUnorderedList) {
+ builder.appendBlockSeparator();
boolean first = true;
for (final DomNode item : htmlUnorderedList.getChildren()) {
if (!first) {
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
}
first = false;
appendNode(builder, item);
}
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
}
/**
@@ -425,15 +275,15 @@ protected void appendUnorderedList(final StringBuilder builder, final HtmlUnorde
* @param builder the StringBuilder to add to
* @param htmlTitle the target to process
*/
- protected void appendTitle(final StringBuilder builder, final HtmlTitle htmlTitle) {
+ protected void appendTitle(final HtmlSerializerTextBuilder builder, final HtmlTitle htmlTitle) {
// optimized version
// for the title there is no need to check the visibility
// of the containing dom text;
// this optimization defers the load of the style sheets
final DomNode child = htmlTitle.getFirstChild();
if (child instanceof DomText) {
- builder.append(((DomText) child).getData());
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.append(((DomText) child).getData(), Mode.NORMALIZE);
+ builder.appendBlockSeparator();
}
}
@@ -443,11 +293,11 @@ protected void appendTitle(final StringBuilder builder, final HtmlTitle htmlTitl
* @param builder the StringBuilder to add to
* @param htmlTableRow the target to process
*/
- protected void appendTableRow(final StringBuilder builder, final HtmlTableRow htmlTableRow) {
+ protected void appendTableRow(final HtmlSerializerTextBuilder builder, final HtmlTableRow htmlTableRow) {
boolean first = true;
for (final HtmlTableCell cell : htmlTableRow.getCells()) {
if (!first) {
- builder.append(AS_TEXT_TAB);
+ builder.appendTab();
}
else {
first = false;
@@ -462,14 +312,9 @@ protected void appendTableRow(final StringBuilder builder, final HtmlTableRow ht
* @param builder the StringBuilder to add to
* @param htmlTextArea the target to process
*/
- protected void appendTextArea(final StringBuilder builder, final HtmlTextArea htmlTextArea) {
+ protected void appendTextArea(final HtmlSerializerTextBuilder builder, final HtmlTextArea htmlTextArea) {
if (isVisible(htmlTextArea)) {
- String text = htmlTextArea.getText();
- text = StringUtils.stripEnd(text, null);
- text = TEXT_AREA_PATTERN.matcher(text).replaceAll(AS_TEXT_NEW_LINE);
- text = StringUtils.replace(text, "\r", AS_TEXT_NEW_LINE);
- text = StringUtils.replace(text, " ", AS_TEXT_BLANK);
- builder.append(text);
+ builder.append(htmlTextArea.getText(), Mode.PRESERVE_BLANK_NEWLINE);
}
}
@@ -479,12 +324,12 @@ protected void appendTextArea(final StringBuilder builder, final HtmlTextArea ht
* @param builder the StringBuilder to add to
* @param htmlTable the target to process
*/
- protected void appendTable(final StringBuilder builder, final HtmlTable htmlTable) {
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ protected void appendTable(final HtmlSerializerTextBuilder builder, final HtmlTable htmlTable) {
+ builder.appendBlockSeparator();
final String caption = htmlTable.getCaptionText();
if (caption != null) {
- builder.append(caption);
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.append(caption, Mode.NORMALIZE);
+ builder.appendBlockSeparator();
}
boolean first = true;
@@ -509,7 +354,7 @@ else if (tableRows.isEmpty()) {
}
}
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
}
/**
@@ -522,7 +367,7 @@ else if (tableRows.isEmpty()) {
* @param skipParent2 skip row if the parent is this
* @return true if this was the first one
*/
- protected boolean appendTableRows(final StringBuilder builder,
+ protected boolean appendTableRows(final HtmlSerializerTextBuilder builder,
final List rows, boolean first, final TableRowGroup skipParent1,
final TableRowGroup skipParent2) {
for (final HtmlTableRow row : rows) {
@@ -530,7 +375,7 @@ protected boolean appendTableRows(final StringBuilder builder,
continue;
}
if (!first) {
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
}
first = false;
appendTableRow(builder, row);
@@ -544,7 +389,7 @@ protected boolean appendTableRows(final StringBuilder builder,
* @param builder the StringBuilder to add to
* @param htmlSelect the target to process
*/
- protected void appendSelect(final StringBuilder builder, final HtmlSelect htmlSelect) {
+ protected void appendSelect(final HtmlSerializerTextBuilder builder, final HtmlSelect htmlSelect) {
final List options;
if (htmlSelect.isMultipleSelectEnabled()) {
options = htmlSelect.getOptions();
@@ -557,7 +402,7 @@ protected void appendSelect(final StringBuilder builder, final HtmlSelect htmlSe
final HtmlOption currentOption = i.next();
appendNode(builder, currentOption);
if (i.hasNext()) {
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
}
}
}
@@ -568,25 +413,25 @@ protected void appendSelect(final StringBuilder builder, final HtmlSelect htmlSe
* @param builder the StringBuilder to add to
* @param htmlOrderedList the OL element
*/
- protected void appendOrderedList(final StringBuilder builder, final HtmlOrderedList htmlOrderedList) {
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ protected void appendOrderedList(final HtmlSerializerTextBuilder builder, final HtmlOrderedList htmlOrderedList) {
+ builder.appendBlockSeparator();
boolean first = true;
int i = 1;
for (final DomNode item : htmlOrderedList.getChildren()) {
if (!first) {
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
}
first = false;
if (item instanceof HtmlListItem) {
- builder.append(Integer.toString(i++));
- builder.append(". ");
+ builder.append(Integer.toString(i++), Mode.NORMALIZE);
+ builder.append(". ", Mode.NORMALIZE);
appendChildren(builder, item);
}
else {
appendNode(builder, item);
}
}
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
}
/**
@@ -595,17 +440,12 @@ protected void appendOrderedList(final StringBuilder builder, final HtmlOrderedL
* @param builder the StringBuilder to add to
* @param htmlPreformattedText the target to process
*/
- protected void appendPreformattedText(final StringBuilder builder,
+ protected void appendPreformattedText(final HtmlSerializerTextBuilder builder,
final HtmlPreformattedText htmlPreformattedText) {
if (isVisible(htmlPreformattedText)) {
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
- String text = htmlPreformattedText.getTextContent();
- text = StringUtils.replace(text, "\t", AS_TEXT_TAB);
- text = StringUtils.replace(text, " ", AS_TEXT_BLANK);
- text = TEXT_AREA_PATTERN.matcher(text).replaceAll(AS_TEXT_NEW_LINE);
- text = StringUtils.replace(text, "\r", AS_TEXT_NEW_LINE);
- builder.append(text);
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
+ builder.append(htmlPreformattedText.getTextContent(), Mode.PRESERVE_BLANK_TAB_NEWLINE);
+ builder.appendBlockSeparator();
}
}
@@ -615,15 +455,15 @@ protected void appendPreformattedText(final StringBuilder builder,
* @param builder the StringBuilder to add to
* @param htmlInlineFrame the target to process
*/
- protected void appendInlineFrame(final StringBuilder builder,
+ protected void appendInlineFrame(final HtmlSerializerTextBuilder builder,
final HtmlInlineFrame htmlInlineFrame) {
if (isVisible(htmlInlineFrame)) {
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
final Page page = htmlInlineFrame.getEnclosedPage();
if (page instanceof SgmlPage) {
- builder.append(((SgmlPage) page).asText());
+ builder.append(((SgmlPage) page).asText(), Mode.NORMALIZE);
}
- builder.append(AS_TEXT_BLOCK_SEPARATOR);
+ builder.appendBlockSeparator();
}
}
@@ -633,10 +473,10 @@ protected void appendInlineFrame(final StringBuilder builder,
* @param builder the StringBuilder to add to
* @param domText the target to process
*/
- protected void appendText(final StringBuilder builder, final DomText domText) {
+ protected void appendText(final HtmlSerializerTextBuilder builder, final DomText domText) {
final DomNode parent = domText.getParentNode();
if (parent == null || parent instanceof HtmlTitle || isVisible(parent)) {
- builder.append(domText.getData());
+ builder.append(domText.getData(), Mode.NORMALIZE);
}
}
@@ -646,7 +486,7 @@ protected void appendText(final StringBuilder builder, final DomText domText) {
* @param builder the StringBuilder to add to
* @param domComment the target to process
*/
- protected void appendComment(final StringBuilder builder, final DomComment domComment) {
+ protected void appendComment(final HtmlSerializerTextBuilder builder, final DomComment domComment) {
// nothing to do
}
@@ -656,7 +496,7 @@ protected void appendComment(final StringBuilder builder, final DomComment domCo
* @param builder the StringBuilder to add to
* @param htmlApplet the target to process
*/
- protected void appendApplet(final StringBuilder builder, final HtmlApplet htmlApplet) {
+ protected void appendApplet(final HtmlSerializerTextBuilder builder, final HtmlApplet htmlApplet) {
// nothing to do
}
@@ -666,8 +506,8 @@ protected void appendApplet(final StringBuilder builder, final HtmlApplet htmlAp
* @param builder the StringBuilder to add to
* @param htmlBreak the target to process
*/
- protected void appendBreak(final StringBuilder builder, final HtmlBreak htmlBreak) {
- builder.append(AS_TEXT_NEW_LINE);
+ protected void appendBreak(final HtmlSerializerTextBuilder builder, final HtmlBreak htmlBreak) {
+ builder.appendNewLine();
}
/**
@@ -676,12 +516,13 @@ protected void appendBreak(final StringBuilder builder, final HtmlBreak htmlBrea
* @param builder the StringBuilder to add to
* @param htmlCheckBoxInput the target to process
*/
- protected void doAppendCheckBoxInput(final StringBuilder builder, final HtmlCheckBoxInput htmlCheckBoxInput) {
+ protected void doAppendCheckBoxInput(final HtmlSerializerTextBuilder builder,
+ final HtmlCheckBoxInput htmlCheckBoxInput) {
if (htmlCheckBoxInput.isChecked()) {
- builder.append("checked");
+ builder.append("checked", Mode.NORMALIZE);
}
else {
- builder.append("unchecked");
+ builder.append("unchecked", Mode.NORMALIZE);
}
}
@@ -691,13 +532,13 @@ protected void doAppendCheckBoxInput(final StringBuilder builder, final HtmlChec
* @param builder the StringBuilder to add to
* @param htmlRadioButtonInput the target to process
*/
- protected void doAppendRadioButtonInput(final StringBuilder builder,
+ protected void doAppendRadioButtonInput(final HtmlSerializerTextBuilder builder,
final HtmlRadioButtonInput htmlRadioButtonInput) {
if (htmlRadioButtonInput.isChecked()) {
- builder.append("checked");
+ builder.append("checked", Mode.NORMALIZE);
}
else {
- builder.append("unchecked");
+ builder.append("unchecked", Mode.NORMALIZE);
}
}
@@ -713,4 +554,196 @@ private boolean isVisible(final DomNode node) {
public void setIgnoreMaskedElements(final boolean ignore) {
ignoreMaskedElements_ = ignore;
}
+
+ protected static class HtmlSerializerTextBuilder {
+ /** Mode. */
+ protected enum Mode {
+ /** Collapse whitespace. */
+ NORMALIZE,
+
+ /** Preserve tab, blank, newline. */
+ PRESERVE_BLANK_TAB_NEWLINE,
+
+ /** Preserve blank, newline. */
+ PRESERVE_BLANK_NEWLINE
+ }
+
+ private enum State {
+ DEFAULT,
+ EMPTY,
+ TRIM,
+ BLANK_AT_END,
+ BLANK_AT_END_AFTER_NEWLINE,
+ NEWLINE_AT_END,
+ BLOCK_SEPARATOR_AT_END
+ }
+
+ private static final String LINE_SEPARATOR = System.lineSeparator();
+ private static final int LINE_SEPARATOR_LENGTH = LINE_SEPARATOR.length();
+
+ private State state_;
+ private final StringBuilder builder_;
+ private int trimRightPos_;
+
+ public HtmlSerializerTextBuilder() {
+ builder_ = new StringBuilder();
+ state_ = State.EMPTY;
+ trimRightPos_ = 0;
+ }
+
+ public void append(final String content, final Mode mode) {
+ final int length = content.length();
+ if (length == 0) {
+ return;
+ }
+
+ String text = content;
+ if (mode == Mode.PRESERVE_BLANK_NEWLINE) {
+ text = StringUtils.stripEnd(text, null);
+ }
+
+ boolean crFound = false;
+ for (final char c : text.toCharArray()) {
+ if (mode == Mode.NORMALIZE) {
+ if (isSpace(c)) {
+ switch (state_) {
+ case EMPTY:
+ case TRIM:
+ case BLANK_AT_END:
+ case BLANK_AT_END_AFTER_NEWLINE:
+ case BLOCK_SEPARATOR_AT_END:
+ break;
+ case NEWLINE_AT_END:
+ builder_.append(' ');
+ state_ = State.BLANK_AT_END_AFTER_NEWLINE;
+ break;
+ default:
+ builder_.append(' ');
+ state_ = State.BLANK_AT_END;
+ break;
+ }
+ }
+ else if (c == (char) 160) {
+ builder_.append(' ');
+ state_ = State.DEFAULT;
+ trimRightPos_ = builder_.length();
+ }
+ else {
+ builder_.append(c);
+ state_ = State.DEFAULT;
+ trimRightPos_ = builder_.length();
+ }
+ continue;
+ }
+
+ // preserve mode
+ if (c == '\n') {
+ appendNewLine();
+ crFound = false;
+ }
+ else {
+ if (crFound) {
+ appendNewLine();
+ }
+ crFound = c == '\r';
+
+ if (c == '\t') {
+ if (mode == Mode.PRESERVE_BLANK_TAB_NEWLINE) {
+ appendTab();
+ }
+ else if (state_ != State.BLOCK_SEPARATOR_AT_END) {
+ builder_.append(' ');
+ }
+ }
+ else if (c == (char) 160) {
+ appendBlank();
+ }
+ else if (c == ' ') {
+ appendBlank();
+ }
+ else {
+ builder_.append(c);
+ }
+ trimRightPos_ = builder_.length();
+ }
+ }
+
+ if (crFound) {
+ appendNewLine();
+ }
+
+ if (mode != Mode.NORMALIZE) {
+ // reset state to empty to restart whitespace normalization afterwards
+ state_ = State.TRIM;
+ }
+ }
+
+ public void appendBlockSeparator() {
+ switch (state_) {
+ case EMPTY:
+ break;
+ case BLANK_AT_END:
+ builder_.setLength(trimRightPos_);
+ if (builder_.length() == 0) {
+ state_ = State.EMPTY;
+ }
+ else {
+ builder_.append(LINE_SEPARATOR);
+ state_ = State.BLOCK_SEPARATOR_AT_END;
+ }
+ break;
+ case BLANK_AT_END_AFTER_NEWLINE:
+ builder_.setLength(trimRightPos_ - LINE_SEPARATOR_LENGTH);
+ if (builder_.length() == 0) {
+ state_ = State.EMPTY;
+ }
+ else {
+ builder_.append(LINE_SEPARATOR);
+ state_ = State.BLOCK_SEPARATOR_AT_END;
+ }
+ break;
+ case BLOCK_SEPARATOR_AT_END:
+ break;
+ case NEWLINE_AT_END:
+ builder_.setLength(builder_.length() - LINE_SEPARATOR_LENGTH);
+ trimRightPos_ = trimRightPos_ - LINE_SEPARATOR_LENGTH;
+ if (builder_.length() == 0) {
+ state_ = State.EMPTY;
+ }
+ else {
+ builder_.append(LINE_SEPARATOR);
+ state_ = State.BLOCK_SEPARATOR_AT_END;
+ }
+ break;
+ default:
+ builder_.append(LINE_SEPARATOR);
+ state_ = State.BLOCK_SEPARATOR_AT_END;
+ break;
+ }
+ }
+
+ public void appendNewLine() {
+ builder_.append(LINE_SEPARATOR);
+ state_ = State.NEWLINE_AT_END;
+ trimRightPos_ = builder_.length();
+ }
+
+ public void appendTab() {
+ builder_.append('\t');
+ trimRightPos_ = builder_.length();
+ }
+
+ private void appendBlank() {
+ builder_.append(' ');
+ trimRightPos_ = builder_.length();
+ }
+
+ public String getText() {
+ return builder_.substring(0, trimRightPos_);
+ }
+
+ private static boolean isSpace(final char ch) {
+ return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\f' || ch == '\r';
+ }
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSerializerVisibleText.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSerializerVisibleText.java
new file mode 100644
index 00000000000..f5618bd27f9
--- /dev/null
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSerializerVisibleText.java
@@ -0,0 +1,940 @@
+/*
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gargoylesoftware.htmlunit.html;
+
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.gargoylesoftware.htmlunit.Page;
+import com.gargoylesoftware.htmlunit.SgmlPage;
+import com.gargoylesoftware.htmlunit.html.HtmlSerializerVisibleText.HtmlSerializerTextBuilder.Mode;
+import com.gargoylesoftware.htmlunit.javascript.host.Element;
+import com.gargoylesoftware.htmlunit.javascript.host.css.ComputedCSSStyleDeclaration;
+import com.gargoylesoftware.htmlunit.javascript.host.css.StyleAttributes.Definition;
+import com.gargoylesoftware.htmlunit.javascript.host.dom.Node;
+
+/**
+ * Special serializer to generate the output we need
+ * at least for selenium WebElement#getText().
+ *
+ * @author Ronald Brill
+ */
+public class HtmlSerializerVisibleText {
+
+ /**
+ * Converts an HTML node to text.
+ * @param node a node
+ * @return the text representation according to the setting of this serializer
+ */
+ public String asText(final DomNode node) {
+ if (node instanceof HtmlBreak) {
+ return "";
+ }
+ final HtmlSerializerTextBuilder builder = new HtmlSerializerTextBuilder();
+ appendNode(builder, node, whiteSpaceStyle(node, Mode.WHITE_SPACE_NORMAL));
+ return builder.getText();
+ }
+
+ /**
+ * Iterate over all Children and call appendNode() for every.
+ *
+ * @param builder the StringBuilder to add to
+ * @param node the node to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendChildren(final HtmlSerializerTextBuilder builder, final DomNode node, final Mode mode) {
+ for (final DomNode child : node.getChildren()) {
+ appendNode(builder, child, mode);
+ }
+ }
+
+ /**
+ * The core distribution method call the different appendXXX
+ * methods depending on the type of the given node.
+ *
+ * @param builder the StringBuilder to add to
+ * @param node the node to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendNode(final HtmlSerializerTextBuilder builder, final DomNode node, final Mode mode) {
+ if (node instanceof DomText) {
+ appendText(builder, (DomText) node, mode);
+ }
+ else if (node instanceof DomComment) {
+ appendComment(builder, (DomComment) node, mode);
+ }
+ else if (node instanceof HtmlApplet
+ && node.getPage().getWebClient().getOptions().isAppletEnabled()) {
+ appendApplet(builder, (HtmlApplet) node, mode);
+ }
+ else if (node instanceof HtmlBreak) {
+ appendBreak(builder, (HtmlBreak) node, mode);
+ }
+ else if (node instanceof HtmlHiddenInput) {
+ appendHiddenInput(builder, (HtmlHiddenInput) node, mode);
+ }
+ else if (node instanceof HtmlScript) {
+ appendScript(builder, (HtmlScript) node, mode);
+ }
+ else if (node instanceof HtmlStyle) {
+ appendStyle(builder, (HtmlStyle) node, mode);
+ }
+ else if (node instanceof HtmlNoFrames) {
+ appendNoFrames(builder, (HtmlNoFrames) node, mode);
+ }
+ else if (node instanceof HtmlTextArea) {
+ appendTextArea(builder, (HtmlTextArea) node, mode);
+ }
+ else if (node instanceof HtmlTitle) {
+ appendTitle(builder, (HtmlTitle) node, mode);
+ }
+ else if (node instanceof HtmlTableRow) {
+ appendTableRow(builder, (HtmlTableRow) node, mode);
+ }
+ else if (node instanceof HtmlSelect) {
+ appendSelect(builder, (HtmlSelect) node, mode);
+ }
+ else if (node instanceof HtmlOption) {
+ appendOption(builder, (HtmlOption) node, mode);
+ }
+ else if (node instanceof HtmlSubmitInput) {
+ appendSubmitInput(builder, (HtmlSubmitInput) node, mode);
+ }
+ else if (node instanceof HtmlResetInput) {
+ appendResetInput(builder, (HtmlResetInput) node, mode);
+ }
+ else if (node instanceof HtmlCheckBoxInput) {
+ doAppendCheckBoxInput(builder, (HtmlCheckBoxInput) node, mode);
+ }
+ else if (node instanceof HtmlRadioButtonInput) {
+ doAppendRadioButtonInput(builder, (HtmlRadioButtonInput) node, mode);
+ }
+ else if (node instanceof HtmlInput) {
+ // nothing
+ }
+ else if (node instanceof HtmlTable) {
+ appendTable(builder, (HtmlTable) node, mode);
+ }
+ else if (node instanceof HtmlOrderedList) {
+ appendOrderedList(builder, (HtmlOrderedList) node, mode);
+ }
+ else if (node instanceof HtmlUnorderedList) {
+ appendUnorderedList(builder, (HtmlUnorderedList) node, mode);
+ }
+ else if (node instanceof HtmlPreformattedText) {
+ appendPreformattedText(builder, (HtmlPreformattedText) node, mode);
+ }
+ else if (node instanceof HtmlInlineFrame) {
+ appendInlineFrame(builder, (HtmlInlineFrame) node, mode);
+ }
+ else if (node instanceof HtmlMenu) {
+ appendMenu(builder, (HtmlMenu) node, mode);
+ }
+ else if (node instanceof HtmlNoScript && node.getPage().getWebClient().isJavaScriptEnabled()) {
+ appendNoScript(builder, (HtmlNoScript) node, mode);
+ }
+ else {
+ appendDomNode(builder, node, mode);
+ }
+ }
+
+ /**
+ * Process {@link HtmlHiddenInput}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param domNode the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendDomNode(final HtmlSerializerTextBuilder builder,
+ final DomNode domNode, final Mode mode) {
+ final boolean block;
+ final Object scriptableObject = domNode.getScriptableObject();
+ if (domNode instanceof HtmlBody) {
+ block = false;
+ }
+ else if (scriptableObject instanceof Element) {
+ final Element element = (Element) scriptableObject;
+ final String display = element.getWindow().getComputedStyle(element, null).getDisplay(true);
+ block = "block".equals(display);
+ }
+ else {
+ block = false;
+ }
+
+ if (block) {
+ builder.appendBlockSeparator();
+ }
+ appendChildren(builder, domNode, mode);
+ if (block) {
+ builder.appendBlockSeparator();
+ }
+ }
+
+ /**
+ * Process {@link HtmlHiddenInput}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlHiddenInput the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendHiddenInput(final HtmlSerializerTextBuilder builder,
+ final HtmlHiddenInput htmlHiddenInput, final Mode mode) {
+ // nothing to do
+ }
+
+ /**
+ * Process {@link HtmlScript}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlScript the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendScript(final HtmlSerializerTextBuilder builder,
+ final HtmlScript htmlScript, final Mode mode) {
+ // nothing to do
+ }
+
+ /**
+ * Process {@link HtmlStyle}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlStyle the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendStyle(final HtmlSerializerTextBuilder builder,
+ final HtmlStyle htmlStyle, final Mode mode) {
+ // nothing to do
+ }
+
+ /**
+ * Process {@link HtmlNoScript}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlNoScript the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendNoScript(final HtmlSerializerTextBuilder builder,
+ final HtmlNoScript htmlNoScript, final Mode mode) {
+ // nothing to do
+ }
+
+ /**
+ * Process {@link HtmlNoFrames}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlNoFrames the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendNoFrames(final HtmlSerializerTextBuilder builder,
+ final HtmlNoFrames htmlNoFrames, final Mode mode) {
+ // nothing to do
+ }
+
+ /**
+ * Process {@link HtmlSubmitInput}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlSubmitInput the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendSubmitInput(final HtmlSerializerTextBuilder builder,
+ final HtmlSubmitInput htmlSubmitInput, final Mode mode) {
+ // nothing to do
+ }
+
+ /**
+ * Process {@link HtmlInput}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlInput the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendInput(final HtmlSerializerTextBuilder builder,
+ final HtmlInput htmlInput, final Mode mode) {
+ builder.append(htmlInput.getValueAttribute(), mode);
+ }
+
+ /**
+ * Process {@link HtmlResetInput}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlResetInput the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendResetInput(final HtmlSerializerTextBuilder builder,
+ final HtmlResetInput htmlResetInput, final Mode mode) {
+ // nothing to do
+ }
+
+ /**
+ * Process {@link HtmlMenu}.
+ * @param builder the StringBuilder to add to
+ * @param htmlMenu the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendMenu(final HtmlSerializerTextBuilder builder,
+ final HtmlMenu htmlMenu, final Mode mode) {
+ builder.appendBlockSeparator();
+ boolean first = true;
+ for (final DomNode item : htmlMenu.getChildren()) {
+ if (!first) {
+ builder.appendBlockSeparator();
+ }
+ first = false;
+ appendNode(builder, item, mode);
+ }
+ builder.appendBlockSeparator();
+ }
+
+ /**
+ * Process {@link HtmlTitle}.
+ * @param builder the StringBuilder to add to
+ * @param htmlTitle the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendTitle(final HtmlSerializerTextBuilder builder,
+ final HtmlTitle htmlTitle, final Mode mode) {
+ // nothing to do
+ }
+
+ /**
+ * Process {@link HtmlTableRow}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlTableRow the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendTableRow(final HtmlSerializerTextBuilder builder,
+ final HtmlTableRow htmlTableRow, final Mode mode) {
+ boolean first = true;
+ for (final HtmlTableCell cell : htmlTableRow.getCells()) {
+ if (!first) {
+ builder.appendBlank();
+ }
+ else {
+ first = false;
+ }
+ appendChildren(builder, cell, mode); // trim?
+ }
+ }
+
+ /**
+ * Process {@link HtmlTextArea}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlTextArea the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendTextArea(final HtmlSerializerTextBuilder builder,
+ final HtmlTextArea htmlTextArea, final Mode mode) {
+ if (isVisible(htmlTextArea)) {
+ builder.append(htmlTextArea.getDefaultValue(), whiteSpaceStyle(htmlTextArea, Mode.PRE));
+ builder.trimRight(Mode.PRE);
+ }
+ }
+
+ /**
+ * Process {@link HtmlTable}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlTable the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendTable(final HtmlSerializerTextBuilder builder,
+ final HtmlTable htmlTable, final Mode mode) {
+ builder.appendBlockSeparator();
+ final String caption = htmlTable.getCaptionText();
+ if (caption != null) {
+ builder.append(caption, mode);
+ builder.appendBlockSeparator();
+ }
+
+ boolean first = true;
+
+ // first thead has to be displayed first and first tfoot has to be displayed last
+ final HtmlTableHeader tableHeader = htmlTable.getHeader();
+ if (tableHeader != null) {
+ first = appendTableRows(builder, mode, tableHeader.getRows(), true, null, null);
+ }
+ final HtmlTableFooter tableFooter = htmlTable.getFooter();
+
+ final List tableRows = htmlTable.getRows();
+ first = appendTableRows(builder, mode, tableRows, first, tableHeader, tableFooter);
+
+ if (tableFooter != null) {
+ first = appendTableRows(builder, mode, tableFooter.getRows(), first, null, null);
+ }
+ else if (tableRows.isEmpty()) {
+ final DomNode firstChild = htmlTable.getFirstChild();
+ if (firstChild != null) {
+ appendNode(builder, firstChild, mode);
+ }
+ }
+
+ builder.appendBlockSeparator();
+ }
+
+ /**
+ * Process {@link HtmlTableRow}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param mode the {@link Mode} to use for processing
+ * @param rows the rows
+ * @param first if true this is the first one
+ * @param skipParent1 skip row if the parent is this
+ * @param skipParent2 skip row if the parent is this
+ * @return true if this was the first one
+ */
+ protected boolean appendTableRows(final HtmlSerializerTextBuilder builder, final Mode mode,
+ final List rows, boolean first, final TableRowGroup skipParent1,
+ final TableRowGroup skipParent2) {
+ for (final HtmlTableRow row : rows) {
+ if (row.getParentNode() == skipParent1 || row.getParentNode() == skipParent2) {
+ continue;
+ }
+ if (!first) {
+ builder.appendBlockSeparator();
+ }
+ first = false;
+ appendTableRow(builder, row, mode);
+ }
+ return first;
+ }
+
+ /**
+ * Process {@link HtmlSelect}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlSelect the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendSelect(final HtmlSerializerTextBuilder builder,
+ final HtmlSelect htmlSelect, final Mode mode) {
+ builder.appendBlockSeparator();
+ boolean leadingNlPending = false;
+ final Mode selectMode = whiteSpaceStyle(htmlSelect, mode);
+ for (final DomNode item : htmlSelect.getChildren()) {
+ if (leadingNlPending) {
+ builder.appendBlockSeparator();
+ leadingNlPending = false;
+ }
+
+ builder.resetContentAdded();
+ appendNode(builder, item, whiteSpaceStyle(item, selectMode));
+ if (!leadingNlPending && builder.contentAdded_) {
+ leadingNlPending = true;
+ }
+ }
+ builder.appendBlockSeparator();
+ }
+
+ /**
+ * Process {@link HtmlSelect}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlOption the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendOption(final HtmlSerializerTextBuilder builder,
+ final HtmlOption htmlOption, final Mode mode) {
+ builder.ignoreHtmlBreaks();
+ appendChildren(builder, htmlOption, mode);
+ builder.processHtmlBreaks();
+ }
+
+ /**
+ * Process {@link HtmlOrderedList}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlOrderedList the OL element
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendOrderedList(final HtmlSerializerTextBuilder builder,
+ final HtmlOrderedList htmlOrderedList, final Mode mode) {
+ builder.appendBlockSeparator();
+ boolean leadingNlPending = false;
+ final Mode olMode = whiteSpaceStyle(htmlOrderedList, mode);
+ for (final DomNode item : htmlOrderedList.getChildren()) {
+ if (leadingNlPending) {
+ builder.appendBlockSeparator();
+ leadingNlPending = false;
+ }
+
+ builder.resetContentAdded();
+ appendNode(builder, item, whiteSpaceStyle(item, olMode));
+ if (!leadingNlPending && builder.contentAdded_) {
+ leadingNlPending = true;
+ }
+ }
+ builder.appendBlockSeparator();
+ }
+
+ /**
+ * Process {@link HtmlUnorderedList}.
+ * @param builder the StringBuilder to add to
+ * @param htmlUnorderedList the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendUnorderedList(final HtmlSerializerTextBuilder builder,
+ final HtmlUnorderedList htmlUnorderedList, final Mode mode) {
+ builder.appendBlockSeparator();
+ boolean leadingNlPending = false;
+ final Mode ulMode = whiteSpaceStyle(htmlUnorderedList, mode);
+ for (final DomNode item : htmlUnorderedList.getChildren()) {
+ if (leadingNlPending) {
+ builder.appendBlockSeparator();
+ leadingNlPending = false;
+ }
+
+ builder.resetContentAdded();
+ appendNode(builder, item, whiteSpaceStyle(item, ulMode));
+ if (!leadingNlPending && builder.contentAdded_) {
+ leadingNlPending = true;
+ }
+ }
+ builder.appendBlockSeparator();
+ }
+
+ /**
+ * Process {@link HtmlPreformattedText}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlPreformattedText the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendPreformattedText(final HtmlSerializerTextBuilder builder,
+ final HtmlPreformattedText htmlPreformattedText, final Mode mode) {
+ if (isVisible(htmlPreformattedText)) {
+ builder.appendBlockSeparator();
+ appendChildren(builder, htmlPreformattedText, whiteSpaceStyle(htmlPreformattedText, Mode.PRE));
+ builder.appendBlockSeparator();
+ }
+ }
+
+ /**
+ * Process {@link HtmlInlineFrame}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlInlineFrame the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendInlineFrame(final HtmlSerializerTextBuilder builder,
+ final HtmlInlineFrame htmlInlineFrame, final Mode mode) {
+ if (isVisible(htmlInlineFrame)) {
+ builder.appendBlockSeparator();
+ final Page page = htmlInlineFrame.getEnclosedPage();
+ if (page instanceof SgmlPage) {
+ builder.append(((SgmlPage) page).asText(), mode);
+ }
+ builder.appendBlockSeparator();
+ }
+ }
+
+ /**
+ * Process {@link DomText}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param domText the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendText(final HtmlSerializerTextBuilder builder, final DomText domText, final Mode mode) {
+ final DomNode parent = domText.getParentNode();
+ if (parent == null || parent instanceof HtmlTitle || isVisible(parent)) {
+ builder.append(domText.getData(), mode);
+ }
+ }
+
+ /**
+ * Process {@link DomComment}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param domComment the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendComment(final HtmlSerializerTextBuilder builder,
+ final DomComment domComment, final Mode mode) {
+ // nothing to do
+ }
+
+ /**
+ * Process {@link HtmlApplet}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlApplet the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendApplet(final HtmlSerializerTextBuilder builder,
+ final HtmlApplet htmlApplet, final Mode mode) {
+ // nothing to do
+ }
+
+ /**
+ * Process {@link HtmlBreak}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlBreak the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void appendBreak(final HtmlSerializerTextBuilder builder,
+ final HtmlBreak htmlBreak, final Mode mode) {
+ builder.appendBreak(mode);
+ }
+
+ /**
+ * Process {@link HtmlCheckBoxInput}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlCheckBoxInput the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void doAppendCheckBoxInput(final HtmlSerializerTextBuilder builder,
+ final HtmlCheckBoxInput htmlCheckBoxInput, final Mode mode) {
+ // nothing to do
+ }
+
+ /**
+ * Process {@link HtmlRadioButtonInput}.
+ *
+ * @param builder the StringBuilder to add to
+ * @param htmlRadioButtonInput the target to process
+ * @param mode the {@link Mode} to use for processing
+ */
+ protected void doAppendRadioButtonInput(final HtmlSerializerTextBuilder builder,
+ final HtmlRadioButtonInput htmlRadioButtonInput, final Mode mode) {
+ // nothing to do
+ }
+
+ private boolean isVisible(final DomNode node) {
+ return node.isDisplayed();
+ }
+
+ private Mode whiteSpaceStyle(final DomNode domNode, final Mode defaultMode) {
+ final Object scriptableObject = domNode.getScriptableObject();
+ if (scriptableObject instanceof Node) {
+ final Page page = domNode.getPage();
+ if (page != null && page.getEnclosingWindow().getWebClient().getOptions().isCssEnabled()) {
+ Node node = (Node) scriptableObject;
+
+ while (node != null) {
+ if (node instanceof Element) {
+ final ComputedCSSStyleDeclaration style = node.getWindow().getComputedStyle(node, null);
+ final String value = style.getStyleAttribute(Definition.WHITE_SPACE, false);
+ if (StringUtils.isNoneEmpty(value)) {
+ if ("normal".equalsIgnoreCase(value)) {
+ return Mode.WHITE_SPACE_NORMAL;
+ }
+ if ("nowrap".equalsIgnoreCase(value)) {
+ return Mode.WHITE_SPACE_NORMAL;
+ }
+ if ("pre".equalsIgnoreCase(value)) {
+ return Mode.WHITE_SPACE_PRE;
+ }
+ if ("pre-wrap".equalsIgnoreCase(value)) {
+ return Mode.WHITE_SPACE_PRE;
+ }
+ if ("pre-line".equalsIgnoreCase(value)) {
+ return Mode.WHITE_SPACE_PRE_LINE;
+ }
+ }
+ }
+ node = node.getParentElement();
+ }
+ }
+ }
+ return defaultMode;
+ }
+
+ protected static class HtmlSerializerTextBuilder {
+ /** Mode. */
+ protected enum Mode {
+ /**
+ * The mode for the pre tag.
+ */
+ PRE,
+
+ /**
+ * Sequences of white space are collapsed. Newline characters
+ * in the source are handled the same as other white space.
+ * Lines are broken as necessary to fill line boxes.
+ */
+ WHITE_SPACE_NORMAL,
+
+ /**
+ * Sequences of white space are preserved. Lines are only broken
+ * at newline characters in the source and at elements.
+ */
+ WHITE_SPACE_PRE,
+
+ /**
+ * Sequences of white space are collapsed. Lines are broken
+ * at newline characters, at , and as necessary
+ * to fill line boxes.
+ */
+ WHITE_SPACE_PRE_LINE
+ }
+
+ private enum State {
+ DEFAULT,
+ EMPTY,
+ BLANK_AT_END,
+ BLANK_AT_END_AFTER_NEWLINE,
+ NEWLINE_AT_END,
+ BREAK_AT_END,
+ BLOCK_SEPARATOR_AT_END
+ }
+
+ private State state_;
+ private final StringBuilder builder_;
+ private int trimRightPos_;
+ private boolean contentAdded_;
+ private boolean ignoreHtmlBreaks_;
+
+ public HtmlSerializerTextBuilder() {
+ builder_ = new StringBuilder();
+ state_ = State.EMPTY;
+ trimRightPos_ = 0;
+ }
+
+ // see https://drafts.csswg.org/css-text-3/#white-space
+ public void append(final String content, final Mode mode) {
+ int length = content.length();
+ if (length == 0) {
+ return;
+ }
+
+ length--;
+ int i = -1;
+ for (char c : content.toCharArray()) {
+ i++;
+
+ // handle \r
+ if (c == '\r') {
+ if (length != i) {
+ continue;
+ }
+ c = '\n';
+ }
+
+ if (c == '\n') {
+ if (mode == Mode.WHITE_SPACE_PRE) {
+ switch (state_) {
+ case EMPTY:
+ case BLOCK_SEPARATOR_AT_END:
+ break;
+ default:
+ builder_.append('\n');
+ state_ = State.NEWLINE_AT_END;
+ trimRightPos_ = builder_.length();
+ break;
+ }
+ continue;
+ }
+
+ if (mode == Mode.PRE) {
+ builder_.append('\n');
+ state_ = State.NEWLINE_AT_END;
+ trimRightPos_ = builder_.length();
+
+ continue;
+ }
+
+ if (mode == Mode.WHITE_SPACE_PRE_LINE) {
+ switch (state_) {
+ case EMPTY:
+ case BLOCK_SEPARATOR_AT_END:
+ break;
+ default:
+ builder_.append('\n');
+ state_ = State.NEWLINE_AT_END;
+ trimRightPos_ = builder_.length();
+ break;
+ }
+ continue;
+ }
+
+ switch (state_) {
+ case EMPTY:
+ case BLANK_AT_END:
+ case BLANK_AT_END_AFTER_NEWLINE:
+ case BLOCK_SEPARATOR_AT_END:
+ case NEWLINE_AT_END:
+ case BREAK_AT_END:
+ break;
+ default:
+ builder_.append(' ');
+ state_ = State.BLANK_AT_END;
+ break;
+ }
+ continue;
+ }
+
+ if (c == ' ' || c == '\t' || c == '\f') {
+ if (mode == Mode.WHITE_SPACE_PRE || mode == Mode.PRE) {
+ appendBlank();
+ continue;
+ }
+
+ if (mode == Mode.WHITE_SPACE_PRE_LINE) {
+ switch (state_) {
+ case EMPTY:
+ case BLANK_AT_END:
+ case BLANK_AT_END_AFTER_NEWLINE:
+ case BREAK_AT_END:
+ break;
+ default:
+ builder_.append(' ');
+ state_ = State.BLANK_AT_END;
+ break;
+ }
+ continue;
+ }
+
+ switch (state_) {
+ case EMPTY:
+ case BLANK_AT_END:
+ case BLANK_AT_END_AFTER_NEWLINE:
+ case BLOCK_SEPARATOR_AT_END:
+ case NEWLINE_AT_END:
+ case BREAK_AT_END:
+ break;
+ default:
+ builder_.append(' ');
+ state_ = State.BLANK_AT_END;
+ break;
+ }
+ continue;
+ }
+
+ if (c == (char) 160) {
+ appendBlank();
+ if (mode == Mode.WHITE_SPACE_NORMAL || mode == Mode.WHITE_SPACE_PRE_LINE) {
+ state_ = State.DEFAULT;
+ }
+ continue;
+ }
+ builder_.append(c);
+ state_ = State.DEFAULT;
+ trimRightPos_ = builder_.length();
+ contentAdded_ = true;
+ }
+ }
+
+ public void appendBlockSeparator() {
+ switch (state_) {
+ case EMPTY:
+ break;
+ case BLANK_AT_END:
+ builder_.setLength(trimRightPos_);
+ if (builder_.length() == 0) {
+ state_ = State.EMPTY;
+ }
+ else {
+ builder_.append('\n');
+ state_ = State.BLOCK_SEPARATOR_AT_END;
+ }
+ break;
+ case BLANK_AT_END_AFTER_NEWLINE:
+ builder_.setLength(trimRightPos_ - 1);
+ if (builder_.length() == 0) {
+ state_ = State.EMPTY;
+ }
+ else {
+ builder_.append('\n');
+ state_ = State.BLOCK_SEPARATOR_AT_END;
+ }
+ break;
+ case BLOCK_SEPARATOR_AT_END:
+ break;
+ case NEWLINE_AT_END:
+ case BREAK_AT_END:
+ builder_.setLength(builder_.length() - 1);
+ trimRightPos_ = trimRightPos_ - 1;
+ if (builder_.length() == 0) {
+ state_ = State.EMPTY;
+ }
+ else {
+ builder_.append('\n');
+ state_ = State.BLOCK_SEPARATOR_AT_END;
+ }
+ break;
+ default:
+ builder_.append('\n');
+ state_ = State.BLOCK_SEPARATOR_AT_END;
+ break;
+ }
+ }
+
+ public void appendBreak(final Mode mode) {
+ if (ignoreHtmlBreaks_) {
+ return;
+ }
+
+ builder_.setLength(trimRightPos_);
+
+ builder_.append('\n');
+ state_ = State.BREAK_AT_END;
+ trimRightPos_ = builder_.length();
+ }
+
+ public void appendBlank() {
+ builder_.append(' ');
+ state_ = State.BLANK_AT_END;
+ trimRightPos_ = builder_.length();
+ }
+
+ public void trimRight(final Mode mode) {
+ if (mode == Mode.PRE) {
+ switch (state_) {
+ case BLOCK_SEPARATOR_AT_END:
+ case NEWLINE_AT_END:
+ case BREAK_AT_END:
+ if (trimRightPos_ == builder_.length()) {
+ trimRightPos_--;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ builder_.setLength(trimRightPos_);
+ state_ = State.DEFAULT;
+ if (builder_.length() == 0) {
+ state_ = State.EMPTY;
+ }
+ }
+
+ public boolean wasContentAdded() {
+ return contentAdded_;
+ }
+
+ public void resetContentAdded() {
+ contentAdded_ = false;
+ }
+
+ public void ignoreHtmlBreaks() {
+ ignoreHtmlBreaks_ = true;
+ }
+
+ public void processHtmlBreaks() {
+ ignoreHtmlBreaks_ = false;
+ }
+
+ public String getText() {
+ return builder_.substring(0, trimRightPos_);
+ }
+ }
+}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSlot.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSlot.java
index f1ce8affc37..1a3a11ebd8c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSlot.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSlot.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSmall.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSmall.java
index d4b1d100a65..812a4bdfed2 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSmall.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSmall.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSource.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSource.java
index 46d970df457..190eb026484 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSource.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSource.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSpan.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSpan.java
index b57a212656e..8f41b65c34f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSpan.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSpan.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStrike.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStrike.java
index 126aafdfbac..baf21ddbf5b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStrike.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStrike.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStrong.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStrong.java
index c09391678a7..621702bb068 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStrong.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStrong.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStyle.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStyle.java
index 0dea1089449..01f5b79ad65 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStyle.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlStyle.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSubmitInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSubmitInput.java
index 15c28b8b7ac..65fdab9bf55 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSubmitInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSubmitInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -94,6 +94,14 @@ protected boolean doClickStateUpdate(final boolean shiftKey, final boolean ctrlK
return false;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc} This method does nothing for submit input elements.
* @see SubmittableElement#reset()
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSubscript.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSubscript.java
index e5d5978da27..f9954bf48e4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSubscript.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSubscript.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSummary.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSummary.java
index f1d4c14248a..4bfe775535b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSummary.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSummary.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSuperscript.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSuperscript.java
index 3e4022a91d8..915d1c0d8b4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSuperscript.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSuperscript.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSvg.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSvg.java
index cb857423bb7..98cc7c82f22 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSvg.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlSvg.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,6 @@ public class HtmlSvg extends HtmlElement {
*/
HtmlSvg(final String qualifiedName, final SgmlPage page,
final Map attributes) {
- super(HTMLParser.SVG_NAMESPACE, qualifiedName, page, attributes);
+ super(Html.SVG_NAMESPACE, qualifiedName, page, attributes);
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTable.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTable.java
index 3bfe8ac55b1..de785784555 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTable.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -139,7 +139,7 @@ public HtmlTableRow getRow(final int index) throws IndexOutOfBoundsException {
}
count++;
}
- throw new IndexOutOfBoundsException();
+ throw new IndexOutOfBoundsException("No row found for index " + index + ".");
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableBody.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableBody.java
index ca20a3fafda..8852759e2d6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableBody.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableBody.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableCell.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableCell.java
index 58f75ab64c6..d701058a0e9 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableCell.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableCell.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableColumn.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableColumn.java
index 8f06009300a..872d748faba 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableColumn.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableColumn.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableColumnGroup.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableColumnGroup.java
index f5264dba9f4..9dbd1026f3f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableColumnGroup.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableColumnGroup.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableDataCell.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableDataCell.java
index e70fc210eb5..9a60620f61a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableDataCell.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableDataCell.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableFooter.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableFooter.java
index 921aa1b136d..6aa67528734 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableFooter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableFooter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableHeader.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableHeader.java
index 1d78d2fb0f8..4dde5398f1d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableHeader.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableHeader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableHeaderCell.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableHeaderCell.java
index 2088671b6e3..77cf0a496c4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableHeaderCell.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableHeaderCell.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableRow.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableRow.java
index 8c76fa28283..6cb469f20b5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableRow.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTableRow.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -82,7 +82,7 @@ public HtmlTableCell getCell(final int index) throws IndexOutOfBoundsException {
}
count++;
}
- throw new IndexOutOfBoundsException();
+ throw new IndexOutOfBoundsException("No cell found for index " + index + ".");
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTelInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTelInput.java
index e0eb9794ea6..c6f6d6da8af 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTelInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTelInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,6 +43,14 @@ public class HtmlTelInput extends HtmlInput implements SelectableTextInput {
super(qualifiedName, page, attributes);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
@@ -111,10 +119,7 @@ public String getText() {
* {@inheritDoc}
*/
@Override
- protected void doType(final char c, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final char c, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, c, this, lastType);
}
@@ -122,10 +127,7 @@ protected void doType(final char c, final boolean startAtEnd, final boolean last
* {@inheritDoc}
*/
@Override
- protected void doType(final int keyCode, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final int keyCode, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, keyCode, this, lastType);
}
@@ -150,4 +152,14 @@ public DomNode cloneNode(final boolean deep) {
return newnode;
}
+
+ /**
+ * {@inheritDoc}
+ * @see HtmlInput#reset()
+ */
+ @Override
+ public void reset() {
+ super.reset();
+ setSelectionEnd(0);
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTeletype.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTeletype.java
index 1fea88d46b1..e5c15b27069 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTeletype.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTeletype.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTemplate.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTemplate.java
index bc27dba19b5..35f5a28934e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTemplate.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTemplate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -64,7 +64,7 @@ public DomDocumentFragment getContent() {
* Parsing of the children is done, we can move our children to the content.
*/
@Override
- protected void onAllChildrenAddedToPage(final boolean postponed) {
+ public void onAllChildrenAddedToPage(final boolean postponed) {
while (getFirstChild() != null) {
final DomNode child = getFirstChild();
child.basicRemove();
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTextArea.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTextArea.java
index 384dcdc9024..90a15bd7551 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTextArea.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTextArea.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -463,10 +463,7 @@ protected void printXml(final String indent, final PrintWriter printWriter) {
* {@inheritDoc}
*/
@Override
- protected void doType(final char c, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getText().length());
- }
+ protected void doType(final char c, final boolean lastType) {
doTypeProcessor_.doType(getText(), selectionDelegate_, c, this, lastType);
}
@@ -474,10 +471,7 @@ protected void doType(final char c, final boolean startAtEnd, final boolean last
* {@inheritDoc}
*/
@Override
- protected void doType(final int keyCode, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getText().length());
- }
+ protected void doType(final int keyCode, final boolean lastType) {
doTypeProcessor_.doType(getText(), selectionDelegate_, keyCode, this, lastType);
}
@@ -512,7 +506,7 @@ public void focus() {
@Override
public void removeFocus() {
super.removeFocus();
- if (!valueAtFocus_.equals(getText())) {
+ if (valueAtFocus_ != null && !valueAtFocus_.equals(getText())) {
HtmlInput.executeOnChangeHandlerIfAppropriate(this);
}
valueAtFocus_ = null;
@@ -540,14 +534,6 @@ public boolean isReadOnly() {
return hasAttribute("readOnly");
}
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object clone() throws CloneNotSupportedException {
- return new HtmlTextArea(getQualifiedName(), getPage(), getAttributesMap());
- }
-
/**
* {@inheritDoc}
*/
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTextInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTextInput.java
index abd993fc638..58c6ec82de6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTextInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTextInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -55,10 +55,7 @@ public class HtmlTextInput extends HtmlInput implements SelectableTextInput {
* {@inheritDoc}
*/
@Override
- protected void doType(final char c, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final char c, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, c, this, lastType);
}
@@ -66,10 +63,7 @@ protected void doType(final char c, final boolean startAtEnd, final boolean last
* {@inheritDoc}
*/
@Override
- protected void doType(final int keyCode, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final int keyCode, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, keyCode, this, lastType);
}
@@ -180,17 +174,27 @@ protected void setAttributeNS(final String namespaceURI, final String qualifiedN
* {@inheritDoc}
*/
@Override
- protected Object clone() throws CloneNotSupportedException {
- return new HtmlTextInput(getQualifiedName(), getPage(), getAttributesMap());
+ public void setDefaultValue(final String defaultValue) {
+ final boolean modifyValue = getValueAttribute().equals(getDefaultValue());
+ setDefaultValue(defaultValue, modifyValue);
}
/**
* {@inheritDoc}
*/
@Override
- public void setDefaultValue(final String defaultValue) {
- final boolean modifyValue = getValueAttribute().equals(getDefaultValue());
- setDefaultValue(defaultValue, modifyValue);
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see HtmlInput#reset()
+ */
+ @Override
+ public void reset() {
+ super.reset();
+ setSelectionEnd(0);
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTime.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTime.java
index 82c1d4c5c5c..0b2771a4cd0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTime.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTime.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTimeInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTimeInput.java
index 0500ca1bebc..6e306b23ef0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTimeInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTimeInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,13 +14,14 @@
*/
package com.gargoylesoftware.htmlunit.html;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INPUT_SET_VALUE_DATE_SUPPORTED;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLINPUT_TYPE_DATETIME_SUPPORTED;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Map;
import com.gargoylesoftware.htmlunit.SgmlPage;
+import org.apache.commons.lang3.StringUtils;
/**
* Wrapper for the HTML element "input" where type is "time".
@@ -43,13 +44,22 @@ public class HtmlTimeInput extends HtmlInput {
super(qualifiedName, page, attributes);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
@Override
public void setValueAttribute(final String newValue) {
try {
- if (hasFeature(JS_INPUT_SET_VALUE_DATE_SUPPORTED)) {
+ if (hasFeature(HTMLINPUT_TYPE_DATETIME_SUPPORTED)
+ && StringUtils.isNotEmpty(newValue)) {
FORMATTER_.parse(newValue);
}
super.setValueAttribute(newValue);
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTitle.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTitle.java
index fb8ca73057c..b2b9fdc9448 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTitle.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTitle.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTrack.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTrack.java
index c8f20afc9c5..366aa22fd87 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTrack.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlTrack.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnderlined.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnderlined.java
index 1a6aadb7d4a..8e0f6e365aa 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnderlined.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnderlined.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnknownElement.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnknownElement.java
index 75bfbe5e048..1367750804d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnknownElement.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnknownElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,10 +14,12 @@
*/
package com.gargoylesoftware.htmlunit.html;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_DIALOG_NONE;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_RP_DISPLAY_NONE;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_RT_DISPLAY_RUBY_TEXT_ALWAYS;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_RUBY_DISPLAY_INLINE;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.MULTICOL_BLOCK;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.SLOT_CONTENTS;
import java.util.Map;
@@ -98,18 +100,26 @@ public DisplayStyle getDefaultStyleDisplay() {
}
break;
case HtmlRt.TAG_NAME:
- if (wasCreatedByJavascript() && getParentNode() == null) {
+ if (!hasFeature(CSS_RT_DISPLAY_RUBY_TEXT_ALWAYS)
+ && wasCreatedByJavascript() && getParentNode() == null) {
return DisplayStyle.BLOCK;
}
- if (hasFeature(CSS_RT_DISPLAY_RUBY_TEXT_ALWAYS)) {
- return DisplayStyle.RUBY_TEXT;
- }
- break;
+ return DisplayStyle.RUBY_TEXT;
case HtmlMultiColumn.TAG_NAME:
if (hasFeature(MULTICOL_BLOCK)) {
return DisplayStyle.BLOCK;
}
break;
+ case HtmlDialog.TAG_NAME:
+ if (hasFeature(CSS_DIALOG_NONE)) {
+ return DisplayStyle.NONE;
+ }
+ break;
+ case HtmlSlot.TAG_NAME:
+ if (getPage().getWebClient().getBrowserVersion().hasFeature(SLOT_CONTENTS)) {
+ return DisplayStyle.CONTENTS;
+ }
+ break;
default:
}
return DisplayStyle.INLINE;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnorderedList.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnorderedList.java
index 07694a51e66..1f67a67148f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnorderedList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUnorderedList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUrlInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUrlInput.java
index 9b0a6ed5e16..ea2d8250aea 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUrlInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlUrlInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,6 +47,14 @@ public class HtmlUrlInput extends HtmlInput implements SelectableTextInput {
super(qualifiedName, page, attributes);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
@@ -126,10 +134,7 @@ public String getText() {
* {@inheritDoc}
*/
@Override
- protected void doType(final char c, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final char c, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, c, this, lastType);
}
@@ -137,10 +142,7 @@ protected void doType(final char c, final boolean startAtEnd, final boolean last
* {@inheritDoc}
*/
@Override
- protected void doType(final int keyCode, final boolean startAtEnd, final boolean lastType) {
- if (startAtEnd) {
- selectionDelegate_.setSelectionStart(getValueAttribute().length());
- }
+ protected void doType(final int keyCode, final boolean lastType) {
doTypeProcessor_.doType(getValueAttribute(), selectionDelegate_, keyCode, this, lastType);
}
@@ -154,6 +156,16 @@ protected void typeDone(final String newValue, final boolean notifyAttributeChan
}
}
+ /**
+ * {@inheritDoc}
+ * @see HtmlInput#reset()
+ */
+ @Override
+ public void reset() {
+ super.reset();
+ setSelectionEnd(0);
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlVariable.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlVariable.java
index 26bd90200e9..dea0cfa8a95 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlVariable.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlVariable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlVideo.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlVideo.java
index ef8ee51e547..5e4f95ecb2d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlVideo.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlVideo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlWeekInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlWeekInput.java
index c3d197409fb..feb44dc6659 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlWeekInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlWeekInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,12 +14,15 @@
*/
package com.gargoylesoftware.htmlunit.html;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INPUT_SET_VALUE_DATE_SUPPORTED;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLINPUT_TYPE_DATETIME_SUPPORTED;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLINPUT_TYPE_MONTH_NOT_SUPPORTED;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+
import com.gargoylesoftware.htmlunit.SgmlPage;
/**
@@ -43,15 +46,28 @@ public class HtmlWeekInput extends HtmlInput {
super(qualifiedName, page, attributes);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefaultChecked(final boolean defaultChecked) {
+ // Empty.
+ }
+
/**
* {@inheritDoc}
*/
@Override
public void setValueAttribute(final String newValue) {
+ if (!hasFeature(HTMLINPUT_TYPE_DATETIME_SUPPORTED)
+ || hasFeature(HTMLINPUT_TYPE_MONTH_NOT_SUPPORTED)
+ || StringUtils.isEmpty(newValue)) {
+ super.setValueAttribute(newValue);
+ return;
+ }
+
try {
- if (hasFeature(JS_INPUT_SET_VALUE_DATE_SUPPORTED)) {
- FORMATTER_.parse(newValue);
- }
+ FORMATTER_.parse(newValue);
super.setValueAttribute(newValue);
}
catch (final DateTimeParseException e) {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlWordBreak.java b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlWordBreak.java
index 3956c0a9927..9454c7eceb7 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlWordBreak.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/HtmlWordBreak.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/InputElementFactory.java b/src/main/java/com/gargoylesoftware/htmlunit/html/InputElementFactory.java
deleted file mode 100644
index c0ec946af26..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/InputElementFactory.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.html;
-
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.xml.sax.Attributes;
-
-import com.gargoylesoftware.htmlunit.SgmlPage;
-
-/**
- * A specialized creator that knows how to create input objects.
- *
- * @author Christian Sell
- * @author Marc Guillemot
- * @author Ahmed Ashour
- * @author David K. Taylor
- * @author Dmitri Zoubkov
- * @author Frank Danek
- */
-public final class InputElementFactory implements ElementFactory {
-
- /** Logging support. */
- private static final Log LOG = LogFactory.getLog(InputElementFactory.class);
-
- /** The singleton instance. */
- public static final InputElementFactory instance = new InputElementFactory();
-
- /** Private singleton constructor. */
- private InputElementFactory() {
- // Empty.
- }
-
- /**
- * Creates an HtmlElement for the specified xmlElement, contained in the specified page.
- *
- * @param page the page that this element will belong to
- * @param tagName the HTML tag name
- * @param attributes the SAX attributes
- *
- * @return a new HtmlInput element
- */
- @Override
- public HtmlElement createElement(
- final SgmlPage page, final String tagName,
- final Attributes attributes) {
- return createElementNS(page, null, tagName, attributes);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public HtmlElement createElementNS(final SgmlPage page, final String namespaceURI,
- final String qualifiedName, final Attributes attributes) {
- return createElementNS(page, namespaceURI, qualifiedName, attributes, false);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public HtmlElement createElementNS(final SgmlPage page, final String namespaceURI,
- final String qualifiedName, final Attributes attributes, final boolean asdf) {
-
- Map attributeMap = DefaultElementFactory.toMap(page, attributes);
- if (attributeMap == null) {
- attributeMap = new HashMap<>();
- }
-
- String type = null;
- for (final Map.Entry entry : attributeMap.entrySet()) {
- if ("type".equalsIgnoreCase(entry.getKey())) {
- type = entry.getValue().getValue();
- }
- }
- if (type == null) {
- type = "";
- }
-
- final HtmlInput result;
- switch (type.toLowerCase(Locale.ROOT)) {
- case "":
- // This not an illegal value, as it defaults to "text"
- // cf http://www.w3.org/TR/REC-html40/interact/forms.html#adef-type-INPUT
- // and the common browsers seem to treat it as a "text" input so we will as well.
- case "text":
- result = new HtmlTextInput(qualifiedName, page, attributeMap);
- break;
-
- case "submit":
- result = new HtmlSubmitInput(qualifiedName, page, attributeMap);
- break;
-
- case "checkbox":
- result = new HtmlCheckBoxInput(qualifiedName, page, attributeMap);
- break;
-
- case "radio":
- result = new HtmlRadioButtonInput(qualifiedName, page, attributeMap);
- break;
-
- case "hidden":
- result = new HtmlHiddenInput(qualifiedName, page, attributeMap);
- break;
-
- case "password":
- result = new HtmlPasswordInput(qualifiedName, page, attributeMap);
- break;
-
- case "image":
- result = new HtmlImageInput(qualifiedName, page, attributeMap);
- break;
-
- case "reset":
- result = new HtmlResetInput(qualifiedName, page, attributeMap);
- break;
-
- case "button":
- result = new HtmlButtonInput(qualifiedName, page, attributeMap);
- break;
-
- case "file":
- result = new HtmlFileInput(qualifiedName, page, attributeMap);
- break;
-
- case "color":
- result = new HtmlColorInput(qualifiedName, page, attributeMap);
- break;
-
- case "date":
- result = new HtmlDateInput(qualifiedName, page, attributeMap);
- break;
-
- case "datetime-local":
- result = new HtmlDateTimeLocalInput(qualifiedName, page, attributeMap);
- break;
-
- case "email":
- result = new HtmlEmailInput(qualifiedName, page, attributeMap);
- break;
-
- case "month":
- result = new HtmlMonthInput(qualifiedName, page, attributeMap);
- break;
-
- case "number":
- result = new HtmlNumberInput(qualifiedName, page, attributeMap);
- break;
-
- case "range":
- result = new HtmlRangeInput(qualifiedName, page, attributeMap);
- break;
-
- case "search":
- result = new HtmlSearchInput(qualifiedName, page, attributeMap);
- break;
-
- case "tel":
- result = new HtmlTelInput(qualifiedName, page, attributeMap);
- break;
-
- case "time":
- result = new HtmlTimeInput(qualifiedName, page, attributeMap);
- break;
-
- case "url":
- result = new HtmlUrlInput(qualifiedName, page, attributeMap);
- break;
-
- case "week":
- result = new HtmlWeekInput(qualifiedName, page, attributeMap);
- break;
-
- default:
- LOG.info("Bad input type: \"" + type + "\", creating a text input");
- result = new HtmlTextInput(qualifiedName, page, attributeMap);
- break;
- }
- return result;
- }
-
- /**
- * Returns whether the specified type is supported or not.
- * @param type the type
- * @return whether the specified type is supported or not
- */
- public static boolean isSupported(final String type) {
- boolean supported = false;
- switch (type) {
- case "text":
- case "submit":
- case "checkbox":
- case "radio":
- case "hidden":
- case "password":
- case "image":
- case "reset":
- case "button":
- case "file":
- case "color":
- case "date":
- case "datetime-local":
- case "email":
- case "month":
- case "number":
- case "range":
- case "search":
- case "tel":
- case "time":
- case "url":
- case "week":
- supported = true;
- break;
-
- default:
- }
- return supported;
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/Keyboard.java b/src/main/java/com/gargoylesoftware/htmlunit/html/Keyboard.java
index 436c0f4e088..cced05ea5f3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/Keyboard.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/Keyboard.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/ScriptElement.java b/src/main/java/com/gargoylesoftware/htmlunit/html/ScriptElement.java
index 38858a91a77..de65105fe44 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/ScriptElement.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/ScriptElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
*/
package com.gargoylesoftware.htmlunit.html;
-import java.nio.charset.Charset;
-
/**
* An element which can handle scripts.
*
@@ -54,14 +52,4 @@ public interface ScriptElement {
* or an empty string if that attribute isn't defined.
*/
String getCharsetAttribute();
-
- /**
- * Returns the {@link Charset}.
- *
- * @return the {@link Charset}
- * @deprecated as of 2.27, not used
- */
- @Deprecated
- Charset getCharset();
-
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/ScriptElementSupport.java b/src/main/java/com/gargoylesoftware/htmlunit/html/ScriptElementSupport.java
index 24d55c3c6b8..2e56e74ddde 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/ScriptElementSupport.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/ScriptElementSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,14 +38,18 @@
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument;
import com.gargoylesoftware.htmlunit.protocol.javascript.JavaScriptURLConnection;
import com.gargoylesoftware.htmlunit.util.EncodingSniffer;
+import com.gargoylesoftware.htmlunit.util.MimeType;
import com.gargoylesoftware.htmlunit.xml.XmlPage;
import net.sourceforge.htmlunit.corejs.javascript.BaseFunction;
/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
* A helper class to be used by elements which support {@link ScriptElement}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
public final class ScriptElementSupport {
@@ -145,7 +149,7 @@ public static void executeScriptIfNeeded(final DomElement element) {
charset = page.getCharset();
}
final JavaScriptLoadResult result = page.loadExternalJavaScriptFile(src, charset);
- if (result == JavaScriptLoadResult.SUCCESS) {
+ if (result == JavaScriptLoadResult.SUCCESS || result == JavaScriptLoadResult.NO_CONTENT) {
executeEvent(element, Event.TYPE_LOAD);
}
else if (result == JavaScriptLoadResult.DOWNLOAD_ERROR) {
@@ -185,7 +189,7 @@ private static boolean isExecutionNeeded(final DomElement element) {
// If JavaScript is disabled, we don't need to execute.
final SgmlPage page = element.getPage();
- if (!page.getWebClient().getOptions().isJavaScriptEnabled()) {
+ if (!page.getWebClient().isJavaScriptEnabled()) {
return false;
}
@@ -212,7 +216,7 @@ private static boolean isExecutionNeeded(final DomElement element) {
final String t = element.getAttributeDirect("type");
final String l = element.getAttributeDirect("language");
if (!isJavaScript(element, t, l)) {
- LOG.warn("Script is not JavaScript (type: " + t + ", language: " + l + "). Skipping execution.");
+ LOG.warn("Script is not JavaScript (type: '" + t + "', language: '" + l + "'). Skipping execution.");
return false;
}
@@ -225,7 +229,7 @@ private static boolean isExecutionNeeded(final DomElement element) {
/**
* Returns true if a script with the specified type and language attributes is actually JavaScript.
* According to W3C recommendation
- * are content types case insensitive.
+ * are content types case insensitive.
* IE supports only a limited number of values for the type attribute. For testing you can
* use http://www.robinlionheart.com/stds/html4/scripts.
* @param element the element
@@ -233,7 +237,7 @@ private static boolean isExecutionNeeded(final DomElement element) {
* @param languageAttribute the language attribute specified in the script tag
* @return true if the script is JavaScript
*/
- static boolean isJavaScript(final DomElement element, String typeAttribute, final String languageAttribute) {
+ public static boolean isJavaScript(final DomElement element, String typeAttribute, final String languageAttribute) {
final BrowserVersion browserVersion = element.getPage().getWebClient().getBrowserVersion();
if (browserVersion.hasFeature(HTMLSCRIPT_TRIM_TYPE)) {
@@ -246,7 +250,7 @@ static boolean isJavaScript(final DomElement element, String typeAttribute, fina
return true;
}
- if ("application/javascript".equalsIgnoreCase(typeAttribute)
+ if (MimeType.APPLICATION_JAVASCRIPT.equalsIgnoreCase(typeAttribute)
|| "application/ecmascript".equalsIgnoreCase(typeAttribute)
|| "application/x-javascript".equalsIgnoreCase(typeAttribute)) {
return true;
@@ -289,7 +293,7 @@ private static void executeInlineScriptIfNeeded(final DomElement element) {
final String scriptCode = getScriptCode(element);
if (event != ATTRIBUTE_NOT_DEFINED && forr != ATTRIBUTE_NOT_DEFINED) {
if (element.hasFeature(JS_SCRIPT_SUPPORTS_FOR_AND_EVENT_WINDOW) && "window".equals(forr)) {
- final Window window = (Window) element.getPage().getEnclosingWindow().getScriptableObject();
+ final Window window = element.getPage().getEnclosingWindow().getScriptableObject();
final BaseFunction function = new EventHandler(element, event, scriptCode);
window.getEventListenersContainer().addEventListener(StringUtils.substring(event, 2), function, false);
return;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/SiblingDomNodeList.java b/src/main/java/com/gargoylesoftware/htmlunit/html/SiblingDomNodeList.java
index f139cb61d74..91de0661abf 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/SiblingDomNodeList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/SiblingDomNodeList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/StaticDomNodeList.java b/src/main/java/com/gargoylesoftware/htmlunit/html/StaticDomNodeList.java
index c9aa4b4ac98..6cb6483434e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/StaticDomNodeList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/StaticDomNodeList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/SubmittableElement.java b/src/main/java/com/gargoylesoftware/htmlunit/html/SubmittableElement.java
index 64e20bab598..e208ae99d99 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/SubmittableElement.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/SubmittableElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,6 +56,12 @@ public interface SubmittableElement {
/**
* Sets the default checked state to use when this element gets reset, if applicable.
+ * The default implementation is empty; only checkboxes and radio buttons
+ * really care what the default checked value is.
+ * @see SubmittableElement#setDefaultChecked(boolean)
+ * @see HtmlRadioButtonInput#setDefaultChecked(boolean)
+ * @see HtmlCheckBoxInput#setDefaultChecked(boolean)
+ *
* @param defaultChecked the default checked state to use when this element gets reset, if applicable
*/
void setDefaultChecked(boolean defaultChecked);
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/TableRowGroup.java b/src/main/java/com/gargoylesoftware/htmlunit/html/TableRowGroup.java
index a808368dc8c..676f9011a82 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/TableRowGroup.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/TableRowGroup.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/UnknownElementFactory.java b/src/main/java/com/gargoylesoftware/htmlunit/html/UnknownElementFactory.java
index 502729514b8..1ac90078f9e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/UnknownElementFactory.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/UnknownElementFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/XHtmlPage.java b/src/main/java/com/gargoylesoftware/htmlunit/html/XHtmlPage.java
index eccd779e058..539b71a37d3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/XHtmlPage.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/XHtmlPage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/XmlSerializer.java b/src/main/java/com/gargoylesoftware/htmlunit/html/XmlSerializer.java
index 437d0a1f683..db442bef814 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/XmlSerializer.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/XmlSerializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,11 +17,12 @@
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.net.URL;
import java.nio.charset.Charset;
+import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
@@ -29,6 +30,8 @@
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.SgmlPage;
@@ -46,6 +49,8 @@ class XmlSerializer {
private static final String FILE_SEPARATOR = "/";
private static final Pattern CREATE_FILE_PATTERN = Pattern.compile(".*/");
+ private static final Log LOG = LogFactory.getLog(XmlSerializer.class);
+
private final StringBuilder builder_ = new StringBuilder();
private final StringBuilder indent_ = new StringBuilder();
private File outputDir_;
@@ -61,7 +66,23 @@ public void save(final SgmlPage page, final File file) throws IOException {
}
fileName = fileName.substring(0, fileName.lastIndexOf('.'));
outputDir_ = new File(file.getParentFile(), fileName);
- FileUtils.writeStringToFile(outputFile, asXml(page.getDocumentElement()), ISO_8859_1);
+
+ // don't use asXml here because we have to sync the encoding from the
+ // header with the one used by the writer
+ final DomElement node = page.getDocumentElement();
+ Charset charsetName = ISO_8859_1;
+ builder_.setLength(0);
+ indent_.setLength(0);
+ if (page.isHtmlPage()) {
+ charsetName = page.getCharset();
+ if (charsetName != null && node instanceof HtmlHtml) {
+ builder_.append("").append('\n');
+ }
+ }
+ printXml(node);
+ final String response = builder_.toString();
+ builder_.setLength(0);
+ FileUtils.writeStringToFile(outputFile, response, charsetName);
}
/**
@@ -95,7 +116,7 @@ protected void printXml(final DomElement node) throws IOException {
builder_.append("/>").append('\n');
}
else {
- builder_.append(">").append('\n');
+ builder_.append('>').append('\n');
for (DomNode child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
indent_.append(" ");
if (child instanceof DomElement) {
@@ -153,7 +174,7 @@ protected void printOpeningTag(final DomElement node) throws IOException {
final Map attributes = readAttributes(node);
for (final Map.Entry entry : attributes.entrySet()) {
- builder_.append(" ");
+ builder_.append(' ');
builder_.append(entry.getKey());
builder_.append("=\"");
final String value = entry.getValue().getNodeValue();
@@ -190,8 +211,8 @@ else if (node instanceof BaseFrameElement) {
}
private Map getAttributesFor(final BaseFrameElement frame) throws IOException {
- final Map map = createAttributesCopyWithClonedAttribute(frame, "src");
- final DomAttr srcAttr = map.get("src");
+ final Map map = createAttributesCopyWithClonedAttribute(frame, DomElement.SRC_ATTRIBUTE);
+ final DomAttr srcAttr = map.get(DomElement.SRC_ATTRIBUTE);
if (srcAttr == null) {
return map;
}
@@ -208,7 +229,7 @@ private Map getAttributesFor(final BaseFrameElement frame) thro
}
else {
try (InputStream is = enclosedPage.getWebResponse().getContentAsStream()) {
- try (FileOutputStream fos = new FileOutputStream(file)) {
+ try (OutputStream fos = Files.newOutputStream(file.toPath())) {
IOUtils.copyLarge(is, fos);
}
}
@@ -240,28 +261,50 @@ protected Map getAttributesFor(final HtmlLink link) throws IOEx
if (hrefAttr != null && StringUtils.isNotBlank(hrefAttr.getValue())) {
final String protocol = link.getWebRequest().getUrl().getProtocol();
if ("http".equals(protocol) || "https".equals(protocol)) {
- final File file = createFile(hrefAttr.getValue(), ".css");
- FileUtils.writeStringToFile(file, link.getWebResponse(true, null).getContentAsString(), ISO_8859_1);
- hrefAttr.setValue(outputDir_.getName() + FILE_SEPARATOR + file.getName());
+ try {
+ final WebResponse response = link.getWebResponse(true, null);
+
+ final File file = createFile(hrefAttr.getValue(), ".css");
+ FileUtils.writeStringToFile(file, response.getContentAsString(), ISO_8859_1);
+ hrefAttr.setValue(outputDir_.getName() + FILE_SEPARATOR + file.getName());
+ }
+ catch (final IOException e) {
+ LOG.error("XmlSerializer: IOException while downloading link content from url '"
+ + hrefAttr + "'", e);
+ }
+ catch (final IllegalStateException e) {
+ LOG.error("XmlSerializer: IllegalStateException while downloading link content from url '"
+ + hrefAttr + "'", e);
+ }
}
}
return map;
}
- protected Map getAttributesFor(final HtmlImage image) throws IOException {
- final Map map = createAttributesCopyWithClonedAttribute(image, "src");
- final DomAttr srcAttr = map.get("src");
+ protected Map getAttributesFor(final HtmlImage image) {
+ final Map map = createAttributesCopyWithClonedAttribute(image, DomElement.SRC_ATTRIBUTE);
+ final DomAttr srcAttr = map.get(DomElement.SRC_ATTRIBUTE);
if (srcAttr != null && StringUtils.isNotBlank(srcAttr.getValue())) {
- final WebResponse response = image.getWebResponse(true);
+ try {
+ final WebResponse response = image.getWebResponse(true);
- final File file = createFile(srcAttr.getValue(), "." + getSuffix(response));
- try (InputStream inputStream = response.getContentAsStream()) {
- FileUtils.copyInputStreamToFile(inputStream, file);
- }
+ try (InputStream inputStream = response.getContentAsStream()) {
+ final File file = createFile(srcAttr.getValue(), "." + getSuffix(response));
+ FileUtils.copyInputStreamToFile(inputStream, file);
- final String valueOnFileSystem = outputDir_.getName() + FILE_SEPARATOR + file.getName();
- srcAttr.setValue(valueOnFileSystem); // this is the clone attribute node, not the original one of the page
+ final String valueOnFileSystem = outputDir_.getName() + FILE_SEPARATOR + file.getName();
+ // this is the clone attribute node, not the original one of the page
+ srcAttr.setValue(valueOnFileSystem);
+ }
+ }
+ catch (final IOException e) {
+ LOG.error("XmlSerializer: IOException while downloading image content from url '" + srcAttr + "'", e);
+ }
+ catch (final IllegalStateException e) {
+ LOG.error("XmlSerializer: IllegalStateException while downloading image content from url '"
+ + srcAttr + "'", e);
+ }
}
return map;
@@ -330,7 +373,7 @@ private File createFile(final String url, final String extension) throws IOExcep
else {
fileName = name;
}
- outputDir_.mkdirs();
+ FileUtils.forceMkdir(outputDir_);
final File f = new File(outputDir_, fileName);
if (f.createNewFile()) {
return f;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletClassLoader.java b/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletClassLoader.java
index 6823ffe2516..798efea46ed 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletClassLoader.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletClassLoader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@
public class AppletClassLoader extends URLClassLoader {
private static final Log LOG = LogFactory.getLog(AppletClassLoader.class);
- private final StringBuilder info_ = new StringBuilder();
+ private final StringBuilder info_ = new StringBuilder(40);
/**
* The constructor.
@@ -49,9 +49,11 @@ public AppletClassLoader(final Window window, final ClassLoader parent) {
super(new URL[0], parent);
if (window.getWebWindow().getWebClient().getOptions().isUseInsecureSSL()) {
- LOG.warn("AppletClassLoader: your WebClient accepts ssl connections without certificate checking."
- + " If you like to load applet archives from a SSL/HTTPS connection you have to configure"
- + " your jvm to accept untrusted certificate for SSL/HTTPS connections also.");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("AppletClassLoader: your WebClient accepts ssl connections without certificate checking."
+ + " If you like to load applet archives from a SSL/HTTPS connection you have to configure"
+ + " your jvm to accept untrusted certificate for SSL/HTTPS connections also.");
+ }
}
try {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletContextImpl.java b/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletContextImpl.java
index 31df3142cf8..c61edcd3ca0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletContextImpl.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletContextImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
import java.util.Enumeration;
import java.util.Iterator;
+import com.gargoylesoftware.htmlunit.NotYetImplementedException;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.javascript.host.Window;
@@ -63,7 +64,7 @@ public Enumeration getApplets() {
*/
@Override
public AudioClip getAudioClip(final URL url) {
- throw new RuntimeException("Not yet implemented!");
+ throw new NotYetImplementedException("AppletContextImpl.getAudioClip(URL)");
}
/**
@@ -71,7 +72,7 @@ public AudioClip getAudioClip(final URL url) {
*/
@Override
public Image getImage(final URL url) {
- throw new RuntimeException("Not yet implemented!");
+ throw new NotYetImplementedException("AppletContextImpl.getImage(URL)");
}
/**
@@ -79,7 +80,7 @@ public Image getImage(final URL url) {
*/
@Override
public InputStream getStream(final String key) {
- throw new RuntimeException("Not yet implemented!");
+ throw new NotYetImplementedException("AppletContextImpl.getStream(String)");
}
/**
@@ -87,7 +88,7 @@ public InputStream getStream(final String key) {
*/
@Override
public Iterator getStreamKeys() {
- throw new RuntimeException("Not yet implemented!");
+ throw new NotYetImplementedException("AppletContextImpl.getStreamKeys()");
}
/**
@@ -95,7 +96,7 @@ public Iterator getStreamKeys() {
*/
@Override
public void setStream(final String key, final InputStream stream) throws IOException {
- throw new RuntimeException("Not yet implemented!");
+ throw new NotYetImplementedException("AppletContextImpl.setStream(String, InputStream)");
}
/**
@@ -103,7 +104,7 @@ public void setStream(final String key, final InputStream stream) throws IOExcep
*/
@Override
public void showDocument(final URL url) {
- throw new RuntimeException("Not yet implemented!");
+ throw new NotYetImplementedException("AppletContextImpl.showDocument(URL)");
}
/**
@@ -111,7 +112,7 @@ public void showDocument(final URL url) {
*/
@Override
public void showDocument(final URL url, final String target) {
- throw new RuntimeException("Not yet implemented!");
+ throw new NotYetImplementedException("AppletContextImpl.showDocument(URL, String)");
}
/**
@@ -121,7 +122,7 @@ public void showDocument(final URL url, final String target) {
public void showStatus(final String status) {
// perhaps should we move status handling to WebWindow
// on the other side this allows "orphaned" pages to be usable
- final Window window = (Window) htmlPage_.getEnclosingWindow().getScriptableObject();
+ final Window window = htmlPage_.getEnclosingWindow().getScriptableObject();
window.setStatus(status);
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletStubImpl.java b/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletStubImpl.java
index d5abdf0b28e..96289ee66ec 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletStubImpl.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/applets/AppletStubImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
import java.net.URL;
import java.util.HashMap;
+import com.gargoylesoftware.htmlunit.NotYetImplementedException;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
/**
@@ -94,7 +95,6 @@ public String getParameter(final String name) {
*/
@Override
public boolean isActive() {
- throw new RuntimeException(
- "Not yet implemented! (com.gargoylesoftware.htmlunit.html.applets.AppletStubImpl.isActive())");
+ throw new NotYetImplementedException("AppletStubImpl.isActive()");
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/applets/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/html/applets/package-info.java
index 9fc797a043b..d2d24a02c29 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/applets/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/applets/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectableTextInput.java b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectableTextInput.java
index deabe0082c2..0c308632e6c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectableTextInput.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectableTextInput.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectableTextSelectionDelegate.java b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectableTextSelectionDelegate.java
index 4bd825d4099..6dc2ca732d1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectableTextSelectionDelegate.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectableTextSelectionDelegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectionDelegate.java b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectionDelegate.java
index 371b448722d..3f0b7ccff2f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectionDelegate.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SelectionDelegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SimpleRange.java b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SimpleRange.java
index 5b60cb04f35..7ab7533c422 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SimpleRange.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SimpleRange.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SimpleSelectionDelegate.java b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SimpleSelectionDelegate.java
index 511a0c255a5..0136c53a704 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SimpleSelectionDelegate.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/SimpleSelectionDelegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/package-info.java
index 614c141ba21..f94c31daf30 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/impl/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/impl/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/html/package-info.java
index 807778a4a6e..fed8ee43b94 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/parser/HTMLParser.java b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/HTMLParser.java
new file mode 100644
index 00000000000..a7076f89373
--- /dev/null
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/HTMLParser.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gargoylesoftware.htmlunit.html.parser;
+
+import java.io.IOException;
+
+import org.xml.sax.SAXException;
+
+import com.gargoylesoftware.htmlunit.SgmlPage;
+import com.gargoylesoftware.htmlunit.WebResponse;
+import com.gargoylesoftware.htmlunit.WebWindow;
+import com.gargoylesoftware.htmlunit.html.DomNode;
+import com.gargoylesoftware.htmlunit.html.ElementFactory;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import com.gargoylesoftware.htmlunit.html.XHtmlPage;
+
+/**
+ * Interface for the parser used to parse HTML into a HtmlUnit-specific DOM (HU-DOM) tree.
+ *
+ * @author Christian Sell
+ * @author David K. Taylor
+ * @author Chris Erskine
+ * @author Ahmed Ashour
+ * @author Marc Guillemot
+ * @author Ethan Glasser-Camp
+ * @author Sudhan Moghe
+ * @author Ronald Brill
+ * @author Frank Danek
+ * @author Carsten Steul
+ */
+public interface HTMLParser {
+
+ /**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
+ * @param tagName an HTML element tag name
+ * @return a factory for creating HtmlElements representing the given tag
+ */
+ ElementFactory getFactory(String tagName);
+
+ /**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
+ * @return a factory for creating SvgElements representing the given tag
+ */
+ ElementFactory getSvgFactory();
+
+ /**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
+ * Returns the pre-registered element factory corresponding to the specified tag, or an UnknownElementFactory.
+ * @param page the page
+ * @param namespaceURI the namespace URI
+ * @param qualifiedName the qualified name
+ * @param insideSvg is the node inside an SVG node or not
+ * @param svgSupport true if called from javascript createElementNS
+ * @return the pre-registered element factory corresponding to the specified tag, or an UnknownElementFactory
+ */
+ ElementFactory getElementFactory(SgmlPage page, String namespaceURI,
+ String qualifiedName, boolean insideSvg, boolean svgSupport);
+
+ /**
+ * Parses the HTML content from the given string into an object tree representation.
+ *
+ * @param parent the parent for the new nodes
+ * @param source the (X)HTML to be parsed
+ * @throws SAXException if a SAX error occurs
+ * @throws IOException if an IO error occurs
+ */
+ void parseFragment(DomNode parent, String source) throws SAXException, IOException;
+
+ /**
+ * Parses the HTML content from the given string into an object tree representation.
+ *
+ * @param parent where the new parsed nodes will be added to
+ * @param context the context to build the fragment context stack
+ * @param source the (X)HTML to be parsed
+ * @throws SAXException if a SAX error occurs
+ * @throws IOException if an IO error occurs
+ */
+ void parseFragment(DomNode parent, DomNode context, String source) throws SAXException, IOException;
+
+ /**
+ * Parses the HTML content from the specified WebResponse into an object tree representation.
+ *
+ * @param webResponse the response data
+ * @param webWindow the web window into which the page is to be loaded
+ * @return the page object which is the root of the DOM tree
+ * @throws IOException if there is an IO error
+ */
+ HtmlPage parseHtml(WebResponse webResponse, WebWindow webWindow) throws IOException;
+
+ /**
+ * Parses the XHTML content from the specified WebResponse into an object tree representation.
+ *
+ * @param webResponse the response data
+ * @param webWindow the web window into which the page is to be loaded
+ * @return the page object which is the root of the DOM tree
+ * @throws IOException if there is an IO error
+ */
+ XHtmlPage parseXHtml(WebResponse webResponse, WebWindow webWindow) throws IOException;
+
+}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/parser/HTMLParserDOMBuilder.java b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/HTMLParserDOMBuilder.java
new file mode 100644
index 00000000000..ce4125c3197
--- /dev/null
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/HTMLParserDOMBuilder.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gargoylesoftware.htmlunit.html.parser;
+
+/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
+ * Interface for the parser.
+ *
+ * @author Christian Sell
+ * @author David K. Taylor
+ * @author Chris Erskine
+ * @author Ahmed Ashour
+ * @author Marc Guillemot
+ * @author Ethan Glasser-Camp
+ * @author Sudhan Moghe
+ * @author Ronald Brill
+ * @author Frank Danek
+ * @author Carsten Steul
+ */
+public interface HTMLParserDOMBuilder {
+
+ /**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
+ * Parses and then inserts the specified HTML content into the HTML content currently being parsed.
+ * @param html the HTML content to push
+ */
+ void pushInputString(String html);
+}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/HTMLParserListener.java b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/HTMLParserListener.java
similarity index 87%
rename from src/main/java/com/gargoylesoftware/htmlunit/html/HTMLParserListener.java
rename to src/main/java/com/gargoylesoftware/htmlunit/html/parser/HTMLParserListener.java
index 18bc435b536..3ce14e80d97 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/HTMLParserListener.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/HTMLParserListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.gargoylesoftware.htmlunit.html;
+package com.gargoylesoftware.htmlunit.html.parser;
import java.net.URL;
@@ -70,7 +70,7 @@ void warning(String message, URL url, String html,
*/
class SimpleHTMLParserListener implements HTMLParserListener {
- private static final Log LOG = LogFactory.getLog(HTMLParserListener.class);
+ private static final Log LOG = LogFactory.getLog(SimpleHTMLParserListener.class);
@Override
public void error(final String message, final URL url, final String html,
@@ -87,18 +87,18 @@ public void warning(final String message, final URL url, final String html,
private static String format(final String message, final URL url, final String html,
final int line, final int column) {
final StringBuilder builder = new StringBuilder(message);
- builder.append(" (");
- builder.append(url.toExternalForm());
- builder.append(" ");
- builder.append(line);
- builder.append(":");
- builder.append(column);
+ builder.append(" (")
+ .append(url.toExternalForm())
+ .append(' ')
+ .append(line)
+ .append(':')
+ .append(column);
if (null != html) {
- builder.append(" htmlSnippet: '");
- builder.append(html);
- builder.append("'");
+ builder.append(" htmlSnippet: '")
+ .append(html)
+ .append('\'');
}
- builder.append(")");
+ builder.append(')');
return builder.toString();
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/parser/neko/HtmlUnitNekoDOMBuilder.java b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/neko/HtmlUnitNekoDOMBuilder.java
new file mode 100644
index 00000000000..81c9965f26d
--- /dev/null
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/neko/HtmlUnitNekoDOMBuilder.java
@@ -0,0 +1,774 @@
+/*
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gargoylesoftware.htmlunit.html.parser.neko;
+
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTML_ATTRIBUTE_LOWER_CASE;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTML_COMMAND_TAG;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTML_ISINDEX_TAG;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTML_MAIN_TAG;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.KEYGEN_AS_SELECT;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.META_X_UA_COMPATIBLE;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Triple;
+import org.apache.xerces.parsers.AbstractSAXParser;
+import org.apache.xerces.xni.Augmentations;
+import org.apache.xerces.xni.QName;
+import org.apache.xerces.xni.XMLAttributes;
+import org.apache.xerces.xni.XNIException;
+import org.apache.xerces.xni.parser.XMLInputSource;
+import org.apache.xerces.xni.parser.XMLParserConfiguration;
+import org.w3c.dom.Node;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+import com.gargoylesoftware.htmlunit.BrowserVersion;
+import com.gargoylesoftware.htmlunit.ObjectInstantiationException;
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.WebResponse;
+import com.gargoylesoftware.htmlunit.html.DomComment;
+import com.gargoylesoftware.htmlunit.html.DomDocumentType;
+import com.gargoylesoftware.htmlunit.html.DomElement;
+import com.gargoylesoftware.htmlunit.html.DomNode;
+import com.gargoylesoftware.htmlunit.html.DomText;
+import com.gargoylesoftware.htmlunit.html.ElementFactory;
+import com.gargoylesoftware.htmlunit.html.Html;
+import com.gargoylesoftware.htmlunit.html.HtmlBody;
+import com.gargoylesoftware.htmlunit.html.HtmlElement;
+import com.gargoylesoftware.htmlunit.html.HtmlForm;
+import com.gargoylesoftware.htmlunit.html.HtmlHtml;
+import com.gargoylesoftware.htmlunit.html.HtmlImage;
+import com.gargoylesoftware.htmlunit.html.HtmlMeta;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import com.gargoylesoftware.htmlunit.html.HtmlTable;
+import com.gargoylesoftware.htmlunit.html.HtmlTableRow;
+import com.gargoylesoftware.htmlunit.html.SubmittableElement;
+import com.gargoylesoftware.htmlunit.html.XHtmlPage;
+import com.gargoylesoftware.htmlunit.html.parser.HTMLParser;
+import com.gargoylesoftware.htmlunit.html.parser.HTMLParserDOMBuilder;
+import com.gargoylesoftware.htmlunit.html.parser.HTMLParserListener;
+import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLBodyElement;
+import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument;
+
+import net.sourceforge.htmlunit.cyberneko.HTMLConfiguration;
+import net.sourceforge.htmlunit.cyberneko.HTMLElements;
+import net.sourceforge.htmlunit.cyberneko.HTMLEventInfo;
+import net.sourceforge.htmlunit.cyberneko.HTMLScanner;
+import net.sourceforge.htmlunit.cyberneko.HTMLTagBalancingListener;
+
+/**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
+ * The parser and DOM builder. This class subclasses Xerces's AbstractSAXParser and implements
+ * the ContentHandler interface. Thus all parser APIs are kept private. The ContentHandler methods
+ * consume SAX events to build the page DOM
+ *
+ * @author Christian Sell
+ * @author David K. Taylor
+ * @author Chris Erskine
+ * @author Ahmed Ashour
+ * @author Marc Guillemot
+ * @author Ethan Glasser-Camp
+ * @author Sudhan Moghe
+ * @author Ronald Brill
+ * @author Frank Danek
+ * @author Carsten Steul
+ */
+final class HtmlUnitNekoDOMBuilder extends AbstractSAXParser
+ implements ContentHandler, LexicalHandler, HTMLTagBalancingListener, HTMLParserDOMBuilder {
+
+ // cache Neko Elements for performance and memory
+ private static final Map, HTMLElements> ELEMENTS;
+ static {
+ ELEMENTS = new HashMap<>();
+
+ Triple key;
+ HTMLElements value;
+
+ final HTMLElements.Element command = new HTMLElements.Element(HTMLElements.COMMAND, "COMMAND",
+ HTMLElements.Element.EMPTY, HTMLElements.BODY, null);
+ final HTMLElements.Element isIndex = new HTMLElements.Element(HTMLElements.ISINDEX, "ISINDEX",
+ HTMLElements.Element.INLINE, HTMLElements.BODY, null);
+ final HTMLElements.Element main = new HTMLElements.Element(HTMLElements.MAIN, "MAIN",
+ HTMLElements.Element.INLINE, HTMLElements.BODY, null);
+
+ key = Triple.of(Boolean.FALSE, Boolean.FALSE, Boolean.FALSE);
+ value = new HTMLElements();
+ ELEMENTS.put(key, value);
+
+ key = Triple.of(Boolean.FALSE, Boolean.FALSE, Boolean.TRUE);
+ value = new HTMLElements();
+ value.setElement(main);
+ ELEMENTS.put(key, value);
+
+ key = Triple.of(Boolean.FALSE, Boolean.TRUE, Boolean.FALSE);
+ value = new HTMLElements();
+ value.setElement(isIndex);
+ ELEMENTS.put(key, value);
+
+ key = Triple.of(Boolean.FALSE, Boolean.TRUE, Boolean.TRUE);
+ value = new HTMLElements();
+ value.setElement(isIndex);
+ value.setElement(main);
+ ELEMENTS.put(key, value);
+
+ key = Triple.of(Boolean.TRUE, Boolean.FALSE, Boolean.FALSE);
+ value = new HTMLElements();
+ value.setElement(command);
+ ELEMENTS.put(key, value);
+
+ key = Triple.of(Boolean.TRUE, Boolean.FALSE, Boolean.TRUE);
+ value = new HTMLElements();
+ value.setElement(command);
+ value.setElement(main);
+ ELEMENTS.put(key, value);
+
+ key = Triple.of(Boolean.TRUE, Boolean.TRUE, Boolean.FALSE);
+ value = new HTMLElements();
+ value.setElement(command);
+ value.setElement(isIndex);
+ ELEMENTS.put(key, value);
+
+ key = Triple.of(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE);
+ value = new HTMLElements();
+ value.setElement(command);
+ value.setElement(isIndex);
+ value.setElement(main);
+ ELEMENTS.put(key, value);
+ }
+
+ private enum HeadParsed { YES, SYNTHESIZED, NO }
+
+ private final HTMLParser htmlParser_;
+ private final HtmlPage page_;
+
+ private Locator locator_;
+ private final Deque stack_ = new ArrayDeque<>();
+
+ /** Did the snippet tried to overwrite the start node? */
+ private boolean snippetStartNodeOverwritten_;
+ private final int initialSize_;
+ private DomNode currentNode_;
+ private StringBuilder characters_;
+ private HtmlUnitNekoDOMBuilder.HeadParsed headParsed_ = HeadParsed.NO;
+ private HtmlElement body_;
+ private boolean lastTagWasSynthesized_;
+ private HtmlForm formWaitingForLostChildren_;
+ private boolean insideSvg_;
+
+ private static final String FEATURE_AUGMENTATIONS = "http://cyberneko.org/html/features/augmentations";
+ private static final String FEATURE_PARSE_NOSCRIPT
+ = "http://cyberneko.org/html/features/parse-noscript-content";
+
+ /**
+ * Parses and then inserts the specified HTML content into the HTML content currently being parsed.
+ * @param html the HTML content to push
+ */
+ @Override
+ public void pushInputString(final String html) {
+ page_.registerParsingStart();
+ page_.registerInlineSnippetParsingStart();
+ try {
+ final WebResponse webResponse = page_.getWebResponse();
+ final Charset charset = webResponse.getContentCharset();
+ final String url = webResponse.getWebRequest().getUrl().toString();
+ final XMLInputSource in = new XMLInputSource(null, url, null, new StringReader(html), charset.name());
+ ((HTMLConfiguration) fConfiguration).evaluateInputSource(in);
+ }
+ finally {
+ page_.registerParsingEnd();
+ page_.registerInlineSnippetParsingEnd();
+ }
+ }
+
+ /**
+ * Creates a new builder for parsing the specified response contents.
+ * @param node the location at which to insert the new content
+ * @param url the page's URL
+ */
+ HtmlUnitNekoDOMBuilder(final HTMLParser htmlParser,
+ final DomNode node, final URL url, final String htmlContent) {
+ super(createConfiguration(node.getPage().getWebClient().getBrowserVersion()));
+
+ htmlParser_ = htmlParser;
+ page_ = (HtmlPage) node.getPage();
+
+ currentNode_ = node;
+ for (final Node ancestor : currentNode_.getAncestors()) {
+ stack_.push((DomNode) ancestor);
+ }
+
+ final WebClient webClient = page_.getWebClient();
+ final HTMLParserListener listener = webClient.getHTMLParserListener();
+ final boolean reportErrors = listener != null;
+ if (reportErrors) {
+ fConfiguration.setErrorHandler(new HtmlUnitNekoHTMLErrorHandler(listener, url, htmlContent));
+ }
+
+ try {
+ setFeature(FEATURE_AUGMENTATIONS, true);
+ if (!webClient.getBrowserVersion().hasFeature(HTML_ATTRIBUTE_LOWER_CASE)) {
+ setProperty("http://cyberneko.org/html/properties/names/attrs", "no-change");
+ }
+ setFeature("http://cyberneko.org/html/features/report-errors", reportErrors);
+ setFeature(FEATURE_PARSE_NOSCRIPT, !webClient.isJavaScriptEnabled());
+ setFeature(HTMLScanner.ALLOW_SELFCLOSING_IFRAME, false);
+
+ setContentHandler(this);
+ setLexicalHandler(this); //comments and CDATA
+ }
+ catch (final SAXException e) {
+ throw new ObjectInstantiationException("unable to create HTML parser", e);
+ }
+ initialSize_ = stack_.size();
+ }
+
+ /**
+ * Create the configuration depending on the simulated browser
+ * @param webClient the current WebClient
+ * @return the configuration
+ */
+ private static XMLParserConfiguration createConfiguration(final BrowserVersion browserVersion) {
+ final HTMLElements elements = ELEMENTS.get(
+ Triple.of(browserVersion.hasFeature(HTML_COMMAND_TAG),
+ browserVersion.hasFeature(HTML_ISINDEX_TAG),
+ browserVersion.hasFeature(HTML_MAIN_TAG)));
+ return new HTMLConfiguration(elements);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDocumentLocator(final Locator locator) {
+ locator_ = locator;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void startDocument() throws SAXException {
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void startElement(final QName element, final XMLAttributes attributes, final Augmentations augs)
+ throws XNIException {
+ // augs might change so we store only the interesting part
+ lastTagWasSynthesized_ = isSynthesized(augs);
+ super.startElement(element, attributes, augs);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void startElement(String namespaceURI, final String localName, String qName, final Attributes atts)
+ throws SAXException {
+
+ if (snippetStartNodeOverwritten_) {
+ snippetStartNodeOverwritten_ = false;
+ return;
+ }
+ handleCharacters();
+
+ String tagLower = localName.toLowerCase(Locale.ROOT);
+ if (page_.isParsingHtmlSnippet() && ("html".equals(tagLower) || "body".equals(tagLower))) {
+ return;
+ }
+
+ if ("head".equals(tagLower)) {
+ if (headParsed_ == HeadParsed.YES || page_.isParsingHtmlSnippet()) {
+ return;
+ }
+
+ headParsed_ = lastTagWasSynthesized_ ? HeadParsed.SYNTHESIZED : HeadParsed.YES;
+ }
+
+ if (namespaceURI != null) {
+ namespaceURI = namespaceURI.trim();
+ }
+
+ // add a head if none was there
+ else if (headParsed_ == HeadParsed.NO && ("body".equals(tagLower) || "frameset".equals(tagLower))) {
+ final ElementFactory factory =
+ htmlParser_.getElementFactory(page_, namespaceURI, "head", insideSvg_, false);
+ final DomElement newElement = factory.createElement(page_, "head", null);
+ currentNode_.appendChild(newElement);
+ headParsed_ = HeadParsed.SYNTHESIZED;
+ }
+
+ // If we're adding a body element, keep track of any temporary synthetic ones
+ // that we may have had to create earlier (for document.write(), for example).
+ HtmlBody oldBody = null;
+ if ("body".equals(qName) && page_.getBody() instanceof HtmlBody) {
+ oldBody = (HtmlBody) page_.getBody();
+ }
+
+ // Need to reset this at each starting form tag because it could be set from a synthesized
+ // end tag.
+ if ("form".equals(tagLower)) {
+ formWaitingForLostChildren_ = null;
+ }
+
+ // Add the new node.
+ if (!(page_ instanceof XHtmlPage) && Html.XHTML_NAMESPACE.equals(namespaceURI)) {
+ namespaceURI = null;
+ }
+
+ final boolean keyGenAsSelect = "keygen".equals(tagLower) && page_.hasFeature(KEYGEN_AS_SELECT);
+ if (keyGenAsSelect) {
+ tagLower = "select";
+ qName = "select";
+ }
+
+ final ElementFactory factory =
+ htmlParser_.getElementFactory(page_, namespaceURI, qName, insideSvg_, false);
+ if (factory == HtmlUnitNekoHtmlParser.SVG_FACTORY) {
+ namespaceURI = Html.SVG_NAMESPACE;
+ }
+ final DomElement newElement = factory.createElementNS(page_, namespaceURI, qName, atts, true);
+ newElement.setStartLocation(locator_.getLineNumber(), locator_.getColumnNumber());
+
+ // parse can't replace everything as it does not buffer elements while parsing
+ addNodeToRightParent(currentNode_, newElement);
+
+ if ("svg".equals(tagLower)) {
+ insideSvg_ = true;
+ }
+
+ // If we had an old synthetic body and we just added a real body element, quietly
+ // remove the old body and move its children to the real body element we just added.
+ if (oldBody != null) {
+ oldBody.quietlyRemoveAndMoveChildrenTo(newElement);
+ }
+
+ if ("body".equals(tagLower)) {
+ body_ = (HtmlElement) newElement;
+ }
+ else if ("meta".equals(tagLower) && page_.hasFeature(META_X_UA_COMPATIBLE)) {
+ final HtmlMeta meta = (HtmlMeta) newElement;
+ if ("X-UA-Compatible".equals(meta.getHttpEquivAttribute())) {
+ final String content = meta.getContentAttribute();
+ if (content.startsWith("IE=")) {
+ final String mode = content.substring(3).trim();
+ final int version = page_.getWebClient().getBrowserVersion().getBrowserVersionNumeric();
+ try {
+ int value = Integer.parseInt(mode);
+ if (value > version) {
+ value = version;
+ }
+ ((HTMLDocument) page_.getScriptableObject()).forceDocumentMode(value);
+ }
+ catch (final Exception e) {
+ // ignore
+ }
+ }
+ }
+ }
+ if (keyGenAsSelect) {
+ DomElement option = factory.createElementNS(page_, namespaceURI, "option", null, true);
+ option.appendChild(new DomText(page_, "High Grade"));
+ newElement.appendChild(option);
+
+ option = factory.createElementNS(page_, namespaceURI, "option", null, true);
+ option.appendChild(new DomText(page_, "Medium Grade"));
+ newElement.appendChild(option);
+ }
+ currentNode_ = newElement;
+ stack_.push(currentNode_);
+ }
+
+ /**
+ * Adds the new node to the right parent that is not necessary the currentNode in case of
+ * malformed HTML code. The method tries to emulate the behavior of Firefox.
+ */
+ private void addNodeToRightParent(final DomNode currentNode, final DomElement newElement) {
+ final String currentNodeName = currentNode.getNodeName();
+ final String newNodeName = newElement.getNodeName();
+
+ DomNode parent = currentNode;
+
+ // If the new node is a table element and the current node isn't one search the stack for the
+ // correct parent.
+ if ("tr".equals(newNodeName) && !isTableChild(currentNodeName)) {
+ parent = findElementOnStack("tbody", "thead", "tfoot");
+ }
+ else if (isTableChild(newNodeName) && !"table".equals(currentNodeName)) {
+ parent = findElementOnStack("table");
+ }
+ else if (isTableCell(newNodeName) && !"tr".equals(currentNodeName)) {
+ parent = findElementOnStack("tr");
+ }
+
+ // If the parent changed and the old parent was a form it is now waiting for lost children.
+ if (parent != currentNode && "form".equals(currentNodeName)) {
+ formWaitingForLostChildren_ = (HtmlForm) currentNode;
+ }
+
+ final String parentNodeName = parent.getNodeName();
+
+ if (("table".equals(parentNodeName) && !isTableChild(newNodeName))
+ || (isTableChild(parentNodeName) && !"caption".equals(parentNodeName)
+ && !"colgroup".equals(parentNodeName) && !"tr".equals(newNodeName))
+ || ("colgroup".equals(parentNodeName) && !"col".equals(newNodeName))
+ || ("tr".equals(parentNodeName) && !isTableCell(newNodeName))) {
+ // If its a form or submittable just add it even though the resulting DOM is incorrect.
+ // Otherwise insert the element before the table.
+ if ("form".equals(newNodeName)) {
+ formWaitingForLostChildren_ = (HtmlForm) newElement;
+ parent.appendChild(newElement);
+ }
+ else if (newElement instanceof SubmittableElement) {
+ if (formWaitingForLostChildren_ != null) {
+ formWaitingForLostChildren_.addLostChild((HtmlElement) newElement);
+ }
+ parent.appendChild(newElement);
+ }
+ else {
+ parent = findElementOnStack("table");
+ parent.insertBefore(newElement);
+ }
+ }
+ else if (formWaitingForLostChildren_ != null && "form".equals(parentNodeName)) {
+ // Do not append any children to invalid form. Submittable are inserted after the form,
+ // everything else before the table.
+ if (newElement instanceof SubmittableElement) {
+ formWaitingForLostChildren_.addLostChild((HtmlElement) newElement);
+ parent.getParentNode().appendChild(newElement);
+ }
+ else {
+ parent = findElementOnStack("table");
+ parent.insertBefore(newElement);
+ }
+ }
+ else if (formWaitingForLostChildren_ != null && newElement instanceof SubmittableElement) {
+ formWaitingForLostChildren_.addLostChild((HtmlElement) newElement);
+ parent.appendChild(newElement);
+ }
+ else {
+ parent.appendChild(newElement);
+ }
+ }
+
+ private DomNode findElementOnStack(final String... searchedElementNames) {
+ DomNode searchedNode = null;
+ for (final DomNode node : stack_) {
+ if (ArrayUtils.contains(searchedElementNames, node.getNodeName())) {
+ searchedNode = node;
+ break;
+ }
+ }
+
+ if (searchedNode == null) {
+ searchedNode = stack_.peek(); // this is surely wrong but at least it won't throw a NPE
+ }
+
+ return searchedNode;
+ }
+
+ private static boolean isTableChild(final String nodeName) {
+ return "thead".equals(nodeName) || "tbody".equals(nodeName)
+ || "tfoot".equals(nodeName) || "caption".equals(nodeName)
+ || "colgroup".equals(nodeName);
+ }
+
+ private static boolean isTableCell(final String nodeName) {
+ return "td".equals(nodeName) || "th".equals(nodeName);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void endElement(final QName element, final Augmentations augs)
+ throws XNIException {
+ // augs might change so we store only the interesting part
+ lastTagWasSynthesized_ = isSynthesized(augs);
+ super.endElement(element, augs);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void endElement(final String namespaceURI, final String localName, final String qName)
+ throws SAXException {
+
+ handleCharacters();
+
+ final String tagLower = localName.toLowerCase(Locale.ROOT);
+
+ if (page_.isParsingHtmlSnippet()) {
+ if ("html".equals(tagLower) || "body".equals(tagLower)) {
+ return;
+ }
+ if (stack_.size() == initialSize_) {
+ snippetStartNodeOverwritten_ = true;
+ return;
+ }
+ }
+
+ if ("svg".equals(tagLower)) {
+ insideSvg_ = false;
+ }
+
+ // Need to reset this at each closing form tag because a valid form could start afterwards.
+ if ("form".equals(tagLower)) {
+ formWaitingForLostChildren_ = null;
+ }
+
+ final DomNode previousNode = stack_.pop(); //remove currentElement from stack
+ previousNode.setEndLocation(locator_.getLineNumber(), locator_.getColumnNumber());
+
+ // special handling for form lost children (malformed HTML code where is synthesized)
+ if (previousNode instanceof HtmlForm && lastTagWasSynthesized_) {
+ formWaitingForLostChildren_ = (HtmlForm) previousNode;
+ }
+
+ if (!stack_.isEmpty()) {
+ currentNode_ = stack_.peek();
+ }
+
+ final boolean postponed = page_.isParsingInlineHtmlSnippet();
+ previousNode.onAllChildrenAddedToPage(postponed);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void characters(final char[] ch, final int start, final int length) throws SAXException {
+ if (characters_ == null) {
+ characters_ = new StringBuilder();
+ }
+ characters_.append(ch, start, length);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void ignorableWhitespace(final char[] ch, final int start, final int length) throws SAXException {
+ if (characters_ == null) {
+ characters_ = new StringBuilder();
+ }
+ characters_.append(ch, start, length);
+ }
+
+ /**
+ * Picks up the character data accumulated so far and add it to the current element as a text node.
+ */
+ private void handleCharacters() {
+ if (characters_ != null && characters_.length() != 0) {
+ if (currentNode_ instanceof HtmlHtml) {
+ // In HTML, the node only has two possible children:
+ // the and the ; any text is ignored.
+ characters_.setLength(0);
+ }
+ else {
+ // Use the normal behavior: append a text node for the accumulated text.
+ final String textValue = characters_.toString();
+ final DomText text = new DomText(page_, textValue);
+ characters_.setLength(0);
+
+ if (StringUtils.isNotBlank(textValue)) {
+ // malformed HTML: some text => text comes before the table
+ if (currentNode_ instanceof HtmlTableRow) {
+ final HtmlTableRow row = (HtmlTableRow) currentNode_;
+ final HtmlTable enclosingTable = row.getEnclosingTable();
+ if (enclosingTable != null) { // may be null when called from Range.createContextualFragment
+ if (enclosingTable.getPreviousSibling() instanceof DomText) {
+ final DomText domText = (DomText) enclosingTable.getPreviousSibling();
+ domText.setTextContent(domText + textValue);
+ }
+ else {
+ enclosingTable.insertBefore(text);
+ }
+ }
+ }
+ else if (currentNode_ instanceof HtmlTable) {
+ final HtmlTable enclosingTable = (HtmlTable) currentNode_;
+ if (enclosingTable.getPreviousSibling() instanceof DomText) {
+ final DomText domText = (DomText) enclosingTable.getPreviousSibling();
+ domText.setTextContent(domText + textValue);
+ }
+ else {
+ enclosingTable.insertBefore(text);
+ }
+ }
+ else if (currentNode_ instanceof HtmlImage) {
+ currentNode_.setNextSibling(text);
+ }
+ else {
+ currentNode_.appendChild(text);
+ }
+ }
+ else {
+ currentNode_.appendChild(text);
+ }
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void endDocument() throws SAXException {
+ handleCharacters();
+ final DomNode currentPage = page_;
+ currentPage.setEndLocation(locator_.getLineNumber(), locator_.getColumnNumber());
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void startPrefixMapping(final String prefix, final String uri) throws SAXException {
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void endPrefixMapping(final String prefix) throws SAXException {
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void processingInstruction(final String target, final String data) throws SAXException {
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void skippedEntity(final String name) throws SAXException {
+ }
+
+ // LexicalHandler methods
+
+ /** {@inheritDoc} */
+ @Override
+ public void comment(final char[] ch, final int start, final int length) {
+ handleCharacters();
+ final String data = new String(ch, start, length);
+ final DomComment comment = new DomComment(page_, data);
+ currentNode_.appendChild(comment);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void endCDATA() {
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void endDTD() {
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void endEntity(final String name) {
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void startCDATA() {
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void startDTD(final String name, final String publicId, final String systemId) {
+ final DomDocumentType type = new DomDocumentType(page_, name, publicId, systemId);
+ page_.setDocumentType(type);
+
+ final Node child;
+ child = type;
+ page_.appendChild(child);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void startEntity(final String name) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void ignoredEndElement(final QName element, final Augmentations augs) {
+ // if real is reached, don't accept fields anymore as lost children
+ if ("form".equals(element.localpart)) {
+ formWaitingForLostChildren_ = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void ignoredStartElement(final QName elem, final XMLAttributes attrs, final Augmentations augs) {
+ // when multiple body elements are encountered, the attributes of the discarded
+ // elements are used when not previously defined
+ if (body_ != null && "body".equalsIgnoreCase(elem.localpart) && attrs != null) {
+ copyAttributes(body_, attrs);
+ }
+ if (body_ != null && "html".equalsIgnoreCase(elem.localpart) && attrs != null) {
+ copyAttributes((DomElement) body_.getParentNode(), attrs);
+ }
+ }
+
+ private static void copyAttributes(final DomElement to, final XMLAttributes attrs) {
+ final int length = attrs.getLength();
+ for (int i = 0; i < length; i++) {
+ final String attrName = attrs.getLocalName(i).toLowerCase(Locale.ROOT);
+ if (to.getAttributes().getNamedItem(attrName) == null) {
+ to.setAttribute(attrName, attrs.getValue(i));
+ if (attrName.startsWith("on") && to.getScriptableObject() instanceof HTMLBodyElement) {
+ final HTMLBodyElement jsBody = to.getScriptableObject();
+ jsBody.createEventHandlerFromAttribute(attrName, attrs.getValue(i));
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void parse(final XMLInputSource inputSource) throws XNIException, IOException {
+ final HTMLParserDOMBuilder oldBuilder = page_.getDOMBuilder();
+ page_.setDOMBuilder(this);
+ try {
+ super.parse(inputSource);
+ }
+ finally {
+ page_.setDOMBuilder(oldBuilder);
+ }
+ }
+
+ HtmlElement getBody() {
+ return body_;
+ }
+
+ private static boolean isSynthesized(final Augmentations augs) {
+ final HTMLEventInfo info = (augs == null) ? null
+ : (HTMLEventInfo) augs.getItem(FEATURE_AUGMENTATIONS);
+ return info != null && info.isSynthesized();
+ }
+}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/parser/neko/HtmlUnitNekoHtmlParser.java b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/neko/HtmlUnitNekoHtmlParser.java
new file mode 100644
index 00000000000..2798e118831
--- /dev/null
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/neko/HtmlUnitNekoHtmlParser.java
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gargoylesoftware.htmlunit.html.parser.neko;
+
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.PAGE_WAIT_LOAD_BEFORE_BODY;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.xerces.util.DefaultErrorHandler;
+import org.apache.xerces.xni.QName;
+import org.apache.xerces.xni.XNIException;
+import org.apache.xerces.xni.parser.XMLErrorHandler;
+import org.apache.xerces.xni.parser.XMLInputSource;
+import org.apache.xerces.xni.parser.XMLParseException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import com.gargoylesoftware.htmlunit.ObjectInstantiationException;
+import com.gargoylesoftware.htmlunit.Page;
+import com.gargoylesoftware.htmlunit.SgmlPage;
+import com.gargoylesoftware.htmlunit.WebAssert;
+import com.gargoylesoftware.htmlunit.WebResponse;
+import com.gargoylesoftware.htmlunit.WebWindow;
+import com.gargoylesoftware.htmlunit.html.DefaultElementFactory;
+import com.gargoylesoftware.htmlunit.html.DomElement;
+import com.gargoylesoftware.htmlunit.html.DomNode;
+import com.gargoylesoftware.htmlunit.html.ElementFactory;
+import com.gargoylesoftware.htmlunit.html.FrameWindow;
+import com.gargoylesoftware.htmlunit.html.Html;
+import com.gargoylesoftware.htmlunit.html.HtmlBody;
+import com.gargoylesoftware.htmlunit.html.HtmlFrameSet;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import com.gargoylesoftware.htmlunit.html.UnknownElementFactory;
+import com.gargoylesoftware.htmlunit.html.XHtmlPage;
+import com.gargoylesoftware.htmlunit.html.parser.HTMLParser;
+import com.gargoylesoftware.htmlunit.html.parser.HTMLParserListener;
+import com.gargoylesoftware.htmlunit.svg.SvgElementFactory;
+
+import net.sourceforge.htmlunit.cyberneko.HTMLScanner;
+import net.sourceforge.htmlunit.cyberneko.HTMLTagBalancer;
+
+/**
+ * SAX parser implementation that uses the NekoHTML {@link net.sourceforge.htmlunit.cyberneko.HTMLConfiguration}
+ * to parse HTML into a HtmlUnit-specific DOM (HU-DOM) tree.
+ *
+ * @author Christian Sell
+ * @author David K. Taylor
+ * @author Chris Erskine
+ * @author Ahmed Ashour
+ * @author Marc Guillemot
+ * @author Ethan Glasser-Camp
+ * @author Sudhan Moghe
+ * @author Ronald Brill
+ * @author Frank Danek
+ * @author Carsten Steul
+ */
+public final class HtmlUnitNekoHtmlParser implements HTMLParser {
+
+ /**
+ * The SVG factory.
+ */
+ public static final SvgElementFactory SVG_FACTORY = new SvgElementFactory();
+
+ private static final Map ELEMENT_FACTORIES = new HashMap<>();
+
+ static {
+ final DefaultElementFactory defaultElementFactory = new DefaultElementFactory();
+ for (final String tagName : DefaultElementFactory.SUPPORTED_TAGS_) {
+ ELEMENT_FACTORIES.put(tagName, defaultElementFactory);
+ }
+ }
+
+ /**
+ * Ctor.
+ */
+ public HtmlUnitNekoHtmlParser() {
+ // Empty.
+ }
+
+ /**
+ * Parses the HTML content from the given string into an object tree representation.
+ *
+ * @param parent the parent for the new nodes
+ * @param source the (X)HTML to be parsed
+ * @throws SAXException if a SAX error occurs
+ * @throws IOException if an IO error occurs
+ */
+ @Override
+ public void parseFragment(final DomNode parent, final String source) throws SAXException, IOException {
+ parseFragment(parent, parent, source);
+ }
+
+ /**
+ * Parses the HTML content from the given string into an object tree representation.
+ *
+ * @param parent where the new parsed nodes will be added to
+ * @param context the context to build the fragment context stack
+ * @param source the (X)HTML to be parsed
+ * @throws SAXException if a SAX error occurs
+ * @throws IOException if an IO error occurs
+ */
+ @Override
+ public void parseFragment(final DomNode parent, final DomNode context, final String source)
+ throws SAXException, IOException {
+ final Page page = parent.getPage();
+ if (!(page instanceof HtmlPage)) {
+ return;
+ }
+ final HtmlPage htmlPage = (HtmlPage) page;
+ final URL url = htmlPage.getUrl();
+
+ final HtmlUnitNekoDOMBuilder domBuilder = new HtmlUnitNekoDOMBuilder(this, parent, url, source);
+ domBuilder.setFeature("http://cyberneko.org/html/features/balance-tags/document-fragment", true);
+ // build fragment context stack
+ DomNode node = context;
+ final List ancestors = new ArrayList<>();
+ while (node != null && node.getNodeType() != Node.DOCUMENT_NODE) {
+ ancestors.add(0, new QName(null, node.getNodeName(), null, null));
+ node = node.getParentNode();
+ }
+ if (ancestors.isEmpty() || !"html".equals(ancestors.get(0).localpart)) {
+ ancestors.add(0, new QName(null, "html", null, null));
+ }
+ if (ancestors.size() == 1 || !"body".equals(ancestors.get(1).localpart)) {
+ ancestors.add(1, new QName(null, "body", null, null));
+ }
+
+ domBuilder.setFeature(HTMLScanner.ALLOW_SELFCLOSING_TAGS, true);
+ domBuilder.setProperty(HTMLTagBalancer.FRAGMENT_CONTEXT_STACK, ancestors.toArray(new QName[] {}));
+
+ final XMLInputSource in = new XMLInputSource(null, url.toString(), null, new StringReader(source), null);
+
+ htmlPage.registerParsingStart();
+ htmlPage.registerSnippetParsingStart();
+ try {
+ domBuilder.parse(in);
+ }
+ finally {
+ htmlPage.registerParsingEnd();
+ htmlPage.registerSnippetParsingEnd();
+ }
+ }
+
+ /**
+ * Parses the HTML content from the specified WebResponse into an object tree representation.
+ *
+ * @param webResponse the response data
+ * @param webWindow the web window into which the page is to be loaded
+ * @return the page object which is the root of the DOM tree
+ * @throws IOException if there is an IO error
+ */
+ @Override
+ public HtmlPage parseHtml(final WebResponse webResponse, final WebWindow webWindow) throws IOException {
+ final HtmlPage page = new HtmlPage(webResponse, webWindow);
+ parse(webResponse, webWindow, page, false);
+ return page;
+ }
+
+ /**
+ * Parses the XHTML content from the specified WebResponse into an object tree representation.
+ *
+ * @param webResponse the response data
+ * @param webWindow the web window into which the page is to be loaded
+ * @return the page object which is the root of the DOM tree
+ * @throws IOException if there is an IO error
+ */
+ @Override
+ public XHtmlPage parseXHtml(final WebResponse webResponse, final WebWindow webWindow) throws IOException {
+ final XHtmlPage page = new XHtmlPage(webResponse, webWindow);
+ parse(webResponse, webWindow, page, true);
+ return page;
+ }
+
+ private void parse(final WebResponse webResponse, final WebWindow webWindow, final HtmlPage page,
+ final boolean xhtml)
+ throws IOException {
+
+ webWindow.setEnclosedPage(page);
+
+ final URL url = webResponse.getWebRequest().getUrl();
+ final HtmlUnitNekoDOMBuilder domBuilder = new HtmlUnitNekoDOMBuilder(this, page, url, null);
+
+ Charset charset = webResponse.getContentCharsetOrNull();
+ try {
+ if (charset == null) {
+ charset = StandardCharsets.ISO_8859_1;
+ }
+ else {
+ domBuilder.setFeature(HTMLScanner.IGNORE_SPECIFIED_CHARSET, true);
+ }
+
+ // xml content is different
+ if (xhtml) {
+ domBuilder.setFeature(HTMLScanner.ALLOW_SELFCLOSING_TAGS, true);
+ domBuilder.setFeature(HTMLScanner.SCRIPT_STRIP_CDATA_DELIMS, true);
+ domBuilder.setFeature(HTMLScanner.STYLE_STRIP_CDATA_DELIMS, true);
+ }
+ }
+ catch (final Exception e) {
+ throw new ObjectInstantiationException("Error setting HTML parser feature", e);
+ }
+
+ try (InputStream content = webResponse.getContentAsStream()) {
+ String encoding = null;
+ if (charset != null) {
+ encoding = charset.name();
+ }
+ final XMLInputSource in = new XMLInputSource(null, url.toString(), null, content, encoding);
+
+ page.registerParsingStart();
+ try {
+ domBuilder.parse(in);
+ }
+ catch (final XNIException e) {
+ // extract enclosed exception
+ final Throwable origin = extractNestedException(e);
+ throw new RuntimeException("Failed parsing content from " + url, origin);
+ }
+ }
+ finally {
+ page.registerParsingEnd();
+ }
+
+ addBodyToPageIfNecessary(page, true, domBuilder.getBody() != null);
+ }
+
+ /**
+ * Adds a body element to the current page, if necessary. Strictly speaking, this should
+ * probably be done by NekoHTML. See the bug linked below. If and when that bug is fixed,
+ * we may be able to get rid of this code.
+ *
+ * http://sourceforge.net/p/nekohtml/bugs/15/
+ * @param page
+ * @param originalCall
+ * @param checkInsideFrameOnly true if the original page had body that was removed by JavaScript
+ */
+ private void addBodyToPageIfNecessary(
+ final HtmlPage page, final boolean originalCall, final boolean checkInsideFrameOnly) {
+ // IE waits for the whole page to load before initializing bodies for frames.
+ final boolean waitToLoad = page.hasFeature(PAGE_WAIT_LOAD_BEFORE_BODY);
+ if (page.getEnclosingWindow() instanceof FrameWindow && originalCall && waitToLoad) {
+ return;
+ }
+
+ // Find out if the document already has a body element (or frameset).
+ final Element doc = page.getDocumentElement();
+ boolean hasBody = false;
+ for (Node child = doc.getFirstChild(); child != null; child = child.getNextSibling()) {
+ if (child instanceof HtmlBody || child instanceof HtmlFrameSet) {
+ hasBody = true;
+ break;
+ }
+ }
+
+ // If the document does not have a body, add it.
+ if (!hasBody && !checkInsideFrameOnly) {
+ final DomElement body = getFactory("body").createElement(page, "body", null);
+ doc.appendChild(body);
+ }
+
+ // If this is IE, we need to initialize the bodies of any frames, as well.
+ // This will already have been done when emulating FF (see above).
+ if (waitToLoad) {
+ for (final FrameWindow frame : page.getFrames()) {
+ final Page containedPage = frame.getEnclosedPage();
+ if (containedPage != null && containedPage.isHtmlPage()) {
+ addBodyToPageIfNecessary((HtmlPage) containedPage, false, false);
+ }
+ }
+ }
+ }
+
+ /**
+ * Extract nested exception within an XNIException (Nekohtml uses reflection and generated
+ * exceptions are wrapped many times within XNIException and InvocationTargetException)
+ *
+ * @param e the original XNIException
+ * @return the cause exception
+ */
+ static Throwable extractNestedException(final Throwable e) {
+ Throwable originalException = e;
+ Throwable cause = ((XNIException) e).getException();
+ while (cause != null) {
+ originalException = cause;
+ if (cause instanceof XNIException) {
+ cause = ((XNIException) cause).getException();
+ }
+ else if (cause instanceof InvocationTargetException) {
+ cause = cause.getCause();
+ }
+ else {
+ cause = null;
+ }
+ }
+ return originalException;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ElementFactory getSvgFactory() {
+ return SVG_FACTORY;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ElementFactory getFactory(final String tagName) {
+ final ElementFactory result = ELEMENT_FACTORIES.get(tagName);
+
+ if (result != null) {
+ return result;
+ }
+ return UnknownElementFactory.instance;
+ }
+
+ /**
+ * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
+ *
+ * Returns the pre-registered element factory corresponding to the specified tag, or an UnknownElementFactory.
+ * @param page the page
+ * @param namespaceURI the namespace URI
+ * @param qualifiedName the qualified name
+ * @param insideSvg is the node inside an SVG node or not
+ * @param svgSupport true if called from javascript createElementNS
+ * @return the pre-registered element factory corresponding to the specified tag, or an UnknownElementFactory
+ */
+ @Override
+ public ElementFactory getElementFactory(final SgmlPage page, final String namespaceURI,
+ final String qualifiedName, final boolean insideSvg, final boolean svgSupport) {
+ if (insideSvg) {
+ return SVG_FACTORY;
+ }
+
+ if (namespaceURI == null || namespaceURI.isEmpty()
+ || Html.XHTML_NAMESPACE.equals(namespaceURI)
+ || Html.SVG_NAMESPACE.equals(namespaceURI)
+ || !qualifiedName.contains(":")) {
+
+ String tagName = qualifiedName;
+ final int index = tagName.indexOf(':');
+ if (index == -1) {
+ tagName = tagName.toLowerCase(Locale.ROOT);
+ }
+ else {
+ tagName = tagName.substring(index + 1);
+ }
+ final ElementFactory factory;
+ if (svgSupport && !"svg".equals(tagName) && Html.SVG_NAMESPACE.equals(namespaceURI)) {
+ factory = SVG_FACTORY;
+ }
+ else {
+ factory = ELEMENT_FACTORIES.get(tagName);
+ }
+
+ if (factory != null) {
+ return factory;
+ }
+ }
+ return UnknownElementFactory.instance;
+ }
+}
+
+/**
+ * Utility to transmit parsing errors to a {@link HTMLParserListener}.
+ */
+class HtmlUnitNekoHTMLErrorHandler implements XMLErrorHandler {
+ private final HTMLParserListener listener_;
+ private final URL url_;
+ private String html_;
+
+ HtmlUnitNekoHTMLErrorHandler(final HTMLParserListener listener, final URL url, final String htmlContent) {
+ WebAssert.notNull("listener", listener);
+ WebAssert.notNull("url", url);
+ listener_ = listener;
+ url_ = url;
+ html_ = htmlContent;
+ }
+
+ /** @see DefaultErrorHandler#error(String,String,XMLParseException) */
+ @Override
+ public void error(final String domain, final String key,
+ final XMLParseException exception) throws XNIException {
+ listener_.error(exception.getMessage(),
+ url_,
+ html_,
+ exception.getLineNumber(),
+ exception.getColumnNumber(),
+ key);
+ }
+
+ /** @see DefaultErrorHandler#warning(String,String,XMLParseException) */
+ @Override
+ public void warning(final String domain, final String key,
+ final XMLParseException exception) throws XNIException {
+ listener_.warning(exception.getMessage(),
+ url_,
+ html_,
+ exception.getLineNumber(),
+ exception.getColumnNumber(),
+ key);
+ }
+
+ @Override
+ public void fatalError(final String domain, final String key,
+ final XMLParseException exception) throws XNIException {
+ listener_.error(exception.getMessage(),
+ url_,
+ html_,
+ exception.getLineNumber(),
+ exception.getColumnNumber(),
+ key);
+ }
+}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/budget/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/neko/package-info.java
similarity index 70%
rename from src/main/java/com/gargoylesoftware/htmlunit/javascript/host/budget/package-info.java
rename to src/main/java/com/gargoylesoftware/htmlunit/html/parser/neko/package-info.java
index a2691115914..87470c3c8a8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/budget/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/neko/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
*/
/**
- * Implementations of the Budget JavaScript host objects - users of HtmlUnit shouldn't
- * need anything in this package.
+ * Contains the neko html parser.
*/
-package com.gargoylesoftware.htmlunit.javascript.host.budget;
+package com.gargoylesoftware.htmlunit.html.parser.neko;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/CanSetReadOnlyStatus.java b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/package-info.java
similarity index 60%
rename from src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/CanSetReadOnlyStatus.java
rename to src/main/java/com/gargoylesoftware/htmlunit/html/parser/package-info.java
index 81660d6c72e..668ffb583b2 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/CanSetReadOnlyStatus.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/parser/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -12,20 +12,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.gargoylesoftware.htmlunit.javascript.configuration;
/**
- * Status for {@link CanSetReadOnly}.
- *
- * @author Ahmed Ashour
+ * Contains the html parser interface.
*/
-public enum CanSetReadOnlyStatus {
- /** Allow to set the value. */
- YES,
-
- /** Ignore setting the value. */
- IGNORE,
-
- /** Throw a runtime exception. */
- EXCEPTION
-}
+package com.gargoylesoftware.htmlunit.html.parser;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/HtmlUnitPrefixResolver.java b/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/HtmlUnitPrefixResolver.java
index feccb2a0b32..5e5148f8df9 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/HtmlUnitPrefixResolver.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/HtmlUnitPrefixResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/LowerCaseFunction.java b/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/LowerCaseFunction.java
index c40ae58b636..78920809aa1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/LowerCaseFunction.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/LowerCaseFunction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/XPathAdapter.java b/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/XPathAdapter.java
index ac2f79b0cca..72ed3fc0353 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/XPathAdapter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/XPathAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -64,25 +64,23 @@ private void initFunctionTable() {
* @param attributeCaseSensitive whether or not the attributes should be case-sensitive
* @throws TransformerException if a syntax or other error occurs
*/
- XPathAdapter(String exprString, final SourceLocator locator, final PrefixResolver prefixResolver,
- ErrorListener errorListener, final boolean caseSensitive, final boolean attributeCaseSensitive)
+ XPathAdapter(final String exprString, final SourceLocator locator, final PrefixResolver prefixResolver,
+ final ErrorListener errorListener, final boolean caseSensitive, final boolean attributeCaseSensitive)
throws TransformerException {
initFunctionTable();
- if (errorListener == null) {
- errorListener = new DefaultErrorHandler();
+ ErrorListener errListener = errorListener;
+ if (errListener == null) {
+ errListener = new DefaultErrorHandler();
}
-
- exprString = preProcessXPath(exprString, caseSensitive, attributeCaseSensitive);
-
- final XPathParser parser = new XPathParser(errorListener, locator);
+ final XPathParser parser = new XPathParser(errListener, locator);
final Compiler compiler = new Compiler(errorListener, locator, funcTable_);
- parser.initXPath(compiler, exprString, prefixResolver);
+ final String expression = preProcessXPath(exprString, caseSensitive, attributeCaseSensitive);
+ parser.initXPath(compiler, expression, prefixResolver);
final Expression expr = compiler.compile(0);
-
mainExp_ = expr;
if (locator instanceof ExpressionNode) {
@@ -99,34 +97,39 @@ private void initFunctionTable() {
* @param attributeCaseSensitive whether or not the attributes should be case-sensitive
* @return the processed XPath expression
*/
- private static String preProcessXPath(String xpath, final boolean caseSensitive,
+ private static String preProcessXPath(final String xpath, final boolean caseSensitive,
final boolean attributeCaseSensitive) {
+
+ String path;
if (!caseSensitive) {
- final char[] charArray = xpath.toCharArray();
- processOutsideBrackets(charArray);
- xpath = new String(charArray);
+ path = processOutsideBrackets(xpath);
+ }
+ else {
+ path = xpath;
}
if (!attributeCaseSensitive) {
- final Matcher matcher = PREPROCESS_XPATH_PATTERN.matcher(xpath);
+ final Matcher matcher = PREPROCESS_XPATH_PATTERN.matcher(path);
while (matcher.find()) {
final String attribute = matcher.group(1);
- xpath = xpath.replace(attribute, attribute.toLowerCase(Locale.ROOT));
+ path = path.replace(attribute, attribute.toLowerCase(Locale.ROOT));
}
}
- return xpath;
+ return path;
}
/**
* Lower case any character outside the brackets.
- * @param array the array to change
+ * @param xpath the XPath expression to change
*/
- private static void processOutsideBrackets(final char[] array) {
- final int length = array.length;
+ private static String processOutsideBrackets(final String xpath) {
+ final char[] charArray = xpath.toCharArray();
+
+ final int length = charArray.length;
int insideBrackets = 0;
for (int i = 0; i < length; i++) {
- final char ch = array[i];
+ final char ch = charArray[i];
switch (ch) {
case '[':
case '(':
@@ -140,10 +143,11 @@ private static void processOutsideBrackets(final char[] array) {
default:
if (insideBrackets == 0) {
- array[i] = Character.toLowerCase(ch);
+ charArray[i] = Character.toLowerCase(ch);
}
}
}
+ return new String(charArray);
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/XPathUtils.java b/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/XPathHelper.java
similarity index 86%
rename from src/main/java/com/gargoylesoftware/htmlunit/html/xpath/XPathUtils.java
rename to src/main/java/com/gargoylesoftware/htmlunit/html/xpath/XPathHelper.java
index 75d4a957882..43d072b22c4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/XPathUtils.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/XPathHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
*/
package com.gargoylesoftware.htmlunit.html.xpath;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.XPATH_ATTRIBUTE_CASE_SENSITIVE;
-
import java.util.ArrayList;
import java.util.List;
@@ -40,14 +38,14 @@
* @author Ahmed Ashour
* @author Chuck Dumont
*/
-public final class XPathUtils {
+public final class XPathHelper {
private static ThreadLocal PROCESS_XPATH_ = ThreadLocal.withInitial(() -> Boolean.FALSE);
/**
* Private to avoid instantiation.
*/
- private XPathUtils() {
+ private XPathHelper() {
// Empty.
}
@@ -58,18 +56,20 @@ private XPathUtils() {
* @param node the node to start searching from
* @param xpathExpr the XPath expression
* @param resolver the prefix resolver to use for resolving namespace prefixes, or null
+ * @param caseSensitiveXpathAttributes true if the browser handles xpath attribute names case sensitive
* @return the list of objects found
*/
@SuppressWarnings("unchecked")
- public static List getByXPath(final DomNode node, final String xpathExpr, final PrefixResolver resolver) {
+ public static List getByXPath(final DomNode node, final String xpathExpr,
+ final PrefixResolver resolver, final boolean caseSensitiveXpathAttributes) {
if (xpathExpr == null) {
- throw new NullPointerException("Null is not a valid XPath expression");
+ throw new IllegalArgumentException("Null is not a valid XPath expression");
}
PROCESS_XPATH_.set(Boolean.TRUE);
final List list = new ArrayList<>();
try {
- final XObject result = evaluateXPath(node, xpathExpr, resolver);
+ final XObject result = evaluateXPath(node, xpathExpr, resolver, caseSensitiveXpathAttributes);
if (result instanceof XNodeSet) {
final NodeList nodelist = ((XNodeSet) result).nodelist();
@@ -112,11 +112,13 @@ public static boolean isProcessingXPath() {
* @param contextNode the node to start searching from
* @param str a valid XPath string
* @param a prefix resolver to use for resolving namespace prefixes, or null
+ * @param caseSensitiveXpathAttributes true if the browser handles xpath attribute names case sensitive
* @return an XObject, which can be used to obtain a string, number, nodelist, etc (should never be {@code null})
* @throws TransformerException if a syntax or other error occurs
*/
private static XObject evaluateXPath(final DomNode contextNode,
- final String str, final PrefixResolver prefixResolver) throws TransformerException {
+ final String str, final PrefixResolver prefixResolver,
+ final boolean caseSensitiveXpathAttributes) throws TransformerException {
final XPathContext xpathSupport = new XPathContext();
final Node xpathExpressionContext;
if (contextNode.getNodeType() == Node.DOCUMENT_NODE) {
@@ -132,9 +134,8 @@ private static XObject evaluateXPath(final DomNode contextNode,
}
final boolean caseSensitive = contextNode.getPage().hasCaseSensitiveTagNames();
- final boolean attributeCaseSensitive = caseSensitive
- || contextNode.getPage().getWebClient()
- .getBrowserVersion().hasFeature(XPATH_ATTRIBUTE_CASE_SENSITIVE);
+ final boolean attributeCaseSensitive = caseSensitive || caseSensitiveXpathAttributes;
+
final XPathAdapter xpath = new XPathAdapter(str, null, resolver, null, caseSensitive, attributeCaseSensitive);
final int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode);
return xpath.execute(xpathSupport, ctxtNode, prefixResolver);
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/package-info.java
index eb35fe983a5..0831b7702d5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/html/xpath/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,6 @@
*/
/**
- * XPath adapter implementation for the Htmlunit DOM.
+ * XPath adapter implementation for the HtmlUnit DOM.
*/
package com.gargoylesoftware.htmlunit.html.xpath;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitBrowserCompatCookieHeaderValueFormatter.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitBrowserCompatCookieHeaderValueFormatter.java
index 198a8a358a6..118d4b3ef38 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitBrowserCompatCookieHeaderValueFormatter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitBrowserCompatCookieHeaderValueFormatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitBrowserCompatCookieSpec.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitBrowserCompatCookieSpec.java
index cbef22f826f..32fd78ab27a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitBrowserCompatCookieSpec.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitBrowserCompatCookieSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitCookieSpecProvider.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitCookieSpecProvider.java
index 25d79d8e6d2..87382199f80 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitCookieSpecProvider.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitCookieSpecProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitCookieStore.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitCookieStore.java
index ebb0d26568a..7ac934712bf 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitCookieStore.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitCookieStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitDomainHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitDomainHandler.java
index 9b8436c61dc..4edf271018a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitDomainHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitDomainHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitExpiresHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitExpiresHandler.java
index c8173b230b0..fdcb2436e0b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitExpiresHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitExpiresHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,16 +46,18 @@ final class HtmlUnitExpiresHandler extends BasicExpiresHandler {
// simplified patterns from BrowserCompatSpec, with yy patterns before similar yyyy patterns
private static final String[] DEFAULT_DATE_PATTERNS = new String[] {
+ "EEE MMM dd yyyy HH mm ss 'GMT'Z",
"EEE dd MMM yy HH mm ss zzz",
"EEE dd MMM yyyy HH mm ss zzz",
"EEE MMM d HH mm ss yyyy",
"EEE dd MMM yy HH mm ss z ",
"EEE dd MMM yyyy HH mm ss z ",
"EEE dd MM yy HH mm ss z ",
- "EEE dd MM yyyy HH mm ss z "
+ "EEE dd MM yyyy HH mm ss z ",
};
private static final String[] EXTENDED_DATE_PATTERNS_1 = new String[] {
+ "EEE MMM dd yyyy HH mm ss 'GMT'Z",
"EEE dd MMM yy HH mm ss zzz",
"EEE dd MMM yyyy HH mm ss zzz",
"EEE MMM d HH mm ss yyyy",
@@ -67,6 +69,7 @@ final class HtmlUnitExpiresHandler extends BasicExpiresHandler {
};
private static final String[] EXTENDED_DATE_PATTERNS_2 = new String[] {
+ "EEE MMM dd yyyy HH mm ss 'GMT'Z",
"EEE dd MMM yy HH mm ss zzz",
"EEE dd MMM yyyy HH mm ss zzz",
"EEE MMM d HH mm ss yyyy",
@@ -75,7 +78,7 @@ final class HtmlUnitExpiresHandler extends BasicExpiresHandler {
"EEE dd MM yy HH mm ss z ",
"EEE dd MM yyyy HH mm ss z ",
"EEE dd MMM yy HH MM ss z",
- "MMM dd yy HH mm ss",
+ "MMM dd yy HH mm ss"
};
private final BrowserVersion browserVersion_;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitHttpOnlyHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitHttpOnlyHandler.java
index eadbdddcbf1..3d9219ac36c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitHttpOnlyHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitHttpOnlyHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitPathHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitPathHandler.java
index e1902890b8c..bc2bf5cbc44 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitPathHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitPathHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitRedirectStrategie.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitRedirectStrategie.java
index 1fdac114330..a2bb864a31a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitRedirectStrategie.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitRedirectStrategie.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitSSLConnectionSocketFactory.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitSSLConnectionSocketFactory.java
index e08ac8bc2e7..03cc8cfc1aa 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitSSLConnectionSocketFactory.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitSSLConnectionSocketFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,9 +36,9 @@
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSocket;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
+import javax.net.ssl.X509ExtendedTrustManager;
import org.apache.http.HttpHost;
import org.apache.http.conn.ConnectTimeoutException;
@@ -107,7 +107,7 @@ public static SSLConnectionSocketFactory buildSSLSocketFactory(final WebClientOp
protocol = "SSL";
}
final SSLContext sslContext = SSLContext.getInstance(protocol);
- sslContext.init(getKeyManagers(options), new TrustManager[]{new InsecureTrustManager()}, null);
+ sslContext.init(getKeyManagers(options), new X509ExtendedTrustManager[] {new InsecureTrustManager()}, null);
return new HtmlUnitSSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE,
useInsecureSSL, sslClientProtocols, sslClientCipherSuites);
@@ -240,8 +240,9 @@ private static KeyManager[] getKeyManagers(final WebClientOptions options) {
*
* @author Daniel Gredler
* @author Marc Guillemot
+ * @author Ronald Brill
*/
-class InsecureTrustManager implements X509TrustManager {
+class InsecureTrustManager extends X509ExtendedTrustManager {
private final Set acceptedIssuers_ = new HashSet<>();
/**
@@ -262,6 +263,34 @@ public void checkServerTrusted(final X509Certificate[] chain, final String authT
acceptedIssuers_.addAll(Arrays.asList(chain));
}
+ @Override
+ public void checkClientTrusted(final X509Certificate[] chain,
+ final String authType, final Socket socket) throws CertificateException {
+ // Everyone is trusted!
+ acceptedIssuers_.addAll(Arrays.asList(chain));
+ }
+
+ @Override
+ public void checkClientTrusted(final X509Certificate[] chain,
+ final String authType, final SSLEngine sslEngine) throws CertificateException {
+ // Everyone is trusted!
+ acceptedIssuers_.addAll(Arrays.asList(chain));
+ }
+
+ @Override
+ public void checkServerTrusted(final X509Certificate[] chain,
+ final String authType, final Socket socket) throws CertificateException {
+ // Everyone is trusted!
+ acceptedIssuers_.addAll(Arrays.asList(chain));
+ }
+
+ @Override
+ public void checkServerTrusted(final X509Certificate[] chain,
+ final String authType, final SSLEngine sslEngine) throws CertificateException {
+ // Everyone is trusted!
+ acceptedIssuers_.addAll(Arrays.asList(chain));
+ }
+
/**
* {@inheritDoc}
*/
@@ -274,6 +303,6 @@ public X509Certificate[] getAcceptedIssuers() {
if (acceptedIssuers_.isEmpty()) {
return new X509Certificate[0];
}
- return acceptedIssuers_.toArray(new X509Certificate[acceptedIssuers_.size()]);
+ return acceptedIssuers_.toArray(new X509Certificate[0]);
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitVersionAttributeHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitVersionAttributeHandler.java
index 8fdb610367c..08f7abff604 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitVersionAttributeHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/HtmlUnitVersionAttributeHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/SocksConnectionSocketFactory.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/SocksConnectionSocketFactory.java
index d7428a197e9..0f3ad56268b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/SocksConnectionSocketFactory.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/SocksConnectionSocketFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/package-info.java
index c26418cb9ed..50ce583c73c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/httpclient/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/httpclient/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/AbstractJavaScriptEngine.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/AbstractJavaScriptEngine.java
index 562c2575413..4229e9cf84d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/AbstractJavaScriptEngine.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/AbstractJavaScriptEngine.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebugFrameAdapter.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebugFrameAdapter.java
index 8fcba0804a2..30ce6fd1c3e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebugFrameAdapter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebugFrameAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebugFrameImpl.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebugFrameImpl.java
index 271af0b9308..fc209641c07 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebugFrameImpl.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebugFrameImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,7 +79,7 @@ public void onEnter(final Context cx, final Scriptable activation, final Scripta
final String line = getFirstLine(cx);
final String source = getSourceName(cx);
- sb.append(source).append(":").append(line).append(" ");
+ sb.append(source).append(':').append(line).append(' ');
Scriptable parent = activation.getParentScope();
while (parent != null) {
@@ -87,7 +87,7 @@ public void onEnter(final Context cx, final Scriptable activation, final Scripta
parent = parent.getParentScope();
}
final String functionName = getFunctionName(thisObj);
- sb.append(functionName).append("(");
+ sb.append(functionName).append('(');
final int nbParams = functionOrScript_.getParamCount();
for (int i = 0; i < nbParams; i++) {
final String argAsString;
@@ -102,7 +102,7 @@ public void onEnter(final Context cx, final Scriptable activation, final Scripta
sb.append(", ");
}
}
- sb.append(")");
+ sb.append(')');
LOG.trace(sb);
}
@@ -144,16 +144,22 @@ public void onExceptionThrown(final Context cx, final Throwable t) {
if (LOG.isTraceEnabled()) {
if (t instanceof JavaScriptException) {
final JavaScriptException e = (JavaScriptException) t;
- LOG.trace(getSourceName(cx) + ":" + getFirstLine(cx)
- + " Exception thrown: " + Context.toString(e.details()));
+ if (LOG.isTraceEnabled()) {
+ LOG.trace(getSourceName(cx) + ":" + getFirstLine(cx)
+ + " Exception thrown: " + Context.toString(e.details()));
+ }
}
else if (t instanceof EcmaError) {
final EcmaError e = (EcmaError) t;
- LOG.trace(getSourceName(cx) + ":" + getFirstLine(cx)
- + " Exception thrown: " + Context.toString(e.details()));
+ if (LOG.isTraceEnabled()) {
+ LOG.trace(getSourceName(cx) + ":" + getFirstLine(cx)
+ + " Exception thrown: " + Context.toString(e.details()));
+ }
}
else {
- LOG.trace(getSourceName(cx) + ":" + getFirstLine(cx) + " Exception thrown: " + t.getCause());
+ if (LOG.isTraceEnabled()) {
+ LOG.trace(getSourceName(cx) + ":" + getFirstLine(cx) + " Exception thrown: " + t.getCause());
+ }
}
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebuggerAdapter.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebuggerAdapter.java
index e34bb2a13c5..bcafd7defd2 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebuggerAdapter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebuggerAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebuggerImpl.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebuggerImpl.java
index 344932de6e9..9db63801b88 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebuggerImpl.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/DebuggerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/DefaultJavaScriptErrorListener.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/DefaultJavaScriptErrorListener.java
index bb82fa554d8..547ac30d975 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/DefaultJavaScriptErrorListener.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/DefaultJavaScriptErrorListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,8 +25,8 @@
import com.gargoylesoftware.htmlunit.html.HtmlPage;
/**
- * Default implementation of {@link JavaScriptErrorListener} that does only
- * logging in some cases.
+ * Default implementation of {@link JavaScriptErrorListener} that does
+ * default logging.
*
* @author Ronald Brill
*/
@@ -34,23 +34,64 @@ public class DefaultJavaScriptErrorListener implements JavaScriptErrorListener,
private static final Log LOG = LogFactory.getLog(DefaultJavaScriptErrorListener.class);
+ /**
+ * {@inheritDoc}
+ */
@Override
public void scriptException(final HtmlPage page, final ScriptException scriptException) {
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Error during JavaScript execution", scriptException);
+ }
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void timeoutError(final HtmlPage page, final long allowedTime, final long executionTime) {
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Timeout during JavaScript execution after "
+ + executionTime + "ms; allowed only " + allowedTime + "ms");
+ }
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void malformedScriptURL(final HtmlPage page, final String url,
final MalformedURLException malformedURLException) {
- LOG.error("Unable to build URL for script src tag [" + url + "]", malformedURLException);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Unable to build URL for script src tag [" + url + "]", malformedURLException);
+ }
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void loadScriptError(final HtmlPage page, final URL scriptUrl, final Exception exception) {
- LOG.error("Error loading JavaScript from [" + scriptUrl + "].", exception);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Error loading JavaScript from [" + scriptUrl + "].", exception);
+ }
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void warn(final String message, final String sourceName,
+ final int line, final String lineSource, final int lineOffset) {
+ if (LOG.isWarnEnabled()) {
+ final StringBuilder msg = new StringBuilder()
+ .append("warning: message=[").append(message)
+ .append("] sourceName=[").append(sourceName)
+ .append("] line=[").append(line)
+ .append("] lineSource=[").append(lineSource)
+ .append("] lineOffset=[").append(lineOffset)
+ .append("]");
+
+ LOG.warn(msg.toString());
+ }
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/FunctionWrapper.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/FunctionWrapper.java
index c92715976db..832a83906a0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/FunctionWrapper.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/FunctionWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -178,5 +178,4 @@ public Object getDefaultValue(final Class> hint) {
public boolean hasInstance(final Scriptable instance) {
return wrapped_.hasInstance(instance);
}
-
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/HiddenFunctionObject.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/HiddenFunctionObject.java
index 22676d3552e..861414fc998 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/HiddenFunctionObject.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/HiddenFunctionObject.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
*/
package com.gargoylesoftware.htmlunit.javascript;
-import java.lang.reflect.Member;
+import java.lang.reflect.Executable;
import net.sourceforge.htmlunit.corejs.javascript.FunctionObject;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
@@ -29,7 +29,7 @@ class HiddenFunctionObject extends FunctionObject {
/**
* Constructor.
*/
- HiddenFunctionObject(final String name, final Member methodOrConstructor, final Scriptable scope) {
+ HiddenFunctionObject(final String name, final Executable methodOrConstructor, final Scriptable scope) {
super(name, methodOrConstructor, scope);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitContextFactory.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitContextFactory.java
index 519263787c8..439581ef338 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitContextFactory.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitContextFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,15 +16,16 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_ARGUMENTS_READ_ONLY_ACCESSED_FROM_FUNCTION;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_ARRAY_CONSTRUCTION_PROPERTIES;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_ENUM_NUMBERS_FIRST;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_ERROR_STACK;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_FUNCTION_DECLARED_FORWARD_IN_BLOCK;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_IGNORES_LAST_LINE_CONTAINING_UNCOMMENTED;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_PRE_WIDTH_STRING;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_PROPERTY_DESCRIPTOR_NAME;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_PROPERTY_DESCRIPTOR_NEW_LINE;
+import java.io.Serializable;
+import java.util.Map;
+
import com.gargoylesoftware.htmlunit.BrowserVersion;
+import com.gargoylesoftware.htmlunit.ScriptException;
import com.gargoylesoftware.htmlunit.ScriptPreProcessor;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
@@ -32,10 +33,13 @@
import com.gargoylesoftware.htmlunit.javascript.regexp.HtmlUnitRegExpProxy;
import net.sourceforge.htmlunit.corejs.javascript.Callable;
+import net.sourceforge.htmlunit.corejs.javascript.ClassShutter;
import net.sourceforge.htmlunit.corejs.javascript.Context;
+import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
import net.sourceforge.htmlunit.corejs.javascript.ContextFactory;
import net.sourceforge.htmlunit.corejs.javascript.ErrorReporter;
import net.sourceforge.htmlunit.corejs.javascript.Evaluator;
+import net.sourceforge.htmlunit.corejs.javascript.EvaluatorException;
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.Script;
import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
@@ -50,6 +54,7 @@
* @author Andre Soereng
* @author Ahmed Ashour
* @author Marc Guillemot
+ * @author Ronald Brill
*/
public class HtmlUnitContextFactory extends ContextFactory {
@@ -59,9 +64,8 @@ public class HtmlUnitContextFactory extends ContextFactory {
private final BrowserVersion browserVersion_;
private long timeout_;
private Debugger debugger_;
- private final ErrorReporter errorReporter_;
private final WrapFactory wrapFactory_ = new HtmlUnitWrapFactory();
- private boolean deminifyFunctionCode_ = false;
+ private boolean deminifyFunctionCode_;
/**
* Creates a new instance of HtmlUnitContextFactory.
@@ -71,7 +75,6 @@ public class HtmlUnitContextFactory extends ContextFactory {
public HtmlUnitContextFactory(final WebClient webClient) {
webClient_ = webClient;
browserVersion_ = webClient.getBrowserVersion();
- errorReporter_ = new StrictErrorReporter();
}
/**
@@ -138,12 +141,15 @@ public boolean isDeminifyFunctionCode() {
*/
private class TimeoutContext extends Context {
private long startTime_;
+
protected TimeoutContext(final ContextFactory factory) {
super(factory);
}
+
public void startClock() {
startTime_ = System.currentTimeMillis();
}
+
public void terminateScriptIfNecessary() {
if (timeout_ > 0) {
final long currentTime = System.currentTimeMillis();
@@ -154,6 +160,7 @@ public void terminateScriptIfNecessary() {
}
}
}
+
@Override
protected Script compileString(String source, final Evaluator compiler,
final ErrorReporter compilationErrorReporter, final String sourceName,
@@ -267,12 +274,23 @@ protected String preProcess(
@Override
protected Context makeContext() {
final TimeoutContext cx = new TimeoutContext(this);
- if (browserVersion_.hasFeature(JS_PRE_WIDTH_STRING)) {
- cx.setLanguageVersion(Context.VERSION_1_8);
- }
- else {
- cx.setLanguageVersion(Context.VERSION_ES6);
- }
+ cx.setLanguageVersion(Context.VERSION_ES6);
+
+ // make sure no java classes are usable from js
+ cx.setClassShutter(new ClassShutter() {
+ @Override
+ public boolean visibleToScripts(final String fullClassName) {
+ final Map activeXObjectMap = webClient_.getActiveXObjectMap();
+ if (activeXObjectMap != null) {
+ for (String mappedClass : activeXObjectMap.values()) {
+ if (fullClassName.equals(mappedClass)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ });
// Use pure interpreter mode to get observeInstructionCount() callbacks.
cx.setOptimizationLevel(-1);
@@ -280,7 +298,7 @@ protected Context makeContext() {
// Set threshold on how often we want to receive the callbacks
cx.setInstructionObserverThreshold(INSTRUCTION_COUNT_THRESHOLD);
- configureErrorReporter(cx);
+ cx.setErrorReporter(new HtmlUnitErrorReporter(webClient_.getJavaScriptErrorListener()));
cx.setWrapFactory(wrapFactory_);
if (debugger_ != null) {
@@ -295,15 +313,6 @@ protected Context makeContext() {
return cx;
}
- /**
- * Configures the {@link ErrorReporter} on the context.
- * @param context the context to configure
- * @see Context#setErrorReporter(ErrorReporter)
- */
- protected void configureErrorReporter(final Context context) {
- context.setErrorReporter(errorReporter_);
- }
-
/**
* Run-time calls this when instruction counting is enabled and the counter
* reaches limit set by setInstructionObserverThreshold(). A script can be
@@ -331,6 +340,25 @@ protected Object doTopCall(final Callable callable,
return super.doTopCall(callable, cx, scope, thisObj, args);
}
+ /**
+ * Same as {@link ContextFactory}{@link #call(ContextAction)} but with handling
+ * of some exceptions.
+ *
+ * @param return type of the action
+ * @param action the contextAction
+ * @param page the page
+ * @return the result of the call
+ */
+ public final T callSecured(final ContextAction action, final HtmlPage page) {
+ try {
+ return call(action);
+ }
+ catch (final StackOverflowError e) {
+ webClient_.getJavaScriptErrorListener().scriptException(page, new ScriptException(page, e));
+ return null;
+ }
+ }
+
/**
* {@inheritDoc}
*/
@@ -350,9 +378,9 @@ protected boolean hasFeature(final Context cx, final int featureIndex) {
case Context.FEATURE_HTMLUNIT_ERROR_STACK:
return browserVersion_.hasFeature(JS_ERROR_STACK);
case Context.FEATURE_HTMLUNIT_FUNCTION_DECLARED_FORWARD_IN_BLOCK:
- return browserVersion_.hasFeature(JS_FUNCTION_DECLARED_FORWARD_IN_BLOCK);
+ return true;
case Context.FEATURE_HTMLUNIT_ENUM_NUMBERS_FIRST:
- return browserVersion_.hasFeature(JS_ENUM_NUMBERS_FIRST);
+ return true;
case Context.FEATURE_HTMLUNIT_MEMBERBOX_NAME:
return browserVersion_.hasFeature(JS_PROPERTY_DESCRIPTOR_NAME);
case Context.FEATURE_HTMLUNIT_MEMBERBOX_NEWLINE:
@@ -363,4 +391,70 @@ protected boolean hasFeature(final Context cx, final int featureIndex) {
return super.hasFeature(cx, featureIndex);
}
}
+
+ private static final class HtmlUnitErrorReporter implements ErrorReporter, Serializable {
+
+ private final JavaScriptErrorListener javaScriptErrorListener_;
+
+ /**
+ * Ctor.
+ *
+ * @param javaScriptErrorListener the listener to be used
+ */
+ HtmlUnitErrorReporter(final JavaScriptErrorListener javaScriptErrorListener) {
+ javaScriptErrorListener_ = javaScriptErrorListener;
+ }
+
+ /**
+ * Logs a warning.
+ *
+ * @param message the message to be displayed
+ * @param sourceName the name of the source file
+ * @param line the line number
+ * @param lineSource the source code that failed
+ * @param lineOffset the line offset
+ */
+ @Override
+ public void warning(
+ final String message, final String sourceName, final int line,
+ final String lineSource, final int lineOffset) {
+ javaScriptErrorListener_.warn(message, sourceName, line, lineSource, lineOffset);
+ }
+
+ /**
+ * Logs an error.
+ *
+ * @param message the message to be displayed
+ * @param sourceName the name of the source file
+ * @param line the line number
+ * @param lineSource the source code that failed
+ * @param lineOffset the line offset
+ */
+ @Override
+ public void error(final String message, final String sourceName, final int line,
+ final String lineSource, final int lineOffset) {
+ // no need to log here, this is only used to create the exception
+ // the exception gets logged if not catched later on
+ throw new EvaluatorException(message, sourceName, line, lineSource, lineOffset);
+ }
+
+ /**
+ * Logs a runtime error.
+ *
+ * @param message the message to be displayed
+ * @param sourceName the name of the source file
+ * @param line the line number
+ * @param lineSource the source code that failed
+ * @param lineOffset the line offset
+ * @return an evaluator exception
+ */
+ @Override
+ public EvaluatorException runtimeError(
+ final String message, final String sourceName, final int line,
+ final String lineSource, final int lineOffset) {
+ // no need to log here, this is only used to create the exception
+ // the exception gets logged if not catched later on
+ return new EvaluatorException(message, sourceName, line, lineSource, lineOffset);
+ }
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitScriptable.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitScriptable.java
index 020154113c2..92e56cc97da 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitScriptable.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitScriptable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitWrapFactory.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitWrapFactory.java
index c44733fd70c..6318db8e658 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitWrapFactory.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/HtmlUnitWrapFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine.java
index 69e40bdef38..08841b964aa 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/JavaScriptEngine.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,14 +19,11 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_ERROR_STACK_TRACE_LIMIT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_FUNCTION_TOSOURCE;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_IMAGE_PROTOTYPE_SAME_AS_HTML_IMAGE;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_Iterator;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_OBJECT_GET_OWN_PROPERTY_SYMBOLS;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_REFLECT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_SYMBOL;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_SYMBOL_FF45;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_ACTIVEXOBJECT_HIDDEN;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_XML;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.STRING_CONTAINS;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.STRING_INCLUDES;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.STRING_REPEAT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.STRING_STARTS_ENDS_WITH;
@@ -34,11 +31,10 @@
import java.io.IOException;
import java.io.ObjectInputStream;
-import java.lang.reflect.Member;
+import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Deque;
import java.util.HashMap;
import java.util.List;
@@ -63,11 +59,9 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.ClassConfiguration.PropertyInfo;
import com.gargoylesoftware.htmlunit.javascript.configuration.JavaScriptConfiguration;
import com.gargoylesoftware.htmlunit.javascript.host.ActiveXObject;
-import com.gargoylesoftware.htmlunit.javascript.host.ArrayCustom;
import com.gargoylesoftware.htmlunit.javascript.host.DateCustom;
import com.gargoylesoftware.htmlunit.javascript.host.NumberCustom;
import com.gargoylesoftware.htmlunit.javascript.host.Reflect;
-import com.gargoylesoftware.htmlunit.javascript.host.StringCustom;
import com.gargoylesoftware.htmlunit.javascript.host.Window;
import com.gargoylesoftware.htmlunit.javascript.host.intl.Intl;
@@ -77,6 +71,7 @@
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.FunctionObject;
import net.sourceforge.htmlunit.corejs.javascript.IdFunctionObject;
+import net.sourceforge.htmlunit.corejs.javascript.RhinoException;
import net.sourceforge.htmlunit.corejs.javascript.Script;
import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
@@ -143,7 +138,9 @@ public JavaScriptEngine(final WebClient webClient) {
webClient_ = webClient;
contextFactory_ = new HtmlUnitContextFactory(webClient);
initTransientFields();
+
jsConfig_ = JavaScriptConfiguration.getInstance(webClient.getBrowserVersion());
+ RhinoException.useMozillaStackStyle(true);
}
/**
@@ -170,27 +167,22 @@ public HtmlUnitContextFactory getContextFactory() {
public void initialize(final WebWindow webWindow) {
WebAssert.notNull("webWindow", webWindow);
- final ContextAction action = new ContextAction() {
- @Override
- public Object run(final Context cx) {
- try {
- init(webWindow, cx);
- }
- catch (final Exception e) {
- LOG.error("Exception while initializing JavaScript for the page", e);
- throw new ScriptException(null, e); // BUG: null is not useful.
- }
-
- return null;
+ getContextFactory().call(cx -> {
+ try {
+ init(webWindow, cx);
}
- };
-
- getContextFactory().call(action);
+ catch (final Exception e) {
+ LOG.error("Exception while initializing JavaScript for the page", e);
+ throw new ScriptException(null, e); // BUG: null is not useful.
+ }
+ return null;
+ });
}
/**
* Returns the JavaScriptExecutor.
- * @return the JavaScriptExecutor.
+ * @return the JavaScriptExecutor or null if javascript is disabled
+ * or no executor was required so far.
*/
public JavaScriptExecutor getJavaScriptExecutor() {
return javaScriptExecutor_;
@@ -210,7 +202,7 @@ private void init(final WebWindow webWindow, final Context context) throws Excep
final Window window = new Window();
((SimpleScriptable) window).setClassName("Window");
- context.initStandardObjects(window);
+ context.initSafeStandardObjects(window);
final ClassConfiguration windowConfig = jsConfig_.getClassConfiguration("Window");
if (windowConfig.getJsConstructor() != null) {
@@ -224,30 +216,17 @@ private void init(final WebWindow webWindow, final Context context) throws Excep
}
// remove some objects, that Rhino defines in top scope but that we don't want
- deleteProperties(window, "java", "javax", "org", "com", "edu", "net",
- "JavaAdapter", "JavaImporter", "Continuation", "Packages", "getClass");
+ deleteProperties(window, "Continuation");
if (!browserVersion.hasFeature(JS_XML)) {
deleteProperties(window, "XML", "XMLList", "Namespace", "QName");
}
- if (!browserVersion.hasFeature(JS_Iterator)) {
- deleteProperties(window, "Iterator", "StopIteration");
- }
+ deleteProperties(window, "Iterator", "StopIteration");
if (!browserVersion.hasFeature(JS_SYMBOL)) {
deleteProperties(window, "Symbol");
}
- if (browserVersion.hasFeature(JS_SYMBOL_FF45)) {
- final ScriptableObject sym = (ScriptableObject) ScriptableObject.getProperty(window, "Symbol");
- final List toDelete = Arrays.asList("hasInstance", "isConcatSpreadable", "replace",
- "search", "split", "string", "toStringTag", "unscopables");
- for (String propName : toDelete) {
- sym.setAttributes(propName, ScriptableObject.EMPTY);
- sym.delete(propName);
- }
- }
-
final ScriptableObject errorObject = (ScriptableObject) ScriptableObject.getProperty(window, "Error");
if (browserVersion.hasFeature(JS_ERROR_STACK_TRACE_LIMIT)) {
errorObject.defineProperty("stackTraceLimit", 10, ScriptableObject.EMPTY);
@@ -299,7 +278,7 @@ private void init(final WebWindow webWindow, final Context context) throws Excep
}
for (final ClassConfiguration config : jsConfig_.getAll()) {
- final Member jsConstructor = config.getJsConstructor();
+ final Executable jsConstructor = config.getJsConstructor();
final String jsClassName = config.getClassName();
Scriptable prototype = prototypesPerJSName.get(jsClassName);
final String hostClassSimpleName = config.getHostClassSimpleName();
@@ -313,18 +292,10 @@ private void init(final WebWindow webWindow, final Context context) throws Excep
}
switch (hostClassSimpleName) {
- case "WebKitAnimationEvent":
- prototype = prototypesPerJSName.get("AnimationEvent");
- break;
-
case "WebKitMutationObserver":
prototype = prototypesPerJSName.get("MutationObserver");
break;
- case "WebKitTransitionEvent":
- prototype = prototypesPerJSName.get("TransitionEvent");
- break;
-
case "webkitURL":
prototype = prototypesPerJSName.get("URL");
break;
@@ -353,9 +324,7 @@ private void init(final WebWindow webWindow, final Context context) throws Excep
function = new RecursiveFunctionObject(jsClassName, jsConstructor, window);
}
- if ("WebKitAnimationEvent".equals(hostClassSimpleName)
- || "WebKitMutationObserver".equals(hostClassSimpleName)
- || "WebKitTransitionEvent".equals(hostClassSimpleName)
+ if ("WebKitMutationObserver".equals(hostClassSimpleName)
|| "webkitURL".equals(hostClassSimpleName)
|| "Image".equals(hostClassSimpleName)
|| "Option".equals(hostClassSimpleName)) {
@@ -455,26 +424,23 @@ private void init(final WebWindow webWindow, final Context context) throws Excep
}
// Rhino defines too much methods for us, particularly since implementation of ECMAScript5
- removePrototypeProperties(window, "String", "equals", "equalsIgnoreCase");
+ final ScriptableObject stringPrototype = (ScriptableObject) ScriptableObject.getClassPrototype(window, "String");
+ deleteProperties(stringPrototype, "equals", "equalsIgnoreCase");
+
+ final ScriptableObject numberPrototype = (ScriptableObject) ScriptableObject.getClassPrototype(window, "Number");
+ final ScriptableObject datePrototype = (ScriptableObject) ScriptableObject.getClassPrototype(window, "Date");
+
if (!browserVersion.hasFeature(STRING_INCLUDES)) {
- removePrototypeProperties(window, "String", "includes");
+ deleteProperties(stringPrototype, "includes");
}
if (!browserVersion.hasFeature(STRING_REPEAT)) {
- removePrototypeProperties(window, "String", "repeat");
+ deleteProperties(stringPrototype, "repeat");
}
if (!browserVersion.hasFeature(STRING_STARTS_ENDS_WITH)) {
- removePrototypeProperties(window, "String", "startsWith");
- removePrototypeProperties(window, "String", "endsWith");
+ deleteProperties(stringPrototype, "startsWith", "endsWith");
}
if (!browserVersion.hasFeature(STRING_TRIM_LEFT_RIGHT)) {
- removePrototypeProperties(window, "String", "trimLeft");
- removePrototypeProperties(window, "String", "trimRight");
- }
- if (browserVersion.hasFeature(STRING_CONTAINS)) {
- final ScriptableObject stringPrototype =
- (ScriptableObject) ScriptableObject.getClassPrototype(window, "String");
- stringPrototype.defineFunctionProperties(new String[] {"contains"},
- StringCustom.class, ScriptableObject.EMPTY);
+ deleteProperties(stringPrototype, "trimLeft", "trimRight");
}
// only FF has toSource
@@ -482,19 +448,21 @@ private void init(final WebWindow webWindow, final Context context) throws Excep
deleteProperties(window, "uneval");
removePrototypeProperties(window, "Object", "toSource");
removePrototypeProperties(window, "Array", "toSource");
- removePrototypeProperties(window, "Date", "toSource");
+ deleteProperties(datePrototype, "toSource");
removePrototypeProperties(window, "Function", "toSource");
- removePrototypeProperties(window, "Number", "toSource");
- removePrototypeProperties(window, "String", "toSource");
+ deleteProperties(numberPrototype, "toSource");
+ deleteProperties(stringPrototype, "toSource");
}
if (browserVersion.hasFeature(JS_WINDOW_ACTIVEXOBJECT_HIDDEN)) {
((IdFunctionObject) ScriptableObject.getProperty(window, "Object")).delete("assign");
+
+ // TODO
+ deleteProperties(window, "WeakSet");
}
deleteProperties(window, "isXMLName");
NativeFunctionToStringFunction.installFix(window, webClient.getBrowserVersion());
- final ScriptableObject datePrototype = (ScriptableObject) ScriptableObject.getClassPrototype(window, "Date");
datePrototype.defineFunctionProperties(new String[] {"toLocaleDateString", "toLocaleTimeString"},
DateCustom.class, ScriptableObject.DONTENUM);
@@ -502,14 +470,10 @@ private void init(final WebWindow webWindow, final Context context) throws Excep
((ScriptableObject) ScriptableObject.getProperty(window, "Object")).delete("getOwnPropertySymbols");
}
- if (browserVersion.hasFeature(JS_ARRAY_FROM)) {
- final ScriptableObject arrayPrototype = (ScriptableObject) ScriptRuntime.name(context, window, "Array");
- arrayPrototype.defineFunctionProperties(new String[] {"from"},
- ArrayCustom.class, ScriptableObject.DONTENUM);
+ if (!browserVersion.hasFeature(JS_ARRAY_FROM)) {
+ deleteProperties((ScriptableObject) ScriptableObject.getProperty(window, "Array"), "from", "of");
}
- final ScriptableObject numberPrototype
- = (ScriptableObject) ScriptableObject.getClassPrototype(window, "Number");
numberPrototype.defineFunctionProperties(new String[] {"toLocaleString"},
NumberCustom.class, ScriptableObject.DONTENUM);
@@ -641,11 +605,11 @@ private static void configureConstants(final ClassConfiguration config, final Sc
private static void configureProperties(final ClassConfiguration config, final ScriptableObject scriptable) {
final Map propertyMap = config.getPropertyMap();
- for (final String propertyName : propertyMap.keySet()) {
- final PropertyInfo info = propertyMap.get(propertyName);
+ for (final Entry propertyEntry : propertyMap.entrySet()) {
+ final PropertyInfo info = propertyEntry.getValue();
final Method readMethod = info.getReadMethod();
final Method writeMethod = info.getWriteMethod();
- scriptable.defineProperty(propertyName, null, readMethod, writeMethod, ScriptableObject.EMPTY);
+ scriptable.defineProperty(propertyEntry.getKey(), null, readMethod, writeMethod, ScriptableObject.EMPTY);
}
}
@@ -734,7 +698,7 @@ public Script compile(final HtmlPage owningPage, final Scriptable scope, final S
LOG.trace("Javascript compile " + sourceName + newline + sourceCode + newline);
}
- final ContextAction action = new HtmlUnitContextAction(scope, owningPage) {
+ final ContextAction action = new HtmlUnitContextAction(scope, owningPage) {
@Override
public Object doRun(final Context cx) {
return cx.compileString(sourceCode, sourceName, startLine, null);
@@ -746,7 +710,7 @@ protected String getSourceCode(final Context cx) {
}
};
- return (Script) getContextFactory().call(action);
+ return (Script) getContextFactory().callSecured(action, owningPage);
}
/**
@@ -783,7 +747,7 @@ public Object execute(final HtmlPage page, final Script script) {
* @return the result of executing the specified code
*/
public Object execute(final HtmlPage page, final Scriptable scope, final Script script) {
- final ContextAction action = new HtmlUnitContextAction(scope, page) {
+ final ContextAction action = new HtmlUnitContextAction(scope, page) {
@Override
public Object doRun(final Context cx) {
return script.exec(cx, scope);
@@ -795,7 +759,7 @@ protected String getSourceCode(final Context cx) {
}
};
- return getContextFactory().call(action);
+ return getContextFactory().callSecured(action, page);
}
/**
@@ -831,7 +795,7 @@ public Object callFunction(
public Object callFunction(final HtmlPage page, final Function function,
final Scriptable scope, final Scriptable thisObject, final Object[] args) {
- final ContextAction action = new HtmlUnitContextAction(scope, page) {
+ final ContextAction action = new HtmlUnitContextAction(scope, page) {
@Override
public Object doRun(final Context cx) {
if (ScriptRuntime.hasTopCall(cx)) {
@@ -844,7 +808,7 @@ protected String getSourceCode(final Context cx) {
return cx.decompileFunction(function, 2);
}
};
- return getContextFactory().call(action);
+ return getContextFactory().callSecured(action, page);
}
private static Scriptable getScope(final HtmlPage page, final DomNode node) {
@@ -869,7 +833,7 @@ public boolean isScriptRunning() {
* ContextAction should be preferred because according to Rhino doc it
* "guarantees proper association of Context instances with the current thread and is faster".
*/
- private abstract class HtmlUnitContextAction implements ContextAction {
+ private abstract class HtmlUnitContextAction implements ContextAction {
private final Scriptable scope_;
private final HtmlPage page_;
@@ -1012,13 +976,12 @@ protected void handleJavaScriptException(final ScriptException scriptException,
}
}
}
- getWebClient().getJavaScriptErrorListener().scriptException(page, scriptException);
+ final WebClient webClient = getWebClient();
+ webClient.getJavaScriptErrorListener().scriptException(page, scriptException);
// Throw a Java exception if the user wants us to.
- if (getWebClient().getOptions().isThrowExceptionOnScriptError()) {
+ if (webClient.getOptions().isThrowExceptionOnScriptError()) {
throw scriptException;
}
- // Log the error; ScriptException instances provide good debug info.
- LOG.info("Caught script exception", scriptException);
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/JavaScriptErrorListener.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/JavaScriptErrorListener.java
index 91c1229668b..39bd3659bba 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/JavaScriptErrorListener.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/JavaScriptErrorListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,8 +51,7 @@ public interface JavaScriptErrorListener {
* @param url the malformed url
* @param malformedURLException the occurred exception
*/
- void malformedScriptURL(HtmlPage page, String url,
- MalformedURLException malformedURLException);
+ void malformedScriptURL(HtmlPage page, String url, MalformedURLException malformedURLException);
/**
* Informs about an exception during load of a javascript file refereed from a page.
@@ -62,4 +61,15 @@ void malformedScriptURL(HtmlPage page, String url,
* @param exception the occurred exception
*/
void loadScriptError(HtmlPage page, URL scriptUrl, Exception exception);
+
+ /**
+ * Informs about a javascript warning.
+ *
+ * @param message the message to be displayed
+ * @param sourceName the name of the source file
+ * @param line the line number
+ * @param lineSource the source code that failed
+ * @param lineOffset the line offset
+ */
+ void warn(String message, String sourceName, int line, String lineSource, int lineOffset);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/MethodWrapper.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/MethodWrapper.java
index 39d03f55ad4..38f17c26802 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/MethodWrapper.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/MethodWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/NamedNodeMap.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/NamedNodeMap.java
index 5643e335353..c8d6cf9f15a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/NamedNodeMap.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/NamedNodeMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.html.DomElement;
@@ -49,7 +48,7 @@ public class NamedNodeMap extends SimpleScriptable {
/**
* We need default constructors to build the prototype instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public NamedNodeMap() {
attributes_ = null;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/NativeFunctionToStringFunction.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/NativeFunctionToStringFunction.java
index f0a8ee68a68..9f5fc10cd10 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/NativeFunctionToStringFunction.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/NativeFunctionToStringFunction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_NATIVE_FUNCTION_TOSTRING_COMPACT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_NATIVE_FUNCTION_TOSTRING_NEW_LINE;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_NATIVE_FUNCTION_TOSTRING_NL;
import com.gargoylesoftware.htmlunit.BrowserVersion;
@@ -55,6 +56,13 @@ else if (browserVersion.hasFeature(JS_NATIVE_FUNCTION_TOSTRING_COMPACT)) {
final Function newToString = new NativeFunctionToStringFunctionChrome(originalToString);
ScriptableObject.putProperty(fnPrototype, "toString", newToString);
}
+ else if (browserVersion.hasFeature(JS_NATIVE_FUNCTION_TOSTRING_NL)) {
+ final ScriptableObject fnPrototype =
+ (ScriptableObject) ScriptableObject.getClassPrototype(window, "Function");
+ final Function originalToString = (Function) ScriptableObject.getProperty(fnPrototype, "toString");
+ final Function newToString = new NativeFunctionToStringFunctionFF(originalToString);
+ ScriptableObject.putProperty(fnPrototype, "toString", newToString);
+ }
}
NativeFunctionToStringFunction(final Function wrapped) {
@@ -92,7 +100,23 @@ public Object call(final Context cx, final Scriptable scope, final Scriptable th
final String functionName = ((BaseFunction) thisObj).getFunctionName();
return "function " + functionName + "() { [native code] }";
}
- return s;
+ return s.replace("function anonymous() {", "function anonymous(\n) {");
+ }
+ }
+
+ static class NativeFunctionToStringFunctionFF extends FunctionWrapper {
+
+ NativeFunctionToStringFunctionFF(final Function wrapped) {
+ super(wrapped);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object call(final Context cx, final Scriptable scope, final Scriptable thisObj, final Object[] args) {
+ final String s = (String) super.call(cx, scope, thisObj, args);
+ return s.replace("function anonymous() {", "function anonymous(\n) {");
}
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/PostponedAction.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/PostponedAction.java
index 0ef00e9a0eb..69144d9b582 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/PostponedAction.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/PostponedAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/RecursiveFunctionObject.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/RecursiveFunctionObject.java
index e32f5aa9a7e..7e0ab9448d2 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/RecursiveFunctionObject.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/RecursiveFunctionObject.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WEBGL_CONTEXT_EVENT_CONSTANTS;
+import java.lang.reflect.Executable;
import java.lang.reflect.Member;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -44,7 +45,7 @@ public class RecursiveFunctionObject extends FunctionObject {
* @param methodOrConstructor a {@link Member} that defines the object
* @param scope the enclosing scope of function
*/
- public RecursiveFunctionObject(final String name, final Member methodOrConstructor,
+ public RecursiveFunctionObject(final String name, final Executable methodOrConstructor,
final Scriptable scope) {
super(name, methodOrConstructor, scope);
}
@@ -85,7 +86,7 @@ public Object[] getIds() {
}
}
}
- return objects.toArray(new Object[objects.size()]);
+ return objects.toArray(new Object[0]);
}
/**
@@ -116,15 +117,9 @@ public String getFunctionName() {
case "webkitSpeechRecognition":
return "SpeechRecognition";
- case "WebKitAnimationEvent":
- return "AnimationEvent";
-
case "WebKitMutationObserver":
return "MutationObserver";
- case "WebKitTransitionEvent":
- return "TransitionEvent";
-
case "webkitMediaStream":
return "MediaStream";
@@ -135,7 +130,7 @@ public String getFunctionName() {
return "SpeechGrammarList";
case "webkitSpeechRecognitionError":
- return "SpeechRecognitionError";
+ return "SpeechRecognitionErrorEvent";
case "webkitSpeechRecognitionEvent":
return "SpeechRecognitionEvent";
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/ScriptableWrapper.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/ScriptableWrapper.java
index 171a6855ec2..094f4315d88 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/ScriptableWrapper.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/ScriptableWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/SilentJavaScriptErrorListener.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/SilentJavaScriptErrorListener.java
new file mode 100644
index 00000000000..5f443d252c1
--- /dev/null
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/SilentJavaScriptErrorListener.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gargoylesoftware.htmlunit.javascript;
+
+import java.io.Serializable;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import com.gargoylesoftware.htmlunit.ScriptException;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+
+/**
+ * Silent implementation of {@link JavaScriptErrorListener} that does no logging at all.
+ *
+ * @author Ronald Brill
+ */
+public class SilentJavaScriptErrorListener implements JavaScriptErrorListener, Serializable {
+
+ @Override
+ public void scriptException(final HtmlPage page, final ScriptException scriptException) {
+ }
+
+ @Override
+ public void timeoutError(final HtmlPage page, final long allowedTime, final long executionTime) {
+ }
+
+ @Override
+ public void malformedScriptURL(final HtmlPage page, final String url,
+ final MalformedURLException malformedURLException) {
+ }
+
+ @Override
+ public void loadScriptError(final HtmlPage page, final URL scriptUrl, final Exception exception) {
+ }
+
+ @Override
+ public void warn(final String message, final String sourceName,
+ final int line, final String lineSource, final int lineOffset) {
+ }
+}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptable.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptable.java
index 20d6d293e78..2068189884d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptable.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLIMAGE_HTMLELEMENT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLIMAGE_HTMLUNKNOWNELEMENT;
-import java.lang.reflect.Method;
import java.util.Deque;
import org.apache.commons.logging.Log;
@@ -30,14 +29,11 @@
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlImage;
-import com.gargoylesoftware.htmlunit.javascript.configuration.CanSetReadOnly;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
import com.gargoylesoftware.htmlunit.javascript.host.Window;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLElement;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLUnknownElement;
import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
import net.sourceforge.htmlunit.corejs.javascript.Undefined;
@@ -110,7 +106,7 @@ protected Object getWithPreemption(final String name) {
@Override
public boolean has(final int index, final Scriptable start) {
final Object found = get(index, start);
- if (Undefined.instance != found && Scriptable.NOT_FOUND != found) {
+ if (!Undefined.isUndefined(found) && Scriptable.NOT_FOUND != found) {
return true;
}
return super.has(index, start);
@@ -387,38 +383,4 @@ public void setCaseSensitive(final boolean caseSensitive) {
((SimpleScriptable) prototype).setCaseSensitive(caseSensitive);
}
}
-
- @Override
- protected boolean isReadOnlySettable(final String name, final Object value) {
- for (final Method m : getClass().getMethods()) {
- final JsxGetter jsxGetter = m.getAnnotation(JsxGetter.class);
- if (jsxGetter != null) {
- String methodProperty;
- if (jsxGetter.propertyName().isEmpty()) {
- final int prefix = m.getName().startsWith("is") ? 2 : 3;
- methodProperty = m.getName().substring(prefix);
- methodProperty = Character.toLowerCase(methodProperty.charAt(0)) + methodProperty.substring(1);
- }
- else {
- methodProperty = jsxGetter.propertyName();
- }
- if (methodProperty.equals(name)) {
- final CanSetReadOnly canSetReadOnly = m.getAnnotation(CanSetReadOnly.class);
- if (canSetReadOnly != null) {
- switch (canSetReadOnly.value()) {
- case YES:
- return true;
- case IGNORE:
- return false;
- case EXCEPTION:
- throw ScriptRuntime.typeError3("msg.set.prop.no.setter",
- name, getClassName(), Context.toString(value));
- default:
- }
- }
- }
- }
- }
- return true;
- }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptableProxy.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptableProxy.java
index 8068937f54e..f5a52c37ce0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptableProxy.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/SimpleScriptableProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/StrictErrorHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/StrictErrorHandler.java
deleted file mode 100644
index d33069b7757..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/StrictErrorHandler.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript;
-
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXParseException;
-
-/**
- * An error handler that throws an exception for all problems no matter how minor.
- *
- * @author Mike Bowler
- */
-public class StrictErrorHandler implements ErrorHandler {
-
- /**
- * A warning occurred.
- *
- * @param rethrow an exception which will be rethrown
- * @throws SAXParseException always
- */
- @Override
- public void warning(final SAXParseException rethrow) throws SAXParseException {
- throw rethrow;
- }
-
- /**
- * An error occurred.
- *
- * @param rethrow an exception which will be rethrown
- * @throws SAXParseException always
- */
- @Override
- public void error(final SAXParseException rethrow) throws SAXParseException {
- throw rethrow;
- }
-
- /**
- * A fatal error occurred.
- *
- * @param rethrow an exception which will be rethrown
- * @throws SAXParseException always
- */
- @Override
- public void fatalError(final SAXParseException rethrow) throws SAXParseException {
- throw rethrow;
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/StrictErrorReporter.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/StrictErrorReporter.java
deleted file mode 100644
index 0cde9c09637..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/StrictErrorReporter.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript;
-
-import java.io.Serializable;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import net.sourceforge.htmlunit.corejs.javascript.ErrorReporter;
-import net.sourceforge.htmlunit.corejs.javascript.EvaluatorException;
-
-/**
- * A JavaScript error reporter that will log all warnings and errors, no matter how trivial.
- *
- * @author Mike Bowler
- * @author Marc Guillemot
- * @author Ronald Brill
- */
-public class StrictErrorReporter implements ErrorReporter, Serializable {
-
- private static final Log LOG = LogFactory.getLog(StrictErrorReporter.class);
-
- /**
- * Logs a warning.
- *
- * @param message the message to be displayed
- * @param sourceName the name of the source file
- * @param line the line number
- * @param lineSource the source code that failed
- * @param lineOffset the line offset
- */
- @Override
- public void warning(
- final String message, final String sourceName, final int line,
- final String lineSource, final int lineOffset) {
- LOG.warn(format("warning", message, sourceName, line, lineSource, lineOffset));
- }
-
- /**
- * Logs an error.
- *
- * @param message the message to be displayed
- * @param sourceName the name of the source file
- * @param line the line number
- * @param lineSource the source code that failed
- * @param lineOffset the line offset
- */
- @Override
- public void error(final String message, final String sourceName, final int line,
- final String lineSource, final int lineOffset) {
- LOG.error(format("error", message, sourceName, line, lineSource, lineOffset));
- throw new EvaluatorException(message, sourceName, line, lineSource, lineOffset);
- }
-
- /**
- * Logs a runtime error.
- *
- * @param message the message to be displayed
- * @param sourceName the name of the source file
- * @param line the line number
- * @param lineSource the source code that failed
- * @param lineOffset the line offset
- * @return an evaluator exception
- */
- @Override
- public EvaluatorException runtimeError(
- final String message, final String sourceName, final int line,
- final String lineSource, final int lineOffset) {
- LOG.error(format("runtimeError", message, sourceName, line, lineSource, lineOffset));
- return new EvaluatorException(message, sourceName, line, lineSource, lineOffset);
- }
-
- private static String format(
- final String prefix, final String message, final String sourceName,
- final int line, final String lineSource, final int lineOffset) {
- return prefix + ": message=[" + message + "] sourceName=[" + sourceName + "] line=[" + line
- + "] lineSource=[" + lineSource + "] lineOffset=[" + lineOffset + "]";
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/TimeoutError.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/TimeoutError.java
index 8d35eebf3a4..df5f077cf8d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/TimeoutError.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/TimeoutError.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BackgroundJavaScriptFactory.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BackgroundJavaScriptFactory.java
index 41317e02426..6c297dd00e1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BackgroundJavaScriptFactory.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BackgroundJavaScriptFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@
* JavaScript engine.
*
* @author Ronald Brill
+ * @author Atsushi Nakagawa
*/
public class BackgroundJavaScriptFactory {
@@ -73,13 +74,14 @@ public JavaScriptJob createJavaScriptJob(final int initialDelay, final Integer p
* @param label the label for the job
* @param window the window to which the job belongs
* @param function the JavaScript code to execute
+ * @param args the arguments to pass into the function call
*
* @return JavaScriptJob the created job
*/
public JavaScriptFunctionJob createJavaScriptJob(final int initialDelay,
final Integer period, final String label,
- final WebWindow window, final Function function) {
- return new JavaScriptFunctionJob(initialDelay, period, label, window, function);
+ final WebWindow window, final Function function, final Object[] args) {
+ return new JavaScriptFunctionJob(initialDelay, period, label, window, function, args);
}
/**
@@ -90,7 +92,7 @@ public JavaScriptFunctionJob createJavaScriptJob(final int initialDelay,
* @return JavaScriptJob the created job
*/
public JavaScriptJob createJavascriptXMLHttpRequestJob(final ContextFactory contextFactory,
- final ContextAction action) {
+ final ContextAction action) {
return new JavascriptXMLHttpRequestJob(contextFactory, action);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BasicJavaScriptJob.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BasicJavaScriptJob.java
index 40a8647edc3..1bea38dca8b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BasicJavaScriptJob.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/BasicJavaScriptJob.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/DefaultJavaScriptExecutor.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/DefaultJavaScriptExecutor.java
index c98cae9dacd..f703534d243 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/DefaultJavaScriptExecutor.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/DefaultJavaScriptExecutor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -33,14 +34,12 @@
*/
public class DefaultJavaScriptExecutor implements JavaScriptExecutor {
- // TODO: is there utility in not having these as transient?
private final transient WeakReference webClient_;
+ private final transient List> jobManagerList_;
- private transient List> jobManagerList_ = new LinkedList<>();
+ private final transient AtomicBoolean shutdown_;
- private volatile boolean shutdown_ = false;
-
- private transient Thread eventLoopThread_ = null;
+ private transient Thread eventLoopThread_;
/** Logging support. */
private static final Log LOG = LogFactory.getLog(DefaultJavaScriptExecutor.class);
@@ -51,6 +50,8 @@ public class DefaultJavaScriptExecutor implements JavaScriptExecutor {
*/
public DefaultJavaScriptExecutor(final WebClient webClient) {
webClient_ = new WeakReference<>(webClient);
+ jobManagerList_ = new LinkedList<>();
+ shutdown_ = new AtomicBoolean();
}
/**
@@ -106,14 +107,17 @@ private void killThread() {
protected JavaScriptJobManager getJobManagerWithEarliestJob() {
JavaScriptJobManager javaScriptJobManager = null;
JavaScriptJob earliestJob = null;
- // iterate over the list and find the earliest job to run.
- for (WeakReference weakReference : jobManagerList_) {
- final JavaScriptJobManager jobManager = weakReference.get();
- if (jobManager != null) {
- final JavaScriptJob newJob = jobManager.getEarliestJob();
- if (newJob != null && (earliestJob == null || earliestJob.compareTo(newJob) > 0)) {
- earliestJob = newJob;
- javaScriptJobManager = jobManager;
+
+ synchronized (jobManagerList_) {
+ // iterate over the list and find the earliest job to run.
+ for (WeakReference weakReference : jobManagerList_) {
+ final JavaScriptJobManager jobManager = weakReference.get();
+ if (jobManager != null) {
+ final JavaScriptJob newJob = jobManager.getEarliestJob();
+ if (newJob != null && (earliestJob == null || earliestJob.compareTo(newJob) > 0)) {
+ earliestJob = newJob;
+ javaScriptJobManager = jobManager;
+ }
}
}
}
@@ -127,7 +131,7 @@ public void run() {
// this has to be a multiple of 10ms
// otherwise the VM has to fight with the OS to get such small periods
final long sleepInterval = 10;
- while (!shutdown_ && !Thread.currentThread().isInterrupted() && webClient_.get() != null) {
+ while (!shutdown_.get() && !Thread.currentThread().isInterrupted() && webClient_.get() != null) {
final JavaScriptJobManager jobManager = getJobManagerWithEarliestJob();
if (jobManager != null) {
@@ -153,7 +157,7 @@ public void run() {
}
// check for cancel
- if (shutdown_ || Thread.currentThread().isInterrupted() || webClient_.get() == null) {
+ if (shutdown_.get() || Thread.currentThread().isInterrupted() || webClient_.get() == null) {
break;
}
@@ -180,32 +184,35 @@ public void addWindow(final WebWindow newWindow) {
}
}
- private synchronized void updateJobMangerList(final JavaScriptJobManager newJobManager) {
- for (WeakReference weakReference : jobManagerList_) {
- final JavaScriptJobManager manager = weakReference.get();
- if (newJobManager == manager) {
- return;
- }
- }
-
+ private void updateJobMangerList(final JavaScriptJobManager newJobManager) {
final List> managers = new LinkedList<>();
- for (WeakReference weakReference : jobManagerList_) {
- final JavaScriptJobManager manager = weakReference.get();
- if (null != manager) {
- managers.add(weakReference);
+ synchronized (jobManagerList_) {
+ for (WeakReference weakReference : jobManagerList_) {
+ final JavaScriptJobManager manager = weakReference.get();
+ if (newJobManager == manager) {
+ return;
+ }
+ if (null != weakReference.get()) {
+ managers.add(weakReference);
+ }
}
+
+ managers.add(new WeakReference<>(newJobManager));
+
+ jobManagerList_.clear();
+ jobManagerList_.addAll(managers);
}
- managers.add(new WeakReference<>(newJobManager));
- jobManagerList_ = managers;
}
/** Notes that this thread has been shutdown. */
@Override
public void shutdown() {
- shutdown_ = true;
+ shutdown_.set(true);
killThread();
webClient_.clear();
- jobManagerList_.clear();
+ synchronized (jobManagerList_) {
+ jobManagerList_.clear();
+ }
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/DownloadBehaviorJob.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/DownloadBehaviorJob.java
index 0f1fec53972..84b1547cd2d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/DownloadBehaviorJob.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/DownloadBehaviorJob.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,8 +26,6 @@
import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
-import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
import net.sourceforge.htmlunit.corejs.javascript.ContextFactory;
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
@@ -73,18 +71,16 @@ public void run() {
LOG.debug("Downloaded content: " + StringUtils.abbreviate(content, 512));
}
final Object[] args = new Object[] {content};
- final ContextAction action = new ContextAction() {
- @Override
- public Object run(final Context cx) {
- callback_.call(cx, scope, scope, args);
- return null;
- }
- };
final ContextFactory cf = ((JavaScriptEngine) client_.getJavaScriptEngine()).getContextFactory();
- cf.call(action);
+ cf.call(cx -> {
+ callback_.call(cx, scope, scope, args);
+ return null;
+ });
}
catch (final IOException e) {
- LOG.error("Behavior #default#download: Cannot download " + url_, e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Behavior #default#download: Cannot download " + url_, e);
+ }
}
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptExecutionJob.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptExecutionJob.java
index ad9139b2061..31eac59e13a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptExecutionJob.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptExecutionJob.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptExecutor.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptExecutor.java
index 956deb38943..32c8db7d526 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptExecutor.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptExecutor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,8 +14,6 @@
*/
package com.gargoylesoftware.htmlunit.javascript.background;
-import java.io.Serializable;
-
import com.gargoylesoftware.htmlunit.WebWindow;
/**
@@ -25,7 +23,7 @@
* @author Kostadin Chikov
* @author Ronald Brill
*/
-public interface JavaScriptExecutor extends Runnable, Serializable {
+public interface JavaScriptExecutor extends Runnable {
/**
* Register a window with the eventLoop.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptFunctionJob.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptFunctionJob.java
index 4f3a40fde78..41692fe35ad 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptFunctionJob.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptFunctionJob.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,11 +24,14 @@
/**
* A {@link JavaScriptJob} created from a {@link Function} object.
* @author Brad Clarke
+ * @author Ronald Brill
+ * @author Atsushi Nakagawa
*/
class JavaScriptFunctionJob extends JavaScriptExecutionJob {
/** The JavaScript code to execute. */
private final Function function_;
+ private final Object[] args_;
/**
* Creates a new JavaScript execution job, where the JavaScript code to execute is a function.
@@ -37,11 +40,13 @@ class JavaScriptFunctionJob extends JavaScriptExecutionJob {
* @param label the label for the job
* @param window the window to which the job belongs
* @param function the JavaScript code to execute
+ * @param args the arguments to pass into the function call
*/
JavaScriptFunctionJob(final int initialDelay, final Integer period, final String label,
- final WebWindow window, final Function function) {
+ final WebWindow window, final Function function, final Object[] args) {
super(initialDelay, period, label, window);
function_ = function;
+ args_ = args;
}
/** {@inheritDoc} */
@@ -49,7 +54,7 @@ class JavaScriptFunctionJob extends JavaScriptExecutionJob {
protected void runJavaScript(final HtmlPage page) {
final DomElement doc = page.getDocumentElement();
final Scriptable scriptable = page.getEnclosingWindow().getScriptableObject();
- page.executeJavaScriptFunction(function_, scriptable, new Object[0], doc);
+ page.executeJavaScriptFunction(function_, scriptable, args_, doc);
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJob.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJob.java
index c14bf5f5f99..64cb5a7d206 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJob.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJob.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJobManager.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJobManager.java
index 5cfbd1c33cc..d986c1b878c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJobManager.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJobManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJobManagerImpl.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJobManagerImpl.java
index f4ef7e1aacf..ec5e14add74 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJobManagerImpl.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptJobManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,7 +56,7 @@ class JavaScriptJobManagerImpl implements JavaScriptJobManager {
private transient ArrayList cancelledJobs_ = new ArrayList<>();
- private transient JavaScriptJob currentlyRunningJob_ = null;
+ private transient JavaScriptJob currentlyRunningJob_;
/** A counter used to generate the IDs assigned to {@link JavaScriptJob}s. */
private static final AtomicInteger NEXT_JOB_ID_ = new AtomicInteger(1);
@@ -309,7 +309,7 @@ private void printQueue() {
*/
@Override
public synchronized String jobStatusDump(final JavaScriptJobFilter filter) {
- final StringBuilder status = new StringBuilder();
+ final StringBuilder status = new StringBuilder(110);
final String lineSeparator = System.lineSeparator();
status.append("------ JavaScript job status -----");
status.append(lineSeparator);
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptStringJob.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptStringJob.java
index dfc22ef77d9..8f836896718 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptStringJob.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavaScriptStringJob.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavascriptXMLHttpRequestJob.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavascriptXMLHttpRequestJob.java
index 626fb113577..a5cf08f4d5b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavascriptXMLHttpRequestJob.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/JavascriptXMLHttpRequestJob.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,9 +23,9 @@
*/
final class JavascriptXMLHttpRequestJob extends BasicJavaScriptJob {
private final ContextFactory contextFactory_;
- private final ContextAction action_;
+ private final ContextAction action_;
- JavascriptXMLHttpRequestJob(final ContextFactory contextFactory, final ContextAction action) {
+ JavascriptXMLHttpRequestJob(final ContextFactory contextFactory, final ContextAction action) {
super();
contextFactory_ = contextFactory;
action_ = action;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/package-info.java
index deb5a6bb7da..9db4fb7bd21 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/background/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/AbstractJavaScriptConfiguration.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/AbstractJavaScriptConfiguration.java
index 003e7200a54..ef3a2583734 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/AbstractJavaScriptConfiguration.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/AbstractJavaScriptConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,10 +15,9 @@
package com.gargoylesoftware.htmlunit.javascript.configuration;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF68;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import java.lang.annotation.Annotation;
@@ -108,14 +107,11 @@ public static ClassConfiguration getClassConfiguration(final Class extends Htm
else if (browser.isIE()) {
expectedBrowser = IE;
}
- else if (browser.isEdge()) {
- expectedBrowser = EDGE;
- }
- else if (browser.isFirefox52()) {
- expectedBrowser = FF52;
+ else if (browser.isFirefox60()) {
+ expectedBrowser = FF60;
}
else if (browser.isFirefox()) {
- expectedBrowser = FF45;
+ expectedBrowser = FF68;
}
else {
expectedBrowser = CHROME; // our current fallback
@@ -147,9 +143,7 @@ else if (browser.isFirefox()) {
extendedClassName = superClass.getSimpleName();
}
- for (int i = 0; i < jsxClassValues.length; i++) {
- final JsxClass jsxClass = jsxClassValues[i];
-
+ for (JsxClass jsxClass : jsxClassValues) {
if (jsxClass != null && isSupported(jsxClass.value(), expectedBrowser)) {
domClasses.add(jsxClass.domClass());
if (jsxClass.isJSObject()) {
@@ -330,8 +324,8 @@ private static boolean isSupported(final SupportedBrowser[] browsers, final Supp
*/
public static boolean isCompatible(final SupportedBrowser browser1, final SupportedBrowser browser2) {
return (browser1 == browser2)
- || (browser1 == FF && (browser2 == FF45 || browser2 == FF52))
- || (browser2 == FF && (browser1 == FF45 || browser1 == FF52));
+ || (browser1 == FF && (browser2 == FF60 || browser2 == FF68))
+ || (browser2 == FF && (browser1 == FF60 || browser1 == FF68));
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/BrowserFeature.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/BrowserFeature.java
index afa75c21226..0c0235b88bb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/BrowserFeature.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/BrowserFeature.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.configuration;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -40,8 +39,7 @@
SupportedBrowser[] value() default {
CHROME,
FF,
- IE,
- EDGE
+ IE
};
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/BrowserName.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/BrowserName.java
index ca82906b5d2..8af0bc7dc0c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/BrowserName.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/BrowserName.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,9 +28,6 @@ public enum BrowserName {
/** Internet Explorer. */
IE,
- /** Edge. */
- EDGE,
-
/** Firefox. */
FF
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/CanSetReadOnly.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/CanSetReadOnly.java
deleted file mode 100644
index 24b5f17653d..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/CanSetReadOnly.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.configuration;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * An annotation to check of whether this getter read-only method allows to set the value,
- * ignore it, or throw an exception.
- *
- * @author Ahmed Ashour
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface CanSetReadOnly {
-
- /**
- * The status.
- * @return the status
- */
- CanSetReadOnlyStatus value() default CanSetReadOnlyStatus.YES;
-}
-
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/ClassConfiguration.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/ClassConfiguration.java
index a2413530545..9743ffe3901 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/ClassConfiguration.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/ClassConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
*/
package com.gargoylesoftware.htmlunit.javascript.configuration;
-import java.lang.reflect.Member;
+import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
@@ -49,7 +49,7 @@ public final class ClassConfiguration {
/**
* The constructor method in the {@link #hostClass_}
*/
- private Member jsConstructor_;
+ private Executable jsConstructor_;
private final Class>[] domClasses_;
private final boolean jsObject_;
private final String className_;
@@ -78,7 +78,7 @@ public ClassConfiguration(final Class extends HtmlUnitScriptable> hostClass, f
extendedClassName_ = extendedClassName;
}
- void setJSConstructor(final Member jsConstructor) {
+ void setJSConstructor(final Executable jsConstructor) {
if (jsConstructor_ != null) {
throw new IllegalStateException("Can not have two constructors for "
+ jsConstructor_.getDeclaringClass().getName());
@@ -122,9 +122,13 @@ public void addConstant(final String name) {
}
constants_.add(new ConstantInfo(name, value, flag));
}
- catch (final Exception e) {
- throw Context.reportRuntimeError("Cannot get field '" + name + "' for type: "
- + getHostClass().getName());
+ catch (final NoSuchFieldException e) {
+ throw Context.reportRuntimeError("Cannot get field '" + name + "' for type: " + getHostClass().getName()
+ + "reason: " + e.getMessage());
+ }
+ catch (final IllegalAccessException e) {
+ throw Context.reportRuntimeError("Cannot get field '" + name + "' for type: " + getHostClass().getName()
+ + "reason: " + e.getMessage());
}
}
@@ -220,7 +224,7 @@ public String getHostClassSimpleName() {
* Gets the JavaScript constructor method in {@link #getHostClass()}.
* @return the JavaScript constructor method in {@link #getHostClass()}
*/
- public Member getJsConstructor() {
+ public Executable getJsConstructor() {
return jsConstructor_;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfiguration.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfiguration.java
index c56434f1bc9..9d25d26d58e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfiguration.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@
import com.gargoylesoftware.htmlunit.javascript.NamedNodeMap;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.host.ActiveXObject;
-import com.gargoylesoftware.htmlunit.javascript.host.Animation;
import com.gargoylesoftware.htmlunit.javascript.host.ApplicationCache;
import com.gargoylesoftware.htmlunit.javascript.host.AudioScheduledSourceNode;
import com.gargoylesoftware.htmlunit.javascript.host.BarProp;
@@ -57,14 +56,12 @@
import com.gargoylesoftware.htmlunit.javascript.host.Plugin;
import com.gargoylesoftware.htmlunit.javascript.host.PluginArray;
import com.gargoylesoftware.htmlunit.javascript.host.Promise;
-import com.gargoylesoftware.htmlunit.javascript.host.Proxy;
import com.gargoylesoftware.htmlunit.javascript.host.PushManager;
import com.gargoylesoftware.htmlunit.javascript.host.PushSubscription;
import com.gargoylesoftware.htmlunit.javascript.host.PushSubscriptionOptions;
import com.gargoylesoftware.htmlunit.javascript.host.ReadableStream;
import com.gargoylesoftware.htmlunit.javascript.host.Screen;
import com.gargoylesoftware.htmlunit.javascript.host.ScreenOrientation;
-import com.gargoylesoftware.htmlunit.javascript.host.Set;
import com.gargoylesoftware.htmlunit.javascript.host.SharedWorker;
import com.gargoylesoftware.htmlunit.javascript.host.SimpleArray;
import com.gargoylesoftware.htmlunit.javascript.host.Storage;
@@ -75,28 +72,15 @@
import com.gargoylesoftware.htmlunit.javascript.host.TouchList;
import com.gargoylesoftware.htmlunit.javascript.host.URL;
import com.gargoylesoftware.htmlunit.javascript.host.URLSearchParams;
-import com.gargoylesoftware.htmlunit.javascript.host.WeakMap;
-import com.gargoylesoftware.htmlunit.javascript.host.WeakSet;
import com.gargoylesoftware.htmlunit.javascript.host.WebSocket;
import com.gargoylesoftware.htmlunit.javascript.host.Window;
import com.gargoylesoftware.htmlunit.javascript.host.XPathExpression;
import com.gargoylesoftware.htmlunit.javascript.host.webkitURL;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.ArrayBuffer;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.ArrayBufferView;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.ArrayBufferViewBase;
+import com.gargoylesoftware.htmlunit.javascript.host.animations.Animation;
+import com.gargoylesoftware.htmlunit.javascript.host.animations.AnimationEvent;
+import com.gargoylesoftware.htmlunit.javascript.host.animations.KeyframeEffect;
import com.gargoylesoftware.htmlunit.javascript.host.arrays.Atomics;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.DataView;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.Float32Array;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.Float64Array;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.Int16Array;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.Int32Array;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.Int8Array;
import com.gargoylesoftware.htmlunit.javascript.host.arrays.SharedArrayBuffer;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.Uint16Array;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.Uint32Array;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.Uint8Array;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.Uint8ClampedArray;
-import com.gargoylesoftware.htmlunit.javascript.host.budget.BudgetService;
import com.gargoylesoftware.htmlunit.javascript.host.canvas.CanvasCaptureMediaStream;
import com.gargoylesoftware.htmlunit.javascript.host.canvas.CanvasCaptureMediaStreamTrack;
import com.gargoylesoftware.htmlunit.javascript.host.canvas.CanvasGradient;
@@ -159,7 +143,6 @@
import com.gargoylesoftware.htmlunit.javascript.host.css.CaretPosition;
import com.gargoylesoftware.htmlunit.javascript.host.css.ComputedCSSStyleDeclaration;
import com.gargoylesoftware.htmlunit.javascript.host.css.MediaQueryList;
-import com.gargoylesoftware.htmlunit.javascript.host.css.MozCSSKeyframesRule;
import com.gargoylesoftware.htmlunit.javascript.host.css.StyleMedia;
import com.gargoylesoftware.htmlunit.javascript.host.css.StyleSheet;
import com.gargoylesoftware.htmlunit.javascript.host.css.StyleSheetList;
@@ -208,7 +191,6 @@
import com.gargoylesoftware.htmlunit.javascript.host.dom.XPathEvaluator;
import com.gargoylesoftware.htmlunit.javascript.host.dom.XPathNSResolver;
import com.gargoylesoftware.htmlunit.javascript.host.dom.XPathResult;
-import com.gargoylesoftware.htmlunit.javascript.host.event.AnimationEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.ApplicationCacheErrorEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.AudioProcessingEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.BeforeInstallPromptEvent;
@@ -245,8 +227,6 @@
import com.gargoylesoftware.htmlunit.javascript.host.event.MouseEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.MouseScrollEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.MouseWheelEvent;
-import com.gargoylesoftware.htmlunit.javascript.host.event.MozContactChangeEvent;
-import com.gargoylesoftware.htmlunit.javascript.host.event.MozSettingsEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.MutationEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.OfflineAudioCompletionEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.PageTransitionEvent;
@@ -270,11 +250,9 @@
import com.gargoylesoftware.htmlunit.javascript.host.event.UIEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.UserProximityEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.WebGLContextEvent;
-import com.gargoylesoftware.htmlunit.javascript.host.event.WebKitAnimationEvent;
-import com.gargoylesoftware.htmlunit.javascript.host.event.WebKitTransitionEvent;
+import com.gargoylesoftware.htmlunit.javascript.host.event.WebkitSpeechRecognitionError;
+import com.gargoylesoftware.htmlunit.javascript.host.event.WebkitSpeechRecognitionEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.WheelEvent;
-import com.gargoylesoftware.htmlunit.javascript.host.event.webkitSpeechRecognitionError;
-import com.gargoylesoftware.htmlunit.javascript.host.event.webkitSpeechRecognitionEvent;
import com.gargoylesoftware.htmlunit.javascript.host.fetch.Headers;
import com.gargoylesoftware.htmlunit.javascript.host.fetch.Request;
import com.gargoylesoftware.htmlunit.javascript.host.fetch.Response;
@@ -357,7 +335,7 @@
import com.gargoylesoftware.htmlunit.javascript.host.media.VTTCue;
import com.gargoylesoftware.htmlunit.javascript.host.media.VideoPlaybackQuality;
import com.gargoylesoftware.htmlunit.javascript.host.media.WaveShaperNode;
-import com.gargoylesoftware.htmlunit.javascript.host.media.webkitMediaStream;
+import com.gargoylesoftware.htmlunit.javascript.host.media.WebkitMediaStream;
import com.gargoylesoftware.htmlunit.javascript.host.media.midi.MIDIAccess;
import com.gargoylesoftware.htmlunit.javascript.host.media.midi.MIDIInput;
import com.gargoylesoftware.htmlunit.javascript.host.media.midi.MIDIInputMap;
@@ -368,16 +346,15 @@
import com.gargoylesoftware.htmlunit.javascript.host.media.presentation.PresentationAvailability;
import com.gargoylesoftware.htmlunit.javascript.host.media.presentation.PresentationConnection;
import com.gargoylesoftware.htmlunit.javascript.host.media.presentation.PresentationRequest;
+import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.MozRTCIceCandidate;
+import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.MozRTCPeerConnection;
+import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.MozRTCSessionDescription;
import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.RTCCertificate;
import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.RTCIceCandidate;
import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.RTCPeerConnection;
import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.RTCSessionDescription;
import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.RTCStatsReport;
-import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.mozRTCIceCandidate;
-import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.mozRTCPeerConnection;
-import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.mozRTCSessionDescription;
-import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.webkitRTCPeerConnection;
-import com.gargoylesoftware.htmlunit.javascript.host.moz.MozPowerManager;
+import com.gargoylesoftware.htmlunit.javascript.host.media.rtc.WebkitRTCPeerConnection;
import com.gargoylesoftware.htmlunit.javascript.host.network.NetworkInformation;
import com.gargoylesoftware.htmlunit.javascript.host.payment.PaymentAddress;
import com.gargoylesoftware.htmlunit.javascript.host.payment.PaymentRequest;
@@ -398,9 +375,9 @@
import com.gargoylesoftware.htmlunit.javascript.host.speech.SpeechSynthesisErrorEvent;
import com.gargoylesoftware.htmlunit.javascript.host.speech.SpeechSynthesisUtterance;
import com.gargoylesoftware.htmlunit.javascript.host.speech.SpeechSynthesisVoice;
-import com.gargoylesoftware.htmlunit.javascript.host.speech.webkitSpeechGrammar;
-import com.gargoylesoftware.htmlunit.javascript.host.speech.webkitSpeechGrammarList;
-import com.gargoylesoftware.htmlunit.javascript.host.speech.webkitSpeechRecognition;
+import com.gargoylesoftware.htmlunit.javascript.host.speech.WebkitSpeechGrammar;
+import com.gargoylesoftware.htmlunit.javascript.host.speech.WebkitSpeechGrammarList;
+import com.gargoylesoftware.htmlunit.javascript.host.speech.WebkitSpeechRecognition;
import com.gargoylesoftware.htmlunit.javascript.host.svg.*;
import com.gargoylesoftware.htmlunit.javascript.host.worker.ServiceWorker;
import com.gargoylesoftware.htmlunit.javascript.host.worker.ServiceWorkerContainer;
@@ -431,14 +408,13 @@ public final class JavaScriptConfiguration extends AbstractJavaScriptConfigurati
AbstractList.class, ActiveXObject.class, AnalyserNode.class, ANGLE_instanced_arrays.class,
Animation.class, AnimationEvent.class,
ApplicationCache.class, ApplicationCacheErrorEvent.class,
- Atomics.class, Attr.class,
- Audio.class, AudioBuffer.class,
+ Atomics.class,
+ Attr.class, Audio.class, AudioBuffer.class,
AudioBufferSourceNode.class, AudioContext.class, AudioDestinationNode.class, AudioListener.class,
AudioNode.class, AudioParam.class, AudioProcessingEvent.class, AudioScheduledSourceNode.class,
BarProp.class, BaseAudioContext.class,
BatteryManager.class, BeforeInstallPromptEvent.class, BeforeUnloadEvent.class, BiquadFilterNode.class,
Blob.class, BlobEvent.class, BroadcastChannel.class,
- BudgetService.class,
Cache.class, CacheStorage.class,
CanvasCaptureMediaStream.class, CanvasCaptureMediaStreamTrack.class,
CanvasGradient.class, CanvasPattern.class, CanvasRenderingContext2D.class, CaretPosition.class,
@@ -468,7 +444,7 @@ public final class JavaScriptConfiguration extends AbstractJavaScriptConfigurati
FileSystem.class, FileSystemDirectoryEntry.class, FileSystemDirectoryReader.class,
FileSystemEntry.class, FileSystemFileEntry.class,
FocusEvent.class, FontFace.class,
- FontFaceSet.class, FormData.class, FormField.class, GainNode.class, Gamepad.class,
+ FontFaceSet.class, FormData.class, GainNode.class, Gamepad.class,
GamepadButton.class, GamepadEvent.class, Geolocation.class, HashChangeEvent.class, Headers.class, History.class,
HTMLAllCollection.class,
HTMLAnchorElement.class, HTMLAppletElement.class, HTMLAreaElement.class, HTMLAudioElement.class,
@@ -507,8 +483,8 @@ public final class JavaScriptConfiguration extends AbstractJavaScriptConfigurati
InputDeviceCapabilities.class, InputEvent.class,
InstallTrigger.class,
IntersectionObserver.class, IntersectionObserverEntry.class,
- KeyboardEvent.class, LocalMediaStream.class,
- Location.class, com.gargoylesoftware.htmlunit.javascript.host.Map.class,
+ KeyboardEvent.class, KeyframeEffect.class,
+ LocalMediaStream.class, Location.class,
MediaDeviceInfo.class,
MediaDevices.class, MediaElementAudioSourceNode.class, MediaEncryptedEvent.class, MediaError.class,
MediaKeyError.class, MediaKeyMessageEvent.class, MediaKeys.class, MediaKeySession.class,
@@ -519,9 +495,7 @@ public final class JavaScriptConfiguration extends AbstractJavaScriptConfigurati
MessageEvent.class, MessagePort.class, MIDIAccess.class, MIDIConnectionEvent.class, MIDIInput.class,
MIDIInputMap.class, MIDIMessageEvent.class, MIDIOutput.class, MIDIOutputMap.class, MIDIPort.class,
MimeType.class, MimeTypeArray.class, MouseEvent.class, MouseScrollEvent.class,
- MouseWheelEvent.class, MozContactChangeEvent.class, MozCSSKeyframesRule.class,
- MozPowerManager.class, mozRTCIceCandidate.class,
- mozRTCPeerConnection.class, mozRTCSessionDescription.class, MozSettingsEvent.class,
+ MouseWheelEvent.class, MozRTCIceCandidate.class, MozRTCPeerConnection.class, MozRTCSessionDescription.class,
MSGestureEvent.class,
MutationEvent.class, MutationObserver.class, MutationRecord.class, NamedNodeMap.class, Namespace.class,
NamespaceCollection.class,
@@ -541,21 +515,21 @@ public final class JavaScriptConfiguration extends AbstractJavaScriptConfigurati
PresentationAvailability.class, PresentationConnection.class, PresentationConnectionAvailableEvent.class,
PresentationConnectionCloseEvent.class, PresentationRequest.class,
ProcessingInstruction.class, ProgressEvent.class, Promise.class, PromiseRejectionEvent.class,
- Proxy.class, PushManager.class,
+ PushManager.class,
PushSubscription.class, PushSubscriptionOptions.class, RadioNodeList.class, Range.class, ReadableStream.class,
RemotePlayback.class, Request.class, Response.class, RowContainer.class, RTCCertificate.class,
RTCDataChannelEvent.class, RTCIceCandidate.class, RTCPeerConnection.class, RTCPeerConnectionIceEvent.class,
RTCSessionDescription.class, RTCStatsReport.class, Screen.class, ScreenOrientation.class,
ScriptProcessorNode.class,
SecurityPolicyViolationEvent.class, Selection.class, ServiceWorker.class, ServiceWorkerContainer.class,
- ServiceWorkerRegistration.class, Set.class, ShadowRoot.class,
- SharedArrayBuffer.class,
+ ServiceWorkerRegistration.class,
+ ShadowRoot.class, SharedArrayBuffer.class,
SharedWorker.class, SimpleArray.class, SourceBuffer.class, SourceBufferList.class,
SpeechSynthesis.class, SpeechSynthesisErrorEvent.class, SpeechSynthesisEvent.class,
SpeechSynthesisUtterance.class, SpeechSynthesisVoice.class,
StereoPannerNode.class, Storage.class, StorageEvent.class, StorageManager.class,
StyleMedia.class, StyleSheet.class, StyleSheetList.class, SubtleCrypto.class,
- SVGAElement.class, SVGAltGlyphElement.class, SVGAngle.class, SVGAnimatedAngle.class,
+ SVGAElement.class, SVGAngle.class, SVGAnimatedAngle.class,
SVGAnimatedBoolean.class, SVGAnimatedEnumeration.class, SVGAnimatedInteger.class,
SVGAnimatedLength.class, SVGAnimatedLengthList.class, SVGAnimatedNumber.class, SVGAnimatedNumberList.class,
SVGAnimatedPreserveAspectRatio.class, SVGAnimatedRect.class, SVGAnimatedString.class,
@@ -563,7 +537,7 @@ public final class JavaScriptConfiguration extends AbstractJavaScriptConfigurati
SVGAnimateMotionElement.class, SVGAnimateTransformElement.class, SVGAnimationElement.class,
SVGCircleElement.class,
SVGClipPathElement.class, SVGComponentTransferFunctionElement.class,
- SVGDefsElement.class, SVGDescElement.class, SVGDiscardElement.class, SVGDocument.class, SVGElement.class,
+ SVGDefsElement.class, SVGDescElement.class, SVGDiscardElement.class, SVGElement.class,
SVGEllipseElement.class, SVGFEBlendElement.class, SVGFEColorMatrixElement.class,
SVGFEComponentTransferElement.class, SVGFECompositeElement.class, SVGFEConvolveMatrixElement.class,
SVGFEDiffuseLightingElement.class, SVGFEDisplacementMapElement.class, SVGFEDistantLightElement.class,
@@ -599,7 +573,7 @@ public final class JavaScriptConfiguration extends AbstractJavaScriptConfigurati
UIEvent.class,
URL.class,
URLSearchParams.class, UserProximityEvent.class, ValidityState.class, VideoPlaybackQuality.class,
- VTTCue.class, WaveShaperNode.class, WeakMap.class, WeakSet.class, WebGL2RenderingContext.class,
+ VTTCue.class, WaveShaperNode.class, WebGL2RenderingContext.class,
WEBGL_compressed_texture_s3tc.class, WEBGL_debug_renderer_info.class, WebGLActiveInfo.class, WebGLBuffer.class,
WebGLContextEvent.class, WebGLFramebuffer.class, WebGLProgram.class,
WebGLQuery.class,
@@ -608,22 +582,14 @@ public final class JavaScriptConfiguration extends AbstractJavaScriptConfigurati
WebGLSampler.class, WebGLShader.class, WebGLShaderPrecisionFormat.class, WebGLSync.class,
WebGLTexture.class, WebGLTransformFeedback.class,
WebGLUniformLocation.class, WebGLVertexArrayObject.class,
- WebKitAnimationEvent.class,
- WebKitCSSMatrix.class, webkitMediaStream.class, WebKitMutationObserver.class,
- webkitRTCPeerConnection.class, webkitSpeechGrammar.class,
- webkitSpeechGrammarList.class, webkitSpeechRecognition.class, webkitSpeechRecognitionError.class,
- webkitSpeechRecognitionEvent.class, WebKitTransitionEvent.class, webkitURL.class,
+ WebKitCSSMatrix.class, WebkitMediaStream.class, WebKitMutationObserver.class,
+ WebkitRTCPeerConnection.class, WebkitSpeechGrammar.class,
+ WebkitSpeechGrammarList.class, WebkitSpeechRecognition.class, WebkitSpeechRecognitionError.class,
+ WebkitSpeechRecognitionEvent.class, webkitURL.class,
WebSocket.class, WheelEvent.class, Window.class, Worker.class, XMLDocument.class,
XMLHttpRequest.class, XMLHttpRequestEventTarget.class, XMLHttpRequestUpload.class, XMLSerializer.class,
XPathEvaluator.class, XPathExpression.class,
- XPathNSResolver.class, XPathResult.class, XSLTProcessor.class,
-
- // we will use the Rhino stuff as soon as possible
- ArrayBuffer.class, ArrayBufferView.class, ArrayBufferViewBase.class,
- DataView.class,
- Float32Array.class, Float64Array.class,
- Int16Array.class, Int32Array.class, Int8Array.class,
- Uint16Array.class, Uint32Array.class, Uint8Array.class, Uint8ClampedArray.class
+ XPathNSResolver.class, XPathResult.class, XSLTProcessor.class
};
/** Cache of browser versions and their corresponding JavaScript configurations. */
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxClass.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxClass.java
index 4313bd58639..d9e828967fd 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxClass.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxClass.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.configuration;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -66,7 +65,6 @@
SupportedBrowser[] value() default {
CHROME,
FF,
- IE,
- EDGE
+ IE
};
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxClasses.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxClasses.java
index ad9631f9f0a..eb2b36ea34b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxClasses.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxClasses.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxConstant.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxConstant.java
index 2f78a83db4f..fe83b060904 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxConstant.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxConstant.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.configuration;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -40,7 +39,6 @@
SupportedBrowser[] value() default {
CHROME,
FF,
- IE,
- EDGE
+ IE
};
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxConstructor.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxConstructor.java
index 16153a96489..dbba4489805 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxConstructor.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxConstructor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.configuration;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -41,7 +40,6 @@
SupportedBrowser[] value() default {
CHROME,
FF,
- IE,
- EDGE
+ IE
};
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxFunction.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxFunction.java
index 309ffa87eff..552efbab231 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxFunction.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxFunction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.configuration;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -40,8 +39,7 @@
SupportedBrowser[] value() default {
CHROME,
FF,
- IE,
- EDGE
+ IE
};
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxGetter.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxGetter.java
index 05e2620518a..a0d0b2ffa3c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxGetter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxGetter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.configuration;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -40,8 +39,7 @@
SupportedBrowser[] value() default {
CHROME,
FF,
- IE,
- EDGE
+ IE
};
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxSetter.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxSetter.java
index 7ba0ad336af..2cb0e2eb118 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxSetter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxSetter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.configuration;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -40,8 +39,7 @@
SupportedBrowser[] value() default {
CHROME,
FF,
- IE,
- EDGE
+ IE
};
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxStaticFunction.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxStaticFunction.java
index c04bbe2f150..7ea428a55e0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxStaticFunction.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxStaticFunction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.configuration;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -40,8 +39,7 @@
SupportedBrowser[] value() default {
CHROME,
FF,
- IE,
- EDGE
+ IE
};
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxStaticGetter.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxStaticGetter.java
index c0e434409e0..4c8dc925bc2 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxStaticGetter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/JsxStaticGetter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.configuration;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -40,7 +39,6 @@
SupportedBrowser[] value() default {
CHROME,
FF,
- IE,
- EDGE
+ IE
};
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/SupportedBrowser.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/SupportedBrowser.java
index 8c212eee546..c395fd642fe 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/SupportedBrowser.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/SupportedBrowser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,15 +27,12 @@ public enum SupportedBrowser {
/** Internet Explorer 11. */
IE,
- /** Edge. */
- EDGE,
-
/** All versions of Firefox. */
FF,
- /** Firefox 45. */
- FF45,
+ /** Firefox 60. */
+ FF60,
- /** Firefox 52. */
- FF52
+ /** Firefox 68. */
+ FF68
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/package-info.java
index c244287fea2..8e033f83096 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/configuration/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ActiveXObject.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ActiveXObject.java
index cc8d5aeb650..7c0dba22714 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ActiveXObject.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ActiveXObject.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -85,7 +85,7 @@ public static Scriptable jsConstructor(
throw Context.reportRuntimeError(
"ActiveXObject Error: constructor must have one or two String parameters.");
}
- if (args[0] == Undefined.instance) {
+ if (Undefined.isUndefined(args[0])) {
throw Context.reportRuntimeError("ActiveXObject Error: constructor parameter is undefined.");
}
if (!(args[0] instanceof String)) {
@@ -127,7 +127,9 @@ public static Scriptable jsConstructor(
}
}
- LOG.warn("Automation server can't create object for '" + activeXName + "'.");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Automation server can't create object for '" + activeXName + "'.");
+ }
throw Context.reportRuntimeError("Automation server can't create object for '" + activeXName + "'.");
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ActiveXObjectImpl.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ActiveXObjectImpl.java
index ee339684192..a72b52fe013 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ActiveXObjectImpl.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ActiveXObjectImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ApplicationCache.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ApplicationCache.java
index 642ed08e3a1..b214b5b9306 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ApplicationCache.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ApplicationCache.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -29,8 +28,6 @@
import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
import com.gargoylesoftware.htmlunit.javascript.host.event.EventTarget;
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
/**
* A collection of offline resources as defined in the HTML5 spec.
* Intended to support offline web applications.
@@ -44,27 +41,27 @@
* @see Offline Resources in Firefox
* @see Mozilla Documentation
*/
-@JsxClass({CHROME, IE, EDGE})
+@JsxClass({CHROME, IE})
@JsxClass(className = "OfflineResourceList", value = FF)
public class ApplicationCache extends EventTarget {
/** The object isn't associated with an application cache. */
- @JsxConstant({CHROME, IE})
+ @JsxConstant
public static final short UNCACHED = 0;
/** The application cache is not in the process of being updated. */
- @JsxConstant({CHROME, IE})
+ @JsxConstant
public static final short IDLE = 1;
/** The application cache manifest is being fetched and checked for updates. */
- @JsxConstant({CHROME, IE})
+ @JsxConstant
public static final short CHECKING = 2;
/** Resources are being downloaded to be added to the cache. */
- @JsxConstant({CHROME, IE})
+ @JsxConstant
public static final short DOWNLOADING = 3;
/** There is a new version of the application cache available. */
- @JsxConstant({CHROME, IE})
+ @JsxConstant
public static final short UPDATEREADY = 4;
/** The application cache group is now obsolete. */
- @JsxConstant({CHROME, IE})
+ @JsxConstant
public static final short OBSOLETE = 5;
private short status_ = UNCACHED;
@@ -72,7 +69,7 @@ public class ApplicationCache extends EventTarget {
/**
* The constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public ApplicationCache() {
}
@@ -224,10 +221,7 @@ private Object getHandlerForJavaScript(final String eventName) {
}
private void setHandlerForJavaScript(final String eventName, final Object handler) {
- if (handler == null || handler instanceof Scriptable) {
- getEventListenersContainer().setEventHandler(eventName, handler);
- }
- // Otherwise, fail silently.
+ getEventListenersContainer().setEventHandler(eventName, handler);
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ArrayCustom.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ArrayCustom.java
deleted file mode 100644
index ef6d2bd6168..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ArrayCustom.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.Function;
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-import net.sourceforge.htmlunit.corejs.javascript.Undefined;
-
-/**
- * Contains some missing features of Rhino NativeArray.
- *
- * @author Ahmed Ashour
- * @author Ronald Brill
- */
-public final class ArrayCustom {
-
- private ArrayCustom() { }
-
- /**
- * Creates a new Array instance from an array-like or iterable object.
- * @param context the JavaScript context
- * @param thisObj the scriptable
- * @param args the arguments passed into the method
- * @param function the function
- * @return converted string
- */
- public static Scriptable from(
- final Context context, final Scriptable thisObj, final Object[] args, final Function function) {
- final Object arrayLike = args[0];
- Object[] array = null;
- if (arrayLike instanceof Scriptable) {
- final Scriptable scriptable = (Scriptable) arrayLike;
- final Object length = scriptable.get("length", scriptable);
- if (length != Scriptable.NOT_FOUND) {
- final int size = (int) Context.toNumber(length);
- array = new Object[size];
- for (int i = 0; i < size; i++) {
- array[i] = scriptable.get(i, scriptable);
- }
- }
- else {
- final List list = new ArrayList<>();
- if (Iterator.iterate(context, thisObj, scriptable,
- value -> {
- if (value != Undefined.instance) {
- list.add(value);
- }
- })) {
- array = list.toArray();
- }
- }
- }
- else if (arrayLike instanceof String) {
- final String string = (String) arrayLike;
- array = new Object[string.length()];
- for (int i = 0; i < array.length; i++) {
- array[i] = string.charAt(i);
- }
- }
- if (array == null) {
- array = new Object[0];
- }
- return context.newArray(thisObj, array);
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/AudioScheduledSourceNode.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/AudioScheduledSourceNode.java
index 948d3376179..d011fcf0b06 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/AudioScheduledSourceNode.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/AudioScheduledSourceNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -25,7 +26,7 @@
*
* @author Ronald Brill
*/
-@JsxClass(CHROME)
+@JsxClass({CHROME, FF})
public class AudioScheduledSourceNode extends AudioNode {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BarProp.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BarProp.java
index 5df661c3f97..5f589da43ff 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BarProp.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BarProp.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -27,7 +26,7 @@
*
* @author Ahmed Ashour
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class BarProp extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BatteryManager.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BatteryManager.java
index 2fbf1619791..910ebb9d0a8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BatteryManager.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BatteryManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BroadcastChannel.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BroadcastChannel.java
index f186b479fe3..a5781a8d96e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BroadcastChannel.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/BroadcastChannel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Cache.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Cache.java
index 437c2518835..fe899e86bc4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Cache.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Cache.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/CacheStorage.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/CacheStorage.java
index bcdc6081b50..285b7fb89b0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/CacheStorage.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/CacheStorage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ClientRect.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ClientRect.java
index 43e75ed4f79..cfc3b9fce50 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ClientRect.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ClientRect.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -32,7 +31,7 @@
* @author Ronald Brill
* @see MSDN Documentation
*/
-@JsxClass({IE, EDGE})
+@JsxClass(IE)
@JsxClass(className = "DOMRect", value = {CHROME, FF})
public class ClientRect extends SimpleScriptable {
@@ -44,7 +43,7 @@ public class ClientRect extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public ClientRect() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ClientRectList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ClientRectList.java
index c1656045f58..05772654c26 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ClientRectList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ClientRectList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CLIENTRECTLIST_DEFAUL_VALUE_FROM_FIRST;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CLIENTRECTLIST_THROWS_IF_ITEM_NOT_FOUND;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -39,9 +38,8 @@
* @author Ahmed Ashour
* @author Ronald Brill
*/
-@JsxClass(className = "DOMRectList", isJSObject = false, value = CHROME)
-@JsxClass(isJSObject = false, value = FF)
-@JsxClass({IE, EDGE})
+@JsxClass(className = "DOMRectList", value = {CHROME, FF})
+@JsxClass(IE)
public class ClientRectList extends SimpleScriptable {
private final List clientRects_;
@@ -49,7 +47,7 @@ public class ClientRectList extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public ClientRectList() {
clientRects_ = new ArrayList<>();
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Console.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Console.java
index ef349f63987..748289ebe0e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Console.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Console.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CONSOLE_HANDLE_WINDOW;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -31,16 +30,17 @@
import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
import net.sourceforge.htmlunit.corejs.javascript.BaseFunction;
+import net.sourceforge.htmlunit.corejs.javascript.ConsString;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.Delegator;
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.NativeArray;
import net.sourceforge.htmlunit.corejs.javascript.NativeFunction;
import net.sourceforge.htmlunit.corejs.javascript.NativeObject;
+import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
@@ -50,7 +50,7 @@
* @author Andrea Martino
*/
@JsxClass(isJSObject = false, value = {FF, CHROME})
-@JsxClass({IE, EDGE})
+@JsxClass(IE)
public class Console extends SimpleScriptable {
private static final Map TIMERS = new HashMap<>();
@@ -61,7 +61,6 @@ public class Console extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor(EDGE)
public Console() {
}
@@ -73,6 +72,44 @@ public void setWebWindow(final WebWindow webWindow) {
webWindow_ = webWindow;
}
+ /**
+ * This method writes an error message to the console if the
+ * assertion is false. If the assertion is true, nothing happens.
+ * @param cx the JavaScript context
+ * @param thisObj the scriptable
+ * @param args the arguments passed into the method
+ * @param funObj the function
+ */
+ @JsxFunction(functionName = "assert")
+ public static void assertMethod(final Context cx, final Scriptable thisObj,
+ final Object[] args, final Function funObj) {
+ if (args.length < 1 || ScriptRuntime.toBoolean(args[0])) {
+ return;
+ }
+
+ if (args.length == 1) {
+ log(cx, thisObj, new String[] {"Assertion failed"}, null);
+ return;
+ }
+
+ final Object[] data;
+ final Object first = args[1];
+ if (first instanceof String
+ || first instanceof ConsString
+ || first instanceof ScriptableObject && ("String".equals(((Scriptable) first).getClassName()))) {
+ data = new Object[args.length - 1];
+ data[0] = "Assertion failed: " + first.toString();
+ System.arraycopy(args, 2, data, 1, data.length - 1);
+ }
+ else {
+ data = new Object[args.length];
+ data[0] = "Assertion failed:";
+ System.arraycopy(args, 1, data, 1, data.length - 1);
+ }
+
+ log(cx, thisObj, data, null);
+ }
+
/**
* This method performs logging to the console at {@code log} level.
* @param cx the JavaScript context
@@ -287,7 +324,7 @@ public void timeStamp(final String label) {
private static class ConsoleFormatter implements Formatter {
private static void appendNativeArray(final NativeArray a, final StringBuilder sb, final int level) {
- sb.append("[");
+ sb.append('[');
if (level < 3) {
for (int i = 0; i < a.size(); i++) {
if (i > 0) {
@@ -299,7 +336,7 @@ private static void appendNativeArray(final NativeArray a, final StringBuilder s
}
}
}
- sb.append("]");
+ sb.append(']');
}
private static void appendNativeObject(final NativeObject obj, final StringBuilder sb, final int level) {
@@ -308,9 +345,9 @@ private static void appendNativeObject(final NativeObject obj, final StringBuild
// root level Firefox puts brackets outside it. This is not the
// case when a native object is printed as part of an array or
// inside another object.
- sb.append("(");
+ sb.append('(');
}
- sb.append("{");
+ sb.append('{');
if (level < 3) {
final Object[] ids = obj.getIds();
if (ids != null && ids.length > 0) {
@@ -320,15 +357,15 @@ private static void appendNativeObject(final NativeObject obj, final StringBuild
sb.append(", ");
}
sb.append(key);
- sb.append(":");
+ sb.append(": ");
appendValue(obj.get(key), sb, level + 1);
needsSeparator = true;
}
}
}
- sb.append("}");
+ sb.append('}');
if (level == 0) {
- sb.append(")");
+ sb.append(')');
}
}
@@ -349,13 +386,13 @@ private static void appendNativeObject(final NativeObject obj, final StringBuild
*/
private static void appendValue(final Object val, final StringBuilder sb, final int level) {
if (val instanceof NativeFunction) {
- sb.append("(");
+ sb.append('(');
// Remove unnecessary new lines and spaces from the function
final Pattern p = Pattern.compile("[ \\t]*\\r?\\n[ \\t]*",
Pattern.MULTILINE);
final Matcher m = p.matcher(((NativeFunction) val).toString());
sb.append(m.replaceAll(" ").trim());
- sb.append(")");
+ sb.append(')');
}
else if (val instanceof BaseFunction) {
sb.append("function ");
@@ -372,7 +409,7 @@ else if (val instanceof Delegator) {
if (level == 0) {
sb.append("[object ");
sb.append(((Delegator) val).getDelegee().getClassName());
- sb.append("]");
+ sb.append(']');
}
else {
sb.append("({})");
@@ -382,7 +419,7 @@ else if (val instanceof SimpleScriptable) {
if (level == 0) {
sb.append("[object ");
sb.append(((SimpleScriptable) val).getClassName());
- sb.append("]");
+ sb.append(']');
}
else {
sb.append("({})");
@@ -415,7 +452,7 @@ else if (val instanceof Number) {
*/
private static String quote(final CharSequence s) {
final StringBuilder sb = new StringBuilder();
- sb.append("\"");
+ sb.append('\"');
for (int i = 0; i < s.length(); i++) {
final char ch = s.charAt(i);
switch (ch) {
@@ -449,7 +486,7 @@ private static String quote(final CharSequence s) {
}
}
}
- sb.append("\"");
+ sb.append('\"');
return sb.toString();
}
@@ -497,7 +534,7 @@ public String parameterAsString(final Object o) {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < ((NativeArray) o).size(); i++) {
if (i > 0) {
- sb.append(",");
+ sb.append(',');
}
sb.append(formatToString(((NativeArray) o).get(i)));
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/DateCustom.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/DateCustom.java
index 78140a3b28d..67fe975eb5a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/DateCustom.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/DateCustom.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,7 @@
import java.util.Date;
import java.util.Locale;
-import java.util.TimeZone;
-import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import com.gargoylesoftware.htmlunit.BrowserVersion;
@@ -39,9 +37,8 @@
*/
public final class DateCustom {
- private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("UTC");
-
- private DateCustom() { }
+ private DateCustom() {
+ }
/**
* Converts a date to a string, returning the "date" portion using the operating system's locale's conventions.
@@ -94,20 +91,6 @@ public static String toLocaleTimeString(
return format.format(getDateValue(thisObj));
}
- /**
- * Converts a date to a UTC string. Special version for IE
- * @param context the JavaScript context
- * @param thisObj the scriptable
- * @param args the arguments passed into the method
- * @param function the function
- * @return converted string
- */
- public static String toUTCString(
- final Context context, final Scriptable thisObj, final Object[] args, final Function function) {
- final Date date = new Date(getDateValue(thisObj));
- return DateFormatUtils.format(date, "EEE, d MMM yyyy HH:mm:ss z", UTC_TIME_ZONE, Locale.ENGLISH);
- }
-
private static long getDateValue(final Scriptable thisObj) {
final Date date = (Date) Context.jsToJava(thisObj, Date.class);
return date.getTime();
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Element.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Element.java
index 0ef97199d99..8d5ca2e6279 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Element.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Element.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,16 +17,14 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_BOUNDINGCLIENTRECT_THROWS_IF_DISCONNECTED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_ELEMENT_GET_ATTRIBUTE_RETURNS_EMPTY;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INNER_HTML_ADD_CHILD_FOR_NULL_VALUE;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INNER_TEXT_CR_NL;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_INNER_TEXT_LF;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_OUTER_HTML_NULL_AS_STRING;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_OUTER_HTML_REMOVES_CHILDREN_FOR_DETACHED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_OUTER_HTML_THROWS_FOR_DETACHED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.QUERYSELECTORALL_NOT_IN_QUIRKS;
import static com.gargoylesoftware.htmlunit.html.DomElement.ATTRIBUTE_NOT_DEFINED;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import java.io.IOException;
@@ -46,7 +44,6 @@
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.DomText;
-import com.gargoylesoftware.htmlunit.html.HTMLParser;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlElement.DisplayStyle;
import com.gargoylesoftware.htmlunit.javascript.NamedNodeMap;
@@ -304,7 +301,7 @@ public boolean hasAttribute(final String name) {
* {@inheritDoc}
*/
@Override
- @JsxFunction({CHROME, FF, EDGE})
+ @JsxFunction({CHROME, FF})
public boolean hasAttributes() {
return super.hasAttributes();
}
@@ -427,7 +424,7 @@ public void setDefaults(final ComputedCSSStyleDeclaration style) {
* {@inheritDoc}
*/
@Override
- @JsxGetter({CHROME, FF, EDGE})
+ @JsxGetter({CHROME, FF})
public HTMLCollection getChildren() {
return super.getChildren();
}
@@ -436,7 +433,7 @@ public HTMLCollection getChildren() {
* Gets the token list of class attribute.
* @return the token list of class attribute
*/
- @JsxGetter({CHROME, FF, EDGE})
+ @JsxGetter({CHROME, FF})
public DOMTokenList getClassList() {
return new DOMTokenList(this, "class");
}
@@ -657,7 +654,7 @@ protected boolean isMatching(final DomNode node) {
return false;
}
String classAttribute = ((HtmlElement) node).getAttributeDirect("class");
- if (classAttribute == DomElement.ATTRIBUTE_NOT_DEFINED) {
+ if (classAttribute == ATTRIBUTE_NOT_DEFINED) {
return false; // probably better performance as most of elements won't have a class attribute
}
@@ -733,7 +730,7 @@ protected TextRange createTextRange() {
*
* @see MSDN
*/
- @JsxFunction({CHROME, FF52})
+ @JsxFunction({CHROME, FF})
public Object insertAdjacentElement(final String where, final Object insertedElement) {
if (insertedElement instanceof Node) {
final DomNode childNode = ((Node) insertedElement).getDomNodeOrDie();
@@ -760,7 +757,7 @@ public Object insertAdjacentElement(final String where, final Object insertedEle
*
* @see MSDN
*/
- @JsxFunction({CHROME, FF52})
+ @JsxFunction({CHROME, FF})
public void insertAdjacentText(final String where, final String text) {
final Object[] values = getInsertAdjacentLocation(where);
final DomNode node = (DomNode) values[0];
@@ -866,7 +863,7 @@ public void insertAdjacentHTML(final String position, final String text) {
*/
private static void parseHtmlSnippet(final DomNode target, final String source) {
try {
- HTMLParser.parseFragment(target, source);
+ target.getPage().getWebClient().getPageCreator().getHtmlParser().parseFragment(target, source);
}
catch (final IOException e) {
LogFactory.getLog(HtmlElement.class).error("Unexpected exception occurred while parsing HTML snippet", e);
@@ -913,10 +910,10 @@ public void setInnerHTML(final Object value) {
}
domNode.removeAllChildren();
+ getWindow().clearComputedStylesUpToRoot(this);
final boolean addChildForNull = getBrowserVersion().hasFeature(JS_INNER_HTML_ADD_CHILD_FOR_NULL_VALUE);
if ((value == null && addChildForNull) || (value != null && !"".equals(value))) {
-
final String valueAsString = Context.toString(value);
parseHtmlSnippet(domNode, valueAsString);
}
@@ -1036,7 +1033,7 @@ else if (html) {
if (scriptObject instanceof HTMLElement) {
htmlElement = scriptObject;
}
- builder.append("<").append(tag);
+ builder.append('<').append(tag);
// Add the attributes. IE does not use quotes, FF does.
for (final DomAttr attr : element.getAttributesMap().values()) {
if (!attr.getSpecified()) {
@@ -1045,27 +1042,27 @@ else if (html) {
final String name = attr.getName();
final String value = PRINT_NODE_QUOTE_PATTERN.matcher(attr.getValue()).replaceAll(""");
- builder.append(' ').append(name).append("=");
- builder.append("\"");
+ builder.append(' ').append(name).append('=');
+ builder.append('\"');
builder.append(value);
- builder.append("\"");
+ builder.append('\"');
}
- builder.append(">");
+ builder.append('>');
// Add the children.
final boolean isHtml = html
&& !(scriptObject instanceof HTMLScriptElement)
&& !(scriptObject instanceof HTMLStyleElement);
printChildren(builder, node, isHtml);
if (null == htmlElement || !htmlElement.isEndTagForbidden()) {
- builder.append("").append(tag).append(">");
+ builder.append("").append(tag).append('>');
}
}
else {
if (node instanceof HtmlElement) {
final HtmlElement element = (HtmlElement) node;
if ("p".equals(element.getTagName())) {
- if (getBrowserVersion().hasFeature(JS_INNER_TEXT_CR_NL)) {
- builder.append("\r\n"); // \r\n because it's to implement something IE specific
+ if (getBrowserVersion().hasFeature(JS_INNER_TEXT_LF)) {
+ builder.append('\n'); // \r\n because it's to implement something IE specific
}
else {
int i = builder.length() - 1;
@@ -1073,7 +1070,7 @@ else if (html) {
i--;
}
builder.setLength(i + 1);
- builder.append("\n");
+ builder.append('\n');
}
}
if (!"script".equals(element.getTagName())) {
@@ -1096,13 +1093,14 @@ protected boolean isEndTagForbidden() {
* Returns the element ID.
* @return the ID of this element
*/
- @JsxGetter({CHROME, FF, EDGE})
+ @JsxGetter({CHROME, FF})
public String getId() {
return getDomNodeOrDie().getId();
}
/**
- * {@inheritDoc}
+ * Sets the id value for this element.
+ * @param newId the newId value for this element
*/
@JsxSetter({CHROME, FF})
public void setId(final String newId) {
@@ -1228,20 +1226,24 @@ protected void setStyle(final String style) {
* is just to prevent scripts that call that method from failing
*/
@JsxFunction({CHROME, FF})
- public void scrollIntoView() { /* do nothing at the moment */ }
+ public void scrollIntoView() {
+ /* do nothing at the moment */
+ }
/**
* Implement the {@code scrollIntoViewIfNeeded()} JavaScript function but don't actually do
* anything.
*/
@JsxFunction(CHROME)
- public void scrollIntoViewIfNeeded() { /* do nothing at the moment */ }
+ public void scrollIntoViewIfNeeded() {
+ /* do nothing at the moment */
+ }
/**
* {@inheritDoc}
*/
@Override
- @JsxGetter({CHROME, FF52, EDGE})
+ @JsxGetter({CHROME, FF})
public Object getPrefix() {
return super.getPrefix();
}
@@ -1250,7 +1252,7 @@ public Object getPrefix() {
* {@inheritDoc}
*/
@Override
- @JsxGetter({CHROME, FF52, EDGE})
+ @JsxGetter({CHROME, FF})
public Object getLocalName() {
return super.getLocalName();
}
@@ -1259,7 +1261,7 @@ public Object getLocalName() {
* {@inheritDoc}
*/
@Override
- @JsxGetter({CHROME, FF52, EDGE})
+ @JsxGetter({CHROME, FF})
public Object getNamespaceURI() {
return super.getNamespaceURI();
}
@@ -1448,7 +1450,6 @@ public void setOnwebkitfullscreenerror(final Object onwebkitfullscreenerror) {
* Returns the {@code onwheel} event handler for this element.
* @return the {@code onwheel} event handler for this element
*/
- @JsxGetter({CHROME, FF})
public Function getOnwheel() {
return getEventHandler("wheel");
}
@@ -1457,7 +1458,6 @@ public Function getOnwheel() {
* Sets the {@code onwheel} event handler for this element.
* @param onwheel the {@code onwheel} event handler for this element
*/
- @JsxSetter({CHROME, FF})
public void setOnwheel(final Object onwheel) {
setEventHandler("wheel", onwheel);
}
@@ -1952,11 +1952,30 @@ public void setOnpointerup(final Object onpointerup) {
* {@inheritDoc}
*/
@Override
- @JsxFunction({CHROME, FF, EDGE})
+ @JsxFunction({CHROME, FF})
public void remove() {
super.remove();
}
+ /**
+ * Mock for the moment.
+ * @param retargetToElement if true, all events are targeted directly to this element;
+ * if false, events can also fire at descendants of this element
+ */
+ @JsxFunction(FF)
+ public void setCapture(final boolean retargetToElement) {
+ // empty
+ }
+
+ /**
+ * Mock for the moment.
+ * @return true for success
+ */
+ @JsxFunction(FF)
+ public boolean releaseCapture() {
+ return true;
+ }
+
/**
* Inserts a set of Node or DOMString objects in the children list of this ChildNode's parent,
* just before this ChildNode.
@@ -2006,7 +2025,7 @@ public static void replaceWith(final Context context, final Scriptable thisObj,
* @param function the function
* @return the value
*/
- @JsxFunction({CHROME, FF, EDGE})
+ @JsxFunction({CHROME, FF})
public static boolean matches(
final Context context, final Scriptable thisObj, final Object[] args, final Function function) {
final String selectorString = (String) args[0];
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/External.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/External.java
index 5eb743df823..084b1eeda26 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/External.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/External.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,8 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_IS_SEARCH_PROVIDER_INSTALLED_ZERO;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -22,6 +23,8 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
+import net.sourceforge.htmlunit.corejs.javascript.Undefined;
+
/**
* A JavaScript object for {@code External}.
*
@@ -29,7 +32,7 @@
* @author Ronald Brill
* @author Ahmed Ashour
*/
-@JsxClass(FF)
+@JsxClass(CHROME)
@JsxClass(isJSObject = false)
public class External extends SimpleScriptable {
@@ -43,16 +46,16 @@ public External() {
/**
* Empty implementation.
*/
- @JsxFunction(IE)
- public void AutoCompleteSaveForm() {
+ @JsxFunction(value = IE, functionName = "AutoCompleteSaveForm")
+ public void autoCompleteSaveForm() {
// dummy
}
/**
* Empty implementation.
*/
- @JsxFunction
- public void AddSearchProvider() {
+ @JsxFunction(functionName = "AddSearchProvider")
+ public void addSearchProvider() {
// dummy
}
@@ -60,8 +63,11 @@ public void AddSearchProvider() {
* Empty implementation.
* @return 0
*/
- @JsxFunction
- public int IsSearchProviderInstalled() {
- return 0;
+ @JsxFunction(functionName = "IsSearchProviderInstalled")
+ public Object isSearchProviderInstalled() {
+ if (getBrowserVersion().hasFeature(JS_IS_SEARCH_PROVIDER_INSTALLED_ZERO)) {
+ return 0;
+ }
+ return Undefined.instance;
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/FontFace.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/FontFace.java
index d2a809ead09..b666e8d186c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/FontFace.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/FontFace.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/FontFaceSet.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/FontFaceSet.java
index 00b67edd02d..28862c81ebe 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/FontFaceSet.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/FontFaceSet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Gamepad.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Gamepad.java
index 3aaa10d9155..8f92e9d2369 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Gamepad.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Gamepad.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -27,7 +26,7 @@
*
* @author Ahmed Ashour
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class Gamepad extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/GamepadButton.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/GamepadButton.java
index 631231f62b9..e09063093d6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/GamepadButton.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/GamepadButton.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -27,7 +26,7 @@
*
* @author Ahmed Ashour
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class GamepadButton extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/History.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/History.java
index a665b3288bd..edc2941ec43 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/History.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/History.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
import java.io.IOException;
import java.net.MalformedURLException;
@@ -56,7 +54,7 @@ public class History extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public History() {
}
@@ -168,7 +166,7 @@ public void pushState(final Object object, final String title, final String url)
* Returns the {@code scrollRestoration} property.
* @return the {@code scrollRestoration} property
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter({CHROME, FF})
public String getScrollRestoration() {
return scrollRestoration_;
}
@@ -176,7 +174,7 @@ public String getScrollRestoration() {
/**
* @param scrollRestoration the new value
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter({CHROME, FF})
public void setScrollRestoration(final String scrollRestoration) {
if (SCROLL_RESTAURATION_AUTO.equals(scrollRestoration)) {
scrollRestoration_ = SCROLL_RESTAURATION_AUTO;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ImageBitmap.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ImageBitmap.java
index b03c493d2bd..2ea66d44b54 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ImageBitmap.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ImageBitmap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/InstallTrigger.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/InstallTrigger.java
index 0501df6287e..52a3b69d52f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/InstallTrigger.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/InstallTrigger.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Iterator.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Iterator.java
index a28980ceb77..1ccc9e8b156 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Iterator.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Iterator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,20 +14,14 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host;
-import java.util.function.Consumer;
-
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
-import net.sourceforge.htmlunit.corejs.javascript.BaseFunction;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.ES6Iterator;
import net.sourceforge.htmlunit.corejs.javascript.FunctionObject;
import net.sourceforge.htmlunit.corejs.javascript.NativeArray;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
-import net.sourceforge.htmlunit.corejs.javascript.SymbolKey;
-import net.sourceforge.htmlunit.corejs.javascript.SymbolScriptable;
import net.sourceforge.htmlunit.corejs.javascript.Undefined;
/**
@@ -58,9 +52,9 @@ public Iterator(final String className, final java.util.Iterator> iterator) {
public void setParentScope(final Scriptable scope) {
super.setParentScope(scope);
try {
- final FunctionObject functionObject = new FunctionObject("next", getClass().getDeclaredMethod("next"),
- scope);
- defineProperty("next", functionObject, ScriptableObject.DONTENUM);
+ final FunctionObject functionObject = new FunctionObject(ES6Iterator.NEXT_METHOD,
+ getClass().getDeclaredMethod(ES6Iterator.NEXT_METHOD), scope);
+ defineProperty(ES6Iterator.NEXT_METHOD, functionObject, ScriptableObject.DONTENUM);
}
catch (final Exception e) {
Context.throwAsScriptRuntimeEx(e);
@@ -98,89 +92,8 @@ public Object getDefaultValue(final Class> hint) {
value = Undefined.instance;
done = true;
}
- object.defineProperty("done", done, ScriptableObject.EMPTY);
- object.defineProperty("value", value, ScriptableObject.EMPTY);
+ object.defineProperty(ES6Iterator.VALUE_PROPERTY, value, ScriptableObject.EMPTY);
+ object.defineProperty(ES6Iterator.DONE_PROPERTY, done, ScriptableObject.EMPTY);
return object;
}
-
- /**
- * Helper to support objects implementing the iterator interface.
- *
- * @param context the Context
- * @param thisObj the this Object
- * @param scriptable the scriptable
- * @param processor the method to be called for every object
- * @return true if @@iterator property was available
- */
- public static boolean iterate(final Context context,
- final Scriptable thisObj,
- final Scriptable scriptable,
- final Consumer processor) {
-
- if (scriptable instanceof ES6Iterator) {
- ScriptableObject next = (ScriptableObject) ScriptableObject.callMethod(scriptable, "next", null);
- boolean done = (boolean) next.get(ES6Iterator.DONE_PROPERTY);
- Object value = next.get(ES6Iterator.VALUE_PROPERTY);
-
- while (!done) {
- processor.accept(value);
-
- next = (ScriptableObject) ScriptableObject.callMethod(scriptable, "next", null);
- done = (boolean) next.get(ES6Iterator.DONE_PROPERTY);
- value = next.get(ES6Iterator.VALUE_PROPERTY);
- }
- return true;
- }
-
- if (!(scriptable instanceof SymbolScriptable)) {
- return false;
- }
- final Object iterator = ((SymbolScriptable) scriptable).get(SymbolKey.ITERATOR, scriptable);
- if (iterator == Scriptable.NOT_FOUND) {
- return false;
- }
-
- final Object obj = ((BaseFunction) iterator).call(context, thisObj.getParentScope(), scriptable, new Object[0]);
-
- if (obj instanceof Iterator) {
- final Iterator it = (Iterator) obj;
- SimpleScriptable next = it.next();
- boolean done = (boolean) next.get(ES6Iterator.DONE_PROPERTY);
- Object value = next.get(ES6Iterator.VALUE_PROPERTY);
-
- while (!done) {
- processor.accept(value);
-
- next = it.next();
- done = (boolean) next.get(ES6Iterator.DONE_PROPERTY);
- value = next.get(ES6Iterator.VALUE_PROPERTY);
- }
- return true;
- }
- if (obj instanceof Scriptable) {
- // handle user defined iterator
- final Scriptable scriptableIterator = (Scriptable) obj;
- final Object nextFunct = scriptableIterator.get(ES6Iterator.NEXT_METHOD, (Scriptable) obj);
- if (!(nextFunct instanceof BaseFunction)) {
- throw ScriptRuntime.typeError("undefined is not a function");
- }
- final Object nextObj = ((BaseFunction) nextFunct)
- .call(context, thisObj.getParentScope(), scriptableIterator, new Object[0]);
-
- ScriptableObject next = (ScriptableObject) nextObj;
- boolean done = (boolean) next.get(ES6Iterator.DONE_PROPERTY);
- Object value = next.get(ES6Iterator.VALUE_PROPERTY);
-
- while (!done) {
- processor.accept(value);
-
- next = (ScriptableObject) ((BaseFunction) nextFunct)
- .call(context, thisObj.getParentScope(), scriptableIterator, new Object[0]);
- done = (boolean) next.get(ES6Iterator.DONE_PROPERTY);
- value = next.get(ES6Iterator.VALUE_PROPERTY);
- }
- return true;
- }
- return false;
- }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Location.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Location.java
index 1c078d839b0..fbe5a36f3bd 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Location.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Location.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,10 +20,9 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_LOCATION_HASH_IS_DECODED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_LOCATION_HASH_RETURNS_HASH_FOR_EMPTY_DEFINED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_LOCATION_HREF_HASH_IS_ENCODED;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_LOCATION_RELOAD_REFERRER;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.URL_ABOUT_BLANK_HAS_BLANK_PATH;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.URL_ABOUT_BLANK_HAS_EMPTY_PATH;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.io.IOException;
@@ -87,7 +86,7 @@ public class Location extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Location() {
}
@@ -137,12 +136,10 @@ public void reload(final boolean force) throws IOException {
final HtmlPage htmlPage = (HtmlPage) getWindow(getStartingScope()).getWebWindow().getEnclosedPage();
final WebRequest request = htmlPage.getWebResponse().getWebRequest();
- String referer = htmlPage.getUrl().toExternalForm();
- request.setAdditionalHeader(HttpHeader.REFERER, referer);
-
- referer = UrlUtils.getUrlWithNewQuery(htmlPage.getUrl(), null).toExternalForm();
- referer = StringUtils.stripEnd(referer, "/");
- request.setAdditionalHeader(HttpHeader.ORIGIN, referer);
+ if (getBrowserVersion().hasFeature(JS_LOCATION_RELOAD_REFERRER)) {
+ final String referer = htmlPage.getUrl().toExternalForm();
+ request.setAdditionalHeader(HttpHeader.REFERER, referer);
+ }
final WebWindow webWindow = window_.getWebWindow();
webWindow.getWebClient().download(webWindow, "", request, true, false, "JS location.reload");
@@ -243,7 +240,9 @@ public void setHref(final String newLocation) throws IOException {
webWindow.getWebClient().download(webWindow, "", request, true, false, "JS set location");
}
catch (final MalformedURLException e) {
- LOG.error("setHref('" + newLocation + "') got MalformedURLException", e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("setHref('" + newLocation + "') got MalformedURLException", e);
+ }
throw e;
}
}
@@ -432,9 +431,6 @@ public void setHost(final String host) throws Exception {
@JsxGetter
public String getPathname() {
if (WebClient.URL_ABOUT_BLANK == getUrl()) {
- if (getBrowserVersion().hasFeature(URL_ABOUT_BLANK_HAS_EMPTY_PATH)) {
- return "";
- }
if (getBrowserVersion().hasFeature(URL_ABOUT_BLANK_HAS_BLANK_PATH)) {
return "blank";
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Map.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Map.java
deleted file mode 100644
index b5539a3eb9a..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Map.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host;
-
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_MAP_CONSTRUCTOR_IGNORE_ARGUMENT;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-
-import java.util.LinkedHashMap;
-
-import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
-import com.gargoylesoftware.htmlunit.javascript.configuration.CanSetReadOnly;
-import com.gargoylesoftware.htmlunit.javascript.configuration.CanSetReadOnlyStatus;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
-
-import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.Delegator;
-import net.sourceforge.htmlunit.corejs.javascript.Function;
-import net.sourceforge.htmlunit.corejs.javascript.NativeArray;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
-import net.sourceforge.htmlunit.corejs.javascript.Symbol;
-import net.sourceforge.htmlunit.corejs.javascript.SymbolKey;
-import net.sourceforge.htmlunit.corejs.javascript.SymbolScriptable;
-import net.sourceforge.htmlunit.corejs.javascript.Undefined;
-
-/**
- * A JavaScript object for {@code Map}.
- *
- * @author Ahmed Ashour
- * @author Ronald Brill
- */
-@JsxClass
-public class Map extends SimpleScriptable implements SymbolScriptable {
-
- private static final String MAP_ITERATOR_NAME = "Map Iterator";
- private static Iterator ITERATOR_PROTOTYPE_;
- private java.util.Map map_ = new LinkedHashMap<>();
-
- /**
- * Creates an instance.
- */
- public Map() {
- }
-
- /**
- * Creates an instance.
- * @param arrayLike an Array or other iterable object
- */
- @JsxConstructor
- public Map(final Object arrayLike) {
- if (arrayLike == Undefined.instance) {
- return;
- }
-
- final Context context = Context.getCurrentContext();
- final Window window = (Window) ScriptRuntime.getTopCallScope(context);
- if (window.getBrowserVersion().hasFeature(JS_MAP_CONSTRUCTOR_IGNORE_ARGUMENT)) {
- return;
- }
-
- if (arrayLike instanceof NativeArray) {
- final NativeArray array = (NativeArray) arrayLike;
- for (int i = 0; i < array.getLength(); i++) {
- final Object entryObject = array.get(i);
- if (entryObject instanceof NativeArray) {
- final Object[] entry = toArray((NativeArray) entryObject);
- if (entry.length > 0) {
- final Object key = entry[0];
- final Object value = entry.length > 1 ? entry[1] : null;
- set(key, value);
- }
- }
- else {
- throw Context.reportRuntimeError("TypeError: object is not iterable ("
- + entryObject.getClass().getName() + ")");
- }
- }
- return;
- }
-
- if (arrayLike instanceof Map) {
- final Map map = (Map) arrayLike;
- map_.putAll(map.map_);
- return;
- }
-
- if (arrayLike instanceof Scriptable) {
- final Scriptable scriptable = (Scriptable) arrayLike;
- if (Iterator.iterate(Context.getCurrentContext(), this, scriptable,
- value -> {
- if (Undefined.instance != value && value instanceof NativeArray) {
- final Object[] entry = toArray((NativeArray) value);
- if (entry.length > 0) {
- final Object key = entry[0];
- if (Undefined.instance != key) {
- final Object entryValue = entry.length > 1 ? entry[1] : null;
- set(key, entryValue);
- }
- }
- }
- else {
- throw Context.reportRuntimeError("TypeError: object is not iterable ("
- + value.getClass().getName() + ")");
- }
- })) {
- return;
- }
- }
-
- throw Context.reportRuntimeError("TypeError: object is not iterable (" + arrayLike.getClass().getName() + ")");
- }
-
- /**
- * Replacement of {@link NativeArray#toArray()}.
- */
- private static Object[] toArray(final NativeArray narray) {
- final long longLen = narray.getLength();
- if (longLen > Integer.MAX_VALUE) {
- throw new IllegalStateException();
- }
-
- final int len = (int) longLen;
- final Object[] arr = new Object[len];
- for (int i = 0; i < len; i++) {
- arr[i] = ScriptableObject.getProperty(narray, i);
- }
- return arr;
- }
-
- /**
- * Returns the size.
- * @return the size
- */
- @JsxGetter
- @CanSetReadOnly(CanSetReadOnlyStatus.IGNORE)
- public int getSize() {
- return map_.size();
- }
-
- /**
- * Returns the value of the given key.
- * @param key the key
- * @return the value
- */
- @Override
- @JsxFunction
- public Object get(final Object key) {
- Object o = map_.get(key);
- if (o == null) {
- o = Undefined.instance;
- }
- return o;
- }
-
- /**
- * Adds the specified pair.
- * @param key the key
- * @param value the value
- * @return the Map object.
- */
- @JsxFunction
- public Map set(Object key, final Object value) {
- if (key instanceof Delegator) {
- key = ((Delegator) key).getDelegee();
- }
- if (key == NOT_FOUND) {
- key = Undefined.instance;
- }
- map_.put(key, value);
- return this;
- }
-
- /**
- * Removes all elements.
- */
- @JsxFunction
- public void clear() {
- map_.clear();
- }
-
- /**
- * Removed the specified element.
- * @param key the key
- * @return whether the element has been successfully removed
- */
- @JsxFunction
- public boolean delete(final Object key) {
- return map_.remove(key) != null;
- }
-
- /**
- * Returns whether an element with the specified key exists or not.
- * @param key the key
- * @return whether the element exists or not
- */
- @JsxFunction
- public boolean has(final Object key) {
- return map_.remove(key) != null;
- }
-
- /**
- * Returns a new {@code Iterator} object that contains the {@code [key, value]} pairs for each element in the
- * Map object in insertion order.
- * @return a new {@code Iterator} object
- */
- @JsxFunction({CHROME, FF, EDGE})
- public Object entries() {
- final SimpleScriptable object = new Iterator(MAP_ITERATOR_NAME, map_.entrySet().iterator());
- object.setParentScope(getParentScope());
- setIteratorPrototype(object);
- return object;
- }
-
- /**
- * Returns a new {@code Iterator} object that contains the keys for each element in the Map object
- * in insertion order.
- * @return a new {@code Iterator} object
- */
- @JsxFunction({CHROME, FF, EDGE})
- public Object keys() {
- final SimpleScriptable object = new Iterator(MAP_ITERATOR_NAME, map_.keySet().iterator());
- object.setParentScope(getParentScope());
- setIteratorPrototype(object);
- return object;
- }
-
- /**
- * Returns a new {@code Iterator} object that contains the values for each element in the Map object
- * in insertion order.
- * @return a new {@code Iterator} object
- */
- @JsxFunction({CHROME, FF, EDGE})
- public Object values() {
- final SimpleScriptable object = new Iterator(MAP_ITERATOR_NAME, map_.values().iterator());
- object.setParentScope(getParentScope());
- setIteratorPrototype(object);
- return object;
- }
-
- private static void setIteratorPrototype(final Scriptable scriptable) {
- if (ITERATOR_PROTOTYPE_ == null) {
- ITERATOR_PROTOTYPE_ = new Iterator(MAP_ITERATOR_NAME, null);
- }
- scriptable.setPrototype(ITERATOR_PROTOTYPE_);
- }
-
- /**
- * Executes a provided function once per each value in the {@link Map} object, in insertion order.
- * @param callback {@link Function} to execute for each element.
- * @param thisArg Value to use as this when executing callback (optional)
- */
- @JsxFunction
- public void forEach(final Function callback, final Object thisArg) {
- if (getBrowserVersion().hasFeature(JS_MAP_CONSTRUCTOR_IGNORE_ARGUMENT)) {
- return;
- }
-
- final Scriptable thisArgument;
- if (thisArg instanceof Scriptable) {
- thisArgument = (Scriptable) thisArg;
- }
- else {
- thisArgument = getWindow();
- }
-
- for (final java.util.Map.Entry entry : map_.entrySet()) {
- callback.call(Context.getCurrentContext(), getParentScope(), thisArgument,
- new Object[] {entry.getValue(), entry.getKey(), this});
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Object get(final Symbol key, final Scriptable start) {
- if (SymbolKey.ITERATOR.equals(key)) {
- return ScriptableObject.getProperty(start, "entries");
- }
- return super.get(key, start);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean has(final Symbol key, final Scriptable start) {
- if (SymbolKey.ITERATOR.equals(key)) {
- return true;
- }
- return super.has(key, start);
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MessageChannel.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MessageChannel.java
index 6dd14dffb6d..4e53c9ca409 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MessageChannel.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MessageChannel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MessagePort.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MessagePort.java
index 77b95993465..4e1c02bffcf 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MessagePort.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MessagePort.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.net.URL;
@@ -31,10 +30,7 @@
import com.gargoylesoftware.htmlunit.javascript.host.event.EventTarget;
import com.gargoylesoftware.htmlunit.javascript.host.event.MessageEvent;
-import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
import net.sourceforge.htmlunit.corejs.javascript.ContextFactory;
-import net.sourceforge.htmlunit.corejs.javascript.Function;
/**
* A JavaScript object for {@code MessagePort}.
@@ -49,7 +45,7 @@ public class MessagePort extends EventTarget {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public MessagePort() {
}
@@ -84,10 +80,7 @@ private Object getHandlerForJavaScript(final String eventName) {
}
private void setHandlerForJavaScript(final String eventName, final Object handler) {
- if (handler == null || handler instanceof Function) {
- getEventListenersContainer().setEventHandler(eventName, handler);
- }
- // Otherwise, fail silently.
+ getEventListenersContainer().setEventHandler(eventName, handler);
}
/**
@@ -112,15 +105,8 @@ public void postMessage(final String message, final Object transfer) {
final PostponedAction action = new PostponedAction(w.getWebWindow().getEnclosedPage()) {
@Override
public void execute() throws Exception {
- final ContextAction contextAction = new ContextAction() {
- @Override
- public Object run(final Context cx) {
- return port1_.dispatchEvent(event);
- }
- };
-
final ContextFactory cf = jsEngine.getContextFactory();
- cf.call(contextAction);
+ cf.call(cx -> port1_.dispatchEvent(event));
}
};
jsEngine.addPostponedAction(action);
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MimeType.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MimeType.java
index 8450f6f9e42..cb717446bf3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MimeType.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MimeType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -42,7 +41,7 @@ public class MimeType extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public MimeType() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MimeTypeArray.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MimeTypeArray.java
index 154b50b02c0..1a5b0724510 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MimeTypeArray.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/MimeTypeArray.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -35,7 +34,7 @@ public class MimeTypeArray extends SimpleArray {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public MimeTypeArray() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Namespace.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Namespace.java
index 746f649bbc9..c0c2142fe56 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Namespace.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Namespace.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NamespaceCollection.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NamespaceCollection.java
index a4cae66f32b..e53739cacc4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NamespaceCollection.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NamespaceCollection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NativeFunctionPrefixResolver.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NativeFunctionPrefixResolver.java
index 1acc109b733..50bc4460937 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NativeFunctionPrefixResolver.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NativeFunctionPrefixResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Navigator.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Navigator.java
index 6576e9d3b5f..505848bd0bf 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Navigator.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Navigator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_NAVIGATOR_DO_NOT_TRACK_UNSPECIFIED;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -51,7 +50,7 @@ public class Navigator extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Navigator() {
}
@@ -159,7 +158,7 @@ public String getProduct() {
* @see Mozilla Doc
* @return false
*/
- @JsxGetter({CHROME, FF, EDGE})
+ @JsxGetter({CHROME, FF})
public String getProductSub() {
return getBrowserVersion().getProductSub();
}
@@ -293,7 +292,7 @@ public String getVendor() {
* Returns the {@code vendorSub} property.
* @return the {@code vendorSub} property
*/
- @JsxGetter({CHROME, FF, EDGE})
+ @JsxGetter({CHROME, FF})
public String getVendorSub() {
return "";
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Netscape.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Netscape.java
index 7f79e29081f..c8fa687af90 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Netscape.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Netscape.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Notification.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Notification.java
index 25f6bdd6f19..28b0af6d777 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Notification.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Notification.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NumberCustom.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NumberCustom.java
index bbadd4952ce..1c651928b46 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NumberCustom.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/NumberCustom.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,8 @@
*/
public final class NumberCustom {
- private NumberCustom() { }
+ private NumberCustom() {
+ }
/**
* Returns a string with a language sensitive representation of this number.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PerformanceObserver.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PerformanceObserver.java
index 4600ccbb35c..6d933efd4e7 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PerformanceObserver.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PerformanceObserver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -25,7 +26,7 @@
*
* @author Ronald Brill
*/
-@JsxClass(CHROME)
+@JsxClass({CHROME, FF})
public class PerformanceObserver extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PerformanceObserverEntryList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PerformanceObserverEntryList.java
index eca8e6ec6de..276a681ce8d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PerformanceObserverEntryList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PerformanceObserverEntryList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -25,7 +26,7 @@
*
* @author Ronald Brill
*/
-@JsxClass(CHROME)
+@JsxClass({CHROME, FF})
public class PerformanceObserverEntryList extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PermissionStatus.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PermissionStatus.java
index 4eea22aaf58..9bc17755745 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PermissionStatus.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PermissionStatus.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -25,8 +25,9 @@
* A JavaScript object for {@code PermissionStatus}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, FF52})
+@JsxClass({CHROME, FF})
public class PermissionStatus extends EventTarget {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Permissions.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Permissions.java
index 58340450ae5..a6f1ddd6bd6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Permissions.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Permissions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -25,8 +25,9 @@
* A JavaScript object for {@code Permissions}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, FF52})
+@JsxClass({CHROME, FF})
public class Permissions extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Plugin.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Plugin.java
index 00d22689189..24308bce858 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Plugin.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Plugin.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -41,7 +40,7 @@ public class Plugin extends SimpleArray {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Plugin() {
}
@@ -100,7 +99,7 @@ public String getName() {
* Gets the plugin's version.
* @return the name
*/
- @JsxGetter({IE, FF, EDGE})
+ @JsxGetter({IE, FF})
public String getVersion() {
return version_;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PluginArray.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PluginArray.java
index ede52f38d22..755421de8af 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PluginArray.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PluginArray.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -36,7 +35,7 @@ public class PluginArray extends SimpleArray {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public PluginArray() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Promise.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Promise.java
index 470fcb8d457..2cc7afb62d1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Promise.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Promise.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
import static com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.KEY_STARTING_SCOPE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.util.ArrayDeque;
@@ -24,6 +23,9 @@
import java.util.Deque;
import java.util.List;
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory;
+import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.background.BasicJavaScriptJob;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -33,7 +35,9 @@
import net.sourceforge.htmlunit.corejs.javascript.BaseFunction;
import net.sourceforge.htmlunit.corejs.javascript.Context;
+import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
import net.sourceforge.htmlunit.corejs.javascript.Function;
+import net.sourceforge.htmlunit.corejs.javascript.IteratorLikeIterable;
import net.sourceforge.htmlunit.corejs.javascript.JavaScriptException;
import net.sourceforge.htmlunit.corejs.javascript.NativeArray;
import net.sourceforge.htmlunit.corejs.javascript.NativeObject;
@@ -50,7 +54,7 @@
* @author Marc Guillemot
* @author Ronald Brill
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class Promise extends SimpleScriptable {
private enum PromiseState { PENDING, FULFILLED, REJECTED }
@@ -86,7 +90,8 @@ public Promise(final Window window) {
@JsxConstructor
public Promise(final Object object) {
if (!(object instanceof Function)) {
- throw ScriptRuntime.typeError("Promise resolver is not a function");
+ throw ScriptRuntime.typeError("Promise resolver '"
+ + ScriptRuntime.toString(object) + "' is not a function");
}
final Function fun = (Function) object;
@@ -178,7 +183,15 @@ private static Promise create(final Scriptable thisObj, final Object[] args, fin
final Object arg = args[0];
if (arg instanceof NativeObject) {
final NativeObject nativeObject = (NativeObject) arg;
- promise = new Promise(nativeObject.get("then", nativeObject));
+ final Object thenFunction = nativeObject.get("then", nativeObject);
+ if (thenFunction != NOT_FOUND) {
+ promise = new Promise(thenFunction);
+ }
+ else {
+ promise = new Promise();
+ promise.value_ = arg;
+ promise.state_ = state;
+ }
}
else {
promise = new Promise();
@@ -279,7 +292,7 @@ else if (promise.state_ == PromiseState.PENDING) {
@JsxStaticFunction
public static Promise all(final Context context, final Scriptable thisObj, final Object[] args,
final Function function) {
- return all(false, thisObj, args);
+ return all(false, context, thisObj, args);
}
/**
@@ -295,37 +308,43 @@ public static Promise all(final Context context, final Scriptable thisObj, final
@JsxStaticFunction
public static Promise race(final Context context, final Scriptable thisObj, final Object[] args,
final Function function) {
- return all(true, thisObj, args);
+ return all(true, context, thisObj, args);
}
- private static Promise all(final boolean race, final Scriptable thisObj, final Object[] args) {
+ private static Promise all(final boolean race,
+ final Context context, final Scriptable thisObj, final Object[] args) {
final Window window = getWindow(thisObj);
final Promise returnPromise = new Promise(window);
if (args.length == 0) {
returnPromise.all_ = new Promise[0];
}
- else if (args[0] instanceof NativeArray) {
- final NativeArray array = (NativeArray) args[0];
- final int length = (int) array.getLength();
- returnPromise.all_ = new Promise[length];
- for (int i = 0; i < length; i++) {
- final Object o = array.get(i);
- if (o instanceof Promise) {
- returnPromise.all_[i] = (Promise) o;
- if (returnPromise.all_[i].dependentPromises_ == null) {
- returnPromise.all_[i].dependentPromises_ = new ArrayList(2);
+ else {
+ // Call the "[Symbol.iterator]" property as a function.
+ final Object ito = ScriptRuntime.callIterator(args[0], context, window);
+ final ArrayList promises = new ArrayList<>();
+ if (!Undefined.isUndefined(ito)) {
+ // run through all the iterated values and add them!
+ try (IteratorLikeIterable it = new IteratorLikeIterable(context, window, ito)) {
+ for (Object val : it) {
+ if (val instanceof Promise) {
+ final Promise promis = (Promise) val;
+ promises.add(promis);
+ if (promis.dependentPromises_ == null) {
+ promis.dependentPromises_ = new ArrayList(2);
+ }
+ promis.dependentPromises_.add(returnPromise);
+ }
+ else {
+ promises.add(create(thisObj, new Object[] {val}, PromiseState.FULFILLED));
+ }
}
- returnPromise.all_[i].dependentPromises_.add(returnPromise);
- }
- else {
- returnPromise.all_[i] = create(thisObj, new Object[] {o}, PromiseState.FULFILLED);
}
+
+ returnPromise.all_ = promises.toArray(new Promise[promises.size()]);
}
}
- else {
- // TODO
- }
+
returnPromise.race_ = race;
returnPromise.settleAll(window);
@@ -350,68 +369,79 @@ public Promise then(final Object onFulfilled, final Object onRejected) {
@Override
public void run() {
- final Context cx = Context.enter();
- try {
- Function toExecute = null;
- if (thisPromise.state_ == PromiseState.FULFILLED && onFulfilled instanceof Function) {
- toExecute = (Function) onFulfilled;
- }
- else if (thisPromise.state_ == PromiseState.REJECTED && onRejected instanceof Function) {
- toExecute = (Function) onRejected;
- }
-
- try {
- final Object callbackResult;
- if (toExecute == null) {
- final Promise dummy = new Promise();
- dummy.state_ = thisPromise.state_;
- dummy.value_ = thisPromise.value_;
- callbackResult = dummy;
+ final WebClient client = window.getWebWindow().getWebClient();
+ final HtmlUnitContextFactory cf = ((JavaScriptEngine) client
+ .getJavaScriptEngine()).getContextFactory();
+
+ final ContextAction contextAction = new ContextAction() {
+ @Override
+ public Object run(final Context cx) {
+ Function toExecute = null;
+ if (thisPromise.state_ == PromiseState.FULFILLED && onFulfilled instanceof Function) {
+ toExecute = (Function) onFulfilled;
}
- else {
- // KEY_STARTING_SCOPE maintains a stack of scopes
- @SuppressWarnings("unchecked")
- Deque stack = (Deque) cx.getThreadLocal(KEY_STARTING_SCOPE);
- if (null == stack) {
- stack = new ArrayDeque<>();
- cx.putThreadLocal(KEY_STARTING_SCOPE, stack);
- }
- stack.push(window);
- try {
- callbackResult = toExecute.call(cx, window, thisPromise, new Object[] {value_});
- }
- finally {
- stack.pop();
+ else if (thisPromise.state_ == PromiseState.REJECTED && onRejected instanceof Function) {
+ toExecute = (Function) onRejected;
+ }
+
+ try {
+ final Object callbackResult;
+ if (toExecute == null) {
+ final Promise dummy = new Promise();
+ dummy.state_ = thisPromise.state_;
+ dummy.value_ = thisPromise.value_;
+ callbackResult = dummy;
}
+ else {
+ // KEY_STARTING_SCOPE maintains a stack of scopes
+ @SuppressWarnings("unchecked")
+ Deque stack = (Deque) cx.getThreadLocal(KEY_STARTING_SCOPE);
+ if (null == stack) {
+ stack = new ArrayDeque<>();
+ cx.putThreadLocal(KEY_STARTING_SCOPE, stack);
+ }
+ stack.push(window);
+ try {
+ if (ScriptRuntime.hasTopCall(cx)) {
+ callbackResult = toExecute.call(cx, window, thisPromise, new Object[] {value_});
+ }
+ else {
+ callbackResult = ScriptRuntime.doTopCall(toExecute, cx, window, thisPromise,
+ new Object[] {value_}, cx.isStrictMode());
+ }
+ }
+ finally {
+ stack.pop();
+ }
- window.getWebWindow().getWebClient().getJavaScriptEngine().processPostponedActions();
- }
- if (callbackResult instanceof Promise) {
- final Promise resultPromise = (Promise) callbackResult;
- if (resultPromise.state_ == PromiseState.FULFILLED) {
- returnPromise.settle(true, resultPromise.value_, window);
+ window.getWebWindow().getWebClient().getJavaScriptEngine().processPostponedActions();
}
- else if (resultPromise.state_ == PromiseState.REJECTED) {
- returnPromise.settle(false, resultPromise.value_, window);
+ if (callbackResult instanceof Promise) {
+ final Promise resultPromise = (Promise) callbackResult;
+ if (resultPromise.state_ == PromiseState.FULFILLED) {
+ returnPromise.settle(true, resultPromise.value_, window);
+ }
+ else if (resultPromise.state_ == PromiseState.REJECTED) {
+ returnPromise.settle(false, resultPromise.value_, window);
+ }
+ else {
+ if (resultPromise.dependentPromises_ == null) {
+ resultPromise.dependentPromises_ = new ArrayList(2);
+ }
+ resultPromise.dependentPromises_.add(returnPromise);
+ }
}
else {
- if (resultPromise.dependentPromises_ == null) {
- resultPromise.dependentPromises_ = new ArrayList(2);
- }
- resultPromise.dependentPromises_.add(returnPromise);
+ returnPromise.settle(true, callbackResult, window);
}
}
- else {
- returnPromise.settle(true, callbackResult, window);
+ catch (final JavaScriptException e) {
+ returnPromise.settle(false, e.getValue(), window);
}
+ return null;
}
- catch (final JavaScriptException e) {
- returnPromise.settle(false, e.getValue(), window);
- }
- }
- finally {
- Context.exit();
- }
+ };
+ cf.call(contextAction);
}
/** {@inheritDoc} */
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushManager.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushManager.java
index a9d39347769..1c052064502 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushManager.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushSubscription.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushSubscription.java
index 7da0b20bd50..9ab0f549d61 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushSubscription.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushSubscription.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushSubscriptionOptions.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushSubscriptionOptions.java
index 69b9c192a09..33d0a0f03e5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushSubscriptionOptions.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/PushSubscriptionOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ReadableStream.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ReadableStream.java
index e18a07c9af1..efc873bfb59 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ReadableStream.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ReadableStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF68;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -24,8 +25,9 @@
* A JavaScript object for {@code ReadableStream}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(CHROME)
+@JsxClass({CHROME, FF68})
public class ReadableStream extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Reflect.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Reflect.java
index 74a3fd593f1..f245335710a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Reflect.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Reflect.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@
* @author Ahmed Ashour
* @author Ronald Brill
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class Reflect extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Screen.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Screen.java
index 9a8885cab25..3c92b0acb91 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Screen.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Screen.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -44,7 +43,7 @@ public class Screen extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Screen() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ScreenOrientation.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ScreenOrientation.java
index 0cb6f6e3065..678e5c59313 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ScreenOrientation.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/ScreenOrientation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Set.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Set.java
deleted file mode 100644
index 407c8a19d3a..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Set.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host;
-
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_SET_CONSTRUCTOR_IGNORE_ARGUMENT;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-
-import java.util.LinkedHashSet;
-
-import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.ArrayBufferViewBase;
-
-import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.Delegator;
-import net.sourceforge.htmlunit.corejs.javascript.Function;
-import net.sourceforge.htmlunit.corejs.javascript.NativeArray;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
-import net.sourceforge.htmlunit.corejs.javascript.Symbol;
-import net.sourceforge.htmlunit.corejs.javascript.SymbolKey;
-import net.sourceforge.htmlunit.corejs.javascript.SymbolScriptable;
-import net.sourceforge.htmlunit.corejs.javascript.Undefined;
-
-/**
- * A JavaScript object for {@code Set}.
- *
- * @author Ahmed Ashour
- * @author Ronald Brill
- */
-@JsxClass
-public class Set extends SimpleScriptable implements SymbolScriptable {
-
- private static final String SET_ITERATOR_NAME = "Set Iterator";
- private static Iterator ITERATOR_PROTOTYPE_;
- private java.util.Set set_ = new LinkedHashSet<>();
-
- /**
- * Creates an instance.
- */
- public Set() {
- }
-
- /**
- * Creates an instance.
- * @param iterable an Array or other iterable object
- */
- @JsxConstructor
- public Set(final Object iterable) {
- if (iterable == Undefined.instance) {
- return;
- }
-
- final Window window = (Window) ScriptRuntime.getTopCallScope(Context.getCurrentContext());
- if (window.getBrowserVersion().hasFeature(JS_SET_CONSTRUCTOR_IGNORE_ARGUMENT)) {
- return;
- }
-
- if (iterable instanceof NativeArray) {
- final NativeArray array = (NativeArray) iterable;
- for (int i = 0; i < array.getLength(); i++) {
- add(ScriptableObject.getProperty(array, i));
- }
- return;
- }
-
- if (iterable instanceof ArrayBufferViewBase) {
- final ArrayBufferViewBase array = (ArrayBufferViewBase) iterable;
- for (int i = 0; i < array.getLength(); i++) {
- add(ScriptableObject.getProperty(array, i));
- }
- return;
- }
-
- if (iterable instanceof String) {
- final String string = (String) iterable;
- for (int i = 0; i < string.length(); i++) {
- add(String.valueOf(string.charAt(i)));
- }
- return;
- }
-
- if (iterable instanceof Set) {
- final Set set = (Set) iterable;
- for (Object object : set.set_) {
- add(object);
- }
- return;
- }
-
- if (iterable instanceof Map) {
- final Iterator iterator = (Iterator) ((Map) iterable).entries();
-
- SimpleScriptable object = iterator.next();
- while (Undefined.instance != object.get("value", null)) {
- add(object);
- object = iterator.next();
- }
- return;
- }
-
- if (iterable instanceof Scriptable) {
- final Scriptable scriptable = (Scriptable) iterable;
- if (Iterator.iterate(Context.getCurrentContext(), this, scriptable,
- value -> {
- if (value != Undefined.instance) {
- add(value);
- }
- })) {
- return;
- }
- }
-
- throw Context.reportRuntimeError("TypeError: object is not iterable (" + iterable.getClass().getName() + ")");
- }
-
- /**
- * Returns the size.
- * @return the size
- */
- @JsxGetter
- public int getSize() {
- return set_.size();
- }
-
- /**
- * Adds the specified value.
- * @param value the value
- * @return the Set object.
- */
- @JsxFunction
- public Set add(Object value) {
- if (value instanceof Delegator) {
- value = ((Delegator) value).getDelegee();
- }
- if (value == NOT_FOUND) {
- value = Undefined.instance;
- }
- set_.add(value);
- return this;
- }
-
- /**
- * Removes all elements.
- */
- @JsxFunction
- public void clear() {
- set_.clear();
- }
-
- /**
- * Removed the specified element.
- * @param key the key
- * @return whether the element has been successfully removed
- */
- @JsxFunction
- public boolean delete(final Object key) {
- return set_.remove(key);
- }
-
- /**
- * Returns whether the specified element exists or not.
- * @param value the value
- * @return whether the element exists or not
- */
- @JsxFunction
- public boolean has(final Object value) {
- return set_.contains(value);
- }
-
- /**
- * Returns a new {@code Iterator} object that contains the values for each element in the Set object
- * in insertion order.
- * @return a new {@code Iterator} object
- */
- @JsxFunction({CHROME, FF, EDGE})
- public Object values() {
- final SimpleScriptable object = new Iterator(SET_ITERATOR_NAME, set_.iterator());
- object.setParentScope(getParentScope());
- setIteratorPrototype(object);
- return object;
- }
-
- private static void setIteratorPrototype(final Scriptable scriptable) {
- if (ITERATOR_PROTOTYPE_ == null) {
- ITERATOR_PROTOTYPE_ = new Iterator(SET_ITERATOR_NAME, null);
- }
- scriptable.setPrototype(ITERATOR_PROTOTYPE_);
- }
-
- /**
- * Executes a provided function once per each value in the {@link Set} object, in insertion order.
- * @param callback {@link Function} to execute for each element.
- * @param thisArg Value to use as this when executing callback (optional)
- */
- @JsxFunction
- public void forEach(final Function callback, final Object thisArg) {
- if (getBrowserVersion().hasFeature(JS_SET_CONSTRUCTOR_IGNORE_ARGUMENT)) {
- return;
- }
-
- final Scriptable thisArgument;
- if (thisArg instanceof Scriptable) {
- thisArgument = (Scriptable) thisArg;
- }
- else {
- thisArgument = getWindow();
- }
- for (final Object object : set_) {
- callback.call(Context.getCurrentContext(), getParentScope(), thisArgument,
- new Object[] {object, object, this});
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Object get(final Symbol key, final Scriptable start) {
- if (SymbolKey.ITERATOR.equals(key)) {
- return ScriptableObject.getProperty(start, "values");
- }
- return super.get(key, start);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean has(final Symbol key, final Scriptable start) {
- if (SymbolKey.ITERATOR.equals(key)) {
- return true;
- }
- return super.has(key, start);
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/SharedWorker.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/SharedWorker.java
index 91d6a4710bb..eea75bb520a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/SharedWorker.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/SharedWorker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/SimpleArray.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/SimpleArray.java
index ae0caa1730c..d23b11e3a9b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/SimpleArray.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/SimpleArray.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Storage.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Storage.java
index 5c6c8efbfba..4a9b6b234e5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Storage.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Storage.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_STORAGE_GET_FROM_ITEMS;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_STORAGE_PRESERVED_INCLUDED;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.util.Arrays;
@@ -51,7 +50,7 @@ public class Storage extends SimpleScriptable {
/**
* Public default constructor only for the prototype.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Storage() {
store_ = null;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/StorageManager.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/StorageManager.java
index 748af3502b0..036113c7604 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/StorageManager.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/StorageManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -24,8 +25,9 @@
* A JavaScript object for {@code StorageManager}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(CHROME)
+@JsxClass({CHROME, FF})
public class StorageManager extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/StringCustom.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/StringCustom.java
index 35d986587a8..d9b2a304cea 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/StringCustom.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/StringCustom.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,10 +14,6 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host;
-import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.Function;
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
/**
* Contains some missing features of Rhino NativeString.
*
@@ -26,30 +22,6 @@
*/
public final class StringCustom {
- private StringCustom() { }
-
- /**
- * Determines whether one string may be found within another string,
- * returning true or false as appropriate.
- * @param context the JavaScript context
- * @param thisObj the scriptable
- * @param args the arguments passed into the method
- * @param function the function
- * @return true or false
- */
- public static boolean contains(
- final Context context, final Scriptable thisObj, final Object[] args, final Function function) {
- if (args.length < 1) {
- return false;
- }
- final String string = Context.toString(thisObj);
- final String search = Context.toString(args[0]);
-
- if (args.length < 2) {
- return string.contains(search);
- }
-
- final int start = (int) Math.max(0, Context.toNumber(args[1]));
- return string.indexOf(search, start) > -1;
+ private StringCustom() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TextDecoder.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TextDecoder.java
index 877dbd3974e..27f3b5c4c8f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TextDecoder.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TextDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,12 +26,12 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.ArrayBuffer;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.ArrayBufferView;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
import net.sourceforge.htmlunit.corejs.javascript.Undefined;
+import net.sourceforge.htmlunit.corejs.javascript.typedarrays.NativeArrayBuffer;
+import net.sourceforge.htmlunit.corejs.javascript.typedarrays.NativeArrayBufferView;
/**
* A JavaScript object for {@code TextDecoder}.
@@ -353,7 +353,7 @@ public TextDecoder() {
*/
@JsxConstructor
public TextDecoder(final Object encoding) {
- if (Undefined.instance == encoding) {
+ if (Undefined.isUndefined(encoding)) {
return;
}
@@ -384,20 +384,20 @@ public String getEncoding() {
*/
@JsxFunction
public String decode(final Object buffer) {
- if (Undefined.instance == buffer) {
+ if (Undefined.isUndefined(buffer)) {
return "";
}
- ArrayBuffer arrayBuffer = null;
- if (buffer instanceof ArrayBuffer) {
- arrayBuffer = (ArrayBuffer) buffer;
+ NativeArrayBuffer arrayBuffer = null;
+ if (buffer instanceof NativeArrayBuffer) {
+ arrayBuffer = (NativeArrayBuffer) buffer;
}
- else if (buffer instanceof ArrayBufferView) {
- arrayBuffer = ((ArrayBufferView) buffer).getBuffer();
+ else if (buffer instanceof NativeArrayBufferView) {
+ arrayBuffer = ((NativeArrayBufferView) buffer).getBuffer();
}
if (arrayBuffer != null) {
- return new String(arrayBuffer.getBytes(), Charset.forName(encoding_));
+ return new String(arrayBuffer.getBuffer(), Charset.forName(encoding_));
}
throw ScriptRuntime.typeError("Argument 1 of TextDecoder.decode could not be"
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TextEncoder.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TextEncoder.java
index 21b6347e5a1..a2c50c4a78b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TextEncoder.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TextEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,10 +24,12 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.Uint8Array;
import net.sourceforge.htmlunit.corejs.javascript.Context;
+import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
import net.sourceforge.htmlunit.corejs.javascript.Undefined;
+import net.sourceforge.htmlunit.corejs.javascript.typedarrays.NativeArrayBuffer;
+import net.sourceforge.htmlunit.corejs.javascript.typedarrays.NativeUint8Array;
/**
* A JavaScript object for {@code TextEncoder}.
@@ -58,9 +60,12 @@ public String getEncoding() {
* @return returns a Uint8Array containing the text given encoded .
*/
@JsxFunction
- public Uint8Array encode(final Object toEncode) {
- if (Undefined.instance == toEncode) {
- return new Uint8Array(new byte[0], getWindow());
+ public NativeUint8Array encode(final Object toEncode) {
+ if (Undefined.isUndefined(toEncode)) {
+ final NativeUint8Array result = new NativeUint8Array(0);
+ result.setParentScope(getParentScope());
+ result.setPrototype(ScriptableObject.getClassPrototype(getWindow(this), result.getClassName()));
+ return result;
}
final String txt;
@@ -72,6 +77,13 @@ public Uint8Array encode(final Object toEncode) {
}
final byte[] bytes = txt.getBytes(StandardCharsets.UTF_8);
- return new Uint8Array(bytes, getWindow());
+
+ final NativeArrayBuffer arrayBuffer = new NativeArrayBuffer(bytes.length);
+ System.arraycopy(bytes, 0, arrayBuffer.getBuffer(), 0, bytes.length);
+
+ final NativeUint8Array result = new NativeUint8Array(arrayBuffer, 0, bytes.length);
+ result.setParentScope(getParentScope());
+ result.setPrototype(ScriptableObject.getClassPrototype(getWindow(this), result.getClassName()));
+ return result;
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Touch.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Touch.java
index 94ae5299981..e7f199e02ce 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Touch.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Touch.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TouchList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TouchList.java
index ae70d8335e2..76366ebd588 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TouchList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/TouchList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/URL.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/URL.java
index 3c4cf227ca1..449705b6a7b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/URL.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/URL.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.net.MalformedURLException;
@@ -59,10 +58,10 @@ public URL() {
* @param base a string representing the base URL to use in case url
* is a relative URL. If not specified, it defaults to ''.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public URL(final String url, final Object base) {
String baseStr = null;
- if (Undefined.instance != base) {
+ if (!Undefined.isUndefined(base)) {
baseStr = Context.toString(base);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/URLSearchParams.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/URLSearchParams.java
index f1db9040dd3..dec12717138 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/URLSearchParams.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/URLSearchParams.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@
@JsxClass({CHROME, FF})
public class URLSearchParams extends SimpleScriptable {
- private static final String ITERATOR_NAME = "URLSearchParamsIterator";
+ private static final String ITERATOR_NAME = "URLSearchParams Iterator";
private static com.gargoylesoftware.htmlunit.javascript.host.Iterator ITERATOR_PROTOTYPE_;
private final List> params_ = new LinkedList<>();
@@ -71,7 +71,7 @@ public URLSearchParams(final Object params) {
// TODO: Pass in a record
// new URLSearchParams({"foo" : 1 , "bar" : 2});
- if (Undefined.instance == params || null == params) {
+ if (params == null || Undefined.isUndefined(params)) {
return;
}
@@ -86,12 +86,12 @@ private void splitQuery(String params) {
// TODO: encoding
final String[] parts = StringUtils.split(params, '&');
- for (int i = 0; i < parts.length; i++) {
- params_.add(splitQueryParameter(parts[i]));
+ for (String part : parts) {
+ params_.add(splitQueryParameter(part));
}
}
- private Entry splitQueryParameter(final String singleParam) {
+ private static Entry splitQueryParameter(final String singleParam) {
final int idx = singleParam.indexOf('=');
if (idx > -1) {
final String key = singleParam.substring(0, idx);
@@ -125,6 +125,7 @@ public void append(final String name, final String value) {
* @param name The name of the parameter to be deleted.
*/
@JsxFunction
+ @Override
public void delete(final String name) {
final Iterator> iter = params_.iterator();
while (iter.hasNext()) {
@@ -298,7 +299,7 @@ public Object getDefaultValue(final Class> hint) {
paramStr.append(delim);
delim = "&";
paramStr.append(param.getKey());
- paramStr.append("=");
+ paramStr.append('=');
// TODO: need to encode value
final String value = param.getValue();
if (value != null) {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WeakMap.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WeakMap.java
deleted file mode 100644
index 78c883ef23e..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WeakMap.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host;
-
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WEAKMAP_CONSTRUCTOR_IGNORE_ARGUMENT;
-
-import java.util.WeakHashMap;
-
-import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
-
-import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.Delegator;
-import net.sourceforge.htmlunit.corejs.javascript.NativeArray;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
-import net.sourceforge.htmlunit.corejs.javascript.Undefined;
-
-/**
- * A JavaScript object for {@code WeakMap}.
- *
- * @author Ahmed Ashour
- */
-@JsxClass
-public class WeakMap extends SimpleScriptable {
-
- private transient java.util.Map map_ = new WeakHashMap<>();
-
- /**
- * Creates an instance.
- */
- public WeakMap() {
- }
-
- /**
- * Creates an instance.
- * @param arrayLike an Array or other iterable object
- */
- @JsxConstructor
- public WeakMap(final Object arrayLike) {
- if (arrayLike == Undefined.instance) {
- return;
- }
-
- final Context context = Context.getCurrentContext();
- final Window window = (Window) ScriptRuntime.getTopCallScope(context);
- if (window.getBrowserVersion().hasFeature(JS_WEAKMAP_CONSTRUCTOR_IGNORE_ARGUMENT)) {
- return;
- }
-
- if (arrayLike instanceof NativeArray) {
- final NativeArray array = (NativeArray) arrayLike;
- for (int i = 0; i < array.getLength(); i++) {
- final Object entryObject = array.get(i);
- if (entryObject instanceof NativeArray) {
- final Object[] entry = toArray((NativeArray) entryObject);
- if (entry.length > 0) {
- final Object key = entry[0];
- if (Undefined.instance != key && key instanceof ScriptableObject) {
- final Object value = entry.length > 1 ? entry[1] : null;
- set(key, value);
- }
- }
- }
- else {
- throw Context.reportRuntimeError("TypeError: object is not iterable ("
- + entryObject.getClass().getName() + ")");
- }
- }
- return;
- }
-
- if (arrayLike instanceof Scriptable) {
- final Scriptable scriptable = (Scriptable) arrayLike;
- if (Iterator.iterate(Context.getCurrentContext(), this, scriptable,
- value -> {
- if (Undefined.instance != value && value instanceof NativeArray) {
- final Object[] entry = toArray((NativeArray) value);
- if (entry.length > 0) {
- final Object key = entry[0];
- if (Undefined.instance != key && key instanceof ScriptableObject) {
- final Object entryValue = entry.length > 1 ? entry[1] : null;
- set(key, entryValue);
- }
- }
- }
- else {
- throw Context.reportRuntimeError("TypeError: object is not iterable ("
- + value.getClass().getName() + ")");
- }
- })) {
- return;
- }
- }
-
- throw Context.reportRuntimeError("TypeError: object is not iterable (" + arrayLike.getClass().getName() + ")");
- }
-
- /**
- * Replacement of {@link NativeArray#toArray()}.
- */
- private static Object[] toArray(final NativeArray narray) {
- final long longLen = narray.getLength();
- if (longLen > Integer.MAX_VALUE) {
- throw new IllegalStateException();
- }
-
- final int len = (int) longLen;
- final Object[] arr = new Object[len];
- for (int i = 0; i < len; i++) {
- arr[i] = ScriptableObject.getProperty(narray, i);
- }
- return arr;
- }
-
- /**
- * Returns the value of the given key.
- * @param key the key
- * @return the value
- */
- @Override
- @JsxFunction
- public Object get(final Object key) {
- Object o = map_.get(key);
- if (o == null) {
- o = Undefined.instance;
- }
- return o;
- }
-
- /**
- * Adds the specified pair.
- * @param key the key
- * @param value the value
- * @return the Map object.
- */
- @JsxFunction
- public WeakMap set(Object key, final Object value) {
- if (key instanceof Delegator) {
- key = ((Delegator) key).getDelegee();
- }
- if (!(key instanceof ScriptableObject)) {
- throw Context.reportRuntimeError("TypeError: key is not an object");
- }
- map_.put(key, value);
- return this;
- }
-
- /**
- * Removes all elements.
- */
- @JsxFunction
- public void clear() {
- map_.clear();
- }
-
- /**
- * Removed the specified element.
- * @param key the key
- * @return whether the element has been successfully removed
- */
- @JsxFunction
- public boolean delete(final Object key) {
- return map_.remove(key) != null;
- }
-
- /**
- * Returns whether an element with the specified key exists or not.
- * @param key the key
- * @return whether the element exists or not
- */
- @JsxFunction
- public boolean has(final Object key) {
- return map_.remove(key) != null;
- }
-
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WeakSet.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WeakSet.java
deleted file mode 100644
index 45bdd1fafb1..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WeakSet.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host;
-
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-
-import java.util.Collections;
-import java.util.WeakHashMap;
-
-import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
-
-import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.Delegator;
-import net.sourceforge.htmlunit.corejs.javascript.NativeArray;
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
-import net.sourceforge.htmlunit.corejs.javascript.Undefined;
-
-/**
- * A JavaScript object for {@code WeakSet}.
- *
- * @author Ahmed Ashour
- * @author Ronald Brill
- */
-@JsxClass({CHROME, FF, EDGE})
-public class WeakSet extends SimpleScriptable {
-
- private transient java.util.Set set_ = Collections.newSetFromMap(new WeakHashMap());
-
- /**
- * Creates an instance.
- */
- public WeakSet() {
- }
-
- /**
- * Creates an instance.
- * @param iterable an Array or other iterable object
- */
- @JsxConstructor
- public WeakSet(final Object iterable) {
- if (iterable == Undefined.instance) {
- return;
- }
-
- if (iterable instanceof NativeArray) {
- final NativeArray array = (NativeArray) iterable;
- for (int i = 0; i < array.getLength(); i++) {
- final Object value = ScriptableObject.getProperty(array, i);
- if (Undefined.instance != value
- && value instanceof ScriptableObject) {
- add(ScriptableObject.getProperty(array, i));
- }
- }
- return;
- }
-
- if (iterable instanceof Scriptable) {
- final Scriptable scriptable = (Scriptable) iterable;
- if (Iterator.iterate(Context.getCurrentContext(), this, scriptable,
- value -> {
- if (Undefined.instance != value
- && value instanceof ScriptableObject) {
- add(value);
- }
- })) {
- return;
- }
- }
-
- throw Context.reportRuntimeError("TypeError: object is not iterable (" + iterable.getClass().getName() + ")");
- }
-
- /**
- * Adds the specified value.
- * @param value the value
- * @return the Set object.
- */
- @JsxFunction
- public WeakSet add(Object value) {
- if (value instanceof Delegator) {
- value = ((Delegator) value).getDelegee();
- }
-
- if (!(value instanceof ScriptableObject)) {
- throw Context.reportRuntimeError("TypeError: key is not an object");
- }
-
- set_.add(value);
- return this;
- }
-
- /**
- * Removes all elements.
- */
- @JsxFunction
- public void clear() {
- set_.clear();
- }
-
- /**
- * Removed the specified element.
- * @param key the key
- * @return whether the element has been successfully removed
- */
- @JsxFunction
- public boolean delete(final Object key) {
- return set_.remove(key);
- }
-
- /**
- * Returns whether the specified element exists or not.
- * @param value the value
- * @return whether the element exists or not
- */
- @JsxFunction
- public boolean has(final Object value) {
- return set_.contains(value);
- }
-
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocket.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocket.java
index d51a4a051be..8aac2bbdf63 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocket.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocket.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,13 +14,14 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.WEBSOCKET_ORIGIN_SET;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.WEBSOCKET_SRC_ELEMENT_SET;
+
import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
-import java.util.Arrays;
import java.util.concurrent.Future;
-import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -32,8 +33,9 @@
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.client.WebSocketClient;
-import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.WebClientOptions;
+import com.gargoylesoftware.htmlunit.WebWindow;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -42,18 +44,18 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.ArrayBuffer;
import com.gargoylesoftware.htmlunit.javascript.host.event.CloseEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
import com.gargoylesoftware.htmlunit.javascript.host.event.EventTarget;
import com.gargoylesoftware.htmlunit.javascript.host.event.MessageEvent;
import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
+import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
import net.sourceforge.htmlunit.corejs.javascript.Undefined;
+import net.sourceforge.htmlunit.corejs.javascript.typedarrays.NativeArrayBuffer;
/**
* A JavaScript object for {@code WebSocket}.
@@ -95,6 +97,8 @@ public class WebSocket extends EventTarget implements AutoCloseable {
private volatile Session incomingSession_;
private Session outgoingSession_;
private WebSocketListener listener_;
+ private boolean srcElementSet_;
+ private boolean originSet_;
/**
* Creates a new instance.
@@ -127,33 +131,41 @@ public WebSocketListener getWebSocketListener() {
*/
private WebSocket(final String url, final Window window) {
try {
- containingPage_ = (HtmlPage) window.getWebWindow().getEnclosedPage();
+ final WebWindow webWindow = window.getWebWindow();
+ containingPage_ = (HtmlPage) webWindow.getEnclosedPage();
setParentScope(window);
setDomNode(containingPage_.getDocumentElement(), false);
- final WebClient webClient = window.getWebWindow().getWebClient();
- if (webClient.getOptions().isUseInsecureSSL()) {
- client_ = new WebSocketClient(new SslContextFactory(true));
+ final WebClient webClient = webWindow.getWebClient();
+ srcElementSet_ = webClient.getBrowserVersion().hasFeature(WEBSOCKET_SRC_ELEMENT_SET);
+ originSet_ = webClient.getBrowserVersion().hasFeature(WEBSOCKET_ORIGIN_SET);
+
+ final WebClientOptions options = webClient.getOptions();
+ if (options.isUseInsecureSSL()) {
+ client_ = new WebSocketClient(new SslContextFactory(true), null, null);
+ // still use the deprecated method here to be backward compatible with older jersey versions
+ // see https://github.com/HtmlUnit/htmlunit/issues/36
+ // client_ = new WebSocketClient(new SslContextFactory.Client(true), null, null);
}
else {
client_ = new WebSocketClient();
}
- client_.setCookieStore(new WebSocketCookieStore(webClient));
+ client_.getHttpClient().setCookieStore(new WebSocketCookieStore(webClient));
final WebSocketPolicy policy = client_.getPolicy();
- int size = webClient.getOptions().getWebSocketMaxBinaryMessageSize();
+ int size = options.getWebSocketMaxBinaryMessageSize();
if (size > 0) {
policy.setMaxBinaryMessageSize(size);
}
- size = webClient.getOptions().getWebSocketMaxBinaryMessageBufferSize();
+ size = options.getWebSocketMaxBinaryMessageBufferSize();
if (size > 0) {
policy.setMaxBinaryMessageBufferSize(size);
}
- size = webClient.getOptions().getWebSocketMaxTextMessageSize();
+ size = options.getWebSocketMaxTextMessageSize();
if (size > 0) {
policy.setMaxTextMessageSize(size);
}
- size = webClient.getOptions().getWebSocketMaxTextMessageBufferSize();
+ size = options.getWebSocketMaxTextMessageBufferSize();
if (size > 0) {
policy.setMaxTextMessageBufferSize(size);
}
@@ -169,17 +181,21 @@ private WebSocket(final String url, final Window window) {
@Override
public void run() {
try {
- readyState_ = CONNECTING;
+ setReadyState(CONNECTING);
incomingSession_ = connectFuture.get();
}
catch (final Exception e) {
- LOG.error("WS connect error", e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("WS connect error for url '" + url + "':", e);
+ }
}
}
});
}
catch (final Exception e) {
- LOG.error("WebSocket Error: 'url' parameter '" + url + "' is invalid.", e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("WebSocket Error: 'url' parameter '" + url + "' is invalid.", e);
+ }
throw Context.reportRuntimeError("WebSocket Error: 'url' parameter '" + url + "' is invalid.");
}
}
@@ -200,7 +216,7 @@ public static Scriptable jsConstructor(
throw Context.reportRuntimeError(
"WebSocket Error: constructor must have one or two String parameters.");
}
- if (args[0] == Undefined.instance) {
+ if (Undefined.isUndefined(args[0])) {
throw Context.reportRuntimeError("WebSocket Error: 'url' parameter is undefined.");
}
if (!(args[0] instanceof String)) {
@@ -295,6 +311,10 @@ public int getReadyState() {
return readyState_;
}
+ private void setReadyState(final int readyState) {
+ readyState_ = readyState;
+ }
+
/**
* @return the url
*/
@@ -346,7 +366,7 @@ public void setBinaryType(final String type) {
* {@inheritDoc}
*/
@Override
- public void close() throws Exception {
+ public void close() throws IOException {
close(null, null);
}
@@ -360,10 +380,20 @@ public void close() throws Exception {
public void close(final Object code, final Object reason) {
if (readyState_ != CLOSED) {
if (incomingSession_ != null) {
- incomingSession_.close();
+ try {
+ incomingSession_.close();
+ }
+ catch (final Throwable e) {
+ LOG.error("WS close error - incomingSession_.close() failed", e);
+ }
}
if (outgoingSession_ != null) {
- outgoingSession_.close();
+ try {
+ outgoingSession_.close();
+ }
+ catch (final Throwable e) {
+ LOG.error("WS close error - outgoingSession_.close() failed", e);
+ }
}
}
@@ -371,6 +401,7 @@ public void close(final Object code, final Object reason) {
if (client_ != null) {
try {
client_.stop();
+ client_.destroy();
}
catch (final UpgradeException e) {
LOG.error("WS stop error (connection was not established so far)", e);
@@ -393,8 +424,8 @@ public void send(final Object content) {
if (content instanceof String) {
outgoingSession_.getRemote().sendString((String) content);
}
- else if (content instanceof ArrayBuffer) {
- final byte[] bytes = ((ArrayBuffer) content).getBytes();
+ else if (content instanceof NativeArrayBuffer) {
+ final byte[] bytes = ((NativeArrayBuffer) content).getBuffer();
final ByteBuffer buffer = ByteBuffer.wrap(bytes);
outgoingSession_.getRemote().sendBytes(buffer);
}
@@ -416,13 +447,16 @@ public void onWebSocketConnect(final Session session) {
listener_.onWebSocketConnect(session);
}
super.onWebSocketConnect(session);
- readyState_ = OPEN;
+ setReadyState(OPEN);
outgoingSession_ = session;
final Event openEvent = new Event();
openEvent.setType(Event.TYPE_OPEN);
+ if (srcElementSet_) {
+ openEvent.setSrcElement(WebSocket.this);
+ }
fire(openEvent);
- callFunction(openHandler_, ArrayUtils.EMPTY_OBJECT_ARRAY);
+ callFunction(openHandler_, new Object[] {openEvent});
}
@Override
@@ -431,7 +465,7 @@ public void onWebSocketClose(final int statusCode, final String reason) {
listener_.onWebSocketClose(statusCode, reason);
}
super.onWebSocketClose(statusCode, reason);
- readyState_ = CLOSED;
+ setReadyState(CLOSED);
outgoingSession_ = null;
final CloseEvent closeEvent = new CloseEvent();
@@ -450,7 +484,12 @@ public void onWebSocketText(final String message) {
super.onWebSocketText(message);
final MessageEvent msgEvent = new MessageEvent(message);
- msgEvent.setOrigin(getUrl());
+ if (originSet_) {
+ msgEvent.setOrigin(getUrl());
+ }
+ if (srcElementSet_) {
+ msgEvent.setSrcElement(WebSocket.this);
+ }
fire(msgEvent);
callFunction(messageHandler_, new Object[] {msgEvent});
}
@@ -462,12 +501,18 @@ public void onWebSocketBinary(final byte[] data, final int offset, final int len
}
super.onWebSocketBinary(data, offset, length);
- final ArrayBuffer buffer = new ArrayBuffer(Arrays.copyOfRange(data, offset, length));
+ final NativeArrayBuffer buffer = new NativeArrayBuffer(length);
+ System.arraycopy(data, offset, buffer.getBuffer(), 0, length);
buffer.setParentScope(getParentScope());
- buffer.setPrototype(getPrototype(buffer.getClass()));
+ buffer.setPrototype(ScriptableObject.getClassPrototype(getWindow(), buffer.getClassName()));
final MessageEvent msgEvent = new MessageEvent(buffer);
- msgEvent.setOrigin(getUrl());
+ if (originSet_) {
+ msgEvent.setOrigin(getUrl());
+ }
+ if (srcElementSet_) {
+ msgEvent.setSrcElement(WebSocket.this);
+ }
fire(msgEvent);
callFunction(messageHandler_, new Object[] {msgEvent});
}
@@ -478,11 +523,14 @@ public void onWebSocketError(final Throwable cause) {
listener_.onWebSocketError(cause);
}
super.onWebSocketError(cause);
- readyState_ = CLOSED;
+ setReadyState(CLOSED);
outgoingSession_ = null;
final Event errorEvent = new Event();
errorEvent.setType(Event.TYPE_ERROR);
+ if (srcElementSet_) {
+ errorEvent.setSrcElement(WebSocket.this);
+ }
fire(errorEvent);
callFunction(errorHandler_, new Object[] {errorEvent});
@@ -499,13 +547,10 @@ private void fire(final Event evt) {
evt.setParentScope(getParentScope());
evt.setPrototype(getPrototype(evt.getClass()));
- final JavaScriptEngine engine
- = (JavaScriptEngine) containingPage_.getWebClient().getJavaScriptEngine();
- engine.getContextFactory().call(new ContextAction() {
- @Override
- public ScriptResult run(final Context cx) {
- return executeEventLocally(evt);
- }
+ final JavaScriptEngine engine = (JavaScriptEngine) containingPage_.getWebClient().getJavaScriptEngine();
+ engine.getContextFactory().call(cx -> {
+ executeEventLocally(evt);
+ return null;
});
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocketCookieStore.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocketCookieStore.java
index b05d881e25e..ecbd0564373 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocketCookieStore.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WebSocketCookieStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java
index decf34c1458..e5fc1ba5a01 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Window.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,16 +22,16 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_SELECTION_NULL_IF_INVISIBLE;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_WINDOW_TOP_WRITABLE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF68;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import java.io.IOException;
import java.io.ObjectInputStream;
+import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
@@ -93,8 +93,6 @@
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.background.BackgroundJavaScriptFactory;
import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJob;
-import com.gargoylesoftware.htmlunit.javascript.configuration.CanSetReadOnly;
-import com.gargoylesoftware.htmlunit.javascript.configuration.CanSetReadOnlyStatus;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -103,7 +101,6 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter;
import com.gargoylesoftware.htmlunit.javascript.host.crypto.Crypto;
import com.gargoylesoftware.htmlunit.javascript.host.css.CSS2Properties;
-import com.gargoylesoftware.htmlunit.javascript.host.css.CSSStyleDeclaration;
import com.gargoylesoftware.htmlunit.javascript.host.css.CSSStyleSheet;
import com.gargoylesoftware.htmlunit.javascript.host.css.MediaQueryList;
import com.gargoylesoftware.htmlunit.javascript.host.css.StyleMedia;
@@ -129,6 +126,7 @@
import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
import net.sourceforge.htmlunit.corejs.javascript.ContextFactory;
import net.sourceforge.htmlunit.corejs.javascript.EcmaError;
+import net.sourceforge.htmlunit.corejs.javascript.EvaluatorException;
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.FunctionObject;
import net.sourceforge.htmlunit.corejs.javascript.JavaScriptException;
@@ -155,6 +153,7 @@
* @author Frank Danek
* @author Carsten Steul
* @author Colin Alworth
+ * @author Atsushi Nakagawa
* @see MSDN documentation
*/
@JsxClass
@@ -162,6 +161,13 @@ public class Window extends EventTarget implements Function, AutoCloseable {
private static final Log LOG = LogFactory.getLog(Window.class);
+ /** Definition of special cases for the smart DomHtmlAttributeChangeListenerImpl */
+ private static final Set ATTRIBUTES_AFFECTING_PARENT = new HashSet<>(Arrays.asList(
+ "style",
+ "class",
+ "height",
+ "width"));
+
/** To be documented. */
@JsxConstant(CHROME)
public static final short TEMPORARY = 0;
@@ -197,14 +203,102 @@ public class Window extends EventTarget implements Function, AutoCloseable {
private Object top_ = NOT_FOUND; // top can be set from JS to any value!
private Crypto crypto_;
+ private CSSPropertiesCache cssPropertiesCache_ = new CSSPropertiesCache();
+
+ private final EnumMap storages_ = new EnumMap<>(Type.class);
+
+ private final transient List animationFrames_ = new ArrayList<>();
+
+ private static final class AnimationFrame {
+ private long id_;
+ private Function callback_;
+
+ private AnimationFrame(final long id, final Function callback) {
+ id_ = id;
+ callback_ = callback;
+ }
+ }
+
/**
* Cache computed styles when possible, because their calculation is very expensive.
* We use a weak hash map because we don't want this cache to be the only reason
* nodes are kept around in the JVM, if all other references to them are gone.
*/
- private transient WeakHashMap> computedStyles_ = new WeakHashMap<>();
+ private static final class CSSPropertiesCache implements Serializable {
+ private transient WeakHashMap> computedStyles_ = new WeakHashMap<>();
- private final EnumMap storages_ = new EnumMap<>(Type.class);
+ public synchronized CSS2Properties get(final Element element, final String normalizedPseudo) {
+ final Map elementMap = computedStyles_.get(element);
+ if (elementMap != null) {
+ return elementMap.get(normalizedPseudo);
+ }
+ return null;
+ }
+
+ public synchronized void put(final Element element, final String normalizedPseudo, final CSS2Properties style) {
+ Map elementMap = computedStyles_.get(element);
+ if (elementMap == null) {
+ elementMap = new WeakHashMap<>();
+ computedStyles_.put(element, elementMap);
+ }
+ elementMap.put(normalizedPseudo, style);
+ }
+
+ public synchronized void nodeChanged(final DomNode changed, final boolean clearParents) {
+ final Iterator>> i = computedStyles_.entrySet().iterator();
+ while (i.hasNext()) {
+ final Map.Entry> entry = i.next();
+ final DomNode node = entry.getKey().getDomNodeOrDie();
+ if (changed == node
+ || changed.getParentNode() == node.getParentNode()
+ || changed.isAncestorOf(node)
+ || clearParents && node.isAncestorOf(changed)) {
+ i.remove();
+ }
+ }
+
+ // maybe this is a better solution but i have to think a bit more about this
+ //
+ // if (computedStyles_.isEmpty()) {
+ // return;
+ // }
+ //
+ // // remove all siblings
+ // DomNode parent = changed.getParentNode();
+ // if (parent != null) {
+ // for (DomNode sibling : parent.getChildNodes()) {
+ // computedStyles_.remove(sibling.getScriptableObject());
+ // }
+ //
+ // if (clearParents) {
+ // // remove all parents
+ // while (parent != null) {
+ // computedStyles_.remove(parent.getScriptableObject());
+ // parent = parent.getParentNode();
+ // }
+ // }
+ // }
+ //
+ // // remove changed itself and all descendants
+ // computedStyles_.remove(changed.getScriptableObject());
+ // for (DomNode descendant : changed.getDescendants()) {
+ // computedStyles_.remove(descendant.getScriptableObject());
+ // }
+ }
+
+ public synchronized void clear() {
+ computedStyles_.clear();
+ }
+
+ public synchronized Map remove(final Element element) {
+ return computedStyles_.remove(element);
+ }
+
+ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ computedStyles_ = new WeakHashMap<>();
+ }
+ }
/**
* Creates an instance.
@@ -221,21 +315,21 @@ public Window() {
* @param inNewExpr Is new or not
* @return the java object to allow JavaScript to access
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public static Scriptable jsConstructor(final Context cx, final Object[] args, final Function ctorObj,
final boolean inNewExpr) {
throw ScriptRuntime.typeError("Illegal constructor");
}
/**
- * Restores the transient {@link #computedStyles_} map during deserialization.
+ * Restores the transient {@link #cssPropertiesCache_} map during deserialization.
* @param stream the stream to read the object from
* @throws IOException if an IO error occurs
* @throws ClassNotFoundException if a class is not found
*/
private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
- computedStyles_ = new WeakHashMap<>();
+ cssPropertiesCache_ = new CSSPropertiesCache();
}
/**
@@ -279,7 +373,9 @@ public void alert(final Object message) {
final String stringMessage = Context.toString(message);
final AlertHandler handler = getWebWindow().getWebClient().getAlertHandler();
if (handler == null) {
- LOG.warn("window.alert(\"" + stringMessage + "\") no alert handler installed");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("window.alert(\"" + stringMessage + "\") no alert handler installed");
+ }
}
else {
handler.handleAlert(document_.getPage(), stringMessage);
@@ -293,7 +389,14 @@ public void alert(final Object message) {
*/
@JsxFunction
public String btoa(final String stringToEncode) {
- return new String(Base64.encodeBase64(stringToEncode.getBytes()));
+ final int l = stringToEncode.length();
+ for (int i = 0; i < l; i++) {
+ if (stringToEncode.charAt(i) > 255) {
+ throw new EvaluatorException("Function btoa supports only latin1 characters");
+ }
+ }
+ final byte[] bytes = stringToEncode.getBytes(StandardCharsets.ISO_8859_1);
+ return new String(Base64.encodeBase64(bytes), StandardCharsets.UTF_8);
}
/**
@@ -303,7 +406,14 @@ public String btoa(final String stringToEncode) {
*/
@JsxFunction
public String atob(final String encodedData) {
- return new String(Base64.decodeBase64(encodedData.getBytes()));
+ final int l = encodedData.length();
+ for (int i = 0; i < l; i++) {
+ if (encodedData.charAt(i) > 255) {
+ throw new EvaluatorException("Function atob supports only latin1 characters");
+ }
+ }
+ final byte[] bytes = encodedData.getBytes(StandardCharsets.ISO_8859_1);
+ return new String(Base64.decodeBase64(bytes), StandardCharsets.ISO_8859_1);
}
/**
@@ -315,8 +425,10 @@ public String atob(final String encodedData) {
public boolean confirm(final String message) {
final ConfirmHandler handler = getWebWindow().getWebClient().getConfirmHandler();
if (handler == null) {
- LOG.warn("window.confirm(\""
- + message + "\") no confirm handler installed, simulating the OK button");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("window.confirm(\""
+ + message + "\") no confirm handler installed, simulating the OK button");
+ }
return true;
}
return handler.handleConfirm(document_.getPage(), message);
@@ -332,10 +444,12 @@ public boolean confirm(final String message) {
public String prompt(final String message, Object defaultValue) {
final PromptHandler handler = getWebWindow().getWebClient().getPromptHandler();
if (handler == null) {
- LOG.warn("window.prompt(\"" + message + "\") no prompt handler installed");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("window.prompt(\"" + message + "\") no prompt handler installed");
+ }
return null;
}
- if (defaultValue == Undefined.instance) {
+ if (Undefined.isUndefined(defaultValue)) {
defaultValue = null;
}
else {
@@ -374,7 +488,7 @@ public ApplicationCache getApplicationCache() {
* Returns the current event.
* @return the current event, or {@code null} if no event is currently available
*/
- @JsxGetter({IE, CHROME})
+ @JsxGetter({IE, CHROME, FF68})
public Object getEvent() {
return currentEvent_;
}
@@ -411,15 +525,15 @@ public void setCurrentEvent(final Event event) {
public WindowProxy open(final Object url, final Object name, final Object features,
final Object replace) {
String urlString = null;
- if (url != Undefined.instance) {
+ if (!Undefined.isUndefined(url)) {
urlString = Context.toString(url);
}
String windowName = "";
- if (name != Undefined.instance) {
+ if (!Undefined.isUndefined(name)) {
windowName = Context.toString(name);
}
String featuresString = null;
- if (features != Undefined.instance) {
+ if (!Undefined.isUndefined(features)) {
featuresString = Context.toString(features);
}
final WebClient webClient = getWebWindow().getWebClient();
@@ -432,7 +546,7 @@ public WindowProxy open(final Object url, final Object name, final Object featur
}
boolean replaceCurrentEntryInBrowsingHistory = false;
- if (replace != Undefined.instance) {
+ if (!Undefined.isUndefined(replace)) {
replaceCurrentEntryInBrowsingHistory = Context.toBoolean(replace);
}
if ((featuresString != null || replaceCurrentEntryInBrowsingHistory) && LOG.isDebugEnabled()) {
@@ -473,7 +587,9 @@ private URL makeUrlForOpenWindow(final String urlString) {
return new URL(urlString);
}
catch (final MalformedURLException e) {
- LOG.error("Unable to create URL for openWindow: relativeUrl=[" + urlString + "]", e);
+ if (LOG.isWarnEnabled()) {
+ LOG.error("Unable to create URL for openWindow: relativeUrl=[" + urlString + "]", e);
+ }
return null;
}
}
@@ -483,32 +599,77 @@ private URL makeUrlForOpenWindow(final String urlString) {
* The invocation occurs only if the window is opened after the delay
* and does not contain an other page than the one that originated the setTimeout.
*
- * @param code specifies the function pointer or string that indicates the code to be executed
- * when the specified interval has elapsed
- * @param timeout specifies the number of milliseconds
- * @param language specifies language
+ * @see
+ * MDN web docs
+ *
+ * @param context the JavaScript context
+ * @param thisObj the scriptable
+ * @param args the arguments passed into the method
+ * @param function the function
* @return the id of the created timer
*/
@JsxFunction
- public int setTimeout(final Object code, int timeout, final Object language) {
+ public static Object setTimeout(final Context context, final Scriptable thisObj,
+ final Object[] args, final Function function) {
+ if (args.length < 1) {
+ throw ScriptRuntime.typeError("Function not provided");
+ }
+
+ final int timeout = ScriptRuntime.toInt32((args.length > 1) ? args[1] : Undefined.instance);
+ final Object[] params = (args.length > 2)
+ ? Arrays.copyOfRange(args, 2, args.length)
+ : ScriptRuntime.emptyArgs;
+ return ((Window) thisObj).setTimeoutIntervalImpl(args[0], timeout, true, params);
+ }
+
+ /**
+ * Sets a chunk of JavaScript to be invoked each time a specified number of milliseconds has elapsed.
+ *
+ * @see
+ * MDN web docs
+ * @param context the JavaScript context
+ * @param thisObj the scriptable
+ * @param args the arguments passed into the method
+ * @param function the function
+ * @return the id of the created interval
+ */
+ @JsxFunction
+ public static Object setInterval(final Context context, final Scriptable thisObj,
+ final Object[] args, final Function function) {
+ if (args.length < 1) {
+ throw ScriptRuntime.typeError("Function not provided");
+ }
+
+ final int timeout = ScriptRuntime.toInt32((args.length > 1) ? args[1] : Undefined.instance);
+ final Object[] params = (args.length > 2)
+ ? Arrays.copyOfRange(args, 2, args.length)
+ : ScriptRuntime.emptyArgs;
+ return ((Window) thisObj).setTimeoutIntervalImpl(args[0], timeout, false, params);
+ }
+
+ private int setTimeoutIntervalImpl(final Object code, int timeout, final boolean isTimeout, final Object[] params) {
if (timeout < MIN_TIMER_DELAY) {
timeout = MIN_TIMER_DELAY;
}
- if (code == null) {
- throw Context.reportRuntimeError("Function not provided.");
- }
- final int id;
final WebWindow webWindow = getWebWindow();
final Page page = (Page) getDomNodeOrNull();
+ Integer period = null;
+ if (!isTimeout) {
+ period = Integer.valueOf(timeout);
+ }
+
if (code instanceof String) {
final String s = (String) code;
- final String description = "window.setTimeout(" + s + ", " + timeout + ")";
+ final String description = "window.set"
+ + (isTimeout ? "Timeout" : "Interval")
+ + "(" + s + ", " + timeout + ")";
final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
- createJavaScriptJob(timeout, null, description, webWindow, s);
- id = webWindow.getJobManager().addJob(job, page);
+ createJavaScriptJob(timeout, period, description, webWindow, s);
+ return webWindow.getJobManager().addJob(job, page);
}
- else if (code instanceof Function) {
+
+ if (code instanceof Function) {
final Function f = (Function) code;
final String functionName;
if (f instanceof FunctionObject) {
@@ -518,21 +679,23 @@ else if (code instanceof Function) {
functionName = String.valueOf(f); // can this happen?
}
- final String description = "window.setTimeout(" + functionName + ", " + timeout + ")";
+ final String description = "window.set"
+ + (isTimeout ? "Timeout" : "Interval")
+ + "(" + functionName + ", " + timeout + ")";
final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
- createJavaScriptJob(timeout, null, description, webWindow, f);
- id = webWindow.getJobManager().addJob(job, page);
+ createJavaScriptJob(timeout, period, description, webWindow, f, params);
+ return webWindow.getJobManager().addJob(job, page);
}
- else {
- throw Context.reportRuntimeError("Unknown type for function.");
- }
- return id;
+
+ throw Context.reportRuntimeError("Unknown type for function.");
}
/**
- * Cancels a time-out previously set with the {@link #setTimeout(Object, int, Object)} method.
+ * Cancels a time-out previously set with the
+ * {@link #setTimeout(Context, Scriptable, Object[], Function)} method.
*
- * @param timeoutId identifier for the timeout to clear (returned by {@link #setTimeout(Object, int, Object)})
+ * @param timeoutId identifier for the timeout to clear
+ * as returned by {@link #setTimeout(Context, Scriptable, Object[], Function)}
*/
@JsxFunction
public void clearTimeout(final int timeoutId) {
@@ -542,6 +705,22 @@ public void clearTimeout(final int timeoutId) {
getWebWindow().getJobManager().removeJob(timeoutId);
}
+ /**
+ * Cancels the interval previously started using the
+ * {@link #setInterval(Context, Scriptable, Object[], Function)} method.
+ * Current implementation does nothing.
+ * @param intervalID specifies the interval to cancel as returned by the
+ * {@link #setInterval(Context, Scriptable, Object[], Function)} method
+ * @see MSDN documentation
+ */
+ @JsxFunction
+ public void clearInterval(final int intervalID) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("clearInterval(" + intervalID + ")");
+ }
+ getWebWindow().getJobManager().removeJob(intervalID);
+ }
+
/**
* Returns the JavaScript property {@code navigator}.
* @return the navigator
@@ -560,6 +739,14 @@ public Navigator getClientInformation() {
return navigator_;
}
+ /**
+ * Special setter for IE to ignore this call.
+ * @param ignore parame gets ignored
+ */
+ @JsxSetter(IE)
+ public void setClientInformation(final Object ignore) {
+ }
+
/**
* Returns the JavaScript property {@code clipboardData}.
* @return the {@link DataTransfer}
@@ -673,25 +860,60 @@ public void dump(final String message) {
}
/**
- * Dummy implementation for {@code requestAnimationFrame}.
+ * Invokes all the animation callbacks registered for this window by
+ * calling {@link #requestAnimationFrame(Object)} once.
+ * @return the number of pending animation callbacks
+ */
+ public int animateAnimationsFrames() {
+ final List animationFrames = new ArrayList<>(animationFrames_);
+ animationFrames_.clear();
+
+ final double now = System.nanoTime() / 1_000_000d;
+ final Object[] args = new Object[] {now};
+
+ final WebWindow ww = getWindow().getWebWindow();
+ final JavaScriptEngine jsEngine = (JavaScriptEngine) ww.getWebClient().getJavaScriptEngine();
+
+ for (AnimationFrame animationFrame : animationFrames) {
+ jsEngine.callFunction((HtmlPage) ww.getEnclosedPage(),
+ animationFrame.callback_, this, getParentScope(), args);
+ }
+ return animationFrames_.size();
+ }
+
+ /**
+ * Add callback to the list of animationFrames.
* @param callback the function to call when it's time to update the animation
* @return an identification id
* @see MDN Doc
*/
@JsxFunction
public int requestAnimationFrame(final Object callback) {
- // nothing for now
- return 1;
+ if (callback instanceof Function) {
+ final int id = animationFrames_.size();
+ final AnimationFrame animationFrame = new AnimationFrame(id, (Function) callback);
+ animationFrames_.add(animationFrame);
+ return id;
+ }
+ return -1;
}
/**
- * Dummy implementation for {@code cancelAnimationFrame}.
+ * Remove the callback from the list of animationFrames.
* @param requestId the ID value returned by the call to window.requestAnimationFrame()
* @see MDN Doc
*/
@JsxFunction
public void cancelAnimationFrame(final Object requestId) {
- // nothing for now
+ final int id = (int) Context.toNumber(requestId);
+
+ final Iterator frames = animationFrames_.iterator();
+ while (frames.hasNext()) {
+ final Window.AnimationFrame animationFrame = frames.next();
+ if (animationFrame.id_ == id) {
+ frames.remove();
+ }
+ }
}
/**
@@ -879,7 +1101,7 @@ public Object getOpener() {
@JsxSetter
public void setOpener(final Object newValue) {
if (getBrowserVersion().hasFeature(JS_WINDOW_CHANGE_OPENER_ONLY_WINDOW_OBJECT)
- && newValue != null && newValue != Undefined.instance && !(newValue instanceof Window)) {
+ && newValue != null && !Undefined.isUndefined(newValue) && !(newValue instanceof Window)) {
throw Context.reportRuntimeError("Can't set opener to something other than a window!");
}
opener_ = newValue;
@@ -913,7 +1135,11 @@ public Window getFrames_js() {
*/
@JsxGetter
public int getLength() {
- return getFrames().getLength();
+ final HTMLCollection frames = getFrames();
+ if (frames != null) {
+ return frames.getLength();
+ }
+ return 0;
}
/**
@@ -921,8 +1147,11 @@ public int getLength() {
* @return the live collection of frames contained by this window
*/
private HTMLCollection getFrames() {
- final HtmlPage page = (HtmlPage) getWebWindow().getEnclosedPage();
- return new HTMLCollectionFrames(page);
+ final Page page = getWebWindow().getEnclosedPage();
+ if (page instanceof HtmlPage) {
+ return new HTMLCollectionFrames((HtmlPage) page);
+ }
+ return null;
}
/**
@@ -971,7 +1200,6 @@ public void close_js() {
* @return {@code true} if this window is closed
*/
@JsxGetter
- @CanSetReadOnly(CanSetReadOnlyStatus.IGNORE)
public boolean isClosed() {
final WebWindow webWindow = getWebWindow();
return !webWindow.getWebClient().containsWebWindow(webWindow);
@@ -1123,7 +1351,7 @@ public Object getOnload() {
*/
@JsxSetter
public void setOnload(final Object onload) {
- getEventListenersContainer().setEventHandler(Event.TYPE_LOAD, onload);
+ setHandlerForJavaScript(Event.TYPE_LOAD, onload);
}
/**
@@ -1132,7 +1360,7 @@ public void setOnload(final Object onload) {
*/
@JsxSetter
public void setOnblur(final Object onblur) {
- getEventListenersContainer().setEventHandler(Event.TYPE_BLUR, onblur);
+ setHandlerForJavaScript(Event.TYPE_BLUR, onblur);
}
/**
@@ -1306,10 +1534,7 @@ else if (e.getCause() instanceof EcmaError) {
}
private void setHandlerForJavaScript(final String eventName, final Object handler) {
- if (handler == null || handler instanceof Function) {
- getEventListenersContainer().setEventHandler(eventName, handler);
- }
- // Otherwise, fail silently.
+ getEventListenersContainer().setEventHandler(eventName, handler);
}
/**
@@ -1380,12 +1605,12 @@ public Object getWithFallback(final String name) {
*/
@Override
public Object get(final int index, final Scriptable start) {
- if (getWebWindow() == null) {
+ if (index < 0 || getWebWindow() == null) {
return Undefined.instance;
}
final HTMLCollection frames = getFrames();
- if (index < 0 || index >= frames.getLength()) {
+ if (frames == null || index >= frames.getLength()) {
return Undefined.instance;
}
return frames.item(Integer.valueOf(index));
@@ -1486,61 +1711,6 @@ public void setStatus(final String message) {
}
}
- /**
- * Sets a chunk of JavaScript to be invoked each time a specified number of milliseconds has elapsed.
- *
- * @see MSDN documentation
- * @param code specifies the function pointer or string that indicates the code to be executed
- * when the specified interval has elapsed
- * @param timeout specifies the number of milliseconds
- * @param language specifies language
- * @return the id of the created interval
- */
- @JsxFunction
- public int setInterval(final Object code, int timeout, final Object language) {
- if (timeout < MIN_TIMER_DELAY) {
- timeout = MIN_TIMER_DELAY;
- }
- final int id;
- final WebWindow w = getWebWindow();
- final Page page = (Page) getDomNodeOrNull();
- final String description = "window.setInterval(" + timeout + ")";
- if (code == null) {
- throw Context.reportRuntimeError("Function not provided.");
- }
- else if (code instanceof String) {
- final String s = (String) code;
- final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
- createJavaScriptJob(timeout, Integer.valueOf(timeout), description, w, s);
- id = w.getJobManager().addJob(job, page);
- }
- else if (code instanceof Function) {
- final Function f = (Function) code;
- final JavaScriptJob job = BackgroundJavaScriptFactory.theFactory().
- createJavaScriptJob(timeout, Integer.valueOf(timeout), description, w, f);
- id = w.getJobManager().addJob(job, page);
- }
- else {
- throw Context.reportRuntimeError("Unknown type for function.");
- }
- return id;
- }
-
- /**
- * Cancels the interval previously started using the {@link #setInterval(Object, int, Object)} method.
- * Current implementation does nothing.
- * @param intervalID specifies the interval to cancel as returned by the
- * {@link #setInterval(Object, int, Object)} method
- * @see MSDN documentation
- */
- @JsxFunction
- public void clearInterval(final int intervalID) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("clearInterval(" + intervalID + ")");
- }
- getWebWindow().getJobManager().removeJob(intervalID);
- }
-
/**
* Returns the {@code innerWidth}.
* @return the {@code innerWidth}
@@ -1653,8 +1823,8 @@ public void releaseEvents(final String type) {
/**
* An undocumented IE function.
*/
- @JsxFunction(IE)
- public void CollectGarbage() {
+ @JsxFunction(value = IE, functionName = "CollectGarbage")
+ public void collectGarbage() {
// Empty.
}
@@ -1681,24 +1851,17 @@ public CSS2Properties getComputedStyle(final Object element, final String pseudo
normalizedPseudo = normalizedPseudo.substring(1);
}
else if (getBrowserVersion().hasFeature(JS_WINDOW_COMPUTED_STYLE_PSEUDO_ACCEPT_WITHOUT_COLON)
- && !normalizedPseudo.startsWith(":")) {
+ && normalizedPseudo.length() > 0 && normalizedPseudo.charAt(0) != ':') {
normalizedPseudo = ":" + normalizedPseudo;
}
}
- synchronized (computedStyles_) {
- final Map elementMap = computedStyles_.get(e);
- if (elementMap != null) {
- final CSS2Properties style = elementMap.get(normalizedPseudo);
- if (style != null) {
- return style;
- }
- }
+ final CSS2Properties styleFromCache = cssPropertiesCache_.get(e, normalizedPseudo);
+ if (styleFromCache != null) {
+ return styleFromCache;
}
- final CSSStyleDeclaration original = e.getStyle();
- final CSS2Properties style = new CSS2Properties(original);
-
+ final CSS2Properties style = new CSS2Properties(e.getStyle());
final Object ownerDocument = e.getOwnerDocument();
if (ownerDocument instanceof HTMLDocument) {
final StyleSheetList sheets = ((HTMLDocument) ownerDocument).getStyleSheets();
@@ -1713,14 +1876,7 @@ else if (getBrowserVersion().hasFeature(JS_WINDOW_COMPUTED_STYLE_PSEUDO_ACCEPT_W
}
}
- synchronized (computedStyles_) {
- Map elementMap = computedStyles_.get(element);
- if (elementMap == null) {
- elementMap = new WeakHashMap<>();
- computedStyles_.put(e, elementMap);
- }
- elementMap.put(normalizedPseudo, style);
- }
+ cssPropertiesCache_.put(e, normalizedPseudo, style);
}
return style;
}
@@ -1765,7 +1921,7 @@ public Selection getSelectionImpl() {
* @see MSDN Documentation
* @see Mozilla Documentation
*/
- @JsxFunction({IE, FF})
+ @JsxFunction(IE)
public Object showModalDialog(final String url, final Object arguments, final String features) {
final WebWindow webWindow = getWebWindow();
final WebClient client = webWindow.getWebClient();
@@ -1841,7 +1997,7 @@ public int getMozInnerScreenX() {
*/
@JsxGetter(FF)
public int getMozInnerScreenY() {
- return 91;
+ return 83;
}
/**
@@ -1853,13 +2009,6 @@ public int getMozPaintCount() {
return 0;
}
- /** Definition of special cases for the smart DomHtmlAttributeChangeListenerImpl */
- private static final Set ATTRIBUTES_AFFECTING_PARENT = new HashSet<>(Arrays.asList(
- "style",
- "class",
- "height",
- "width"));
-
private static final class Filter {
private final boolean includeFormFields_;
@@ -1889,9 +2038,7 @@ private boolean matches(final Object object) {
* Clears the computed styles.
*/
public void clearComputedStyles() {
- synchronized (computedStyles_) {
- computedStyles_.clear();
- }
+ cssPropertiesCache_.clear();
}
/**
@@ -1899,8 +2046,21 @@ public void clearComputedStyles() {
* @param element the element to clear its cache
*/
public void clearComputedStyles(final Element element) {
- synchronized (computedStyles_) {
- computedStyles_.remove(element);
+ cssPropertiesCache_.remove(element);
+ }
+
+ /**
+ * Clears the computed styles for a specific {@link Element}
+ * and all parent elements.
+ * @param element the element to clear its cache
+ */
+ public void clearComputedStylesUpToRoot(final Element element) {
+ cssPropertiesCache_.remove(element);
+
+ Element parent = element.getParentElement();
+ while (parent != null) {
+ cssPropertiesCache_.remove(parent);
+ parent = parent.getParentElement();
}
}
@@ -1992,21 +2152,10 @@ private void nodeChanged(final DomNode changed, final String attribName) {
return;
}
}
+
// Apparently it wasn't a stylesheet that changed; be semi-smart about what we evict and when.
- synchronized (computedStyles_) {
- final boolean clearParents = ATTRIBUTES_AFFECTING_PARENT.contains(attribName);
- for (final Iterator>> i
- = computedStyles_.entrySet().iterator(); i.hasNext();) {
- final Map.Entry> entry = i.next();
- final DomNode node = entry.getKey().getDomNodeOrDie();
- if (changed == node
- || changed.getParentNode() == node.getParentNode()
- || changed.isAncestorOf(node)
- || clearParents && node.isAncestorOf(changed)) {
- i.remove();
- }
- }
- }
+ final boolean clearParents = ATTRIBUTES_AFFECTING_PARENT.contains(attribName);
+ cssPropertiesCache_.nodeChanged(changed, clearParents);
}
}
@@ -2015,8 +2164,8 @@ private void nodeChanged(final DomNode changed, final String attribName) {
* @see MSDN doc
* @return "JScript"
*/
- @JsxFunction(IE)
- public String ScriptEngine() {
+ @JsxFunction(value = IE, functionName = "ScriptEngine")
+ public String scriptEngine() {
return "JScript";
}
@@ -2025,8 +2174,8 @@ public String ScriptEngine() {
* @see MSDN doc
* @return the build version
*/
- @JsxFunction(IE)
- public int ScriptEngineBuildVersion() {
+ @JsxFunction(value = IE, functionName = "ScriptEngineBuildVersion")
+ public int scriptEngineBuildVersion() {
return 12345;
}
@@ -2035,8 +2184,8 @@ public int ScriptEngineBuildVersion() {
* @see MSDN doc
* @return the major version
*/
- @JsxFunction(IE)
- public int ScriptEngineMajorVersion() {
+ @JsxFunction(value = IE, functionName = "ScriptEngineMajorVersion")
+ public int scriptEngineMajorVersion() {
return getBrowserVersion().getBrowserVersionNumeric();
}
@@ -2045,8 +2194,8 @@ public int ScriptEngineMajorVersion() {
* @see MSDN doc
* @return the minor version
*/
- @JsxFunction(IE)
- public int ScriptEngineMinorVersion() {
+ @JsxFunction(value = IE, functionName = "ScriptEngineMinorVersion")
+ public int scriptEngineMinorVersion() {
return 0;
}
@@ -2209,7 +2358,7 @@ public void postMessage(final String message, final String targetOrigin, final O
final PostponedAction action = new PostponedAction(page) {
@Override
public void execute() throws Exception {
- final ContextAction contextAction = new ContextAction() {
+ final ContextAction contextAction = new ContextAction() {
@Override
public Object run(final Context cx) {
return dispatchEvent(event);
@@ -2488,7 +2637,7 @@ public void setOnratechange(final Object onratechange) {
* Returns the {@code onanimationiteration} event handler.
* @return the {@code onanimationiteration} event handler
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOnanimationiteration() {
return getEventHandler("animationiteration");
}
@@ -2497,7 +2646,7 @@ public Function getOnanimationiteration() {
* Sets the {@code onanimationiteration} event handler.
* @param onanimationiteration the {@code onanimationiteration} event handler
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOnanimationiteration(final Object onanimationiteration) {
setHandlerForJavaScript("animationiteration", onanimationiteration);
}
@@ -2646,29 +2795,11 @@ public void setOnmspointerleave(final Object onmspointerleave) {
setHandlerForJavaScript("mspointerleave", onmspointerleave);
}
- /**
- * Returns the {@code onmozpointerlockchange} event handler.
- * @return the {@code onmozpointerlockchange} event handler
- */
- @JsxGetter(FF45)
- public Function getOnmozpointerlockchange() {
- return getEventHandler("mozpointerlockchange");
- }
-
- /**
- * Sets the {@code onmozpointerlockchange} event handler.
- * @param onmozpointerlockchange the {@code onmozpointerlockchange} event handler
- */
- @JsxSetter(FF45)
- public void setOnmozpointerlockchange(final Object onmozpointerlockchange) {
- setHandlerForJavaScript("mozpointerlockchange", onmozpointerlockchange);
- }
-
/**
* Returns the {@code onwebkitanimationstart} event handler.
* @return the {@code onwebkitanimationstart} event handler
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOnwebkitanimationstart() {
return getEventHandler("webkitanimationstart");
}
@@ -2677,7 +2808,7 @@ public Function getOnwebkitanimationstart() {
* Sets the {@code onwebkitanimationstart} event handler.
* @param onwebkitanimationstart the {@code onwebkitanimationstart} event handler
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOnwebkitanimationstart(final Object onwebkitanimationstart) {
setHandlerForJavaScript("webkitanimationstart", onwebkitanimationstart);
}
@@ -2866,7 +2997,7 @@ public void setOndeviceorientation(final Object ondeviceorientation) {
* Returns the {@code ontoggle} event handler.
* @return the {@code ontoggle} event handler
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOntoggle() {
return getEventHandler("toggle");
}
@@ -2875,7 +3006,7 @@ public Function getOntoggle() {
* Sets the {@code ontoggle} event handler.
* @param ontoggle the {@code ontoggle} event handler
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOntoggle(final Object ontoggle) {
setHandlerForJavaScript("toggle", ontoggle);
}
@@ -3100,7 +3231,7 @@ public void setOnclose(final Object onclose) {
* Returns the {@code onanimationend} event handler.
* @return the {@code onanimationend} event handler
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOnanimationend() {
return getEventHandler("animationend");
}
@@ -3109,7 +3240,7 @@ public Function getOnanimationend() {
* Sets the {@code onanimationend} event handler.
* @param onanimationend the {@code onanimationend} event handler
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOnanimationend(final Object onanimationend) {
setHandlerForJavaScript("animationend", onanimationend);
}
@@ -3766,7 +3897,7 @@ public void setOndevicelight(final Object ondevicelight) {
* Returns the {@code onanimationstart} event handler.
* @return the {@code onanimationstart} event handler
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOnanimationstart() {
return getEventHandler("animationstart");
}
@@ -3775,7 +3906,7 @@ public Function getOnanimationstart() {
* Sets the {@code onanimationstart} event handler.
* @param onanimationstart the {@code onanimationstart} event handler
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOnanimationstart(final Object onanimationstart) {
setHandlerForJavaScript("animationstart", onanimationstart);
}
@@ -3838,7 +3969,7 @@ public void setOnpagehide(final Object onpagehide) {
* Returns the {@code onwebkitanimationiteration} event handler.
* @return the {@code onwebkitanimationiteration} event handler
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOnwebkitanimationiteration() {
return getEventHandler("webkitanimationiteration");
}
@@ -3847,7 +3978,7 @@ public Function getOnwebkitanimationiteration() {
* Sets the {@code onwebkitanimationiteration} event handler.
* @param onwebkitanimationiteration the {@code onwebkitanimationiteration} event handler
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOnwebkitanimationiteration(final Object onwebkitanimationiteration) {
setHandlerForJavaScript("webkitanimationiteration", onwebkitanimationiteration);
}
@@ -4050,29 +4181,11 @@ public void setOninput(final Object oninput) {
setHandlerForJavaScript(Event.TYPE_INPUT, oninput);
}
- /**
- * Returns the {@code onmozpointerlockerror} event handler.
- * @return the {@code onmozpointerlockerror} event handler
- */
- @JsxGetter(FF45)
- public Function getOnmozpointerlockerror() {
- return getEventHandler("mozpointerlockerror");
- }
-
- /**
- * Sets the {@code onmozpointerlockerror} event handler.
- * @param onmozpointerlockerror the {@code onmozpointerlockerror} event handler
- */
- @JsxSetter(FF45)
- public void setOnmozpointerlockerror(final Object onmozpointerlockerror) {
- setHandlerForJavaScript("mozpointerlockerror", onmozpointerlockerror);
- }
-
/**
* Returns the {@code onwebkittransitionend} event handler.
* @return the {@code onwebkittransitionend} event handler
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOnwebkittransitionend() {
return getEventHandler("webkittransitionend");
}
@@ -4081,7 +4194,7 @@ public Function getOnwebkittransitionend() {
* Sets the {@code onwebkittransitionend} event handler.
* @param onwebkittransitionend the {@code onwebkittransitionend} event handler
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOnwebkittransitionend(final Object onwebkittransitionend) {
setHandlerForJavaScript("webkittransitionend", onwebkittransitionend);
}
@@ -4234,7 +4347,7 @@ public void setOnunload(final Object onunload) {
* Returns the {@code onwebkitanimationend} event handler.
* @return the {@code onwebkitanimationend} event handler
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOnwebkitanimationend() {
return getEventHandler("webkitanimationend");
}
@@ -4243,7 +4356,7 @@ public Function getOnwebkitanimationend() {
* Sets the {@code onwebkitanimationend} event handler.
* @param onwebkitanimationend the {@code onwebkitanimationend} event handler
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOnwebkitanimationend(final Object onwebkitanimationend) {
setHandlerForJavaScript("webkitanimationend", onwebkitanimationend);
}
@@ -4270,7 +4383,7 @@ public void setOndragstart(final Object ondragstart) {
* Returns the {@code ontransitionend} event handler.
* @return the {@code ontransitionend} event handler
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOntransitionend() {
return getEventHandler("transitionend");
}
@@ -4279,7 +4392,7 @@ public Function getOntransitionend() {
* Sets the {@code ontransitionend} event handler.
* @param ontransitionend the {@code ontransitionend} event handler
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOntransitionend(final Object ontransitionend) {
setHandlerForJavaScript("transitionend", ontransitionend);
}
@@ -4410,78 +4523,6 @@ public void setOnpopstate(final Object onpopstate) {
setHandlerForJavaScript(Event.TYPE_POPSTATE, onpopstate);
}
- /**
- * Returns the {@code onabsolutedeviceorientation} event handler.
- * @return the {@code onabsolutedeviceorientation} event handler
- */
- @JsxGetter(FF52)
- public Function getOnabsolutedeviceorientation() {
- return getEventHandler("absolutedeviceorientation");
- }
-
- /**
- * Sets the {@code onabsolutedeviceorientation} event handler.
- * @param absolutedeviceorientation the {@code onabsolutedeviceorientation} event handler
- */
- @JsxSetter(FF52)
- public void setOnabsolutedeviceorientation(final Object absolutedeviceorientation) {
- setEventHandler("absolutedeviceorientation", absolutedeviceorientation);
- }
-
- /**
- * Returns the {@code ondragexit} event handler.
- * @return the {@code ondragexit} event handler
- */
- @JsxGetter(FF52)
- public Function getOndragexit() {
- return getEventHandler("dragexit");
- }
-
- /**
- * Sets the {@code ondragexit} event handler.
- * @param dragexit the {@code ondragexit} event handler
- */
- @JsxSetter(FF52)
- public void setOndragexit(final Object dragexit) {
- setEventHandler("dragexit", dragexit);
- }
-
- /**
- * Returns the {@code onloadend} event handler.
- * @return the {@code onloadend} event handler
- */
- @JsxGetter(FF52)
- public Function getOnloadend() {
- return getEventHandler("loadend");
- }
-
- /**
- * Sets the {@code onloadend} event handler.
- * @param loadend the {@code onloadend} event handler
- */
- @JsxSetter(FF52)
- public void setOnloadend(final Object loadend) {
- setEventHandler("loadend", loadend);
- }
-
- /**
- * Returns the {@code onselectstart} event handler.
- * @return the {@code onselectstart} event handler
- */
- @JsxGetter(FF52)
- public Function getOnselectstart() {
- return getEventHandler("selectstart");
- }
-
- /**
- * Sets the {@code onselectstart} event handler.
- * @param selectstart the {@code onselectstart} event handler
- */
- @JsxSetter(FF52)
- public void setOnselectstart(final Object selectstart) {
- setEventHandler("selectstart", selectstart);
- }
-
/**
* Returns the {@code doNotTrack} property.
* @return the {@code doNotTrack} property
@@ -4494,6 +4535,14 @@ public Object getDoNotTrack() {
}
return null;
}
+
+ @Override
+ protected boolean isReadOnlySettable(final String name, final Object value) {
+ if ("closed".equals(name)) {
+ return false; //ignore
+ }
+ return super.isReadOnlySettable(name, value);
+ }
}
class HTMLCollectionFrames extends HTMLCollection {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WindowProxy.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WindowProxy.java
index d14c55b3d5f..3cbec24193f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WindowProxy.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/WindowProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XPathExpression.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XPathExpression.java
index cf9a5556ab7..2239485d8f7 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XPathExpression.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/XPathExpression.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -27,7 +26,7 @@
*
* @author Ahmed Ashour
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class XPathExpression extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Animation.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/Animation.java
similarity index 71%
rename from src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Animation.java
rename to src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/Animation.java
index f082f5c7f97..576f369fb90 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Animation.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/Animation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -12,21 +12,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.gargoylesoftware.htmlunit.javascript.host;
+package com.gargoylesoftware.htmlunit.javascript.host.animations;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
+import com.gargoylesoftware.htmlunit.javascript.host.event.EventTarget;
/**
* A JavaScript object for {@code Animation}.
*
* @author Ronald Brill
*/
-@JsxClass(FF52)
-public class Animation extends SimpleScriptable {
+@JsxClass({CHROME, FF})
+public class Animation extends EventTarget {
/**
* Creates a new instance.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/AnimationEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/AnimationEvent.java
similarity index 82%
rename from src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/AnimationEvent.java
rename to src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/AnimationEvent.java
index 19d321766f2..d60b68ec27f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/AnimationEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/AnimationEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -12,14 +12,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.gargoylesoftware.htmlunit.javascript.host.event;
+package com.gargoylesoftware.htmlunit.javascript.host.animations;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
+import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
/**
* A JavaScript object for {@code AnimationEvent}.
@@ -32,7 +32,7 @@ public class AnimationEvent extends Event {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public AnimationEvent() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Proxy.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/KeyframeEffect.java
similarity index 70%
rename from src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Proxy.java
rename to src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/KeyframeEffect.java
index aaea7e26f14..eb28115464b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Proxy.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/KeyframeEffect.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -12,29 +12,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.gargoylesoftware.htmlunit.javascript.host;
+package com.gargoylesoftware.htmlunit.javascript.host.animations;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF68;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
/**
- * A JavaScript object for {@code Proxy}.
+ * A JavaScript object for {@code KeyframeEffect}.
*
- * @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, FF, EDGE})
-public class Proxy extends SimpleScriptable {
+@JsxClass({CHROME, FF68})
+public class KeyframeEffect extends SimpleScriptable {
/**
- * Creates an instance.
+ * Creates a new instance.
*/
@JsxConstructor
- public Proxy() {
+ public KeyframeEffect() {
}
-
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/moz/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/package-info.java
similarity index 72%
rename from src/main/java/com/gargoylesoftware/htmlunit/javascript/host/moz/package-info.java
rename to src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/package-info.java
index 9deced31fca..6382b9bf455 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/moz/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/animations/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
*/
/**
- * Implementations of the Mozilla JavaScript host objects - users of HtmlUnit shouldn't
+ * Implementations of the JavaScript host objects for the Web Animations API - users of HtmlUnit shouldn't
* need anything in this package.
*/
-package com.gargoylesoftware.htmlunit.javascript.host.moz;
+package com.gargoylesoftware.htmlunit.javascript.host.animations;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBuffer.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBuffer.java
deleted file mode 100644
index 4504095418f..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBuffer.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
-
-import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
-import net.sourceforge.htmlunit.corejs.javascript.Undefined;
-
-/**
- * A data type that is used to represent a generic, fixed-length binary data buffer.
- *
- * @author Ahmed Ashour
- * @author Frank Danek
- * @author Ronald Brill
- */
-@JsxClass
-public class ArrayBuffer extends SimpleScriptable {
-
- private byte[] bytes_;
-
- /**
- * Ctor.
- */
- public ArrayBuffer() {
- }
-
- /**
- * Ctor with given bytes.
- * @param bytes the initial bytes
- */
- public ArrayBuffer(final byte[] bytes) {
- bytes_ = bytes;
- }
-
- /**
- * The constructor.
- * @param length the size, in bytes, of the array buffer to create.
- */
- @JsxConstructor
- public void constructor(final int length) {
- if (length < 0) {
- throw ScriptRuntime.rangeError("invalid array length '" + length + "'.");
- }
- bytes_ = new byte[length];
- }
-
- /**
- * Returns the size, in bytes, of the array. This is established during construction and cannot be changed.
- * @return the byte length.
- */
- @JsxGetter
- public int getByteLength() {
- return bytes_.length;
- }
-
- /**
- * Returns a new ArrayBuffer whose contents are a copy of this ArrayBuffer's bytes
- * from begin, inclusive, up to end, exclusive.
- * @param begin byte index to start slicing
- * @param end (optional) byte index to end slicing
- * @return the newly created ArrayBuffer
- */
- @JsxFunction
- public ArrayBuffer slice(final Object begin, final Object end) {
- if (begin == Undefined.instance || begin instanceof Boolean) {
- throw Context.reportRuntimeError("Invalid type " + begin.getClass().getName());
- }
-
- final double beginNumber = Context.toNumber(begin);
- final int beginInt;
- if (Double.isNaN(beginNumber)) {
- beginInt = 0;
- }
- else if (Double.isInfinite(beginNumber)) {
- if (beginNumber > 0) {
- final byte[] byteArray = new byte[0];
- return new ArrayBuffer(byteArray);
- }
- beginInt = 0;
- }
- else {
- beginInt = (int) beginNumber;
- if (beginInt != beginNumber) {
- throw Context.reportRuntimeError("Invalid type " + begin.getClass().getName());
- }
- }
-
- double endNumber;
- if (end == Undefined.instance) {
- endNumber = getByteLength();
- }
- else {
- endNumber = Context.toNumber(end);
- }
-
- if (Double.isNaN(endNumber) || Double.isInfinite(endNumber) || endNumber < beginInt) {
- endNumber = beginInt;
- }
-
- final byte[] byteArray = new byte[(int) endNumber - beginInt];
- System.arraycopy(bytes_, beginInt, byteArray, 0, byteArray.length);
- return new ArrayBuffer(byteArray);
- }
-
- byte getByte(final int index) {
- return bytes_[index];
- }
-
- /**
- * Sets the bytes.
- * @param index the starting index
- * @param array the array
- */
- public void setBytes(final int index, final byte[] array) {
- int i = array.length - 1;
- if (index + i >= bytes_.length) {
- i = bytes_.length - index - 1;
- }
- for ( ; i >= 0; i--) {
- bytes_[index + i] = array[i];
- }
- }
-
- /**
- * @return the bytes
- */
- public byte[] getBytes() {
- return bytes_;
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBufferView.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBufferView.java
deleted file mode 100644
index 0413c9075cc..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBufferView.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
-
-/**
- * The ArrayBufferView type describes a particular view on the contents of an {@link ArrayBuffer}'s data.
- *
- * @author Ahmed Ashour
- * @author Frank Danek
- */
-@JsxClass(isJSObject = false)
-public class ArrayBufferView extends SimpleScriptable {
-
- private ArrayBuffer buffer_;
- private int byteLength_;
- private int byteOffset_;
-
- /**
- * The constructor.
- * @param buffer the array buffer
- * @param byteOffset the byte offset
- * @param length the length
- */
- protected void constructor(final ArrayBuffer buffer, final int byteOffset, final int length) {
- buffer_ = buffer;
- byteOffset_ = byteOffset;
- byteLength_ = length;
- }
-
- /**
- * Returns the buffer this view references.
- * @return the buffer
- */
- @JsxGetter
- public ArrayBuffer getBuffer() {
- return buffer_;
- }
-
- /**
- * Sets the buffer.
- * @param buffer the buffer
- */
- protected void setBuffer(final ArrayBuffer buffer) {
- buffer_ = buffer;
- }
-
- /**
- * Returns the length, in bytes, of the view.
- * @return the length
- */
- @JsxGetter
- public int getByteLength() {
- return byteLength_;
- }
-
- /**
- * Sets the bytes length.
- * @param byteLength the bytes length
- */
- protected void setByteLength(final int byteLength) {
- byteLength_ = byteLength;
- }
-
- /**
- * Returns the offset, in bytes, to the first byte of the view within the {@link ArrayBuffer}.
- * @return the offset
- */
- @JsxGetter
- public int getByteOffset() {
- return byteOffset_;
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBufferViewBase.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBufferViewBase.java
deleted file mode 100644
index d7668e02993..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/ArrayBufferViewBase.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_TYPED_ARRAYS_NULL;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
-
-import net.sourceforge.htmlunit.corejs.javascript.Context;
-import net.sourceforge.htmlunit.corejs.javascript.NativeArray;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
-import net.sourceforge.htmlunit.corejs.javascript.Undefined;
-import net.sourceforge.htmlunit.corejs.javascript.Wrapper;
-
-/**
- * The parent class of all typed arrays, {@link DataView} is not included.
- *
- * @author Ahmed Ashour
- * @author Marc Guillemot
- * @author Frank Danek
- * @author Ronald Brill
- */
-@JsxClass(isJSObject = false)
-public class ArrayBufferViewBase extends ArrayBufferView {
-
- /**
- * The constructor.
- *
- * @param object the object
- * @param byteOffset optional byteOffset
- * @param length optional length
- */
- public void constructor(final Object object, final Object byteOffset, final Object length) {
- if (object instanceof Number) {
- constructor(((Number) object).intValue());
- }
- else if (object instanceof NativeArray) {
- constructor((NativeArray) object);
- }
- else if (object instanceof ArrayBufferViewBase) {
- constructor((ArrayBufferViewBase) object);
- }
- else if (object instanceof ArrayBuffer) {
- final ArrayBuffer array = (ArrayBuffer) object;
-
- double dbByteOffset = Context.toNumber(byteOffset);
- if (Double.isNaN(dbByteOffset)) {
- dbByteOffset = 0;
- }
-
- double dbLength = Context.toNumber(length);
- if (Double.isNaN(dbLength)) {
- dbLength = array.getByteLength();
- }
- super.constructor(array, (int) dbByteOffset, (int) dbLength);
- }
- else if (object == Undefined.instance || getBrowserVersion().hasFeature(JS_TYPED_ARRAYS_NULL)) {
- constructor(0);
- }
- else {
- throw ScriptRuntime.typeError("invalid arguments");
- }
- }
-
- private void constructor(final int length) {
- final int byteLength = length * getBytesPerElement();
- setByteLength(byteLength);
- initBuffer(byteLength);
- }
-
- private void constructor(final NativeArray array) {
- final int byteLength = (int) array.getLength() * getBytesPerElement();
- setByteLength(byteLength);
- initBuffer(byteLength);
- set(array, 0);
- }
-
- private void constructor(final ArrayBufferViewBase array) {
- final int byteLength = array.getLength() * getBytesPerElement();
- setByteLength(byteLength);
- initBuffer(byteLength);
- set(array, 0);
- }
-
- private void initBuffer(final int lengthInBytes) {
- final ArrayBuffer buffer = new ArrayBuffer();
- buffer.constructor(lengthInBytes);
- buffer.setPrototype(getPrototype(buffer.getClass()));
- buffer.setParentScope(getParentScope());
- setBuffer(buffer);
- }
-
- /**
- * Returns the number of entries in the array.
- * @return the number of entries
- */
- @JsxGetter
- public int getLength() {
- return getByteLength() / getBytesPerElement();
- }
-
- /**
- * Sets multiple values in the typed array, reading input values from a specified array.
- * @param sourceArray the source array
- * @param offset the offset into the target array at which to begin writing values from the source one
- */
- @JsxFunction
- public void set(final ScriptableObject sourceArray, final int offset) {
- final Object lengthProperty = ScriptableObject.getProperty(sourceArray, "length");
- if (lengthProperty instanceof Number) {
- final int length = ((Number) lengthProperty).intValue();
- for (int i = 0; i < length; i++) {
- final Object value = sourceArray.get(i, sourceArray);
- if (value == Scriptable.NOT_FOUND || value == Undefined.instance) {
- put(i + offset, this, Double.NaN);
- }
- else if (value == null) {
- put(i + offset, this, 0);
- }
- else if (value instanceof Wrapper) {
- put(i + offset, this, ((Wrapper) value).unwrap());
- }
- else {
- put(i + offset, this, value);
- }
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Object get(final int index, final Scriptable start) {
- final int offset = index * getBytesPerElement() + getByteOffset();
- final ArrayBuffer buffer = getBuffer();
- if (buffer == null) {
- return Scriptable.NOT_FOUND;
- }
- return fromArray(buffer.getBytes(), offset);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void put(final int index, final Scriptable start, final Object value) {
- getBuffer().setBytes(index * getBytesPerElement() + getByteOffset(),
- value == null ? toByteArray(null) : toByteArray(Context.toNumber(value)));
- }
-
- /**
- * Converts the provided number to byte array.
- * @param number the number
- * @return the byte array
- */
- protected byte[] toByteArray(final Number number) {
- return null;
- }
-
- /**
- * Converts the provided byte array to number.
- * @param array the array
- * @param offset the offset
- * @return the byte array
- */
- protected Object fromArray(final byte[] array, final int offset) {
- return null;
- }
-
- /**
- * Returns a new view on the ArrayBuffer store for this object.
- * @param begin the offset to the first element in the array to be referenced by the new object
- * @param end the end offset (exclusive), optional to return at the end.
- * @return the newly created array
- */
- @JsxFunction
- public ArrayBufferView subarray(final int begin, Object end) {
- if (end == Undefined.instance) {
- end = getLength();
- }
- try {
- final ArrayBufferView object = getClass().newInstance();
- object.setPrototype(getPrototype());
- object.setParentScope(getParentScope());
- object.constructor(getBuffer(), begin, ((Number) end).intValue() - begin);
- return object;
- }
- catch (final Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Returns the size in bytes of an item in this array.
- * @return the size of bytes of an item
- */
- protected int getBytesPerElement() {
- return 1;
- }
-
- /**
- * @return the string version
- */
- @JsxFunction(functionName = "toString")
- public String jsToString() {
- final int arrayLength = getLength();
- final StringBuilder builder = new StringBuilder();
- if (arrayLength > 0) {
- builder.append(ScriptRuntime.toString(get(0, this)));
- }
- for (int i = 1; i < arrayLength; i++) {
- builder.append(',');
- builder.append(ScriptRuntime.toString(get(i, this)));
- }
- return builder.toString();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Object getDefaultValue(final Class> hint) {
- if (String.class.equals(hint) || hint == null) {
- return jsToString();
- }
- return super.getDefaultValue(hint);
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Atomics.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Atomics.java
index cbd2d42da4b..6a0ccddce5c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Atomics.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Atomics.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/DataView.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/DataView.java
deleted file mode 100644
index 2e0767b3df8..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/DataView.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
-
-import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
-import net.sourceforge.htmlunit.corejs.javascript.Undefined;
-
-/**
- * The ArrayBufferView type describes a particular view on the contents of an {@link ArrayBuffer}'s data.
- *
- * @author Ahmed Ashour
- * @author Frank Danek
- */
-@JsxClass
-public class DataView extends ArrayBufferView {
-
- /**
- * JavaScript constructor.
- * @param array the array
- * @param byteOffset the byte offset
- * @param length the length
- */
- @JsxConstructor
- public void constructor(final Object array, final int byteOffset, Object length) {
- if (!(array instanceof ArrayBuffer)) {
- throw ScriptRuntime.typeError("First argument to DataView constructor must be an ArrayBuffer");
- }
- if (length == Undefined.instance) {
- length = ((ArrayBuffer) array).getByteLength();
- }
- super.constructor((ArrayBuffer) array, byteOffset, ((Number) length).intValue());
- }
-
- /**
- * Gets a signed 8-bit integer at the specified byte offset from the start of the view.
- * @param byteOffset the byte offset
- * @return the byte
- */
- @JsxFunction
- public byte getInt8(final int byteOffset) {
- return getBuffer().getBytes()[getByteOffset() + byteOffset];
- }
-
- /**
- * Sets the given signed 8-bit integer at the specified offset.
- * @param byteOffset the byte offset
- * @param value the value
- */
- @JsxFunction
- public void setInt8(final int byteOffset, final int value) {
- final byte[] array = getBuffer().getBytes();
- array[getByteOffset() + byteOffset] = (byte) value;
- }
-
- /**
- * Gets a signed 16-bit integer at the specified byte offset from the start of the view.
- * @param byteOffset the byte offset
- * @param littleEndian whether the value is stored in little- or big-endian format
- * @return the value
- */
- @JsxFunction
- public short getInt16(final int byteOffset, final boolean littleEndian) {
- final ByteBuffer buff = ByteBuffer.wrap(getBuffer().getBytes());
- if (littleEndian) {
- buff.order(ByteOrder.LITTLE_ENDIAN);
- }
- return buff.getShort(getByteOffset() + byteOffset);
- }
-
- /**
- * Sets the given signed 16-bit integer at the specified offset.
- * @param byteOffset the byte offset
- * @param value the value
- * @param littleEndian whether the value is stored in little- or big-endian format
- */
- @JsxFunction
- public void setInt16(final int byteOffset, final int value, final boolean littleEndian) {
- final ByteBuffer buff = ByteBuffer.wrap(getBuffer().getBytes());
- if (littleEndian) {
- buff.order(ByteOrder.LITTLE_ENDIAN);
- }
- buff.putShort(getByteOffset() + byteOffset, (short) value);
- }
-
- /**
- * Gets a signed 32-bit integer at the specified byte offset from the start of the view.
- * @param byteOffset the byte offset
- * @param littleEndian whether the value is stored in little- or big-endian format
- * @return the value
- */
- @JsxFunction
- public int getInt32(final int byteOffset, final boolean littleEndian) {
- final ByteBuffer buff = ByteBuffer.wrap(getBuffer().getBytes());
- if (littleEndian) {
- buff.order(ByteOrder.LITTLE_ENDIAN);
- }
- return buff.getInt(getByteOffset() + byteOffset);
- }
-
- /**
- * Sets the given signed 32-bit integer at the specified offset.
- * @param byteOffset the byte offset
- * @param value the value
- * @param littleEndian whether the value is stored in little- or big-endian format
- */
- @JsxFunction
- public void setInt32(final int byteOffset, final int value, final boolean littleEndian) {
- final ByteBuffer buff = ByteBuffer.wrap(getBuffer().getBytes());
- if (littleEndian) {
- buff.order(ByteOrder.LITTLE_ENDIAN);
- }
- buff.putInt(getByteOffset() + byteOffset, value);
- }
-
- /**
- * Gets an unsigned 8-bit integer at the specified byte offset from the start of the view.
- * @param byteOffset the byte offset
- * @return the value
- */
- @JsxFunction
- public int getUint8(final int byteOffset) {
- return getBuffer().getBytes()[getByteOffset() + byteOffset] & 0xFF;
- }
-
- /**
- * Sets the given unsigned 8-bit integer at the specified offset.
- * @param byteOffset the byte offset
- * @param value the value
- */
- @JsxFunction
- public void setUint8(final int byteOffset, final int value) {
- setInt8(byteOffset, value);
- }
-
- /**
- * Gets an unsigned 16-bit integer at the specified byte offset from the start of the view.
- * @param byteOffset the byte offset
- * @param littleEndian whether the value is stored in little- or big-endian format
- * @return the value
- */
- @JsxFunction
- public int getUint16(final int byteOffset, final boolean littleEndian) {
- final ByteBuffer buff = ByteBuffer.wrap(getBuffer().getBytes());
- if (littleEndian) {
- buff.order(ByteOrder.LITTLE_ENDIAN);
- }
- return buff.getShort(getByteOffset() + byteOffset) & 0xFFFF;
- }
-
- /**
- * Sets the given unsigned 16-bit integer at the specified offset.
- * @param byteOffset the byte offset
- * @param value the value
- * @param littleEndian whether the value is stored in little- or big-endian format
- */
- @JsxFunction
- public void setUint16(final int byteOffset, final int value, final boolean littleEndian) {
- setInt16(byteOffset, value, littleEndian);
- }
-
- /**
- * Gets an unsigned 32-bit integer at the specified byte offset from the start of the view.
- * @param byteOffset the byte offset
- * @param littleEndian whether the value is stored in little- or big-endian format
- * @return the value
- */
- @JsxFunction
- public long getUint32(final int byteOffset, final boolean littleEndian) {
- final ByteBuffer buff = ByteBuffer.wrap(getBuffer().getBytes());
- if (littleEndian) {
- buff.order(ByteOrder.LITTLE_ENDIAN);
- }
- return buff.getInt(getByteOffset() + byteOffset) & 0xFFFFFFFFL;
- }
-
- /**
- * Sets the given unsigned 32-bit integer at the specified offset.
- * @param byteOffset the byte offset
- * @param value the value
- * @param littleEndian whether the value is stored in little- or big-endian format
- */
- @JsxFunction
- public void setUint32(final int byteOffset, final int value, final boolean littleEndian) {
- setInt32(byteOffset, value, littleEndian);
- }
-
- /**
- * Gets a 32-bit floating point number at the specified byte offset from the start of the view.
- * @param byteOffset the byte offset
- * @param littleEndian whether the value is stored in little- or big-endian format
- * @return the value
- */
- @JsxFunction
- public float getFloat32(final int byteOffset, final boolean littleEndian) {
- final ByteBuffer buff = ByteBuffer.wrap(getBuffer().getBytes());
- if (littleEndian) {
- buff.order(ByteOrder.LITTLE_ENDIAN);
- }
- return buff.getFloat(getByteOffset() + byteOffset);
- }
-
- /**
- * Sets the given 32-bit floating point number at the specified offset.
- * @param byteOffset the byte offset
- * @param value the value
- * @param littleEndian whether the value is stored in little- or big-endian format
- */
- @JsxFunction
- public void setFloat32(final int byteOffset, final double value, final boolean littleEndian) {
- final ByteBuffer buff = ByteBuffer.wrap(getBuffer().getBytes());
- if (littleEndian) {
- buff.order(ByteOrder.LITTLE_ENDIAN);
- }
- buff.putFloat(getByteOffset() + byteOffset, (float) value);
- }
-
- /**
- * Gets a 64-bit floating point number at the specified byte offset from the start of the view.
- * @param byteOffset the byte offset
- * @param littleEndian whether the value is stored in little- or big-endian format
- * @return the value
- */
- @JsxFunction
- public double getFloat64(final int byteOffset, final boolean littleEndian) {
- final ByteBuffer buff = ByteBuffer.wrap(getBuffer().getBytes());
- if (littleEndian) {
- buff.order(ByteOrder.LITTLE_ENDIAN);
- }
- return buff.getDouble(getByteOffset() + byteOffset);
- }
-
- /**
- * Sets the given 32-bit floating point number at the specified offset.
- * @param byteOffset the byte offset
- * @param value the value
- * @param littleEndian whether the value is stored in little- or big-endian format
- */
- @JsxFunction
- public void setFloat64(final int byteOffset, final double value, final boolean littleEndian) {
- final ByteBuffer buff = ByteBuffer.wrap(getBuffer().getBytes());
- if (littleEndian) {
- buff.order(ByteOrder.LITTLE_ENDIAN);
- }
- buff.putDouble(getByteOffset() + byteOffset, value);
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Float32Array.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Float32Array.java
deleted file mode 100644
index 11076f7ed69..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Float32Array.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
-/**
- * Represents an array of 32-bit floating point numbers.
- *
- * @author Ahmed Ashour
- * @author Frank Danek
- * @author Ronald Brill
- * @author Michael Rimov
- */
-@JsxClass
-public class Float32Array extends ArrayBufferViewBase {
-
- /** The size, in bytes, of each array element. */
- @JsxConstant
- public static final int BYTES_PER_ELEMENT = 4;
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxConstructor
- public void constructor(final Object object, final Object byteOffset, final Object length) {
- super.constructor(object, byteOffset, length);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected byte[] toByteArray(final Number number) {
- final ByteBuffer buff = ByteBuffer.allocate(BYTES_PER_ELEMENT);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- buff.putFloat(number != null ? number.floatValue() : Float.NaN);
- return buff.array();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object fromArray(final byte[] array, final int offset) {
- if (offset < 0 || offset >= array.length) {
- return Scriptable.NOT_FOUND;
- }
- final ByteBuffer buff = ByteBuffer.wrap(array);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- return buff.getFloat(offset);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected int getBytesPerElement() {
- return BYTES_PER_ELEMENT;
- }
-
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Float64Array.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Float64Array.java
deleted file mode 100644
index 92ea811ec95..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Float64Array.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
-/**
- * Represents an array of 64-bit floating point numbers.
- *
- * @author Ahmed Ashour
- * @author Frank Danek
- * @author Ronald Brill
- * @author Michael Rimov
- */
-@JsxClass
-public class Float64Array extends ArrayBufferViewBase {
-
- /** The size, in bytes, of each array element. */
- @JsxConstant
- public static final int BYTES_PER_ELEMENT = 8;
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxConstructor
- public void constructor(final Object object, final Object byteOffset, final Object length) {
- super.constructor(object, byteOffset, length);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected byte[] toByteArray(final Number number) {
- final ByteBuffer buff = ByteBuffer.allocate(BYTES_PER_ELEMENT);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- buff.putDouble(number != null ? number.doubleValue() : Double.NaN);
- return buff.array();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object fromArray(final byte[] array, final int offset) {
- if (offset < 0 || offset >= array.length) {
- return Scriptable.NOT_FOUND;
- }
- final ByteBuffer buff = ByteBuffer.wrap(array);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- return buff.getDouble(offset);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected int getBytesPerElement() {
- return BYTES_PER_ELEMENT;
- }
-
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Int16Array.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Int16Array.java
deleted file mode 100644
index 68e6e3bba60..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Int16Array.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
-/**
- * Represents an array of twos-complement 16-bit signed integers.
- *
- * @author Ahmed Ashour
- * @author Frank Danek
- * @author Ronald Brill
- * @author Michael Rimov
- */
-@JsxClass
-public class Int16Array extends ArrayBufferViewBase {
-
- /** The size, in bytes, of each array element. */
- @JsxConstant
- public static final int BYTES_PER_ELEMENT = 2;
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxConstructor
- public void constructor(final Object object, final Object byteOffset, final Object length) {
- super.constructor(object, byteOffset, length);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected byte[] toByteArray(final Number number) {
- final ByteBuffer buff = ByteBuffer.allocate(BYTES_PER_ELEMENT);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- if (number == null || Double.isInfinite(number.doubleValue())) {
- buff.putShort((short) 0);
- return buff.array();
- }
- buff.putShort(number.shortValue());
- return buff.array();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object fromArray(final byte[] array, final int offset) {
- if (offset < 0 || offset >= array.length) {
- return Scriptable.NOT_FOUND;
- }
- final ByteBuffer buff = ByteBuffer.wrap(array);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- return buff.getShort(offset);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected int getBytesPerElement() {
- return BYTES_PER_ELEMENT;
- }
-
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Int32Array.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Int32Array.java
deleted file mode 100644
index 6ffff08d4db..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Int32Array.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
-/**
- * Represents an array of twos-complement 32-bit signed integers.
- *
- * @author Ahmed Ashour
- * @author Frank Danek
- * @author Ronald Brill
- * @author Michael Rimov
- */
-@JsxClass
-public class Int32Array extends ArrayBufferViewBase {
-
- /** The size, in bytes, of each array element. */
- @JsxConstant
- public static final int BYTES_PER_ELEMENT = 4;
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxConstructor
- public void constructor(final Object object, final Object byteOffset, final Object length) {
- super.constructor(object, byteOffset, length);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected byte[] toByteArray(final Number number) {
- final ByteBuffer buff = ByteBuffer.allocate(BYTES_PER_ELEMENT);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- if (number == null || Double.isInfinite(number.doubleValue())) {
- buff.putInt(0);
- return buff.array();
- }
- buff.putInt(number.intValue());
- return buff.array();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object fromArray(final byte[] array, final int offset) {
- if (offset < 0 || offset >= array.length) {
- return Scriptable.NOT_FOUND;
- }
- final ByteBuffer buff = ByteBuffer.wrap(array);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- return buff.getInt(offset);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected int getBytesPerElement() {
- return BYTES_PER_ELEMENT;
- }
-
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Int8Array.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Int8Array.java
deleted file mode 100644
index 8bb493a682f..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Int8Array.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
-/**
- * Represents an array of twos-complement 8-bit signed integers.
- *
- * @author Ahmed Ashour
- * @author Frank Danek
- * @author Ronald Brill
- * @author Michael Rimov
- */
-@JsxClass
-public class Int8Array extends ArrayBufferViewBase {
-
- /** The size, in bytes, of each array element. */
- @JsxConstant
- public static final int BYTES_PER_ELEMENT = 1;
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxConstructor
- public void constructor(final Object object, final Object byteOffset, final Object length) {
- super.constructor(object, byteOffset, length);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected byte[] toByteArray(final Number number) {
- if (number == null || Double.isInfinite(number.doubleValue())) {
- return new byte[] {0};
- }
- return new byte[] {number.byteValue()};
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object fromArray(final byte[] array, final int offset) {
- if (offset < 0 || offset >= array.length) {
- return Scriptable.NOT_FOUND;
- }
- return array[offset];
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected int getBytesPerElement() {
- return BYTES_PER_ELEMENT;
- }
-
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/SharedArrayBuffer.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/SharedArrayBuffer.java
index a3b887eee60..038b84727c9 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/SharedArrayBuffer.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/SharedArrayBuffer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint16Array.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint16Array.java
deleted file mode 100644
index 081435bb151..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint16Array.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
-/**
- * Represents an array of unsigned 16-bit integers.
- *
- * @author Ahmed Ashour
- * @author Frank Danek
- * @author Ronald Brill
- * @author Michael Rimov
- */
-@JsxClass
-public class Uint16Array extends ArrayBufferViewBase {
-
- /** The size, in bytes, of each array element. */
- @JsxConstant
- public static final int BYTES_PER_ELEMENT = 2;
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxConstructor
- public void constructor(final Object object, final Object byteOffset, final Object length) {
- super.constructor(object, byteOffset, length);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected byte[] toByteArray(final Number number) {
- final ByteBuffer buff = ByteBuffer.allocate(BYTES_PER_ELEMENT);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- if (number == null || Double.isInfinite(number.doubleValue())) {
- buff.putShort((short) 0);
- return buff.array();
- }
- buff.putShort(number.shortValue());
- return buff.array();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object fromArray(final byte[] array, final int offset) {
- if (offset < 0 || offset >= array.length) {
- return Scriptable.NOT_FOUND;
- }
- final ByteBuffer buff = ByteBuffer.wrap(array);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- return buff.getShort(offset) & 0xFFFF;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected int getBytesPerElement() {
- return BYTES_PER_ELEMENT;
- }
-
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint32Array.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint32Array.java
deleted file mode 100644
index 51256ac110d..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint32Array.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
-/**
- * Represents an array of unsigned 32-bit integers.
- *
- * @author Ahmed Ashour
- * @author Frank Danek
- * @author Ronald Brill
- * @author Michael Rimov
- */
-@JsxClass
-public class Uint32Array extends ArrayBufferViewBase {
-
- /** The size, in bytes, of each array element. */
- @JsxConstant
- public static final int BYTES_PER_ELEMENT = 4;
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxConstructor
- public void constructor(final Object object, final Object byteOffset, final Object length) {
- super.constructor(object, byteOffset, length);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected byte[] toByteArray(final Number number) {
- final ByteBuffer buff = ByteBuffer.allocate(BYTES_PER_ELEMENT);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- if (number == null || Double.isInfinite(number.doubleValue())) {
- buff.putInt(0);
- return buff.array();
- }
- buff.putInt(number.intValue());
- return buff.array();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object fromArray(final byte[] array, final int offset) {
- if (offset < 0 || offset >= array.length) {
- return Scriptable.NOT_FOUND;
- }
- final ByteBuffer buff = ByteBuffer.wrap(array);
- buff.order(ByteOrder.LITTLE_ENDIAN);
- return buff.getInt(offset) & 0xFFFFFFFFL;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected int getBytesPerElement() {
- return BYTES_PER_ELEMENT;
- }
-
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint8Array.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint8Array.java
deleted file mode 100644
index c7f4dd5878e..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint8Array.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-import com.gargoylesoftware.htmlunit.javascript.host.Window;
-
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
-/**
- * Represents an array of unsigned 16-bit integers.
- *
- * @author Ahmed Ashour
- * @author Frank Danek
- * @author Ronald Brill
- * @author Michael Rimov
- */
-@JsxClass
-public class Uint8Array extends ArrayBufferViewBase {
-
- /**
- * Ctor.
- */
- public Uint8Array() {
- super();
- }
-
- /**
- * Ctor.
- *
- * @param bytes the bytes to store
- * @param window the context
- */
- public Uint8Array(final byte[] bytes, final Window window) {
- this();
- setPrototype(window.getPrototype(getClass()));
- setParentScope(getParentScope());
-
- setByteLength(bytes.length);
-
- final ArrayBuffer buffer = new ArrayBuffer(bytes);
- buffer.setPrototype(window.getPrototype(buffer.getClass()));
- buffer.setParentScope(getParentScope());
- setBuffer(buffer);
- }
-
- /** The size, in bytes, of each array element. */
- @JsxConstant
- public static final int BYTES_PER_ELEMENT = 1;
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxConstructor
- public void constructor(final Object object, final Object byteOffset, final Object length) {
- super.constructor(object, byteOffset, length);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected byte[] toByteArray(final Number number) {
- if (number == null || Double.isInfinite(number.doubleValue())) {
- return new byte[] {0};
- }
- return new byte[] {number.byteValue()};
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object fromArray(final byte[] array, final int offset) {
- if (offset < 0 || offset >= array.length) {
- return Scriptable.NOT_FOUND;
- }
- return array[offset] & 0xFF;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected int getBytesPerElement() {
- return BYTES_PER_ELEMENT;
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint8ClampedArray.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint8ClampedArray.java
deleted file mode 100644
index 8f9c6bcfaf4..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/Uint8ClampedArray.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.arrays;
-
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
-/**
- * Represents an array of unsigned 16-bit integers. Values stored in this array are clamped to the range 0-255.
- *
- * @author Ahmed Ashour
- * @author Ronald Brill
- * @author Michael Rimov
- */
-@JsxClass
-public class Uint8ClampedArray extends ArrayBufferViewBase {
-
- /** The size, in bytes, of each array element. */
- @JsxConstant
- public static final int BYTES_PER_ELEMENT = 1;
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxConstructor
- public void constructor(final Object object, final Object byteOffset, final Object length) {
- super.constructor(object, byteOffset, length);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected byte[] toByteArray(Number number) {
- if (number == null || number.intValue() < 0) {
- number = 0;
- }
- else if (number.intValue() > 255) {
- number = 255;
- }
- return new byte[] {number.byteValue()};
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Object fromArray(final byte[] array, final int offset) {
- if (offset < 0 || offset >= array.length) {
- return Scriptable.NOT_FOUND;
- }
- return array[offset] & 0xFF;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected int getBytesPerElement() {
- return BYTES_PER_ELEMENT;
- }
-
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/package-info.java
index 8f19c521c48..8ed8d00eb2d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/arrays/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/budget/BudgetService.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/budget/BudgetService.java
deleted file mode 100644
index ed9cb66919e..00000000000
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/budget/BudgetService.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.gargoylesoftware.htmlunit.javascript.host.budget;
-
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-
-import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
-
-/**
- * A JavaScript object for {@code BudgetService}.
- *
- * @author Ahmed Ashour
- * @author Ronald Brill
- */
-@JsxClass(CHROME)
-public class BudgetService extends SimpleScriptable {
-
- /**
- * Creates an instance.
- */
- @JsxConstructor
- public BudgetService() {
- }
-}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasCaptureMediaStream.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasCaptureMediaStream.java
index c317c6592d1..3248f8e8c85 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasCaptureMediaStream.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasCaptureMediaStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasCaptureMediaStreamTrack.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasCaptureMediaStreamTrack.java
index 1f34c8e0575..ae0f77c3c49 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasCaptureMediaStreamTrack.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasCaptureMediaStreamTrack.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasGradient.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasGradient.java
index 143a43ab971..5092a6479c8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasGradient.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasGradient.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -35,7 +34,7 @@ public class CanvasGradient extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public CanvasGradient() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasPattern.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasPattern.java
index cdfdbbd730e..114cc2dcefb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasPattern.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasPattern.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class CanvasPattern extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public CanvasPattern() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasRenderingContext2D.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasRenderingContext2D.java
index 6fa05d8be13..440e7800906 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasRenderingContext2D.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/CanvasRenderingContext2D.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,16 +14,16 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CANVAS_DRAW_THROWS_FOR_MISSING_IMG;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
import java.io.IOException;
import javax.imageio.ImageReader;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import com.gargoylesoftware.htmlunit.html.HtmlImage;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -49,13 +49,16 @@
*/
@JsxClass
public class CanvasRenderingContext2D extends SimpleScriptable {
+
+ private static final Log LOG = LogFactory.getLog(CanvasRenderingContext2D.class);
+
private final HTMLCanvasElement canvas_;
private RenderingBackend renderingBackend_;
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public CanvasRenderingContext2D() {
canvas_ = null;
renderingBackend_ = null;
@@ -79,12 +82,32 @@ private RenderingBackend getRenderingBackend() {
return renderingBackend_;
}
+ /**
+ * Specifies the alpha (transparency) value that is applied to shapes and images
+ * before they are drawn onto the canvas..
+ * @return the {@code globalAlpha} property
+ */
+ @JsxGetter
+ public double getGlobalAlpha() {
+ return getRenderingBackend().getGlobalAlpha();
+ }
+
+ /**
+ * Sets the {@code globalAlpha} property.
+ * @param globalAlpha the {@code globalAlpha} property
+ */
+ @JsxSetter
+ public void setGlobalAlpha(final double globalAlpha) {
+ getRenderingBackend().setGlobalAlpha(globalAlpha);
+ }
+
/**
* Returns the {@code fillStyle} property.
* @return the {@code fillStyle} property
*/
@JsxGetter
public Object getFillStyle() {
+ LOG.info("CanvasRenderingContext2D.getFillStyle() not yet implemented");
return null;
}
@@ -103,6 +126,7 @@ public void setFillStyle(final String fillStyle) {
*/
@JsxGetter
public Object getStrokeStyle() {
+ LOG.info("CanvasRenderingContext2D.getStrokeStyle() not yet implemented");
return null;
}
@@ -111,8 +135,8 @@ public Object getStrokeStyle() {
* @param strokeStyle the {@code strokeStyle} property
*/
@JsxSetter
- public void setStrokeStyle(final Object strokeStyle) {
- //empty
+ public void setStrokeStyle(final String strokeStyle) {
+ getRenderingBackend().setStrokeStyle(strokeStyle);
}
/**
@@ -121,7 +145,7 @@ public void setStrokeStyle(final Object strokeStyle) {
*/
@JsxGetter
public double getLineWidth() {
- return 0;
+ return getRenderingBackend().getLineWidth();
}
/**
@@ -130,25 +154,12 @@ public double getLineWidth() {
*/
@JsxSetter
public void setLineWidth(final Object lineWidth) {
- //empty
- }
-
- /**
- * Returns the {@code globalAlpha} property.
- * @return the {@code globalAlpha} property
- */
- @JsxGetter
- public double getGlobalAlpha() {
- return 0;
- }
-
- /**
- * Sets the {@code globalAlpha} property.
- * @param globalAlpha the {@code globalAlpha} property
- */
- @JsxSetter
- public void setGlobalAlpha(final Object globalAlpha) {
- //empty
+ if (!Undefined.isUndefined(lineWidth)) {
+ final double width = Context.toNumber(lineWidth);
+ if (!Double.isNaN(width)) {
+ getRenderingBackend().setLineWidth((int) width);
+ }
+ }
}
/**
@@ -163,7 +174,7 @@ public void setGlobalAlpha(final Object globalAlpha) {
@JsxFunction
public void arc(final double x, final double y, final double radius, final double startAngle,
final double endAngle, final boolean anticlockwise) {
- //empty
+ getRenderingBackend().arc(x, y, radius, startAngle, endAngle, anticlockwise);
}
/**
@@ -177,7 +188,7 @@ public void arc(final double x, final double y, final double radius, final doubl
@JsxFunction
public void arcTo(final double x1, final double y1, final double x2, final double y2,
final double radius) {
- //empty
+ LOG.info("CanvasRenderingContext2D.arcTo() not yet implemented");
}
/**
@@ -185,7 +196,7 @@ public void arcTo(final double x1, final double y1, final double x2, final doubl
*/
@JsxFunction
public void beginPath() {
- //empty
+ getRenderingBackend().beginPath();
}
/**
@@ -200,7 +211,7 @@ public void beginPath() {
@JsxFunction
public void bezierCurveTo(final double cp1x, final double cp1y, final double cp2x, final double cp2y,
final double x, final double y) {
- //empty
+ getRenderingBackend().bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
}
/**
@@ -220,15 +231,15 @@ public void clearRect(final int x, final int y, final int w, final int h) {
*/
@JsxFunction
public void clip() {
- //empty
+ LOG.info("CanvasRenderingContext2D.clip() not yet implemented");
}
/**
- * Closes the subpaths.
+ * Closes the current subpath.
*/
@JsxFunction
public void closePath() {
- //empty
+ getRenderingBackend().closePath();
}
/**
@@ -236,7 +247,7 @@ public void closePath() {
*/
@JsxFunction
public void createImageData() {
- //empty
+ LOG.info("CanvasRenderingContext2D.createImageData() not yet implemented");
}
/**
@@ -263,7 +274,7 @@ public CanvasGradient createLinearGradient(final double x0, final double y0, fin
*/
@JsxFunction
public void createPattern() {
- //empty
+ LOG.info("CanvasRenderingContext2D.createPattern() not yet implemented");
}
/**
@@ -310,7 +321,7 @@ public void drawImage(final Object image, final int sx, final int sy, final Obje
Integer dHeightI = null;
Integer sWidthI = null;
Integer sHeightI = null;
- if (dx != Undefined.instance) {
+ if (!Undefined.isUndefined(dx)) {
dxI = ((Number) dx).intValue();
dyI = ((Number) dy).intValue();
dWidthI = ((Number) dWidth).intValue();
@@ -320,7 +331,7 @@ public void drawImage(final Object image, final int sx, final int sy, final Obje
dxI = sx;
dyI = sy;
}
- if (sWidth != Undefined.instance) {
+ if (!Undefined.isUndefined(sWidth)) {
sWidthI = ((Number) sWidth).intValue();
sHeightI = ((Number) sHeight).intValue();
}
@@ -333,9 +344,6 @@ public void drawImage(final Object image, final int sx, final int sy, final Obje
}
}
catch (final IOException ioe) {
- if (getBrowserVersion().hasFeature(JS_CANVAS_DRAW_THROWS_FOR_MISSING_IMG)) {
- throw Context.throwAsScriptRuntimeEx(ioe);
- }
}
}
@@ -368,12 +376,12 @@ public String toDataURL(String type) {
* @param endAngle the endAngle
* @param anticlockwise the anticlockwise
*/
- @JsxFunction({CHROME, FF52})
+ @JsxFunction({CHROME, FF})
public void ellipse(final double x, final double y,
final double radiusX, final double radiusY,
final double rotation, final double startAngle, final double endAngle,
final boolean anticlockwise) {
- //empty
+ getRenderingBackend().ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);
}
/**
@@ -381,7 +389,7 @@ public void ellipse(final double x, final double y,
*/
@JsxFunction
public void fill() {
- //empty
+ getRenderingBackend().fill();
}
/**
@@ -428,7 +436,7 @@ public ImageData getImageData(final int sx, final int sy, final int sw, final in
*/
@JsxFunction
public void getLineDash() {
- //empty
+ LOG.info("CanvasRenderingContext2D.getLineDash() not yet implemented");
}
/**
@@ -436,7 +444,7 @@ public void getLineDash() {
*/
@JsxFunction
public void getLineData() {
- //empty
+ LOG.info("CanvasRenderingContext2D.getLineData() not yet implemented");
}
/**
@@ -444,7 +452,7 @@ public void getLineData() {
*/
@JsxFunction
public void isPointInPath() {
- //empty
+ LOG.info("CanvasRenderingContext2D.isPointInPath() not yet implemented");
}
/**
@@ -454,7 +462,7 @@ public void isPointInPath() {
*/
@JsxFunction
public void lineTo(final double x, final double y) {
- //empty
+ getRenderingBackend().lineTo(x, y);
}
/**
@@ -464,7 +472,7 @@ public void lineTo(final double x, final double y) {
*/
@JsxFunction
public TextMetrics measureText(final Object text) {
- if (text == null || Undefined.instance == text) {
+ if (text == null || Undefined.isUndefined(text)) {
throw Context.throwAsScriptRuntimeEx(
new RuntimeException("Missing argument for CanvasRenderingContext2D.measureText()."));
}
@@ -487,7 +495,7 @@ public TextMetrics measureText(final Object text) {
*/
@JsxFunction
public void moveTo(final double x, final double y) {
- //empty
+ getRenderingBackend().moveTo(x, y);
}
/**
@@ -495,7 +503,7 @@ public void moveTo(final double x, final double y) {
*/
@JsxFunction
public void putImageData() {
- //empty
+ LOG.info("CanvasRenderingContext2D.putImageData() not yet implemented");
}
/**
@@ -508,7 +516,7 @@ public void putImageData() {
@JsxFunction
public void quadraticCurveTo(final double controlPointX, final double controlPointY,
final double endPointX, final double endPointY) {
- //empty
+ getRenderingBackend().quadraticCurveTo(controlPointX, controlPointY, endPointX, endPointY);
}
/**
@@ -520,7 +528,7 @@ public void quadraticCurveTo(final double controlPointX, final double controlPoi
*/
@JsxFunction
public void rect(final double x, final double y, final double w, final double h) {
- //empty
+ getRenderingBackend().rect(x, y, w, h);
}
/**
@@ -528,15 +536,16 @@ public void rect(final double x, final double y, final double w, final double h)
*/
@JsxFunction
public void restore() {
- //empty
+ getRenderingBackend().restore();
}
/**
- * Dummy placeholder.
+ * Adds a rotation to the transformation matrix.
+ * @param angle the angle
*/
@JsxFunction
- public void rotate() {
- //empty
+ public void rotate(final double angle) {
+ getRenderingBackend().rotate(angle);
}
/**
@@ -544,7 +553,7 @@ public void rotate() {
*/
@JsxFunction
public void save() {
- //empty
+ getRenderingBackend().save();
}
/**
@@ -554,7 +563,7 @@ public void save() {
*/
@JsxFunction
public void scale(final Object x, final Object y) {
- //empty
+ LOG.info("CanvasRenderingContext2D.scale() not yet implemented");
}
/**
@@ -562,15 +571,24 @@ public void scale(final Object x, final Object y) {
*/
@JsxFunction
public void setLineDash() {
- //empty
+ LOG.info("CanvasRenderingContext2D.setLineDash() not yet implemented");
}
/**
- * Dummy placeholder.
+ * Resets (overrides) the current transformation to the identity matrix,
+ * and then invokes a transformation described by the arguments of this method.
+ * This lets you scale, rotate, translate (move), and skew the context.
+ * @param m11 Horizontal scaling. A value of 1 results in no scaling
+ * @param m12 Vertical skewing
+ * @param m21 Horizontal skewing
+ * @param m22 Vertical scaling. A value of 1 results in no scaling
+ * @param dx Horizontal translation (moving)
+ * @param dy Vertical translation (moving).
*/
@JsxFunction
- public void setTransform() {
- //empty
+ public void setTransform(final double m11, final double m12,
+ final double m21, final double m22, final double dx, final double dy) {
+ getRenderingBackend().setTransform(m11, m12, m21, m22, dx, dy);
}
/**
@@ -578,7 +596,7 @@ public void setTransform() {
*/
@JsxFunction
public void stroke() {
- //empty
+ getRenderingBackend().stroke();
}
/**
@@ -598,15 +616,24 @@ public void strokeRect(final int x, final int y, final int w, final int h) {
*/
@JsxFunction
public void strokeText() {
- //empty
+ LOG.info("CanvasRenderingContext2D.strokeText() not yet implemented");
}
/**
- * Dummy placeholder.
+ * Multiplies the current transformation with the matrix described by the
+ * arguments of this method. This lets you scale, rotate, translate (move),
+ * and skew the context.
+ * @param m11 Horizontal scaling. A value of 1 results in no scaling
+ * @param m12 Vertical skewing
+ * @param m21 Horizontal skewing
+ * @param m22 Vertical scaling. A value of 1 results in no scaling
+ * @param dx Horizontal translation (moving)
+ * @param dy Vertical translation (moving).
*/
@JsxFunction
- public void transform() {
- //empty
+ public void transform(final double m11, final double m12,
+ final double m21, final double m22, final double dx, final double dy) {
+ getRenderingBackend().transform(m11, m12, m21, m22, dx, dy);
}
/**
@@ -615,8 +642,8 @@ public void transform() {
* @param y the translation distance in the vertical direction
*/
@JsxFunction
- public void translate(final Object x, final Object y) {
- // empty
+ public void translate(final int x, final int y) {
+ getRenderingBackend().translate(x, y);
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ImageBitmapRenderingContext.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ImageBitmapRenderingContext.java
index 290bc02e925..24d37119318 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ImageBitmapRenderingContext.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ImageBitmapRenderingContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -25,8 +25,9 @@
* A JavaScript object for {@code ImageBitmapRenderingContext}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, FF52})
+@JsxClass({CHROME, FF})
public class ImageBitmapRenderingContext extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ImageData.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ImageData.java
index 0ee972c6e83..fb750079956 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ImageData.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ImageData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,17 +15,18 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.ArrayBuffer;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.Uint8ClampedArray;
import com.gargoylesoftware.htmlunit.javascript.host.canvas.rendering.RenderingBackend;
+import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
+import net.sourceforge.htmlunit.corejs.javascript.typedarrays.NativeArrayBuffer;
+import net.sourceforge.htmlunit.corejs.javascript.typedarrays.NativeUint8ClampedArray;
+
/**
* A JavaScript object for {@code ImageData}.
*
@@ -40,12 +41,12 @@ public class ImageData extends SimpleScriptable {
private final int sy_;
private final int width_;
private final int height_;
- private Uint8ClampedArray data_;
+ private NativeUint8ClampedArray data_;
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public ImageData() {
this(null, 0, 0, 0, 0);
}
@@ -77,23 +78,20 @@ public int getHeight() {
}
/**
- * Returns a {@link Uint8ClampedArray} representing a one-dimensional array containing
+ * Returns a {@link NativeUint8ClampedArray} representing a one-dimensional array containing
* the data in the RGBA order, with integer values between 0 and 255 (included).
* @return the {@code data} property
*/
@JsxGetter
- public Uint8ClampedArray getData() {
+ public NativeUint8ClampedArray getData() {
if (data_ == null) {
final byte[] bytes = renderingContext_.getBytes(width_, height_, sx_, sy_);
- final ArrayBuffer arrayBuffer = new ArrayBuffer();
- arrayBuffer.constructor(bytes.length);
- arrayBuffer.setBytes(0, bytes);
+ final NativeArrayBuffer arrayBuffer = new NativeArrayBuffer(bytes.length);
+ System.arraycopy(bytes, 0, arrayBuffer.getBuffer(), 0, bytes.length);
- data_ = new Uint8ClampedArray();
+ data_ = new NativeUint8ClampedArray(arrayBuffer, 0, bytes.length);
data_.setParentScope(getParentScope());
- data_.setPrototype(getPrototype(data_.getClass()));
-
- data_.constructor(arrayBuffer, 0, bytes.length);
+ data_.setPrototype(ScriptableObject.getClassPrototype(getWindow(this), data_.getClassName()));
}
return data_;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/IntersectionObserver.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/IntersectionObserver.java
index 542e9960c68..00ac3a554a9 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/IntersectionObserver.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/IntersectionObserver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -26,8 +27,9 @@
* A JavaScript object for {@code IntersectionObserver}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(CHROME)
+@JsxClass({CHROME, FF})
public class IntersectionObserver extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/IntersectionObserverEntry.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/IntersectionObserverEntry.java
index f337b14ffe4..f4ed38fba75 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/IntersectionObserverEntry.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/IntersectionObserverEntry.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -24,8 +25,9 @@
* A JavaScript object for {@code IntersectionObserverEntry}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(CHROME)
+@JsxClass({CHROME, FF})
public class IntersectionObserverEntry extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/Path2D.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/Path2D.java
index 892bece68ef..fa7a07ca794 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/Path2D.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/Path2D.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/TextMetrics.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/TextMetrics.java
index 18443ab5e75..cd7b48ff1de 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/TextMetrics.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/TextMetrics.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -37,7 +36,7 @@ public class TextMetrics extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public TextMetrics() {
width_ = 0;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGL2RenderingContext.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGL2RenderingContext.java
index b1eda2fc26f..3dbbbde82c8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGL2RenderingContext.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGL2RenderingContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -28,8 +27,9 @@
* A JavaScript object for {@code WebGL2RenderingContext}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, FF52})
+@JsxClass({CHROME, FF})
public class WebGL2RenderingContext extends SimpleScriptable {
/** The constant {@code ACTIVE_ATTRIBUTES}. */
@@ -1645,7 +1645,7 @@ public class WebGL2RenderingContext extends SimpleScriptable {
public static final long STENCIL_FUNC = 2962L;
/** The constant {@code STENCIL_INDEX}. */
- @JsxConstant({FF52, FF45, IE})
+ @JsxConstant(IE)
public static final long STENCIL_INDEX = 6401L;
/** The constant {@code STENCIL_INDEX8}. */
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLActiveInfo.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLActiveInfo.java
index a4023708bff..9d79498c0ec 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLActiveInfo.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLActiveInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class WebGLActiveInfo extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public WebGLActiveInfo() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLBuffer.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLBuffer.java
index 47c64ffab2b..a1533395422 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLBuffer.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLBuffer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class WebGLBuffer extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public WebGLBuffer() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLFramebuffer.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLFramebuffer.java
index d953f315ad1..ba18426202e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLFramebuffer.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLFramebuffer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class WebGLFramebuffer extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public WebGLFramebuffer() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLProgram.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLProgram.java
index c8762169dfd..b4cbdde2423 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLProgram.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLProgram.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class WebGLProgram extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public WebGLProgram() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLQuery.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLQuery.java
index d4e3c7fa0da..d1e05aca93f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLQuery.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLQuery.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -26,7 +26,7 @@
*
* @author Ronald Brill
*/
-@JsxClass({CHROME, FF52})
+@JsxClass({CHROME, FF})
public class WebGLQuery extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLRenderbuffer.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLRenderbuffer.java
index 527c518d350..6d1baf79788 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLRenderbuffer.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLRenderbuffer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class WebGLRenderbuffer extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public WebGLRenderbuffer() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLRenderingContext.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLRenderingContext.java
index 4f2e0226d64..c3c83a94f3f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLRenderingContext.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLRenderingContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,10 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -340,7 +337,7 @@ public class WebGLRenderingContext extends SimpleScriptable {
@JsxConstant
public static final int TEXTURE = 0x1702;
/** The constant {@code STENCIL_INDEX}. */
- @JsxConstant({FF52, FF45, IE})
+ @JsxConstant(IE)
public static final int STENCIL_INDEX = 0x1901;
/** The constant {@code DEPTH_COMPONENT}. */
@JsxConstant
@@ -934,7 +931,7 @@ public class WebGLRenderingContext extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public WebGLRenderingContext() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLSampler.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLSampler.java
index f0946a04556..3fb1af6693c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLSampler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLSampler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -26,7 +26,7 @@
*
* @author Ronald Brill
*/
-@JsxClass({CHROME, FF52})
+@JsxClass({CHROME, FF})
public class WebGLSampler extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLShader.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLShader.java
index 4fb1fa71718..f1dfcc277cc 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLShader.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLShader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class WebGLShader extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public WebGLShader() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLShaderPrecisionFormat.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLShaderPrecisionFormat.java
index f13ad3468e1..3b5eee6e27a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLShaderPrecisionFormat.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLShaderPrecisionFormat.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class WebGLShaderPrecisionFormat extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public WebGLShaderPrecisionFormat() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLSync.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLSync.java
index a25ae96f438..2869b5dfb55 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLSync.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLSync.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -26,7 +26,7 @@
*
* @author Ronald Brill
*/
-@JsxClass({CHROME, FF52})
+@JsxClass({CHROME, FF})
public class WebGLSync extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLTexture.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLTexture.java
index ff4db482fe4..4d7390d2231 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLTexture.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLTexture.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class WebGLTexture extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public WebGLTexture() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLTransformFeedback.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLTransformFeedback.java
index 1b7b0fea6f7..0d8ee52ebe9 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLTransformFeedback.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLTransformFeedback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -26,7 +26,7 @@
*
* @author Ronald Brill
*/
-@JsxClass({CHROME, FF52})
+@JsxClass({CHROME, FF})
public class WebGLTransformFeedback extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLUniformLocation.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLUniformLocation.java
index 78af882600e..e86cb4896db 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLUniformLocation.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLUniformLocation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class WebGLUniformLocation extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public WebGLUniformLocation() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLVertexArrayObject.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLVertexArrayObject.java
index 88d60d608d3..9f172d4f7f8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLVertexArrayObject.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/WebGLVertexArrayObject.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.canvas;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -26,7 +26,7 @@
*
* @author Ronald Brill
*/
-@JsxClass({CHROME, FF52})
+@JsxClass({CHROME, FF})
public class WebGLVertexArrayObject extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/ANGLE_instanced_arrays.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/ANGLE_instanced_arrays.java
index 483343b0dac..352a96c0263 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/ANGLE_instanced_arrays.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/ANGLE_instanced_arrays.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/EXT_texture_filter_anisotropic.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/EXT_texture_filter_anisotropic.java
index 17922e340b5..e3483fd78a5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/EXT_texture_filter_anisotropic.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/EXT_texture_filter_anisotropic.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_element_index_uint.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_element_index_uint.java
index 0f0b261ef89..274c78f026e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_element_index_uint.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_element_index_uint.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_standard_derivatives.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_standard_derivatives.java
index db5125eeef4..4bd4848729d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_standard_derivatives.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_standard_derivatives.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_texture_float.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_texture_float.java
index 101f5df6304..4696b8dfd10 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_texture_float.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_texture_float.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_texture_float_linear.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_texture_float_linear.java
index 4825f1ed606..cc7b1439ceb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_texture_float_linear.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/OES_texture_float_linear.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/WEBGL_compressed_texture_s3tc.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/WEBGL_compressed_texture_s3tc.java
index 7159b1395dc..e79dae5bfc3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/WEBGL_compressed_texture_s3tc.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/WEBGL_compressed_texture_s3tc.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/WEBGL_debug_renderer_info.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/WEBGL_debug_renderer_info.java
index 6bfac0cb75a..c1bea127ae1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/WEBGL_debug_renderer_info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/WEBGL_debug_renderer_info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/package-info.java
index 0b0ad6030fc..3ed5b2a1175 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/ext/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/package-info.java
index c5fb4194da3..56e303986e7 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/AwtRenderingBackend.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/AwtRenderingBackend.java
index ce032d00a01..f1b69dc3143 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/AwtRenderingBackend.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/AwtRenderingBackend.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,12 +14,26 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.canvas.rendering;
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
import java.awt.Color;
+import java.awt.FontMetrics;
import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.List;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
@@ -28,6 +42,8 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import com.gargoylesoftware.htmlunit.util.StringUtils;
+
/**
* The default implementation of {@link RenderingBackend}.
*
@@ -40,6 +56,15 @@ public class AwtRenderingBackend implements RenderingBackend {
private final BufferedImage image_;
private final Graphics2D graphics2D_;
+ private AffineTransform transformation_;
+ private float globalAlpha_;
+ private int lineWidth_;
+ private Color fillColor_;
+ private Color strokeColor_;
+
+ private List subPaths_;
+ private Deque savedStates_;
+
/**
* Constructor.
* @param imageWidth the width
@@ -48,9 +73,272 @@ public class AwtRenderingBackend implements RenderingBackend {
public AwtRenderingBackend(final int imageWidth, final int imageHeight) {
image_ = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
graphics2D_ = image_.createGraphics();
+
+ graphics2D_.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ graphics2D_.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+ graphics2D_.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+
+ reset();
+
graphics2D_.setBackground(new Color(0f, 0f, 0f, 0f));
graphics2D_.setColor(Color.black);
graphics2D_.clearRect(0, 0, imageWidth, imageHeight);
+
+ subPaths_ = new ArrayList<>();
+ savedStates_ = new ArrayDeque<>();
+ }
+
+ private void reset() {
+ fillColor_ = Color.black;
+ strokeColor_ = Color.black;
+ lineWidth_ = 1;
+ transformation_ = new AffineTransform();
+ setGlobalAlpha(1.0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double getGlobalAlpha() {
+ return globalAlpha_;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setGlobalAlpha(final double globalAlpha) {
+ if (globalAlpha >= 0 && globalAlpha <= 1) {
+ globalAlpha_ = (float) globalAlpha;
+ final AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, globalAlpha_);
+ graphics2D_.setComposite(composite);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void beginPath() {
+ subPaths_.clear();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void ellipse(final double x, final double y,
+ final double radiusX, final double radiusY,
+ final double rotation, final double startAngle, final double endAngle,
+ final boolean anticlockwise) {
+ final Path2D subPath = getCurrentSubPath();
+ if (subPath != null) {
+ final Point2D p = transformation_.transform(new Point2D.Double(x, y), null);
+ final double startAngleDegree = 360 - (startAngle * 180 / Math.PI);
+ final double endAngleDegree = 360 - (endAngle * 180 / Math.PI);
+
+ double extendAngle = startAngleDegree - endAngleDegree;
+ extendAngle = Math.min(360, Math.abs(extendAngle));
+ if (anticlockwise && extendAngle < 360) {
+ extendAngle = extendAngle - 360;
+ }
+
+ final AffineTransform transformation = new AffineTransform();
+ transformation.rotate(rotation, p.getX(), p.getY());
+ final Arc2D arc = new Arc2D.Double(p.getX() - radiusX, p.getY() - radiusY, radiusX * 2, radiusY * 2,
+ startAngleDegree, extendAngle * -1, Arc2D.OPEN);
+ subPath.append(transformation.createTransformedShape(arc), false);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void bezierCurveTo(final double cp1x, final double cp1y,
+ final double cp2x, final double cp2y, final double x, final double y) {
+ final Path2D subPath = getCurrentSubPath();
+ if (subPath != null) {
+ final Point2D cp1 = transformation_.transform(new Point2D.Double(cp1x, cp1y), null);
+ final Point2D cp2 = transformation_.transform(new Point2D.Double(cp2x, cp2y), null);
+ final Point2D p = transformation_.transform(new Point2D.Double(x, y), null);
+ subPath.curveTo(cp1.getX(), cp1.getY(), cp2.getX(), cp2.getY(), p.getX(), p.getY());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void arc(final double x, final double y, final double radius, final double startAngle,
+ final double endAngle, final boolean anticlockwise) {
+ final Path2D subPath = getCurrentSubPath();
+ if (subPath != null) {
+ final Point2D p = transformation_.transform(new Point2D.Double(x, y), null);
+ final double startAngleDegree = 360 - (startAngle * 180 / Math.PI);
+ final double endAngleDegree = 360 - (endAngle * 180 / Math.PI);
+
+ double extendAngle = startAngleDegree - endAngleDegree;
+ extendAngle = Math.min(360, Math.abs(extendAngle));
+ if (anticlockwise && extendAngle < 360) {
+ extendAngle = extendAngle - 360;
+ }
+ final Arc2D arc = new Arc2D.Double(p.getX() - radius, p.getY() - radius, radius * 2, radius * 2,
+ startAngleDegree, extendAngle * -1, Arc2D.OPEN);
+ subPath.append(arc, false);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void clearRect(final int x, final int y, final int w, final int h) {
+ graphics2D_.setTransform(transformation_);
+ graphics2D_.setColor(fillColor_);
+ graphics2D_.clearRect(x, y, w, h);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void drawImage(final ImageReader imageReader, final int dxI, final int dyI) throws IOException {
+ if (imageReader.getNumImages(true) != 0) {
+ final BufferedImage img = imageReader.read(0);
+ graphics2D_.setTransform(transformation_);
+ graphics2D_.setColor(fillColor_);
+ graphics2D_.drawImage(img, dxI, dyI, image_.getWidth(), image_.getHeight(), null);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String encodeToString(final String type) throws IOException {
+ String imageType = type;
+ if (imageType != null && imageType.startsWith("image/")) {
+ imageType = imageType.substring(6);
+ }
+ try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
+ ImageIO.write(image_, imageType, bos);
+
+ final byte[] imageBytes = bos.toByteArray();
+ return new String(new Base64().encode(imageBytes), StandardCharsets.US_ASCII);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void fill() {
+ graphics2D_.setTransform(new AffineTransform());
+ graphics2D_.setStroke(new BasicStroke(getLineWidth()));
+ graphics2D_.setColor(fillColor_);
+ for (Path2D path2d : subPaths_) {
+ graphics2D_.fill(path2d);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void fillRect(final int x, final int y, final int w, final int h) {
+ graphics2D_.setTransform(transformation_);
+ graphics2D_.setColor(fillColor_);
+ graphics2D_.fillRect(x, y, w, h);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void fillText(final String text, final int x, final int y) {
+ graphics2D_.setTransform(new AffineTransform());
+
+ final FontMetrics metrics = graphics2D_.getFontMetrics();
+ final int width = metrics.stringWidth(text);
+ final int ascent = metrics.getAscent();
+
+ final float posX = x - width / 2;
+ final float posY = y + ascent / 2;
+
+ graphics2D_.setTransform(transformation_);
+ graphics2D_.setColor(fillColor_);
+ graphics2D_.drawString(text, posX, posY);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public byte[] getBytes(final int width, final int height, final int sx, final int sy) {
+ final byte[] array = new byte[width * height * 4];
+ int index = 0;
+ for (int x = 0; x < width; x++) {
+ for (int y = 0; y < height; y++) {
+ final int color = image_.getRGB(sx + x, sy + y);
+ array[index++] = (byte) ((color & 0xff0000) >> 16);
+ array[index++] = (byte) ((color & 0xff00) >> 8);
+ array[index++] = (byte) (color & 0xff);
+ array[index++] = (byte) ((color & 0xff000000) >>> 24);
+ }
+ }
+ return array;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void lineTo(final double x, final double y) {
+ final Path2D subPath = getCurrentSubPath();
+ if (subPath != null) {
+ final Point2D p = transformation_.transform(new Point2D.Double(x, y), null);
+ subPath.lineTo(p.getX(), p.getY());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void moveTo(final double x, final double y) {
+ final Path2D subPath = new Path2D.Double();
+ final Point2D p = transformation_.transform(new Point2D.Double(x, y), null);
+ subPath.moveTo(p.getX(), p.getY());
+ subPaths_.add(subPath);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void quadraticCurveTo(final double cpx, final double cpy,
+ final double x, final double y) {
+ final Path2D subPath = getCurrentSubPath();
+ if (subPath != null) {
+ final Point2D cp = transformation_.transform(new Point2D.Double(cpx, cpy), null);
+ final Point2D p = transformation_.transform(new Point2D.Double(x, y), null);
+ subPath.quadTo(cp.getX(), cp.getY(), p.getX(), p.getY());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void rect(final double x, final double y, final double w, final double h) {
+ final Path2D subPath = getCurrentSubPath();
+ if (subPath != null) {
+ final Point2D p = transformation_.transform(new Point2D.Double(x, y), null);
+ final Rectangle2D rect = new Rectangle2D.Double(p.getX(), p.getY(), w, h);
+ subPath.append(rect, false);
+ }
}
/**
@@ -69,7 +357,7 @@ else if (tmpFillStyle.startsWith("rgba(")) {
color = new Color(Integer.parseInt(colors[0]), Integer.parseInt(colors[1]), Integer.parseInt(colors[2]),
(int) (Float.parseFloat(colors[3]) * 255));
}
- else if (tmpFillStyle.startsWith("#")) {
+ else if (tmpFillStyle.length() > 0 && tmpFillStyle.charAt(0) == '#') {
color = Color.decode(tmpFillStyle);
}
else {
@@ -78,89 +366,181 @@ else if (tmpFillStyle.startsWith("#")) {
color = (Color) f.get(null);
}
catch (final Exception e) {
- LOG.info("Can not find color '" + tmpFillStyle + '\'');
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Can not find color '" + tmpFillStyle + '\'');
+ }
color = Color.black;
}
}
- graphics2D_.setColor(color);
+ fillColor_ = color;
}
/**
* {@inheritDoc}
*/
@Override
- public void clearRect(final int x, final int y, final int w, final int h) {
- graphics2D_.clearRect(x, y, w, h);
+ public void setStrokeStyle(final String strokeStyle) {
+ final String tmpFillStyle = strokeStyle.replaceAll("\\s", "");
+ Color color = StringUtils.findColorRGB(tmpFillStyle);
+ if (color == null) {
+ color = StringUtils.findColorRGBA(tmpFillStyle);
+ }
+
+ if (color == null) {
+ if (tmpFillStyle.length() > 0 && tmpFillStyle.charAt(0) == '#') {
+ color = Color.decode(tmpFillStyle);
+ }
+ else {
+ try {
+ final Field f = Color.class.getField(tmpFillStyle);
+ color = (Color) f.get(null);
+ }
+ catch (final Exception e) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Can not find color '" + tmpFillStyle + '\'');
+ }
+ color = Color.black;
+ }
+ }
+ }
+ strokeColor_ = color;
}
/**
* {@inheritDoc}
*/
@Override
- public void fillRect(final int x, final int y, final int w, final int h) {
- graphics2D_.fillRect(x, y, w, h);
+ public int getLineWidth() {
+ return lineWidth_;
}
/**
* {@inheritDoc}
*/
@Override
- public void strokeRect(final int x, final int y, final int w, final int h) {
- graphics2D_.drawRect(x, y, w, h);
+ public void restore() {
+ if (savedStates_.isEmpty()) {
+ return;
+ }
+
+ savedStates_.pop().applyOn(this);
}
/**
* {@inheritDoc}
*/
@Override
- public void fillText(final String text, final int x, final int y) {
- graphics2D_.drawString(text, x, y);
+ public void rotate(final double angle) {
+ transformation_.rotate(angle);
}
/**
* {@inheritDoc}
*/
@Override
- public void drawImage(final ImageReader imageReader, final int dxI, final int dyI) throws IOException {
- if (imageReader.getNumImages(true) != 0) {
- final BufferedImage img = imageReader.read(0);
- graphics2D_.drawImage(img, dxI, dyI, image_.getWidth(), image_.getHeight(), null);
- }
+ public void save() {
+ savedStates_.push(new SaveState(this));
+ reset();
}
/**
* {@inheritDoc}
*/
@Override
- public byte[] getBytes(final int width, final int height, final int sx, final int sy) {
- final byte[] array = new byte[width * height * 4];
- int index = 0;
- for (int x = 0; x < width; x++) {
- for (int y = 0; y < height; y++) {
- final Color c = new Color(image_.getRGB(sx + x, sy + y), true);
- array[index++] = (byte) c.getRed();
- array[index++] = (byte) c.getGreen();
- array[index++] = (byte) c.getBlue();
- array[index++] = (byte) c.getAlpha();
- }
+ public void setLineWidth(final int lineWidth) {
+ lineWidth_ = lineWidth;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setTransform(final double m11, final double m12,
+ final double m21, final double m22, final double dx, final double dy) {
+ transformation_ = new AffineTransform(m11, m12, m21, m22, dx, dy);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void stroke() {
+ graphics2D_.setTransform(new AffineTransform());
+ graphics2D_.setStroke(new BasicStroke(getLineWidth()));
+ graphics2D_.setColor(strokeColor_);
+ for (Path2D path2d : subPaths_) {
+ graphics2D_.draw(path2d);
}
- return array;
}
/**
* {@inheritDoc}
*/
@Override
- public String encodeToString(final String type) throws IOException {
- String imageType = type;
- if (imageType != null && imageType.startsWith("image/")) {
- imageType = imageType.substring(6);
+ public void strokeRect(final int x, final int y, final int w, final int h) {
+ graphics2D_.setTransform(transformation_);
+ graphics2D_.setColor(strokeColor_);
+ graphics2D_.drawRect(x, y, w, h);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void transform(final double m11, final double m12,
+ final double m21, final double m22, final double dx, final double dy) {
+ transformation_.concatenate(new AffineTransform(m11, m12, m21, m22, dx, dy));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void translate(final int x, final int y) {
+ transformation_.translate(x, y);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void closePath() {
+ if (subPaths_.isEmpty()) {
+ return;
}
- try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
- ImageIO.write(image_, imageType, bos);
+ subPaths_.get(subPaths_.size() - 1).closePath();
+ }
- final byte[] imageBytes = bos.toByteArray();
- return new String(new Base64().encode(imageBytes));
+ private Path2D getCurrentSubPath() {
+ if (subPaths_.isEmpty()) {
+ final Path2D subPath = new Path2D.Double();
+ subPaths_.add(subPath);
+ return subPath;
+ }
+ return subPaths_.get(subPaths_.size() - 1);
+ }
+
+ private static final class SaveState {
+ private AffineTransform transformation_;
+ private float globalAlpha_;
+ private int lineWidth_;
+ private Color fillColor_;
+ private Color strokeColor_;
+
+ private SaveState(final AwtRenderingBackend backend) {
+ transformation_ = backend.transformation_;
+ globalAlpha_ = backend.globalAlpha_;
+ lineWidth_ = backend.lineWidth_;
+ fillColor_ = backend.fillColor_;
+ strokeColor_ = backend.strokeColor_;
+ }
+
+ private void applyOn(final AwtRenderingBackend backend) {
+ backend.transformation_ = transformation_;
+ backend.globalAlpha_ = globalAlpha_;
+ backend.lineWidth_ = lineWidth_;
+ backend.fillColor_ = fillColor_;
+ backend.strokeColor_ = strokeColor_;
}
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/RenderingBackend.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/RenderingBackend.java
index 4534a097363..39afbfc7b3f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/RenderingBackend.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/RenderingBackend.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,10 +27,37 @@
public interface RenderingBackend {
/**
- * Sets the {@code fillStyle} property.
- * @param fillStyle the {@code fillStyle} property
+ * Starts a new path by emptying the list of sub-paths.
*/
- void setFillStyle(String fillStyle);
+ void beginPath();
+
+ /**
+ * Adds a cubic Bézier curve to the current sub-path. It requires
+ * three points: the first two are control points and the third one
+ * is the end point. The starting point is the latest point in the
+ * current path, which can be changed using moveTo() before
+ * creating the Bézier curve.
+ * @param cp1x the cp1x
+ * @param cp1y the cp1y
+ * @param cp2x the cp2x
+ * @param cp2y the cp2y
+ * @param x the x
+ * @param y the y
+ */
+ void bezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y,
+ double x, double y);
+
+ /**
+ * Adds a circular arc to the current sub-path.
+ * @param x the x
+ * @param y the y
+ * @param radius the radius
+ * @param startAngle the start angle
+ * @param endAngle the end angle
+ * @param anticlockwise is anti-clockwise
+ */
+ void arc(double x, double y, double radius, double startAngle,
+ double endAngle, boolean anticlockwise);
/**
* Paints the specified rectangular area.
@@ -42,13 +69,46 @@ public interface RenderingBackend {
void clearRect(int x, int y, int w, int h);
/**
- * Paints the specified rectangular area.
+ * Draws images onto the context.
+ *
+ * @param imageReader the reader to read the image from 8the first one)
+ * @param dxI the x coordinate of the starting point (top left)
+ * @param dyI the y coordinate of the starting point (top left)
+ * @throws IOException in case o problems
+ */
+ void drawImage(ImageReader imageReader, int dxI, int dyI) throws IOException;
+
+ /**
+ * Constructs a base64 encoded string out of the image data.
+ *
+ * @param type the name of the image format
+ * @return the base64 encoded string
+ * @throws IOException in case o problems
+ */
+ String encodeToString(String type) throws IOException;
+
+ /**
+ * Creates an elliptical arc centered at (x, y) with the radii radiusX and radiusY.
+ * The path starts at startAngle and ends at endAngle, and travels in the direction
+ * given by anticlockwise (defaulting to clockwise).
* @param x the x
* @param y the y
- * @param w the width
- * @param h the height
+ * @param radiusX the radiusX
+ * @param radiusY the radiusY
+ * @param rotation the rotation
+ * @param startAngle the start angle
+ * @param endAngle the end angle
+ * @param anticlockwise is anti-clockwise
*/
- void fillRect(int x, int y, int w, int h);
+ void ellipse(double x, double y,
+ double radiusX, double radiusY,
+ double rotation, double startAngle, double endAngle,
+ boolean anticlockwise);
+
+ /**
+ * Fills the current or given path with the current fillStyle.
+ */
+ void fill();
/**
* Paints the specified rectangular area.
@@ -57,7 +117,7 @@ public interface RenderingBackend {
* @param w the width
* @param h the height
*/
- void strokeRect(int x, int y, int w, int h);
+ void fillRect(int x, int y, int w, int h);
/**
* Fills a given text at the given (x, y) position.
@@ -67,16 +127,6 @@ public interface RenderingBackend {
*/
void fillText(String text, int x, int y);
- /**
- * Draws images onto the context.
- *
- * @param imageReader the reader to read the image from 8the first one)
- * @param dxI the x coordinate of the starting point (top left)
- * @param dyI the y coordinate of the starting point (top left)
- * @throws IOException in case o problems
- */
- void drawImage(ImageReader imageReader, int dxI, int dyI) throws IOException;
-
/**
* Creates a byte array containing the (4) color values of all pixels.
*
@@ -89,11 +139,149 @@ public interface RenderingBackend {
byte[] getBytes(int width, int height, int sx, int sy);
/**
- * Constructs a base64 encoded string out of the image data.
- *
- * @param type the name of the image format
- * @return the base64 encoded string
- * @throws IOException in case o problems
+ * Adds a straight line to the current sub-path by connecting the
+ * sub-path's last point to the specified (x, y) coordinates.
+ * @param x the x
+ * @param y the y
*/
- String encodeToString(String type) throws IOException;
+ void lineTo(double x, double y);
+
+ /**
+ * Begins a new sub-path at the point specified
+ * by the given (x, y) coordinates.
+ * @param x the x
+ * @param y the y
+ */
+ void moveTo(double x, double y);
+
+ /**
+ * Adds a quadratic Bézier curve to the current sub-path. It requires
+ * two points: the first one is a control point and the second one is
+ * the end point. The starting point is the latest point in the
+ * current path, which can be changed using moveTo() before
+ * creating the quadratic Bézier curve.
+ * @param cpx the cpx
+ * @param cpy the cpy
+ * @param x the x
+ * @param y the y
+ */
+ void quadraticCurveTo(double cpx, double cpy, double x, double y);
+
+ /**
+ * Adds a rectangle to the current path.
+ * @param x the x
+ * @param y the y
+ * @param w the width
+ * @param h the height
+ */
+ void rect(double x, double y, double w, double h);
+
+ /**
+ * Restores the most recently saved canvas state by popping the top
+ * entry in the drawing state stack. If there is no saved state,
+ * this method does nothing.
+ */
+ void restore();
+
+ /**
+ * Adds a rotation to the transformation matrix.
+ * @param angle the angle
+ */
+ void rotate(double angle);
+
+ /**
+ * Saves the entire state of the canvas by pushing
+ * the current state onto a stack.
+ */
+ void save();
+
+ /**
+ * Sets the {@code fillStyle} property.
+ * @param fillStyle the {@code fillStyle} property
+ */
+ void setFillStyle(String fillStyle);
+
+ /**
+ * Sets the {@code strokeStyle} property.
+ * @param strokeStyle the {@code strokeStyle} property
+ */
+ void setStrokeStyle(String strokeStyle);
+
+ /**
+ * Returns the {@code lineWidth} property.
+ * @return the {@code lineWidth} property
+ */
+ int getLineWidth();
+
+ /**
+ * Sets the {@code lineWidth} property.
+ * @param lineWidth the {@code lineWidth} property
+ */
+ void setLineWidth(int lineWidth);
+
+ /**
+ * Resets (overrides) the current transformation to the identity matrix,
+ * and then invokes a transformation described by the arguments of this method.
+ * This lets you scale, rotate, translate (move), and skew the context.
+ * @param m11 Horizontal scaling. A value of 1 results in no scaling
+ * @param m12 Vertical skewing
+ * @param m21 Horizontal skewing
+ * @param m22 Vertical scaling. A value of 1 results in no scaling
+ * @param dx Horizontal translation (moving)
+ * @param dy Vertical translation (moving).
+ */
+ void setTransform(double m11, double m12, double m21, double m22, double dx, double dy);
+
+ /**
+ * Strokes (outlines) the current or given path with the current stroke style.
+ */
+ void stroke();
+
+ /**
+ * Paints the specified rectangular area.
+ * @param x the x
+ * @param y the y
+ * @param w the width
+ * @param h the height
+ */
+ void strokeRect(int x, int y, int w, int h);
+
+ /**
+ * Multiplies the current transformation with the matrix described by the
+ * arguments of this method. This lets you scale, rotate, translate (move),
+ * and skew the context.
+ * @param m11 Horizontal scaling. A value of 1 results in no scaling
+ * @param m12 Vertical skewing
+ * @param m21 Horizontal skewing
+ * @param m22 Vertical scaling. A value of 1 results in no scaling
+ * @param dx Horizontal translation (moving)
+ * @param dy Vertical translation (moving).
+ */
+ void transform(double m11, double m12, double m21, double m22, double dx, double dy);
+
+ /**
+ * Adds a translation transformation to the current matrix.
+ * @param x the x
+ * @param y the y
+ */
+ void translate(int x, int y);
+
+ /**
+ * Attempts to add a straight line from the current point to the start of the current sub-path.
+ * If the shape has already been closed or has only one point, this function does nothing.
+ */
+ void closePath();
+
+ /**
+ * @return the alpha (transparency) value that is applied to shapes and images
+ * before they are drawn onto the canvas.
+ */
+ double getGlobalAlpha();
+
+ /**
+ * Specifies the alpha (transparency) value that is applied to shapes and images
+ * before they are drawn onto the canvas.
+ * @param globalAlpha the new alpha
+ */
+ void setGlobalAlpha(double globalAlpha);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/package-info.java
index 44893e29a55..ab1ab05a6e4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/canvas/rendering/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/Crypto.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/Crypto.java
index de48c5b4bde..33299e50daa 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/Crypto.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/Crypto.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.crypto;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.util.Random;
@@ -26,9 +25,9 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
import com.gargoylesoftware.htmlunit.javascript.host.Window;
-import com.gargoylesoftware.htmlunit.javascript.host.arrays.ArrayBufferViewBase;
import net.sourceforge.htmlunit.corejs.javascript.Context;
+import net.sourceforge.htmlunit.corejs.javascript.typedarrays.NativeTypedArrayView;
/**
* A JavaScript object for {@code Crypto}.
@@ -43,7 +42,7 @@ public class Crypto extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Crypto() {
}
@@ -62,13 +61,13 @@ public Crypto(final Window window) {
* @see MDN Doc
*/
@JsxFunction
- public void getRandomValues(final ArrayBufferViewBase array) {
+ public void getRandomValues(final NativeTypedArrayView> array) {
if (array == null) {
throw Context.reportRuntimeError("TypeError: Argument 1 of Crypto.getRandomValues is not an object.");
}
final Random random = new Random();
- for (int i = 0; i < array.getLength(); i++) {
+ for (int i = 0; i < array.getByteLength() / array.getBytesPerElement(); i++) {
array.put(i, array, random.nextInt());
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/CryptoKey.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/CryptoKey.java
index d935b417a8e..8bddd1a0d31 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/CryptoKey.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/CryptoKey.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.crypto;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -27,7 +26,7 @@
*
* @author Ahmed Ashour
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class CryptoKey extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/SubtleCrypto.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/SubtleCrypto.java
index 003c0f7b687..182466297d3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/SubtleCrypto.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/SubtleCrypto.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.crypto;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -34,7 +33,7 @@ public class SubtleCrypto extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public SubtleCrypto() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/package-info.java
index 68c69b974b5..49997ac47e5 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/crypto/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/BrowserConfiguration.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/BrowserConfiguration.java
index 5e014c77c02..7f978630d15 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/BrowserConfiguration.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/BrowserConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,12 +53,12 @@ static BrowserConfiguration chrome(final String defaultValue) {
return browserConfiguration;
}
- static BrowserConfiguration ffBelow52(final String defaultValue) {
- return ff(defaultValue).upTo(51);
+ static BrowserConfiguration ffBelow68(final String defaultValue) {
+ return ff(defaultValue).upTo(67);
}
- static BrowserConfiguration ff52up(final String defaultValue) {
- return ff(defaultValue).startingWith(52);
+ static BrowserConfiguration ff68up(final String defaultValue) {
+ return ff(defaultValue).startingWith(68);
}
static BrowserConfiguration getMatchingConfiguration(
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSS.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSS.java
index 43aeb13e565..3923cd2e3da 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSS.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSS.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,8 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -28,14 +28,15 @@
* A JavaScript object for {@code CSS}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class CSS extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor
+ @JsxConstructor({CHROME, FF60})
public CSS() {
}
@@ -49,4 +50,15 @@ public Object get(final String name, final Scriptable start) {
}
return super.get(name, start);
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getDefaultValue(final Class> hint) {
+ if (String.class.equals(hint) || hint == null) {
+ return "[object Object]";
+ }
+ return super.getDefaultValue(hint);
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSS2Properties.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSS2Properties.java
index 741f9c41d96..27ab2caea25 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSS2Properties.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSS2Properties.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSConditionRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSConditionRule.java
index cea1ead08bb..1e8f15b8900 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSConditionRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSConditionRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,10 +15,10 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
+import com.gargoylesoftware.css.dom.CSSMediaRuleImpl;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -26,15 +26,16 @@
* A JavaScript object for {@code CSSConditionRule}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
@JsxClass(isJSObject = false, value = IE)
public class CSSConditionRule extends CSSGroupingRule {
/**
* Creates a new instance.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSConditionRule() {
}
@@ -43,7 +44,7 @@ public CSSConditionRule() {
* @param stylesheet the Stylesheet of this rule.
* @param rule the wrapped rule
*/
- protected CSSConditionRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSSMediaRule rule) {
+ protected CSSConditionRule(final CSSStyleSheet stylesheet, final CSSMediaRuleImpl rule) {
super(stylesheet, rule);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSCounterStyleRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSCounterStyleRule.java
index 781d062199f..f1a967b6947 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSCounterStyleRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSCounterStyleRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,13 +17,21 @@
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
+import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
/**
* A JavaScript object for {@code CSSCounterStyleRule}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
@JsxClass(FF)
public class CSSCounterStyleRule extends CSSRule {
+ /**
+ * Creates a new instance.
+ */
+ @JsxConstructor(FF)
+ public CSSCounterStyleRule() {
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSFontFaceRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSFontFaceRule.java
index b3f484d6b46..b9c6fab0943 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSFontFaceRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSFontFaceRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,15 +14,17 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.css;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_FONTFACERULE_CSSTEXT_CRLF;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_FONTFACERULE_CSSTEXT_NO_CRLF;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_FONTFACERULE_CSSTEXT_CHROME_STYLE;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_FONTFACERULE_CSSTEXT_FF60_STYLE;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_FONTFACERULE_CSSTEXT_IE_STYLE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
+import com.gargoylesoftware.css.dom.CSSFontFaceRuleImpl;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -44,7 +46,7 @@ public class CSSFontFaceRule extends CSSRule {
/**
* Creates a new instance.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSFontFaceRule() {
}
@@ -53,7 +55,7 @@ public CSSFontFaceRule() {
* @param stylesheet the Stylesheet of this rule.
* @param rule the wrapped rule
*/
- protected CSSFontFaceRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSSFontFaceRule rule) {
+ protected CSSFontFaceRule(final CSSStyleSheet stylesheet, final CSSFontFaceRuleImpl rule) {
super(stylesheet, rule);
}
@@ -72,25 +74,32 @@ public short getType() {
public String getCssText() {
String cssText = super.getCssText();
final BrowserVersion browserVersion = getBrowserVersion();
- if (browserVersion.hasFeature(CSS_FONTFACERULE_CSSTEXT_CRLF)) {
- cssText = StringUtils.replace(cssText, "{", "{\r\n\t");
- cssText = StringUtils.replace(cssText, "}", ";\r\n}\r\n");
- cssText = StringUtils.replace(cssText, "; ", ";\r\n\t");
+ if (browserVersion.hasFeature(CSS_FONTFACERULE_CSSTEXT_IE_STYLE)) {
+ cssText = StringUtils.replace(cssText, "{", "{\n\t");
+ cssText = StringUtils.replace(cssText, "}", ";\n}\n");
+ cssText = StringUtils.replace(cssText, "; ", ";\n\t");
}
- else if (browserVersion.hasFeature(CSS_FONTFACERULE_CSSTEXT_NO_CRLF)) {
+ else if (browserVersion.hasFeature(CSS_FONTFACERULE_CSSTEXT_CHROME_STYLE)) {
cssText = StringUtils.replace(cssText, "{", "{ ");
cssText = StringUtils.replace(cssText, "}", "; }");
cssText = StringUtils.replace(cssText, "; ", "; ");
cssText = REPLACEMENT_1.matcher(cssText).replaceFirst("font-family: $1;");
cssText = REPLACEMENT_2.matcher(cssText).replaceFirst("src: url(\"$1\");");
}
- else {
+ else if (browserVersion.hasFeature(CSS_FONTFACERULE_CSSTEXT_FF60_STYLE)) {
cssText = StringUtils.replace(cssText, "{", "{\n ");
cssText = StringUtils.replace(cssText, "}", ";\n}");
cssText = StringUtils.replace(cssText, "; ", ";\n ");
cssText = REPLACEMENT_1.matcher(cssText).replaceFirst("font-family: \"$1\";");
cssText = REPLACEMENT_2.matcher(cssText).replaceFirst("src: url(\"$1\");");
}
+ else {
+ cssText = StringUtils.replace(cssText, "{", "{\n ");
+ cssText = StringUtils.replace(cssText, "}", ";\n}");
+ cssText = StringUtils.replace(cssText, "; ", ";\n ");
+ cssText = REPLACEMENT_1.matcher(cssText).replaceFirst("font-family: $1;");
+ cssText = REPLACEMENT_2.matcher(cssText).replaceFirst("src: url(\"$1\");");
+ }
return cssText;
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSGroupingRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSGroupingRule.java
index e52aa18d0d1..61989b034ac 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSGroupingRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSGroupingRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,10 +15,10 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
+import com.gargoylesoftware.css.dom.CSSMediaRuleImpl;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -26,15 +26,16 @@
* A JavaScript object for {@code CSSGroupingRule}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
@JsxClass(isJSObject = false, value = IE)
public class CSSGroupingRule extends CSSRule {
/**
* Creates a new instance.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSGroupingRule() {
}
@@ -43,7 +44,7 @@ public CSSGroupingRule() {
* @param stylesheet the Stylesheet of this rule.
* @param rule the wrapped rule
*/
- protected CSSGroupingRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSSMediaRule rule) {
+ protected CSSGroupingRule(final CSSStyleSheet stylesheet, final CSSMediaRuleImpl rule) {
super(stylesheet, rule);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSImportRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSImportRule.java
index f47bd2e920d..8e8d4fa5c7d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSImportRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSImportRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,11 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import com.gargoylesoftware.css.dom.CSSImportRuleImpl;
+import com.gargoylesoftware.css.dom.CSSStyleSheetImpl;
+import com.gargoylesoftware.css.dom.MediaListImpl;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
@@ -28,6 +31,7 @@
*
* @author Daniel Gredler
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
@JsxClass
public class CSSImportRule extends CSSRule {
@@ -38,7 +42,7 @@ public class CSSImportRule extends CSSRule {
/**
* Creates a new instance.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSImportRule() {
}
@@ -47,7 +51,7 @@ public CSSImportRule() {
* @param stylesheet the Stylesheet of this rule.
* @param rule the wrapped rule
*/
- protected CSSImportRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSSImportRule rule) {
+ protected CSSImportRule(final CSSStyleSheet stylesheet, final CSSImportRuleImpl rule) {
super(stylesheet, rule);
}
@@ -68,7 +72,7 @@ public String getHref() {
public MediaList getMedia() {
if (media_ == null) {
final CSSStyleSheet parent = getParentStyleSheet();
- final org.w3c.dom.stylesheets.MediaList ml = getImportRule().getMedia();
+ final MediaListImpl ml = getImportRule().getMedia();
media_ = new MediaList(parent, ml);
}
return media_;
@@ -83,7 +87,7 @@ public CSSStyleSheet getStyleSheet() {
if (importedStylesheet_ == null) {
final CSSStyleSheet owningSheet = getParentStyleSheet();
final HTMLElement ownerNode = owningSheet.getOwnerNode();
- final org.w3c.dom.css.CSSStyleSheet importedStylesheet = getImportRule().getStyleSheet();
+ final CSSStyleSheetImpl importedStylesheet = getImportRule().getStyleSheet();
importedStylesheet_ = new CSSStyleSheet(ownerNode, importedStylesheet, owningSheet.getUri());
}
return importedStylesheet_;
@@ -93,8 +97,8 @@ public CSSStyleSheet getStyleSheet() {
* Returns the wrapped rule, as an import rule.
* @return the wrapped rule, as an import rule
*/
- private org.w3c.dom.css.CSSImportRule getImportRule() {
- return (org.w3c.dom.css.CSSImportRule) getRule();
+ private CSSImportRuleImpl getImportRule() {
+ return (CSSImportRuleImpl) getRule();
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSKeyframeRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSKeyframeRule.java
index a745f54c3da..08fe71e2004 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSKeyframeRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSKeyframeRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -26,14 +24,15 @@
* A JavaScript object for {@code CSSKeyframeRule}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, FF52, IE, EDGE})
+@JsxClass
public class CSSKeyframeRule extends CSSRule {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSKeyframeRule() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSKeyframesRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSKeyframesRule.java
index 1193047178b..b77914e3078 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSKeyframesRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSKeyframesRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,12 +14,11 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.css;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CSS_MOZ_CSS_KEYFRAMES_RULE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
+import com.gargoylesoftware.css.dom.CSSUnknownRuleImpl;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
@@ -30,13 +29,13 @@
* @author Ahmed Ashour
* @author Ronald Brill
*/
-@JsxClass({CHROME, FF52, IE, EDGE})
+@JsxClass({CHROME, FF, IE})
public class CSSKeyframesRule extends CSSRule {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSKeyframesRule() {
}
@@ -45,7 +44,7 @@ public CSSKeyframesRule() {
* @param stylesheet the Stylesheet of this rule.
* @param rule the wrapped rule
*/
- protected CSSKeyframesRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSSUnknownRule rule) {
+ protected CSSKeyframesRule(final CSSStyleSheet stylesheet, final CSSUnknownRuleImpl rule) {
super(stylesheet, rule);
}
@@ -58,16 +57,4 @@ protected CSSKeyframesRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css
public short getType() {
return KEYFRAMES_RULE;
}
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Object getDefaultValue(final Class> hint) {
- if ((String.class.equals(hint) || hint == null)
- && getBrowserVersion().hasFeature(JS_CSS_MOZ_CSS_KEYFRAMES_RULE)) {
- return "[object MozCSSKeyframesRule]";
- }
- return super.getDefaultValue(hint);
- }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSMediaRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSMediaRule.java
index e1d3759a59d..428ecf418b6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSMediaRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSMediaRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,15 +15,17 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import com.gargoylesoftware.css.dom.CSSMediaRuleImpl;
+import com.gargoylesoftware.css.dom.MediaListImpl;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
import com.gargoylesoftware.htmlunit.javascript.host.dom.MediaList;
/**
- * A JavaScript object for a {@link org.w3c.dom.css.CSSMediaRule}.
+ * A JavaScript object for a {@link CSSMediaRuleImpl}.
*
* @author Ronald Brill
* @author Ahmed Ashour
@@ -36,7 +38,7 @@ public class CSSMediaRule extends CSSConditionRule {
/**
* Creates a new instance.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSMediaRule() {
}
@@ -45,7 +47,7 @@ public CSSMediaRule() {
* @param stylesheet the Stylesheet of this rule.
* @param rule the wrapped rule
*/
- protected CSSMediaRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSSMediaRule rule) {
+ protected CSSMediaRule(final CSSStyleSheet stylesheet, final CSSMediaRuleImpl rule) {
super(stylesheet, rule);
}
@@ -57,7 +59,7 @@ protected CSSMediaRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSS
public MediaList getMedia() {
if (media_ == null) {
final CSSStyleSheet parent = getParentStyleSheet();
- final org.w3c.dom.stylesheets.MediaList ml = getMediaRule().getMedia();
+ final MediaListImpl ml = getMediaRule().getMediaList();
media_ = new MediaList(parent, ml);
}
return media_;
@@ -67,7 +69,7 @@ public MediaList getMedia() {
* Returns the wrapped rule, as a media rule.
* @return the wrapped rule, as a media rule
*/
- private org.w3c.dom.css.CSSMediaRule getMediaRule() {
- return (org.w3c.dom.css.CSSMediaRule) getRule();
+ private CSSMediaRuleImpl getMediaRule() {
+ return (CSSMediaRuleImpl) getRule();
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSNamespaceRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSNamespaceRule.java
index be281a0f27f..c1b24be9215 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSNamespaceRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSNamespaceRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -25,14 +25,15 @@
* A JavaScript object for {@code CSSNamespaceRule}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, IE, EDGE})
+@JsxClass({CHROME, FF, IE})
public class CSSNamespaceRule extends CSSRule {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSNamespaceRule() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSPageRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSPageRule.java
index fea816fe122..8b6f926d6a4 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSPageRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSPageRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -24,6 +24,7 @@
* A JavaScript object for {@code CSSPageRule}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
@JsxClass
public class CSSPageRule extends CSSRule {
@@ -31,7 +32,7 @@ public class CSSPageRule extends CSSRule {
/**
* Creates a new instance.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSPageRule() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSPrimitiveValue.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSPrimitiveValue.java
index fecee28e165..7bd712a54bb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSPrimitiveValue.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSPrimitiveValue.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,8 +14,9 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.css;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
+import com.gargoylesoftware.css.dom.CSSValueImpl;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -25,10 +26,10 @@
/**
* A JavaScript object for {@code CSSPrimitiveValue}.
*
- * @see org.w3c.dom.css.CSSPrimitiveValue
* @author Marc Guillemot
+ * @author Ronald Brill
*/
-@JsxClass(FF)
+@JsxClass(FF60)
public class CSSPrimitiveValue extends CSSValue {
/**
@@ -213,7 +214,7 @@ public class CSSPrimitiveValue extends CSSValue {
@JsxConstant
public static final short CSS_RGBCOLOR = org.w3c.dom.css.CSSPrimitiveValue.CSS_RGBCOLOR;
- private org.w3c.dom.css.CSSPrimitiveValue wrappedCssPrimitiveValue_;
+ private CSSValueImpl wrappedCssValueImpl_;
/**
* Creates an instance.
@@ -226,12 +227,12 @@ public CSSPrimitiveValue() {
* Creates an instance and sets its parent scope to the one of the provided element.
* @param element the element to which this style is bound
*/
- CSSPrimitiveValue(final Element element, final org.w3c.dom.css.CSSPrimitiveValue cssValue) {
+ CSSPrimitiveValue(final Element element, final CSSValueImpl cssValue) {
super(element, cssValue);
setParentScope(element.getParentScope());
setPrototype(getPrototype(getClass()));
setDomNode(element.getDomNodeOrNull(), false);
- wrappedCssPrimitiveValue_ = cssValue;
+ wrappedCssValueImpl_ = cssValue;
}
/**
@@ -241,6 +242,6 @@ public CSSPrimitiveValue() {
*/
@JsxFunction
public double getFloatValue(final int unitType) {
- return wrappedCssPrimitiveValue_.getFloatValue((short) unitType);
+ return wrappedCssValueImpl_.getDoubleValue();
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSRule.java
index 15f342b2ba3..1a62de7e95f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,13 +15,20 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import com.gargoylesoftware.css.dom.AbstractCSSRuleImpl;
+import com.gargoylesoftware.css.dom.CSSCharsetRuleImpl;
+import com.gargoylesoftware.css.dom.CSSFontFaceRuleImpl;
+import com.gargoylesoftware.css.dom.CSSImportRuleImpl;
+import com.gargoylesoftware.css.dom.CSSMediaRuleImpl;
+import com.gargoylesoftware.css.dom.CSSPageRuleImpl;
+import com.gargoylesoftware.css.dom.CSSStyleRuleImpl;
+import com.gargoylesoftware.css.dom.CSSUnknownRuleImpl;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
@@ -44,7 +51,7 @@ public class CSSRule extends SimpleScriptable {
/**
* The rule is a {@code CSSUnknownRule}.
*/
- @JsxConstant({FF, IE, EDGE})
+ @JsxConstant(IE)
public static final short UNKNOWN_RULE = org.w3c.dom.css.CSSRule.UNKNOWN_RULE;
/**
@@ -89,24 +96,12 @@ public class CSSRule extends SimpleScriptable {
@JsxConstant
public static final short KEYFRAMES_RULE = 7;
- /**
- * The rule is a {@code CSSKeyframesRule}.
- */
- @JsxConstant(FF)
- public static final short MOZ_KEYFRAMES_RULE = 7;
-
/**
* The rule is a {@code CSSKeyframeRule}.
*/
@JsxConstant
public static final short KEYFRAME_RULE = 8;
- /**
- * The rule is a {@code CSSKeyframeRule}.
- */
- @JsxConstant(FF)
- public static final short MOZ_KEYFRAME_RULE = 8;
-
/**
* The rule is a {@code CSSNamespaceRule}.
*/
@@ -139,12 +134,12 @@ public class CSSRule extends SimpleScriptable {
private final CSSStyleSheet stylesheet_;
- private final org.w3c.dom.css.CSSRule rule_;
+ private final AbstractCSSRuleImpl rule_;
/**
* Creates a new instance.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSRule() {
stylesheet_ = null;
rule_ = null;
@@ -156,29 +151,36 @@ public CSSRule() {
* @param rule the wrapped rule
* @return a CSSRule subclass according to the rule type
*/
- public static CSSRule create(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSSRule rule) {
- switch (rule.getType()) {
- case STYLE_RULE:
- return new CSSStyleRule(stylesheet, (org.w3c.dom.css.CSSStyleRule) rule);
- case IMPORT_RULE:
- return new CSSImportRule(stylesheet, (org.w3c.dom.css.CSSImportRule) rule);
-// case CHARSET_RULE:
-// return new CSSCharsetRule(stylesheet, (org.w3c.dom.css.CSSCharsetRule) rule);
- case MEDIA_RULE:
- return new CSSMediaRule(stylesheet, (org.w3c.dom.css.CSSMediaRule) rule);
- case FONT_FACE_RULE:
- return new CSSFontFaceRule(stylesheet, (org.w3c.dom.css.CSSFontFaceRule) rule);
- case UNKNOWN_RULE:
- final org.w3c.dom.css.CSSUnknownRule unknownRule = (org.w3c.dom.css.CSSUnknownRule) rule;
- if (unknownRule.getCssText().startsWith("@keyframes")) {
- return new CSSKeyframesRule(stylesheet, (org.w3c.dom.css.CSSUnknownRule) rule);
- }
+ public static CSSRule create(final CSSStyleSheet stylesheet, final AbstractCSSRuleImpl rule) {
+ if (rule instanceof CSSStyleRuleImpl) {
+ return new CSSStyleRule(stylesheet, (CSSStyleRuleImpl) rule);
+ }
+ if (rule instanceof CSSImportRuleImpl) {
+ return new CSSImportRule(stylesheet, (CSSImportRuleImpl) rule);
+ }
+// if (rule instanceof CSSCharsetRuleImpl) {
+// return new CSSCharsetRule(stylesheet, (CSSCharsetRuleImpl) rule);
+// }
+ if (rule instanceof CSSMediaRuleImpl) {
+ return new CSSMediaRule(stylesheet, (CSSMediaRuleImpl) rule);
+ }
+ if (rule instanceof CSSFontFaceRuleImpl) {
+ return new CSSFontFaceRule(stylesheet, (CSSFontFaceRuleImpl) rule);
+ }
+ if (rule instanceof CSSUnknownRuleImpl) {
+ final CSSUnknownRuleImpl unknownRule = (CSSUnknownRuleImpl) rule;
+ if (unknownRule.getCssText().startsWith("@keyframes")) {
+ return new CSSKeyframesRule(stylesheet, (CSSUnknownRuleImpl) rule);
+ }
+ if (LOG.isWarnEnabled()) {
LOG.warn("Unknown CSSRule " + rule.getClass().getName()
+ " is not yet supported; rule content: '" + rule.getCssText() + "'");
- break;
- default:
- LOG.warn("CSSRule " + rule.getClass().getName()
- + " is not yet supported; rule content: '" + rule.getCssText() + "'");
+ }
+ }
+
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("CSSRule " + rule.getClass().getName()
+ + " is not yet supported; rule content: '" + rule.getCssText() + "'");
}
return null;
@@ -189,7 +191,7 @@ public static CSSRule create(final CSSStyleSheet stylesheet, final org.w3c.dom.c
* @param stylesheet the Stylesheet of this rule.
* @param rule the wrapped rule
*/
- protected CSSRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSSRule rule) {
+ protected CSSRule(final CSSStyleSheet stylesheet, final AbstractCSSRuleImpl rule) {
stylesheet_ = stylesheet;
rule_ = rule;
setParentScope(stylesheet);
@@ -202,7 +204,29 @@ protected CSSRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSSRule
*/
@JsxGetter
public short getType() {
- return rule_.getType();
+ if (rule_ instanceof CSSCharsetRuleImpl) {
+ return CSSRule.CHARSET_RULE;
+ }
+ if (rule_ instanceof CSSFontFaceRuleImpl) {
+ return CSSRule.FONT_FACE_RULE;
+ }
+ if (rule_ instanceof CSSImportRuleImpl) {
+ return CSSRule.IMPORT_RULE;
+ }
+ if (rule_ instanceof CSSMediaRuleImpl) {
+ return CSSRule.MEDIA_RULE;
+ }
+ if (rule_ instanceof CSSPageRuleImpl) {
+ return CSSRule.PAGE_RULE;
+ }
+ if (rule_ instanceof CSSStyleRuleImpl) {
+ return CSSRule.STYLE_RULE;
+ }
+ if (rule_ instanceof CSSUnknownRuleImpl) {
+ return CSSRule.UNKNOWN_RULE;
+ }
+
+ return CSSRule.UNKNOWN_RULE;
}
/**
@@ -240,7 +264,7 @@ public CSSStyleSheet getParentStyleSheet() {
*/
@JsxGetter
public CSSRule getParentRule() {
- final org.w3c.dom.css.CSSRule parentRule = rule_.getParentRule();
+ final AbstractCSSRuleImpl parentRule = rule_.getParentRule();
if (parentRule != null) {
return CSSRule.create(stylesheet_, parentRule);
}
@@ -251,7 +275,7 @@ public CSSRule getParentRule() {
* Returns the wrapped rule.
* @return the wrapped rule.
*/
- protected org.w3c.dom.css.CSSRule getRule() {
+ protected AbstractCSSRuleImpl getRule() {
return rule_;
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSRuleList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSRuleList.java
index 3ed72850976..a5d0d78ad9f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSRuleList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSRuleList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CSSRULELIST_ENUM_ITEM_LENGTH;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.util.ArrayList;
@@ -44,7 +43,7 @@ public class CSSRuleList extends SimpleScriptable {
/**
* Creates a new instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSRuleList() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleDeclaration.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleDeclaration.java
index 8b258280fb8..891808c2e55 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleDeclaration.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleDeclaration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_BACKGROUND_INITIAL;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_BACKGROUND_RGBA;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_LENGTH_INITIAL;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_OUTLINE_WIDTH_UNIT_NOT_REQUIRED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_SET_NULL_THROWS;
@@ -26,8 +27,8 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_STYLE_WORD_SPACING_ACCEPTS_PERCENT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_STYLE_WRONG_INDEX_RETURNS_UNDEFINED;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import static com.gargoylesoftware.htmlunit.javascript.host.css.StyleAttributes.Definition.ACCELERATOR;
import static com.gargoylesoftware.htmlunit.javascript.host.css.StyleAttributes.Definition.BACKGROUND;
@@ -100,7 +101,6 @@
import java.awt.Color;
import java.io.IOException;
-import java.io.StringReader;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.ArrayList;
@@ -121,18 +121,16 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import com.gargoylesoftware.css.dom.CSSStyleDeclarationImpl;
import com.gargoylesoftware.css.dom.CSSValueImpl;
import com.gargoylesoftware.css.parser.CSSErrorHandler;
import com.gargoylesoftware.css.parser.CSSOMParser;
-import com.gargoylesoftware.css.parser.InputSource;
import com.gargoylesoftware.css.parser.javacc.CSS3Parser;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebAssert;
import com.gargoylesoftware.htmlunit.css.StyleElement;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
-import com.gargoylesoftware.htmlunit.javascript.configuration.CanSetReadOnly;
-import com.gargoylesoftware.htmlunit.javascript.configuration.CanSetReadOnlyStatus;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
@@ -208,14 +206,17 @@ public class CSSStyleDeclaration extends SimpleScriptable {
MAX_WIDTH.getAttributeName()
));
+ static final String NONE = "none";
static final String AUTO = "auto";
static final String STATIC = "static";
static final String INHERIT = "inherit";
private static final String INITIAL = "initial";
- private static final String RELATIVE = "relative";
- private static final String FIXED = "fixed";
- private static final String ABSOLUTE = "absolute";
+ static final String RELATIVE = "relative";
+ static final String FIXED = "fixed";
+ static final String ABSOLUTE = "absolute";
private static final String REPEAT = "repeat";
+ static final String BLOCK = "block";
+ static final String INLINE = "inline";
private static final Log LOG = LogFactory.getLog(CSSStyleDeclaration.class);
private static final Map CSSColors_ = new HashMap<>();
@@ -230,7 +231,7 @@ public class CSSStyleDeclaration extends SimpleScriptable {
private Element jsElement_;
/** The wrapped CSSStyleDeclaration (if created from CSSStyleRule). */
- private org.w3c.dom.css.CSSStyleDeclaration styleDeclaration_;
+ private CSSStyleDeclarationImpl styleDeclaration_;
static {
CSSColors_.put("aqua", "rgb(0, 255, 255)");
@@ -254,7 +255,7 @@ public class CSSStyleDeclaration extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSStyleDeclaration() {
}
@@ -273,7 +274,7 @@ public CSSStyleDeclaration(final Element element) {
* @param parentScope the parent scope to use
* @param styleDeclaration the style declaration to wrap
*/
- CSSStyleDeclaration(final Scriptable parentScope, final org.w3c.dom.css.CSSStyleDeclaration styleDeclaration) {
+ CSSStyleDeclaration(final Scriptable parentScope, final CSSStyleDeclarationImpl styleDeclaration) {
setParentScope(parentScope);
setPrototype(getPrototype(getClass()));
styleDeclaration_ = styleDeclaration;
@@ -302,7 +303,9 @@ private void initialize(final Element element) {
}
}
catch (final ParseException e) {
- LOG.warn("Invalid behavior: '" + behavior + "'.");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Invalid behavior: '" + behavior + "'.");
+ }
}
}
}
@@ -398,19 +401,7 @@ private StyleElement getStyleElementCaseInSensitive(final String name) {
*/
private String getStyleAttribute(final Definition name1, final Definition name2) {
final String value;
- if (styleDeclaration_ != null) {
- final String value1 = styleDeclaration_.getPropertyValue(name1.getAttributeName());
- final String value2 = styleDeclaration_.getPropertyValue(name2.getAttributeName());
-
- if ("".equals(value1) && "".equals(value2)) {
- return "";
- }
- if (!"".equals(value1) && "".equals(value2)) {
- return value1;
- }
- value = value2;
- }
- else {
+ if (styleDeclaration_ == null) {
final StyleElement element1 = getStyleElement(name1.getAttributeName());
final StyleElement element2 = getStyleElement(name2.getAttributeName());
@@ -430,6 +421,18 @@ private String getStyleAttribute(final Definition name1, final Definition name2)
value = element2.getValue();
}
}
+ else {
+ final String value1 = styleDeclaration_.getPropertyValue(name1.getAttributeName());
+ final String value2 = styleDeclaration_.getPropertyValue(name2.getAttributeName());
+
+ if ("".equals(value1) && "".equals(value2)) {
+ return "";
+ }
+ if (!"".equals(value1) && "".equals(value2)) {
+ return value1;
+ }
+ value = value2;
+ }
final String[] values = StringUtils.split(value);
if (name1.name().contains("TOP")) {
@@ -631,6 +634,9 @@ public String getBackgroundColor() {
}
return "rgba(0, 0, 0, 0)";
}
+ if (getBrowserVersion().hasFeature(CSS_BACKGROUND_RGBA)) {
+ return "rgba(0, 0, 0, 0)";
+ }
return "transparent"; // default if shorthand is used
}
return value;
@@ -664,7 +670,7 @@ public String getBackgroundImage() {
final boolean isComputed = getClass() != CSSStyleDeclaration.class;
final boolean backgroundInitial = getBrowserVersion().hasFeature(CSS_BACKGROUND_INITIAL);
if (value == null) {
- return backgroundInitial && !isComputed ? INITIAL : "none";
+ return backgroundInitial && !isComputed ? INITIAL : NONE;
}
if (isComputed) {
try {
@@ -1339,11 +1345,11 @@ private void updateFont(final String font, final boolean force) {
if (browserVersion.hasFeature(CSS_ZINDEX_TYPE_INTEGER) || !lineHeight.equals(defaultLineHeight)) {
newFont.append('/');
- if (!lineHeight.equals(defaultLineHeight)) {
- newFont.append(lineHeight);
+ if (lineHeight.equals(defaultLineHeight)) {
+ newFont.append(LINE_HEIGHT.getDefaultComputedValue(browserVersion));
}
else {
- newFont.append(LINE_HEIGHT.getDefaultComputedValue(browserVersion));
+ newFont.append(lineHeight);
}
}
@@ -1420,7 +1426,6 @@ public void setLeft(final Object left) {
* @return the {@code length} property
*/
@JsxGetter
- @CanSetReadOnly(CanSetReadOnlyStatus.IGNORE)
public int getLength() {
return getStyleMap().size();
}
@@ -1675,8 +1680,7 @@ private String getStyleAttributeImpl(final String string) {
final StyleElement element = getStyleElement(string);
if (element != null && element.getValue() != null) {
final String value = element.getValue();
- if (!value.contains("url")
- && getBrowserVersion().hasFeature(JS_STYLE_SET_PROPERTY_IMPORTANT_IGNORES_CASE)) {
+ if (!value.contains("url")) {
return value.toLowerCase(Locale.ROOT);
}
return value;
@@ -1778,7 +1782,7 @@ public String getOpacity() {
*/
@JsxSetter
public void setOpacity(final Object opacity) {
- if (ScriptRuntime.NaNobj == opacity) {
+ if (ScriptRuntime.isNaN(opacity)) {
return;
}
@@ -2524,7 +2528,7 @@ public void setZIndex(final Object zIndex) {
return;
}
// undefined
- if (Undefined.instance.equals(zIndex)) {
+ if (Undefined.isUndefined(zIndex)) {
return;
}
@@ -2566,31 +2570,30 @@ public String getPropertyValue(final String name) {
* @param name the name of the property to retrieve
* @return the value
*/
- @JsxFunction(FF)
+ @JsxFunction(FF60)
public CSSValue getPropertyCSSValue(final String name) {
- LOG.info("getPropertyCSSValue(" + name + "): getPropertyCSSValue support is experimental");
+ if (LOG.isInfoEnabled()) {
+ LOG.info("getPropertyCSSValue(" + name + "): getPropertyCSSValue support is experimental");
+ }
+
// following is a hack, just to have basic support for getPropertyCSSValue
// TODO: rework the whole CSS processing here! we should *always* parse the style!
if (styleDeclaration_ == null) {
- final String uri = getDomNodeOrDie().getPage().getWebResponse().getWebRequest()
- .getUrl().toExternalForm();
final String styleAttribute = jsElement_.getDomNodeOrDie().getAttributeDirect("style");
- final InputSource source = new InputSource(new StringReader(styleAttribute));
- source.setURI(uri);
final CSSErrorHandler errorHandler = getWindow().getWebWindow().getWebClient().getCssErrorHandler();
final CSSOMParser parser = new CSSOMParser(new CSS3Parser());
parser.setErrorHandler(errorHandler);
try {
- styleDeclaration_ = parser.parseStyleDeclaration(source);
+ styleDeclaration_ = parser.parseStyleDeclaration(styleAttribute);
}
catch (final IOException e) {
throw new RuntimeException(e);
}
}
- org.w3c.dom.css.CSSValue cssValue = styleDeclaration_.getPropertyCSSValue(name);
+ CSSValueImpl cssValue = styleDeclaration_.getPropertyCSSValue(name);
if (cssValue == null) {
final CSSValueImpl newValue = new CSSValueImpl(null, false);
- newValue.setFloatValue(CSSPrimitiveValue.CSS_PX, 0);
+ newValue.setDoubleValue(0);
cssValue = newValue;
}
@@ -2601,7 +2604,7 @@ public CSSValue getPropertyCSSValue(final String name) {
cssValue.setCssText(formatedCssText);
}
- return new CSSPrimitiveValue(jsElement_, (org.w3c.dom.css.CSSPrimitiveValue) cssValue);
+ return new CSSPrimitiveValue(jsElement_, cssValue);
}
/**
@@ -2881,7 +2884,7 @@ public static String toRGBColor(final String color) {
* @return whether the token is a border style or not
*/
private static boolean isBorderStyle(final String token) {
- return "none".equalsIgnoreCase(token) || "hidden".equalsIgnoreCase(token)
+ return NONE.equalsIgnoreCase(token) || "hidden".equalsIgnoreCase(token)
|| "dotted".equalsIgnoreCase(token) || "dashed".equalsIgnoreCase(token)
|| "solid".equalsIgnoreCase(token) || "double".equalsIgnoreCase(token)
|| "groove".equalsIgnoreCase(token) || "ridge".equalsIgnoreCase(token)
@@ -2984,11 +2987,11 @@ protected static int pixelValue(final String value) {
if (value.length() < 2) {
return i;
}
-
if (value.endsWith("px")) {
- // nothing to do
+ return i;
}
- else if (value.endsWith("em")) {
+
+ if (value.endsWith("em")) {
i = i * 16;
}
else if (value.endsWith("%")) {
@@ -3015,6 +3018,14 @@ else if (value.endsWith("pc")) {
return i;
}
+ @Override
+ protected boolean isReadOnlySettable(final String name, final Object value) {
+ if ("length".equals(name)) {
+ return false; //ignore
+ }
+ return super.isReadOnlySettable(name, value);
+ }
+
/**
* Encapsulates the retrieval of a style attribute, given a DOM element from which to retrieve it.
*/
@@ -3091,7 +3102,7 @@ public String toString() {
private void setStyleLengthAttribute(final String name, final Object value, final String important,
final boolean auto, final boolean percent, final boolean thinMedThick, final boolean unitRequired) {
- if (ScriptRuntime.NaNobj == value) {
+ if (ScriptRuntime.isNaN(value)) {
return;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleRule.java
index 89a5405b77c..4c334219586 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,13 +16,14 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_SELECTOR_TEXT_LOWERCASE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import com.gargoylesoftware.css.dom.CSSStyleRuleImpl;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
@@ -34,6 +35,7 @@
*
* @author Ahmed Ashour
* @author Marc Guillemot
+ * @author Ronald Brill
*/
@JsxClass
public class CSSStyleRule extends CSSRule {
@@ -43,7 +45,7 @@ public class CSSStyleRule extends CSSRule {
/**
* Creates a new instance.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSStyleRule() {
}
@@ -52,7 +54,7 @@ public CSSStyleRule() {
* @param stylesheet the Stylesheet of this rule.
* @param rule the wrapped rule
*/
- protected CSSStyleRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSSStyleRule rule) {
+ protected CSSStyleRule(final CSSStyleSheet stylesheet, final CSSStyleRuleImpl rule) {
super(stylesheet, rule);
}
@@ -62,7 +64,7 @@ protected CSSStyleRule(final CSSStyleSheet stylesheet, final org.w3c.dom.css.CSS
*/
@JsxGetter
public String getSelectorText() {
- String selectorText = ((org.w3c.dom.css.CSSStyleRule) getRule()).getSelectorText();
+ String selectorText = ((CSSStyleRuleImpl) getRule()).getSelectorText();
final Matcher m = SELECTOR_PARTS_PATTERN.matcher(selectorText);
final StringBuffer sb = new StringBuffer();
while (m.find()) {
@@ -88,7 +90,7 @@ public String getSelectorText() {
*/
@JsxSetter
public void setSelectorText(final String selectorText) {
- ((org.w3c.dom.css.CSSStyleRule) getRule()).setSelectorText(selectorText);
+ ((CSSStyleRuleImpl) getRule()).setSelectorText(selectorText);
}
/**
@@ -97,7 +99,7 @@ public void setSelectorText(final String selectorText) {
*/
@JsxGetter
public CSSStyleDeclaration getStyle() {
- return new CSSStyleDeclaration(getParentScope(), ((org.w3c.dom.css.CSSStyleRule) getRule()).getStyle());
+ return new CSSStyleDeclaration(getParentScope(), ((CSSStyleRuleImpl) getRule()).getStyle());
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java
index 27d1fe41e6a..7048650317a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSStyleSheet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,17 +16,17 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLLINK_CHECK_TYPE_FOR_STYLESHEET;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.QUERYSELECTORALL_NOT_IN_QUIRKS;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.QUERYSELECTORALL_NO_TARGET;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.QUERYSELECTOR_CSS3_PSEUDO_REQUIRE_ATTACHED_NODE;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.STYLESHEET_ADD_RULE_RETURNS_POS;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.STYLESHEET_HREF_EMPTY_IS_NULL;
import static com.gargoylesoftware.htmlunit.html.DomElement.ATTRIBUTE_NOT_DEFINED;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF68;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.net.MalformedURLException;
@@ -48,17 +48,17 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.DOMException;
-import org.w3c.dom.css.CSSImportRule;
-import org.w3c.dom.css.CSSRule;
-import org.w3c.dom.css.CSSRuleList;
-import org.w3c.dom.stylesheets.MediaList;
+import com.gargoylesoftware.css.dom.AbstractCSSRuleImpl;
+import com.gargoylesoftware.css.dom.CSSCharsetRuleImpl;
import com.gargoylesoftware.css.dom.CSSImportRuleImpl;
import com.gargoylesoftware.css.dom.CSSMediaRuleImpl;
import com.gargoylesoftware.css.dom.CSSRuleListImpl;
+import com.gargoylesoftware.css.dom.CSSStyleDeclarationImpl;
import com.gargoylesoftware.css.dom.CSSStyleRuleImpl;
import com.gargoylesoftware.css.dom.CSSStyleSheetImpl;
import com.gargoylesoftware.css.dom.CSSValueImpl;
+import com.gargoylesoftware.css.dom.CSSValueImpl.CSSPrimitiveValueType;
import com.gargoylesoftware.css.dom.MediaListImpl;
import com.gargoylesoftware.css.dom.Property;
import com.gargoylesoftware.css.parser.CSSErrorHandler;
@@ -66,18 +66,9 @@
import com.gargoylesoftware.css.parser.CSSOMParser;
import com.gargoylesoftware.css.parser.CSSParseException;
import com.gargoylesoftware.css.parser.InputSource;
-import com.gargoylesoftware.css.parser.condition.AttributeCondition;
-import com.gargoylesoftware.css.parser.condition.BeginHyphenAttributeCondition;
-import com.gargoylesoftware.css.parser.condition.ClassCondition;
+import com.gargoylesoftware.css.parser.LexicalUnit;
import com.gargoylesoftware.css.parser.condition.Condition;
import com.gargoylesoftware.css.parser.condition.Condition.ConditionType;
-import com.gargoylesoftware.css.parser.condition.IdCondition;
-import com.gargoylesoftware.css.parser.condition.LangCondition;
-import com.gargoylesoftware.css.parser.condition.OneOfAttributeCondition;
-import com.gargoylesoftware.css.parser.condition.PrefixAttributeCondition;
-import com.gargoylesoftware.css.parser.condition.PseudoClassCondition;
-import com.gargoylesoftware.css.parser.condition.SubstringAttributeCondition;
-import com.gargoylesoftware.css.parser.condition.SuffixAttributeCondition;
import com.gargoylesoftware.css.parser.javacc.CSS3Parser;
import com.gargoylesoftware.css.parser.media.MediaQuery;
import com.gargoylesoftware.css.parser.selector.ChildSelector;
@@ -119,8 +110,11 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
import com.gargoylesoftware.htmlunit.javascript.host.Element;
+import com.gargoylesoftware.htmlunit.javascript.host.Window;
+import com.gargoylesoftware.htmlunit.javascript.host.dom.MediaList;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLElement;
+import com.gargoylesoftware.htmlunit.util.MimeType;
import com.gargoylesoftware.htmlunit.util.UrlUtils;
import net.sourceforge.htmlunit.corejs.javascript.Context;
@@ -146,7 +140,7 @@ public class CSSStyleSheet extends StyleSheet {
private static final Pattern UNESCAPE_SELECTOR = Pattern.compile("\\\\([\\[\\]\\.:])");
/** The parsed stylesheet which this host object wraps. */
- private final org.w3c.dom.css.CSSStyleSheet wrapped_;
+ private final CSSStyleSheetImpl wrapped_;
/** The HTML element which owns this stylesheet. */
private final HTMLElement ownerNode_;
@@ -156,10 +150,10 @@ public class CSSStyleSheet extends StyleSheet {
private List cssRulesIndexFix_;
/** The CSS import rules and their corresponding stylesheets. */
- private final Map imports_ = new HashMap<>();
+ private final Map imports_ = new HashMap<>();
/** cache parsed media strings */
- private static final transient Map media_ = new HashMap<>();
+ private static final transient Map media_ = new HashMap<>();
/** This stylesheet's URI (used to resolved contained @import rules). */
private String uri_;
@@ -183,7 +177,7 @@ public class CSSStyleSheet extends StyleSheet {
/**
* Creates a new empty stylesheet.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSStyleSheet() {
wrapped_ = new CSSStyleSheetImpl();
ownerNode_ = null;
@@ -196,12 +190,39 @@ 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) {
- setParentScope(element.getWindow());
+ final Window win = element.getWindow();
+
+ setParentScope(win);
setPrototype(getPrototype(CSSStyleSheet.class));
if (source != null) {
source.setURI(uri);
}
- wrapped_ = parseCSS(source);
+ wrapped_ = parseCSS(source, win.getWebWindow().getWebClient());
+ uri_ = uri;
+ ownerNode_ = element;
+ }
+
+ /**
+ * Creates a new stylesheet representing the CSS stylesheet for the specified input source.
+ * @param element the owning node
+ * @param styleSheet the source which contains the CSS stylesheet which this stylesheet host object represents
+ * @param uri this stylesheet's URI (used to resolved contained @import rules)
+ */
+ public CSSStyleSheet(final HTMLElement element, final String styleSheet, final String uri) {
+ final Window win = element.getWindow();
+
+ CSSStyleSheetImpl css = null;
+ try (InputSource source = new InputSource(new StringReader(styleSheet))) {
+ source.setURI(uri);
+ css = parseCSS(source, win.getWebWindow().getWebClient());
+ }
+ catch (final IOException e) {
+ LOG.error(e.getMessage(), e);
+ }
+
+ setParentScope(win);
+ setPrototype(getPrototype(CSSStyleSheet.class));
+ wrapped_ = css;
uri_ = uri;
ownerNode_ = element;
}
@@ -212,7 +233,7 @@ public CSSStyleSheet(final HTMLElement element, final InputSource source, final
* @param wrapped the CSS stylesheet which this stylesheet host object represents
* @param uri this stylesheet's URI (used to resolved contained @import rules)
*/
- public CSSStyleSheet(final HTMLElement element, final org.w3c.dom.css.CSSStyleSheet wrapped, final String uri) {
+ public CSSStyleSheet(final HTMLElement element, final CSSStyleSheetImpl wrapped, final String uri) {
setParentScope(element.getWindow());
setPrototype(getPrototype(CSSStyleSheet.class));
wrapped_ = wrapped;
@@ -224,7 +245,7 @@ public CSSStyleSheet(final HTMLElement element, final org.w3c.dom.css.CSSStyleSh
* Returns the wrapped stylesheet.
* @return the wrapped stylesheet
*/
- public org.w3c.dom.css.CSSStyleSheet getWrappedSheet() {
+ public CSSStyleSheetImpl getWrappedSheet() {
return wrapped_;
}
@@ -245,7 +266,7 @@ public void modifyIfNecessary(final ComputedCSSStyleDeclaration style, final Ele
final List matchingRules =
selects(getRuleIndex(), this, browser, e, pseudoElement, false);
for (CSSStyleSheetImpl.SelectorEntry entry : matchingRules) {
- final org.w3c.dom.css.CSSStyleDeclaration dec = entry.getRule().getStyle();
+ final CSSStyleDeclarationImpl dec = entry.getRule().getStyle();
style.applyStyleFromSelector(dec, entry.getSelector());
}
}
@@ -266,15 +287,25 @@ public static CSSStyleSheet loadStylesheet(final HTMLElement element, final Html
final WebRequest request;
final WebResponse response;
final WebClient client = page.getWebClient();
- if (link != null) {
+ if (link == null) {
+ // Use href.
+ final BrowserVersion browser = client.getBrowserVersion();
+ request = new WebRequest(new URL(url), browser.getCssAcceptHeader(), browser.getAcceptEncodingHeader());
+ request.setAdditionalHeader(HttpHeader.REFERER, uri);
+
+ // our cache is a bit strange;
+ // loadWebResponse check the cache for the web response
+ // AND also fixes the request url for the following cache lookups
+ response = client.loadWebResponse(request);
+ }
+ else {
// Use link.
request = link.getWebRequest();
if (element.getBrowserVersion().hasFeature(HTMLLINK_CHECK_TYPE_FOR_STYLESHEET)) {
final String type = link.getTypeAttribute();
- if (StringUtils.isNotBlank(type) && !"text/css".equals(type)) {
- final InputSource source = new InputSource(new StringReader(""));
- return new CSSStyleSheet(element, source, uri);
+ if (StringUtils.isNotBlank(type) && !MimeType.TEXT_CSS.equals(type)) {
+ return new CSSStyleSheet(element, "", uri);
}
}
@@ -283,25 +314,14 @@ public static CSSStyleSheet loadStylesheet(final HTMLElement element, final Html
// AND also fixes the request url for the following cache lookups
response = link.getWebResponse(true, request);
}
- else {
- // Use href.
- final String accept = client.getBrowserVersion().getCssAcceptHeader();
- request = new WebRequest(new URL(url), accept);
- request.setAdditionalHeader(HttpHeader.REFERER, uri);
-
- // our cache is a bit strange;
- // loadWebResponse check the cache for the web response
- // AND also fixes the request url for the following cache lookups
- response = client.loadWebResponse(request);
- }
// now we can look into the cache with the fixed request for
// a cached script
final Cache cache = client.getCache();
final Object fromCache = cache.getCachedObject(request);
- if (fromCache instanceof org.w3c.dom.css.CSSStyleSheet) {
+ if (fromCache instanceof CSSStyleSheetImpl) {
uri = request.getUrl().toExternalForm();
- sheet = new CSSStyleSheet(element, (org.w3c.dom.css.CSSStyleSheet) fromCache, uri);
+ sheet = new CSSStyleSheet(element, (CSSStyleSheetImpl) fromCache, uri);
}
else {
uri = response.getWebRequest().getUrl().toExternalForm();
@@ -309,15 +329,19 @@ public static CSSStyleSheet loadStylesheet(final HTMLElement element, final Html
client.throwFailingHttpStatusCodeExceptionIfNecessary(response);
// CSS content must have downloaded OK; go ahead and build the corresponding stylesheet.
- final InputSource source;
final String contentType = response.getContentType();
- if (StringUtils.isEmpty(contentType) || "text/css".equals(contentType)) {
- source = new InputSource(response.getContentAsStream(), response.getContentCharset().name());
+ if (StringUtils.isEmpty(contentType) || MimeType.TEXT_CSS.equals(contentType)) {
+ try (InputSource source =
+ new InputSource(
+ new InputStreamReader(response.getContentAsStream(),
+ response.getContentCharset().name()))) {
+ source.setURI(uri);
+ sheet = new CSSStyleSheet(element, source, uri);
+ }
}
else {
- source = new InputSource(new StringReader(""));
+ sheet = new CSSStyleSheet(element, "", uri);
}
- sheet = new CSSStyleSheet(element, source, uri);
// cache the style sheet
if (!cache.cacheIfPossible(request, response, sheet.getWrappedSheet())) {
@@ -327,24 +351,30 @@ public static CSSStyleSheet loadStylesheet(final HTMLElement element, final Html
}
catch (final FailingHttpStatusCodeException e) {
// Got a 404 response or something like that; behave nicely.
- LOG.error("Exception loading " + uri, e);
- final InputSource source = new InputSource(new StringReader(""));
- sheet = new CSSStyleSheet(element, source, uri);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Exception loading " + uri, e);
+ }
+ sheet = new CSSStyleSheet(element, "", uri);
}
catch (final IOException e) {
// Got a basic IO error; behave nicely.
- LOG.error("IOException loading " + uri, e);
- final InputSource source = new InputSource(new StringReader(""));
- sheet = new CSSStyleSheet(element, source, uri);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("IOException loading " + uri, e);
+ }
+ sheet = new CSSStyleSheet(element, "", uri);
}
catch (final RuntimeException e) {
// Got something unexpected; we can throw an exception in this case.
- LOG.error("RuntimeException loading " + uri, e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("RuntimeException loading " + uri, e);
+ }
throw Context.reportRuntimeError("Exception: " + e);
}
catch (final Exception e) {
// Got something unexpected; we can throw an exception in this case.
- LOG.error("Exception loading " + uri, e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Exception loading " + uri, e);
+ }
throw Context.reportRuntimeError("Exception: " + e);
}
return sheet;
@@ -438,14 +468,16 @@ && selects(browserVersion, gas.getSelector(), (HtmlElement) prev1,
}
return false;
case PSEUDO_ELEMENT_SELECTOR:
- if (pseudoElement != null && !pseudoElement.isEmpty() && pseudoElement.charAt(0) == ':') {
+ if (pseudoElement != null && pseudoElement.length() != 0 && pseudoElement.charAt(0) == ':') {
final String pseudoName = ((PseudoElementSelector) selector).getLocalName();
return pseudoName.equals(pseudoElement.substring(1));
}
return false;
default:
- LOG.error("Unknown CSS selector type '" + selector.getSelectorType() + "'.");
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Unknown CSS selector type '" + selector.getSelectorType() + "'.");
+ }
return false;
}
}
@@ -464,12 +496,10 @@ static boolean selects(final BrowserVersion browserVersion, final Condition cond
switch (condition.getConditionType()) {
case ID_CONDITION:
- final IdCondition ac4 = (IdCondition) condition;
- return ac4.getValue().equals(element.getId());
+ return condition.getValue().equals(element.getId());
case CLASS_CONDITION:
- final ClassCondition ac3 = (ClassCondition) condition;
- String v3 = ac3.getValue();
+ String v3 = condition.getValue();
if (v3.indexOf('\\') > -1) {
v3 = UNESCAPE_SELECTOR.matcher(v3).replaceAll("$1");
}
@@ -477,46 +507,43 @@ static boolean selects(final BrowserVersion browserVersion, final Condition cond
return selectsWhitespaceSeparated(v3, a3);
case ATTRIBUTE_CONDITION:
- final AttributeCondition ac1 = (AttributeCondition) condition;
- String value = ac1.getValue();
+ String value = condition.getValue();
if (value != null) {
if (value.indexOf('\\') > -1) {
value = UNESCAPE_SELECTOR.matcher(value).replaceAll("$1");
}
- final String attrValue = element.getAttribute(ac1.getLocalName());
+ final String attrValue = element.getAttribute(condition.getLocalName());
return ATTRIBUTE_NOT_DEFINED != attrValue && attrValue.equals(value);
}
- return element.hasAttribute(ac1.getLocalName());
+ return element.hasAttribute(condition.getLocalName());
case PREFIX_ATTRIBUTE_CONDITION:
- final PrefixAttributeCondition pac = (PrefixAttributeCondition) condition;
- final String prefixValue = pac.getValue();
- return !"".equals(prefixValue) && element.getAttribute(pac.getLocalName()).startsWith(prefixValue);
+ final String prefixValue = condition.getValue();
+ return !"".equals(prefixValue)
+ && element.getAttribute(condition.getLocalName()).startsWith(prefixValue);
case SUFFIX_ATTRIBUTE_CONDITION:
- final SuffixAttributeCondition sac = (SuffixAttributeCondition) condition;
- final String suffixValue = sac.getValue();
- return !"".equals(suffixValue) && element.getAttribute(sac.getLocalName()).endsWith(suffixValue);
+ final String suffixValue = condition.getValue();
+ return !"".equals(suffixValue)
+ && element.getAttribute(condition.getLocalName()).endsWith(suffixValue);
case SUBSTRING_ATTRIBUTE_CONDITION:
- final SubstringAttributeCondition suac = (SubstringAttributeCondition) condition;
- final String substringValue = suac.getValue();
- return !"".equals(substringValue) && element.getAttribute(suac.getLocalName()).contains(substringValue);
+ final String substringValue = condition.getValue();
+ return !"".equals(substringValue)
+ && element.getAttribute(condition.getLocalName()).contains(substringValue);
case BEGIN_HYPHEN_ATTRIBUTE_CONDITION:
- final BeginHyphenAttributeCondition bhac = (BeginHyphenAttributeCondition) condition;
- final String v = bhac.getValue();
- final String a = element.getAttribute(bhac.getLocalName());
+ final String v = condition.getValue();
+ final String a = element.getAttribute(condition.getLocalName());
return selects(v, a, '-');
case ONE_OF_ATTRIBUTE_CONDITION:
- final OneOfAttributeCondition ooac = (OneOfAttributeCondition) condition;
- final String v2 = ooac.getValue();
- final String a2 = element.getAttribute(ooac.getLocalName());
+ final String v2 = condition.getValue();
+ final String a2 = element.getAttribute(condition.getLocalName());
return selects(v2, a2, ' ');
case LANG_CONDITION:
- final String lcLang = ((LangCondition) condition).getLang();
+ final String lcLang = condition.getValue();
final int lcLangLength = lcLang.length();
for (DomNode node = element; node instanceof HtmlElement; node = node.getParentNode()) {
final String nodeLang = ((HtmlElement) node).getAttributeDirect("lang");
@@ -529,11 +556,12 @@ static boolean selects(final BrowserVersion browserVersion, final Condition cond
return false;
case PSEUDO_CLASS_CONDITION:
- return selectsPseudoClass(browserVersion,
- (PseudoClassCondition) condition, element, fromQuerySelectorAll);
+ return selectsPseudoClass(browserVersion, condition, element, fromQuerySelectorAll);
default:
- LOG.error("Unknown CSS condition type '" + condition.getConditionType() + "'.");
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Unknown CSS condition type '" + condition.getConditionType() + "'.");
+ }
return false;
}
}
@@ -600,7 +628,7 @@ private static boolean selectsWhitespaceSeparated(final String condition, final
}
private static boolean selectsPseudoClass(final BrowserVersion browserVersion,
- final PseudoClassCondition condition, final DomElement element, final boolean fromQuerySelectorAll) {
+ final Condition condition, final DomElement element, final boolean fromQuerySelectorAll) {
if (browserVersion.hasFeature(QUERYSELECTORALL_NOT_IN_QUIRKS)) {
final Object sobj = element.getPage().getScriptableObject();
if (sobj instanceof HTMLDocument && ((HTMLDocument) sobj).getDocumentMode() < 8) {
@@ -709,9 +737,6 @@ private static boolean selectsPseudoClass(final BrowserVersion browserVersion,
return isEmpty(element);
case "target":
- if (fromQuerySelectorAll && browserVersion.hasFeature(QUERYSELECTORALL_NO_TARGET)) {
- return false;
- }
final String ref = element.getPage().getUrl().getRef();
return StringUtils.isNotBlank(ref) && ref.equals(element.getId());
@@ -783,8 +808,7 @@ public void error(final CSSParseException exception) throws CSSException {
final CSSOMParser parser = new CSSOMParser(new CSS3Parser());
parser.setErrorHandler(errorHandler);
try {
- final SelectorList selectorList
- = parser.parseSelectors(new InputSource(new StringReader(selectors)));
+ final SelectorList selectorList = parser.parseSelectors(selectors);
if (errorOccured.get() || selectorList == null || selectorList.size() != 1) {
throw new CSSException("Invalid selectors: " + selectors);
}
@@ -830,7 +854,7 @@ private static boolean getNth(final String nth, final int index) {
a = -1;
}
else {
- if (value.startsWith("+")) {
+ if (value.length() > 0 && value.charAt(0) == '+') {
value = value.substring(1);
}
a = NumberUtils.toInt(value, 1);
@@ -838,7 +862,7 @@ private static boolean getNth(final String nth, final int index) {
}
String value = nth.substring(nIndex + 1).trim();
- if (value.startsWith("+")) {
+ if (value.length() > 0 && value.charAt(0) == '+') {
value = value.substring(1);
}
final int b = NumberUtils.toInt(value, 0);
@@ -855,18 +879,21 @@ private static boolean getNth(final String nth, final int index) {
* returns an empty stylesheet.
*
* @param source the source from which to retrieve the CSS to be parsed
+ * @param client the client
* @return the stylesheet parsed from the specified input source
*/
- private org.w3c.dom.css.CSSStyleSheet parseCSS(final InputSource source) {
- org.w3c.dom.css.CSSStyleSheet ss;
+ private static CSSStyleSheetImpl parseCSS(final InputSource source, final WebClient client) {
+ CSSStyleSheetImpl ss;
try {
- final CSSErrorHandler errorHandler = getWindow().getWebWindow().getWebClient().getCssErrorHandler();
+ final CSSErrorHandler errorHandler = client.getCssErrorHandler();
final CSSOMParser parser = new CSSOMParser(new CSS3Parser());
parser.setErrorHandler(errorHandler);
ss = parser.parseStyleSheet(source, null);
}
catch (final Throwable t) {
- LOG.error("Error parsing CSS from '" + toString(source) + "': " + t.getMessage(), t);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Error parsing CSS from '" + toString(source) + "': " + t.getMessage(), t);
+ }
ss = new CSSStyleSheetImpl();
}
return ss;
@@ -879,7 +906,7 @@ private org.w3c.dom.css.CSSStyleSheet parseCSS(final InputSource source) {
* @param source the source from which to retrieve the selectors to be parsed
* @return the selectors parsed from the specified input source
*/
- public SelectorList parseSelectors(final InputSource source) {
+ public SelectorList parseSelectors(final String source) {
SelectorList selectors;
try {
final CSSErrorHandler errorHandler = getWindow().getWebWindow().getWebClient().getCssErrorHandler();
@@ -892,7 +919,9 @@ public SelectorList parseSelectors(final InputSource source) {
}
}
catch (final Throwable t) {
- LOG.error("Error parsing CSS selectors from '" + toString(source) + "': " + t.getMessage(), t);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Error parsing CSS selectors from '" + source + "': " + t.getMessage(), t);
+ }
selectors = new SelectorListImpl();
}
return selectors;
@@ -905,8 +934,8 @@ public SelectorList parseSelectors(final InputSource source) {
* @param source the source from which to retrieve the media to be parsed
* @return the media parsed from the specified input source
*/
- static MediaList parseMedia(final CSSErrorHandler errorHandler, final String mediaString) {
- MediaList media = media_.get(mediaString);
+ static MediaListImpl parseMedia(final CSSErrorHandler errorHandler, final String mediaString) {
+ MediaListImpl media = media_.get(mediaString);
if (media != null) {
return media;
}
@@ -915,15 +944,14 @@ static MediaList parseMedia(final CSSErrorHandler errorHandler, final String med
final CSSOMParser parser = new CSSOMParser(new CSS3Parser());
parser.setErrorHandler(errorHandler);
- final InputSource source = new InputSource(new StringReader(mediaString));
- media = new MediaListImpl(parser.parseMedia(source));
- if (media != null) {
- media_.put(mediaString, media);
- return media;
- }
+ media = new MediaListImpl(parser.parseMedia(mediaString));
+ media_.put(mediaString, media);
+ return media;
}
catch (final Exception e) {
- LOG.error("Error parsing CSS media from '" + mediaString + "': " + e.getMessage(), e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Error parsing CSS media from '" + mediaString + "': " + e.getMessage(), e);
+ }
}
media = new MediaListImpl(null);
@@ -950,6 +978,7 @@ private static String toString(final InputSource source) {
return "";
}
catch (final IOException e) {
+ LOG.error(e.getMessage(), e);
return "";
}
}
@@ -1035,9 +1064,9 @@ public String getHref() {
public int insertRule(final String rule, final int position) {
try {
initCssRules();
- final int result = wrapped_.insertRule(rule, fixIndex(position));
+ wrapped_.insertRule(rule, fixIndex(position));
refreshCssRules();
- return result;
+ return position;
}
catch (final DOMException e) {
// in case of error try with an empty rule
@@ -1045,9 +1074,9 @@ public int insertRule(final String rule, final int position) {
if (pos > -1) {
final String newRule = rule.substring(0, pos) + "{}";
try {
- final int result = wrapped_.insertRule(newRule, fixIndex(position));
+ wrapped_.insertRule(newRule, fixIndex(position));
refreshCssRules();
- return result;
+ return position;
}
catch (final DOMException ex) {
throw Context.throwAsScriptRuntimeEx(ex);
@@ -1065,11 +1094,11 @@ private void refreshCssRules() {
cssRules_.clearRules();
cssRulesIndexFix_.clear();
- final CSSRuleListImpl ruleList = (CSSRuleListImpl) getWrappedSheet().getCssRules();
- final List rules = ruleList.getRules();
+ final CSSRuleListImpl ruleList = getWrappedSheet().getCssRules();
+ final List rules = ruleList.getRules();
int pos = 0;
- for (CSSRule rule : rules) {
- if (rule instanceof org.w3c.dom.css.CSSCharsetRule) {
+ for (AbstractCSSRuleImpl rule : rules) {
+ if (rule instanceof CSSCharsetRuleImpl) {
cssRulesIndexFix_.add(pos);
continue;
}
@@ -1086,7 +1115,7 @@ private void refreshCssRules() {
}
// reset our index also
- ((CSSStyleSheetImpl) getWrappedSheet()).resetRuleIndex();
+ getWrappedSheet().resetRuleIndex();
}
private int fixIndex(int index) {
@@ -1123,7 +1152,7 @@ public void deleteRule(final int position) {
* @param rule the rule
* @return always return -1 as of MSDN documentation
*/
- @JsxFunction({IE, CHROME})
+ @JsxFunction({IE, CHROME, FF68})
public int addRule(final String selector, final String rule) {
String completeRule = selector + " {" + rule + "}";
try {
@@ -1153,7 +1182,7 @@ public int addRule(final String selector, final String rule) {
* @param position the position of the rule to be deleted
* @see MSDN
*/
- @JsxFunction({IE, CHROME})
+ @JsxFunction({IE, CHROME, FF68})
public void removeRule(final int position) {
try {
initCssRules();
@@ -1197,7 +1226,7 @@ else if (e instanceof HtmlLink) {
}
final WebClient webClient = getWindow().getWebWindow().getWebClient();
- final MediaList mediaList = parseMedia(webClient.getCssErrorHandler(), media);
+ final MediaListImpl mediaList = parseMedia(webClient.getCssErrorHandler(), media);
return isActive(this, mediaList);
}
@@ -1223,13 +1252,13 @@ public void setEnabled(final boolean enabled) {
* @param mediaList the media list
* @return whether the specified {@link MediaList} is active or not
*/
- static boolean isActive(final SimpleScriptable scriptable, final MediaList mediaList) {
+ static boolean isActive(final SimpleScriptable scriptable, final MediaListImpl mediaList) {
if (mediaList.getLength() == 0) {
return true;
}
for (int i = 0; i < mediaList.getLength(); i++) {
- final MediaQuery mediaQuery = ((MediaListImpl) mediaList).mediaQuery(i);
+ final MediaQuery mediaQuery = mediaList.mediaQuery(i);
boolean isActive = isActive(scriptable, mediaQuery);
if (mediaQuery.isNot()) {
isActive = !isActive;
@@ -1245,87 +1274,99 @@ private static boolean isActive(final SimpleScriptable scriptable, final MediaQu
final String mediaType = mediaQuery.getMedia();
if ("screen".equalsIgnoreCase(mediaType) || "all".equalsIgnoreCase(mediaType)) {
for (final Property property : mediaQuery.getProperties()) {
- final float val;
+ final double val;
switch (property.getName()) {
case "max-width":
- val = pixelValue((CSSValueImpl) property.getValue(), scriptable);
- if (val < scriptable.getWindow().getWebWindow().getInnerWidth()) {
+ val = pixelValue(property.getValue(), scriptable);
+ if (val == -1 || val < scriptable.getWindow().getWebWindow().getInnerWidth()) {
return false;
}
break;
case "min-width":
- val = pixelValue((CSSValueImpl) property.getValue(), scriptable);
- if (val > scriptable.getWindow().getWebWindow().getInnerWidth()) {
+ val = pixelValue(property.getValue(), scriptable);
+ if (val == -1 || val > scriptable.getWindow().getWebWindow().getInnerWidth()) {
return false;
}
break;
case "max-device-width":
- val = pixelValue((CSSValueImpl) property.getValue(), scriptable);
- if (val < scriptable.getWindow().getScreen().getWidth()) {
+ val = pixelValue(property.getValue(), scriptable);
+ if (val == -1 || val < scriptable.getWindow().getScreen().getWidth()) {
return false;
}
break;
case "min-device-width":
- val = pixelValue((CSSValueImpl) property.getValue(), scriptable);
- if (val > scriptable.getWindow().getScreen().getWidth()) {
+ val = pixelValue(property.getValue(), scriptable);
+ if (val == -1 || val > scriptable.getWindow().getScreen().getWidth()) {
return false;
}
break;
case "max-height":
- val = pixelValue((CSSValueImpl) property.getValue(), scriptable);
- if (val < scriptable.getWindow().getWebWindow().getInnerWidth()) {
+ val = pixelValue(property.getValue(), scriptable);
+ if (val == -1 || val < scriptable.getWindow().getWebWindow().getInnerWidth()) {
return false;
}
break;
case "min-height":
- val = pixelValue((CSSValueImpl) property.getValue(), scriptable);
- if (val > scriptable.getWindow().getWebWindow().getInnerWidth()) {
+ val = pixelValue(property.getValue(), scriptable);
+ if (val == -1 || val > scriptable.getWindow().getWebWindow().getInnerWidth()) {
return false;
}
break;
case "max-device-height":
- val = pixelValue((CSSValueImpl) property.getValue(), scriptable);
- if (val < scriptable.getWindow().getScreen().getWidth()) {
+ val = pixelValue(property.getValue(), scriptable);
+ if (val == -1 || val < scriptable.getWindow().getScreen().getWidth()) {
return false;
}
break;
case "min-device-height":
- val = pixelValue((CSSValueImpl) property.getValue(), scriptable);
- if (val > scriptable.getWindow().getScreen().getWidth()) {
+ val = pixelValue(property.getValue(), scriptable);
+ if (val == -1 || val > scriptable.getWindow().getScreen().getWidth()) {
return false;
}
break;
case "resolution":
- val = resolutionValue((CSSValueImpl) property.getValue());
- if (Math.round(val) != scriptable.getWindow().getScreen().getDeviceXDPI()) {
+ final CSSValueImpl propValue = property.getValue();
+ val = resolutionValue(propValue);
+ if (propValue == null) {
+ return true;
+ }
+ if (val == -1 || Math.round(val) != scriptable.getWindow().getScreen().getDeviceXDPI()) {
return false;
}
break;
case "max-resolution":
- val = resolutionValue((CSSValueImpl) property.getValue());
- if (val < scriptable.getWindow().getScreen().getDeviceXDPI()) {
+ val = resolutionValue(property.getValue());
+ if (val == -1 || val < scriptable.getWindow().getScreen().getDeviceXDPI()) {
return false;
}
break;
case "min-resolution":
- val = resolutionValue((CSSValueImpl) property.getValue());
- if (val > scriptable.getWindow().getScreen().getDeviceXDPI()) {
+ val = resolutionValue(property.getValue());
+ if (val == -1 || val > scriptable.getWindow().getScreen().getDeviceXDPI()) {
return false;
}
break;
case "orientation":
- final String orient = property.getValue().getCssText();
+ final CSSValueImpl cssValue = property.getValue();
+ if (cssValue == null) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("CSSValue is null not supported for feature 'orientation'");
+ }
+ return true;
+ }
+
+ final String orient = cssValue.getCssText();
final WebWindow window = scriptable.getWindow().getWebWindow();
if ("portrait".equals(orient)) {
if (window.getInnerWidth() > window.getInnerHeight()) {
@@ -1338,8 +1379,10 @@ else if ("landscape".equals(orient)) {
}
}
else {
- LOG.warn("CSSValue '" + property.getValue().getCssText()
- + "' not supported for feature 'orientation'.");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("CSSValue '" + property.getValue().getCssText()
+ + "' not supported for feature 'orientation'.");
+ }
return false;
}
break;
@@ -1352,51 +1395,77 @@ else if ("landscape".equals(orient)) {
return false;
}
- private static float pixelValue(final CSSValueImpl cssValue, final SimpleScriptable scriptable) {
- final int dpi;
- switch (cssValue.getPrimitiveType()) {
- case CSSPrimitiveValue.CSS_PX:
- return cssValue.getFloatValue(CSSPrimitiveValue.CSS_PX);
- case CSSPrimitiveValue.CSS_EMS:
- // hard coded default for the moment 16px = 1 em
- return 16f * cssValue.getFloatValue(CSSPrimitiveValue.CSS_EMS);
- case CSSPrimitiveValue.CSS_PERCENTAGE:
- // hard coded default for the moment 16px = 100%
- return 0.16f * cssValue.getFloatValue(CSSPrimitiveValue.CSS_PERCENTAGE);
- case CSSPrimitiveValue.CSS_EXS:
- // hard coded default for the moment 16px = 100%
- return 0.16f * cssValue.getFloatValue(CSSPrimitiveValue.CSS_EXS);
- case CSSPrimitiveValue.CSS_MM:
- dpi = scriptable.getWindow().getScreen().getDeviceXDPI();
- return (dpi / 25.4f) * cssValue.getFloatValue(CSSPrimitiveValue.CSS_MM);
- case CSSPrimitiveValue.CSS_CM:
- dpi = scriptable.getWindow().getScreen().getDeviceXDPI();
- return (dpi / 254f) * cssValue.getFloatValue(CSSPrimitiveValue.CSS_CM);
- case CSSPrimitiveValue.CSS_PT:
- dpi = scriptable.getWindow().getScreen().getDeviceXDPI();
- return (dpi / 72f) * cssValue.getFloatValue(CSSPrimitiveValue.CSS_PT);
- default:
- break;
+ private static double pixelValue(final CSSValueImpl cssValue, final SimpleScriptable scriptable) {
+ if (cssValue == null) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("CSSValue is null but has to be a 'px', 'em', '%', 'mm', 'ex', or 'pt' value.");
+ }
+ return -1;
+ }
+
+ final LexicalUnit.LexicalUnitType luType = cssValue.getLexicalUnitType();
+ if (luType != null) {
+ final int dpi;
+
+ switch (luType) {
+ case PIXEL:
+ return cssValue.getDoubleValue();
+ case EM:
+ // hard coded default for the moment 16px = 1 em
+ return 16f * cssValue.getDoubleValue();
+ case PERCENTAGE:
+ // hard coded default for the moment 16px = 100%
+ return 0.16f * cssValue.getDoubleValue();
+ case EX:
+ // hard coded default for the moment 16px = 100%
+ return 0.16f * cssValue.getDoubleValue();
+ case REM:
+ // hard coded default for the moment 16px = 100%
+ return 0.16f * cssValue.getDoubleValue();
+ case MILLIMETER:
+ dpi = scriptable.getWindow().getScreen().getDeviceXDPI();
+ return (dpi / 25.4f) * cssValue.getDoubleValue();
+ case CENTIMETER:
+ dpi = scriptable.getWindow().getScreen().getDeviceXDPI();
+ return (dpi / 254f) * cssValue.getDoubleValue();
+ case POINT:
+ dpi = scriptable.getWindow().getScreen().getDeviceXDPI();
+ return (dpi / 72f) * cssValue.getDoubleValue();
+ default:
+ break;
+ }
+ }
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("CSSValue '" + cssValue.getCssText()
+ + "' has to be a 'px', 'em', '%', 'mm', 'ex', or 'pt' value.");
}
- LOG.warn("CSSValue '" + cssValue.getCssText() + "' has to be a 'px', 'em', '%', 'mm', 'ex', or 'pt' value.");
return -1;
}
- private static float resolutionValue(final CSSValueImpl cssValue) {
- if (cssValue.getPrimitiveType() == CSSPrimitiveValue.CSS_DIMENSION) {
+ private static double resolutionValue(final CSSValueImpl cssValue) {
+ if (cssValue == null) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("CSSValue is null but has to be a 'dpi', 'dpcm', or 'dppx' value.");
+ }
+ return -1;
+ }
+
+ if (cssValue.getPrimitiveType() == CSSPrimitiveValueType.CSS_DIMENSION) {
final String text = cssValue.getCssText();
if (text.endsWith("dpi")) {
- return cssValue.getFloatValue(CSSPrimitiveValue.CSS_DIMENSION);
+ return cssValue.getDoubleValue();
}
if (text.endsWith("dpcm")) {
- return 2.54f * cssValue.getFloatValue(CSSPrimitiveValue.CSS_DIMENSION);
+ return 2.54f * cssValue.getDoubleValue();
}
if (text.endsWith("dppx")) {
- return 96 * cssValue.getFloatValue(CSSPrimitiveValue.CSS_DIMENSION);
+ return 96 * cssValue.getDoubleValue();
}
}
- LOG.warn("CSSValue '" + cssValue.getCssText() + "' has to be a 'dpi', 'dpcm', or 'dppx' value.");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("CSSValue '" + cssValue.getCssText() + "' has to be a 'dpi', 'dpcm', or 'dppx' value.");
+ }
return -1;
}
@@ -1448,7 +1517,10 @@ private static boolean isValidSelector(final Selector selector, final int docume
return isValidSelector(gas.getSelector(), documentMode, domNode)
&& isValidSelector(gas.getSimpleSelector(), documentMode, domNode);
default:
- LOG.warn("Unhandled CSS selector type '" + selector.getSelectorType() + "'. Accepting it silently.");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Unhandled CSS selector type '"
+ + selector.getSelectorType() + "'. Accepting it silently.");
+ }
return true; // at least in a first time to break less stuff
}
}
@@ -1464,10 +1536,12 @@ private static boolean isValidCondition(final Condition condition, final int doc
case ONE_OF_ATTRIBUTE_CONDITION:
case BEGIN_HYPHEN_ATTRIBUTE_CONDITION:
case CLASS_CONDITION:
+ case PREFIX_ATTRIBUTE_CONDITION:
+ case SUBSTRING_ATTRIBUTE_CONDITION:
+ case SUFFIX_ATTRIBUTE_CONDITION:
return true;
case PSEUDO_CLASS_CONDITION:
- final PseudoClassCondition pcc = (PseudoClassCondition) condition;
- String value = pcc.getValue();
+ String value = condition.getValue();
if (value.endsWith(")")) {
if (value.endsWith("()")) {
return false;
@@ -1486,14 +1560,17 @@ private static boolean isValidCondition(final Condition condition, final int doc
}
if ("nth-child()".equals(value)) {
- final String arg = StringUtils.substringBetween(pcc.getValue(), "(", ")").trim();
+ final String arg = StringUtils.substringBetween(condition.getValue(), "(", ")").trim();
return "even".equalsIgnoreCase(arg) || "odd".equalsIgnoreCase(arg)
|| NTH_NUMERIC.matcher(arg).matches()
|| NTH_COMPLEX.matcher(arg).matches();
}
return CSS3_PSEUDO_CLASSES.contains(value);
default:
- LOG.warn("Unhandled CSS condition type '" + condition.getConditionType() + "'. Accepting it silently.");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Unhandled CSS condition type '"
+ + condition.getConditionType() + "'. Accepting it silently.");
+ }
return true;
}
}
@@ -1507,12 +1584,12 @@ private void initCssRules() {
}
private CSSStyleSheetImpl.CSSStyleSheetRuleIndex getRuleIndex() {
- final CSSStyleSheetImpl styleSheet = (CSSStyleSheetImpl) getWrappedSheet();
+ final CSSStyleSheetImpl styleSheet = getWrappedSheet();
CSSStyleSheetImpl.CSSStyleSheetRuleIndex index = styleSheet.getRuleIndex();
if (index == null) {
index = new CSSStyleSheetImpl.CSSStyleSheetRuleIndex();
- final CSSRuleListImpl ruleList = (CSSRuleListImpl) styleSheet.getCssRules();
+ final CSSRuleListImpl ruleList = styleSheet.getCssRules();
index(index, ruleList, new HashSet());
styleSheet.setRuleIndex(index);
@@ -1523,9 +1600,8 @@ private CSSStyleSheetImpl.CSSStyleSheetRuleIndex getRuleIndex() {
private void index(final CSSStyleSheetImpl.CSSStyleSheetRuleIndex index, final CSSRuleListImpl ruleList,
final Set alreadyProcessing) {
- for (CSSRule rule : ruleList.getRules()) {
- final short ruleType = rule.getType();
- if (CSSRule.STYLE_RULE == ruleType) {
+ for (AbstractCSSRuleImpl rule : ruleList.getRules()) {
+ if (rule instanceof CSSStyleRuleImpl) {
final CSSStyleRuleImpl styleRule = (CSSStyleRuleImpl) rule;
final SelectorList selectors = styleRule.getSelectors();
for (Selector selector : selectors) {
@@ -1537,7 +1613,7 @@ private void index(final CSSStyleSheetImpl.CSSStyleSheetRuleIndex index, final C
if (conds != null && conds.size() == 1) {
final Condition c = conds.get(0);
if (ConditionType.CLASS_CONDITION == c.getConditionType()) {
- index.addClassSelector(es, ((ClassCondition) c).getValue(), selector, styleRule);
+ index.addClassSelector(es, c.getValue(), selector, styleRule);
wasClass = true;
}
}
@@ -1550,9 +1626,9 @@ private void index(final CSSStyleSheetImpl.CSSStyleSheetRuleIndex index, final C
}
}
}
- else if (CSSRule.IMPORT_RULE == ruleType) {
+ else if (rule instanceof CSSImportRuleImpl) {
final CSSImportRuleImpl importRule = (CSSImportRuleImpl) rule;
- final MediaList mediaList = importRule.getMedia();
+ final MediaListImpl mediaList = importRule.getMedia();
CSSStyleSheet sheet = imports_.get(importRule);
if (sheet == null) {
@@ -1563,25 +1639,25 @@ else if (CSSRule.IMPORT_RULE == ruleType) {
}
if (!alreadyProcessing.contains(sheet.getUri())) {
- final CSSRuleList sheetRuleList = sheet.getWrappedSheet().getCssRules();
+ final CSSRuleListImpl sheetRuleList = sheet.getWrappedSheet().getCssRules();
alreadyProcessing.add(sheet.getUri());
if (mediaList.getLength() == 0 && index.getMediaList().getLength() == 0) {
- index(index, (CSSRuleListImpl) sheetRuleList, alreadyProcessing);
+ index(index, sheetRuleList, alreadyProcessing);
}
else {
- index(index.addMedia(mediaList), (CSSRuleListImpl) sheetRuleList, alreadyProcessing);
+ index(index.addMedia(mediaList), sheetRuleList, alreadyProcessing);
}
}
}
- else if (CSSRule.MEDIA_RULE == ruleType) {
+ else if (rule instanceof CSSMediaRuleImpl) {
final CSSMediaRuleImpl mediaRule = (CSSMediaRuleImpl) rule;
- final MediaList mediaList = mediaRule.getMedia();
+ final MediaListImpl mediaList = mediaRule.getMediaList();
if (mediaList.getLength() == 0 && index.getMediaList().getLength() == 0) {
- index(index, (CSSRuleListImpl) mediaRule.getCssRules(), alreadyProcessing);
+ index(index, mediaRule.getCssRules(), alreadyProcessing);
}
else {
- index(index.addMedia(mediaList), (CSSRuleListImpl) mediaRule.getCssRules(), alreadyProcessing);
+ index(index.addMedia(mediaList), mediaRule.getCssRules(), alreadyProcessing);
}
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSSupportsRule.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSSupportsRule.java
index 7c26b94a6e0..ebcf1fa73ef 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSSupportsRule.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSSupportsRule.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -25,14 +24,15 @@
* A JavaScript object for {@code CSSSupportsRule}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class CSSSupportsRule extends CSSConditionRule {
/**
* Creates a new instance.
*/
- @JsxConstructor({CHROME, EDGE})
+ @JsxConstructor({CHROME, FF})
public CSSSupportsRule() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSValue.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSValue.java
index fcb4099be4c..c37d7cc36b8 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSValue.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSValue.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,8 +14,9 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.css;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
+import com.gargoylesoftware.css.dom.CSSValueImpl;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstant;
@@ -26,10 +27,10 @@
/**
* A JavaScript object for {@code CSSValue}.
*
- * @see org.w3c.dom.css.CSSValue
* @author Marc Guillemot
+ * @author Ronald Brill
*/
-@JsxClass(FF)
+@JsxClass(FF60)
public class CSSValue extends SimpleScriptable {
/**
@@ -65,7 +66,7 @@ public class CSSValue extends SimpleScriptable {
/**
* The wrapped CSS value.
*/
- private org.w3c.dom.css.CSSValue wrappedCssValue_;
+ private CSSValueImpl wrappedCssValue_;
/**
* Creates an instance.
@@ -78,7 +79,7 @@ public CSSValue() {
* Creates an instance and sets its parent scope to the one of the provided element.
* @param element the element to which this style is bound
*/
- CSSValue(final Element element, final org.w3c.dom.css.CSSValue cssValue) {
+ CSSValue(final Element element, final CSSValueImpl cssValue) {
setParentScope(element.getParentScope());
setPrototype(getPrototype(getClass()));
setDomNode(element.getDomNodeOrNull(), false);
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSValueList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSValueList.java
index 4d19d71ccc1..919d62ef562 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSValueList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CSSValueList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.css;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -23,8 +23,9 @@
* A JavaScript object for {@code CSSValueList}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(FF)
+@JsxClass(FF60)
public class CSSValueList extends CSSValue {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CaretPosition.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CaretPosition.java
index 65302d971c4..8531601ce1b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CaretPosition.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/CaretPosition.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedCSSStyleDeclaration.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedCSSStyleDeclaration.java
index 2c90f0b6c1b..940db39a59f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedCSSStyleDeclaration.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedCSSStyleDeclaration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,9 +14,12 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.css;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_COMPUTED_BLOCK_IF_NOT_ATTACHED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_COMPUTED_NO_Z_INDEX;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_STYLE_PROP_FONT_DISCONNECTED_IS_EMPTY;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLDEFINITION_INLINE_IN_QUIRKS;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CLIENTHIGHT_INPUT_17;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CLIENTHIGHT_INPUT_21;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CLIENTWIDTH_INPUT_TEXT_143;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_CLIENTWIDTH_INPUT_TEXT_169;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
@@ -94,6 +97,8 @@
import org.apache.commons.lang3.StringUtils;
+import com.gargoylesoftware.css.dom.CSSStyleDeclarationImpl;
+import com.gargoylesoftware.css.dom.Property;
import com.gargoylesoftware.css.parser.selector.Selector;
import com.gargoylesoftware.css.parser.selector.SelectorSpecificity;
import com.gargoylesoftware.htmlunit.BrowserVersion;
@@ -105,6 +110,7 @@
import com.gargoylesoftware.htmlunit.html.HtmlButton;
import com.gargoylesoftware.htmlunit.html.HtmlButtonInput;
import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
+import com.gargoylesoftware.htmlunit.html.HtmlDefinitionDescription;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlFileInput;
@@ -117,7 +123,6 @@
import com.gargoylesoftware.htmlunit.html.HtmlResetInput;
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
-import com.gargoylesoftware.htmlunit.html.HtmlTableRow;
import com.gargoylesoftware.htmlunit.html.HtmlTextArea;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -129,6 +134,7 @@
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLElement;
import net.sourceforge.htmlunit.corejs.javascript.Context;
+import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
/**
* An object for a CSSStyleDeclaration, which is computed.
@@ -259,11 +265,11 @@ protected void setStyleAttribute(final String name, final String newValue) {
* @param declaration the style declaration
* @param selector the selector determining that the style applies to this element
*/
- public void applyStyleFromSelector(final org.w3c.dom.css.CSSStyleDeclaration declaration, final Selector selector) {
+ public void applyStyleFromSelector(final CSSStyleDeclarationImpl declaration, final Selector selector) {
final BrowserVersion browserVersion = getBrowserVersion();
final SelectorSpecificity specificity = selector.getSelectorSpecificity();
- for (int i = 0; i < declaration.getLength(); i++) {
- final String name = declaration.item(i);
+ for (Property prop : declaration.getProperties()) {
+ final String name = prop.getName();
if (!browserVersion.hasFeature(CSS_COMPUTED_NO_Z_INDEX) || !"z-index".equals(name)) {
final String value = declaration.getPropertyValue(name);
final String priority = declaration.getPropertyPriority(name);
@@ -341,7 +347,7 @@ private String defaultIfEmpty(final String str, final StyleAttributes.Definition
private String defaultIfEmpty(final String str, final StyleAttributes.Definition definition,
final boolean isPixel) {
if (!getElement().getDomNodeOrDie().isAttachedToPage()
- && getBrowserVersion().hasFeature(CSS_COMPUTED_NO_Z_INDEX)) {
+ && getBrowserVersion().hasFeature(CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY)) {
return EMPTY_FINAL;
}
if (str == null || str.isEmpty()) {
@@ -360,7 +366,7 @@ && getBrowserVersion().hasFeature(CSS_COMPUTED_NO_Z_INDEX)) {
*/
private String defaultIfEmpty(final String str, final String toReturnIfEmptyOrDefault, final String defaultValue) {
if (!getElement().getDomNodeOrDie().isAttachedToPage()
- && getBrowserVersion().hasFeature(CSS_COMPUTED_NO_Z_INDEX)) {
+ && getBrowserVersion().hasFeature(CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY)) {
return EMPTY_FINAL;
}
if (str == null || str.isEmpty() || str.equals(defaultValue)) {
@@ -483,7 +489,7 @@ public String getBorderRightColor() {
*/
@Override
public String getBorderRightStyle() {
- return defaultIfEmpty(super.getBorderRightStyle(), "none", null);
+ return defaultIfEmpty(super.getBorderRightStyle(), NONE, null);
}
/**
@@ -507,7 +513,7 @@ public String getBorderTopColor() {
*/
@Override
public String getBorderTopStyle() {
- return defaultIfEmpty(super.getBorderTopStyle(), "none", null);
+ return defaultIfEmpty(super.getBorderTopStyle(), NONE, null);
}
/**
@@ -553,22 +559,22 @@ public String getDisplay() {
/**
* Returns the {@code display} attribute.
- * @param ignoreBlockIfNotAttached is
- * {@link com.gargoylesoftware.htmlunit.BrowserVersionFeatures#CSS_COMPUTED_BLOCK_IF_NOT_ATTACHED} ignored
+ * @param ignoreBlockIfNotAttached flag
* @return the {@code display} attribute
*/
public String getDisplay(final boolean ignoreBlockIfNotAttached) {
// don't use defaultIfEmpty for performance
// (no need to calculate the default if not empty)
- final Element elem = getElement();
- final DomElement domElem = elem.getDomNodeOrDie();
+ final DomElement domElem = getElement().getDomNodeOrDie();
boolean changeValueIfEmpty = false;
if (!domElem.isAttachedToPage()) {
final BrowserVersion browserVersion = getBrowserVersion();
- if (browserVersion.hasFeature(CSS_COMPUTED_NO_Z_INDEX)) {
+ if (browserVersion.hasFeature(CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY)) {
return "";
}
- if (!ignoreBlockIfNotAttached && browserVersion.hasFeature(CSS_COMPUTED_BLOCK_IF_NOT_ATTACHED)) {
+ if (!ignoreBlockIfNotAttached
+ && (domElem instanceof HtmlDefinitionDescription
+ && browserVersion.hasFeature(HTMLDEFINITION_INLINE_IN_QUIRKS))) {
changeValueIfEmpty = true;
}
}
@@ -590,7 +596,7 @@ public String getDisplay(final boolean ignoreBlockIfNotAttached) {
case "table-row-group":
case "list-item":
case "ruby":
- return "block";
+ return BLOCK;
default:
}
@@ -607,7 +613,7 @@ public String getDisplay(final boolean ignoreBlockIfNotAttached) {
*/
@Override
public String getFont() {
- if (getBrowserVersion().hasFeature(CSS_COMPUTED_NO_Z_INDEX)
+ if (getBrowserVersion().hasFeature(CSS_STYLE_PROP_FONT_DISCONNECTED_IS_EMPTY)
&& getElement().getDomNodeOrDie().isAttachedToPage()) {
return super.getFont();
}
@@ -649,7 +655,7 @@ public String getFontFamily() {
public String getHeight() {
final Element elem = getElement();
if (!elem.getDomNodeOrDie().isAttachedToPage()) {
- if (getBrowserVersion().hasFeature(CSS_COMPUTED_NO_Z_INDEX)) {
+ if (getBrowserVersion().hasFeature(CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY)) {
return "";
}
if (getStyleAttribute(HEIGHT, true).isEmpty()) {
@@ -733,7 +739,8 @@ private String getMarginX(final String superMarginX, final Definition definition
return pixelString(defaultIfEmpty(superMarginX, "0px", null));
}
final Element elem = getElement();
- if (!elem.getDomNodeOrDie().isAttachedToPage() && getBrowserVersion().hasFeature(CSS_COMPUTED_NO_Z_INDEX)) {
+ if (!elem.getDomNodeOrDie().isAttachedToPage()
+ && getBrowserVersion().hasFeature(CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY)) {
return "";
}
@@ -762,7 +769,7 @@ public String getMarginTop() {
*/
@Override
public String getMaxHeight() {
- return defaultIfEmpty(super.getMaxHeight(), "none", null);
+ return defaultIfEmpty(super.getMaxHeight(), NONE, null);
}
/**
@@ -770,7 +777,7 @@ public String getMaxHeight() {
*/
@Override
public String getMaxWidth() {
- return defaultIfEmpty(super.getMaxWidth(), "none", null);
+ return defaultIfEmpty(super.getMaxWidth(), NONE, null);
}
/**
@@ -868,7 +875,7 @@ public String getTextIndent() {
public String getTop() {
final Element elem = getElement();
if (!elem.getDomNodeOrDie().isAttachedToPage()
- && getBrowserVersion().hasFeature(CSS_COMPUTED_NO_Z_INDEX)) {
+ && getBrowserVersion().hasFeature(CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY)) {
return "";
}
final String superTop = super.getTop();
@@ -924,13 +931,13 @@ public String getPosition() {
*/
@Override
public String getWidth() {
- if ("none".equals(getDisplay())) {
+ if (NONE.equals(getDisplay())) {
return AUTO;
}
final Element elem = getElement();
if (!elem.getDomNodeOrDie().isAttachedToPage()) {
- if (getBrowserVersion().hasFeature(CSS_COMPUTED_NO_Z_INDEX)) {
+ if (getBrowserVersion().hasFeature(CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY)) {
return "";
}
if (getStyleAttribute(WIDTH, true).isEmpty()) {
@@ -944,7 +951,7 @@ public String getWidth() {
public String get(final ComputedCSSStyleDeclaration style) {
final String value = style.getStyleAttribute(WIDTH, true);
if (StringUtils.isEmpty(value)) {
- if ("absolute".equals(getStyleAttribute(POSITION, true))) {
+ if (ABSOLUTE.equals(getStyleAttribute(POSITION, true))) {
final String content = getDomNodeOrDie().getTextContent();
// do this only for small content
// at least for empty div's this is more correct
@@ -1012,7 +1019,7 @@ private int getCalculatedWidth() {
}
final String display = getDisplay();
- if ("none".equals(display)) {
+ if (NONE.equals(display)) {
width_ = Integer.valueOf(0);
return 0;
}
@@ -1033,11 +1040,11 @@ private int getCalculatedWidth() {
// Width not explicitly set.
final String cssFloat = getCssFloat();
if ("right".equals(cssFloat) || "left".equals(cssFloat)
- || "absolute".equals(getStyleAttribute(POSITION, true))) {
+ || ABSOLUTE.equals(getStyleAttribute(POSITION, true))) {
// We're floating; simplistic approximation: text content * pixels per character.
width = node.getTextContent().length() * getBrowserVersion().getPixesPerChar();
}
- else if ("block".equals(display)) {
+ else if (BLOCK.equals(display)) {
if (element instanceof HTMLBodyElement) {
width = windowWidth - 16;
}
@@ -1066,7 +1073,7 @@ else if (node instanceof HtmlTextInput || node instanceof HtmlPasswordInput) {
if (browserVersion.hasFeature(JS_CLIENTWIDTH_INPUT_TEXT_169)) {
return 169;
}
- width = 141; // FF45
+ width = 141; // FF60
}
else if (node instanceof HtmlRadioButtonInput || node instanceof HtmlCheckBoxInput) {
width = 13;
@@ -1169,21 +1176,16 @@ private int getCalculatedHeight() {
return height_.intValue();
}
- int height = getEmptyHeight();
- if (height == 0) {
- height_ = Integer.valueOf(0);
- return 0;
- }
-
if (super.getHeight().isEmpty()) {
final int contentHeight = getContentHeight();
if (contentHeight > 0) {
- height = contentHeight;
+ height_ = Integer.valueOf(contentHeight);
+ return height_;
}
}
- height_ = Integer.valueOf(height);
- return height;
+ height_ = Integer.valueOf(getEmptyHeight());
+ return height_;
}
/**
@@ -1204,7 +1206,7 @@ private int getEmptyHeight() {
return 0;
}
- if ("none".equals(getDisplay())) {
+ if (NONE.equals(getDisplay())) {
height2_ = Integer.valueOf(0);
return 0;
}
@@ -1231,12 +1233,16 @@ else if (node instanceof HtmlButton) {
defaultHeight = 20;
}
else if (node instanceof HtmlInput && !(node instanceof HtmlHiddenInput)) {
- if (getBrowserVersion().hasFeature(JS_CLIENTHIGHT_INPUT_17)) {
+ final BrowserVersion browser = getBrowserVersion();
+ if (browser.hasFeature(JS_CLIENTHIGHT_INPUT_17)) {
defaultHeight = 17;
}
- else {
+ else if (browser.hasFeature(JS_CLIENTHIGHT_INPUT_21)) {
defaultHeight = 21;
}
+ else {
+ defaultHeight = 20;
+ }
}
else if (node instanceof HtmlSelect) {
defaultHeight = 20;
@@ -1301,10 +1307,10 @@ public int getContentHeight() {
final HTMLElement e = (HTMLElement) scriptObj;
final ComputedCSSStyleDeclaration style = e.getWindow().getComputedStyle(e, null);
final String pos = style.getPositionWithInheritance();
- if (STATIC.equals(pos) || "relative".equals(pos)) {
+ if (STATIC.equals(pos) || RELATIVE.equals(pos)) {
lastFlowing = style;
}
- else if ("absolute".equals(pos)) {
+ else if (ABSOLUTE.equals(pos)) {
styles.add(style);
}
}
@@ -1366,7 +1372,7 @@ public int getTop(final boolean includeMargin, final boolean includeBorder, fina
int top = 0;
if (null == top_) {
final String p = getPositionWithInheritance();
- if ("absolute".equals(p)) {
+ if (ABSOLUTE.equals(p)) {
top = getTopForAbsolutePositionWithInheritance();
}
else {
@@ -1377,32 +1383,37 @@ public int getTop(final boolean includeMargin, final boolean includeBorder, fina
if (prev instanceof HtmlElement) {
final Element e = prev.getScriptableObject();
final ComputedCSSStyleDeclaration style = e.getWindow().getComputedStyle(e, null);
- int prevTop = 0;
- if (style.top_ == null) {
- final String prevPosition = style.getPositionWithInheritance();
- if ("absolute".equals(prevPosition)) {
- prevTop += style.getTopForAbsolutePositionWithInheritance();
+
+ // only previous block elements are counting
+ final String display = style.getDisplay();
+ if (isBlock(display)) {
+ int prevTop = 0;
+ if (style.top_ == null) {
+ final String prevPosition = style.getPositionWithInheritance();
+ if (ABSOLUTE.equals(prevPosition)) {
+ prevTop += style.getTopForAbsolutePositionWithInheritance();
+ }
+ else {
+ if (RELATIVE.equals(prevPosition)) {
+ final String t = style.getTopWithInheritance();
+ prevTop += pixelValue(t);
+ }
+ }
}
else {
- if ("relative".equals(prevPosition)) {
- final String t = style.getTopWithInheritance();
- prevTop += pixelValue(t);
- }
+ prevHadComputedTop = true;
+ prevTop += style.top_;
}
+ prevTop += style.getCalculatedHeight(true, true);
+ final int margin = pixelValue(style.getMarginTop());
+ prevTop += margin;
+ top += prevTop;
}
- else {
- prevHadComputedTop = true;
- prevTop += style.top_;
- }
- prevTop += style.getCalculatedHeight(true, true);
- final int margin = pixelValue(style.getMarginTop());
- prevTop += margin;
- top += prevTop;
}
prev = prev.getPreviousSibling();
}
// If the position is relative, we also need to add the specified "top" displacement.
- if ("relative".equals(p)) {
+ if (RELATIVE.equals(p)) {
final String t = getTopWithInheritance();
top += pixelValue(t);
}
@@ -1431,33 +1442,38 @@ public int getTop(final boolean includeMargin, final boolean includeBorder, fina
return top;
}
+ private static boolean isBlock(final String display) {
+ return display != null
+ && !INLINE.equals(display)
+ && !NONE.equals(display);
+ }
+
private int getTopForAbsolutePositionWithInheritance() {
- int top = 0;
final String t = getTopWithInheritance();
if (!AUTO.equals(t)) {
// No need to calculate displacement caused by sibling nodes.
- top = pixelValue(t);
- }
- else {
- final String b = getBottomWithInheritance();
-
- if (!AUTO.equals(b)) {
- // Estimate the vertical displacement caused by *all* siblings.
- // This is very rough, and doesn't even take position or display types into account.
- // It also doesn't take into account the fact that the parent's height may be hardcoded in CSS.
- top = 0;
- DomNode child = getElement().getDomNodeOrDie().getParentNode().getFirstChild();
- while (child != null) {
- if (child instanceof HtmlElement && child.mayBeDisplayed()) {
- top += 20;
- }
- child = child.getNextSibling();
+ return pixelValue(t);
+ }
+
+ final String b = getBottomWithInheritance();
+ if (!AUTO.equals(b)) {
+ // Estimate the vertical displacement caused by *all* siblings.
+ // This is very rough, and doesn't even take position or display types into account.
+ // It also doesn't take into account the fact that the parent's height may be hardcoded in CSS.
+ int top = 0;
+ DomNode child = getElement().getDomNodeOrDie().getParentNode().getFirstChild();
+ while (child != null) {
+ if (child instanceof HtmlElement && child.mayBeDisplayed()) {
+ top += 20;
}
- top -= pixelValue(b);
+ child = child.getNextSibling();
}
+ top -= pixelValue(b);
+ return top;
}
- return top;
+
+ return 0;
}
/**
@@ -1473,24 +1489,24 @@ public int getLeft(final boolean includeMargin, final boolean includeBorder, fin
final String r = getRightWithInheritance();
int left;
- if ("absolute".equals(p) && !AUTO.equals(l)) {
+ if (ABSOLUTE.equals(p) && !AUTO.equals(l)) {
// No need to calculate displacement caused by sibling nodes.
left = pixelValue(l);
}
- else if ("absolute".equals(p) && !AUTO.equals(r)) {
+ else if (ABSOLUTE.equals(p) && !AUTO.equals(r)) {
// Need to calculate the horizontal displacement caused by *all* siblings.
final HTMLElement parent = (HTMLElement) getElement().getParentElement();
final ComputedCSSStyleDeclaration style = parent.getWindow().getComputedStyle(parent, null);
final int parentWidth = style.getCalculatedWidth(false, false);
left = parentWidth - pixelValue(r);
}
- else if ("fixed".equals(p) && !AUTO.equals(r)) {
+ else if (FIXED.equals(p) && !AUTO.equals(r)) {
final HTMLElement parent = (HTMLElement) getElement().getParentElement();
final ComputedCSSStyleDeclaration style = getWindow().getComputedStyle(getElement(), null);
final ComputedCSSStyleDeclaration parentStyle = parent.getWindow().getComputedStyle(parent, null);
left = pixelValue(parentStyle.getWidth()) - pixelValue(style.getWidth()) - pixelValue(r);
}
- else if ("fixed".equals(p) && AUTO.equals(l)) {
+ else if (FIXED.equals(p) && AUTO.equals(l)) {
// Fixed to the location at which the browser puts it via normal element flowing.
final HTMLElement parent = (HTMLElement) getElement().getParentElement();
final ComputedCSSStyleDeclaration style = parent.getWindow().getComputedStyle(parent, null);
@@ -1499,24 +1515,27 @@ else if ("fixed".equals(p) && AUTO.equals(l)) {
else if (STATIC.equals(p)) {
// We need to calculate the horizontal displacement caused by *previous* siblings.
left = 0;
- for (DomNode n = getDomNodeOrDie(); n != null; n = n.getPreviousSibling()) {
- if (n.getScriptableObject() instanceof HTMLElement) {
- final HTMLElement e = n.getScriptableObject();
+ DomNode prev = getElement().getDomNodeOrDie().getPreviousSibling();
+ while (prev != null) {
+ final Scriptable prevScriptable = prev.getScriptableObject();
+ if (prevScriptable instanceof HTMLElement) {
+ final HTMLElement e = (HTMLElement) prevScriptable;
final ComputedCSSStyleDeclaration style = e.getWindow().getComputedStyle(e, null);
final String d = style.getDisplay();
- if ("block".equals(d)) {
+ if (isBlock(d)) {
break;
}
- else if (!"none".equals(d)) {
+ else if (!NONE.equals(d)) {
left += style.getCalculatedWidth(true, true);
}
}
- else if (n.getScriptableObject() instanceof Text) {
- left += n.getTextContent().length() * getBrowserVersion().getPixesPerChar();
- }
- if (n instanceof HtmlTableRow) {
- break;
+ else if (prevScriptable instanceof Text) {
+ final String content = prev.getTextContent();
+ if (content != null) {
+ left += content.trim().length() * getBrowserVersion().getPixesPerChar();
+ }
}
+ prev = prev.getPreviousSibling();
}
}
else {
@@ -1704,7 +1723,7 @@ public int getPaddingBottomValue() {
private int getPaddingHorizontal() {
if (paddingHorizontal_ == null) {
paddingHorizontal_ =
- Integer.valueOf("none".equals(getDisplay()) ? 0 : getPaddingLeftValue() + getPaddingRightValue());
+ Integer.valueOf(NONE.equals(getDisplay()) ? 0 : getPaddingLeftValue() + getPaddingRightValue());
}
return paddingHorizontal_.intValue();
}
@@ -1712,7 +1731,7 @@ private int getPaddingHorizontal() {
private int getPaddingVertical() {
if (paddingVertical_ == null) {
paddingVertical_ =
- Integer.valueOf("none".equals(getDisplay()) ? 0 : getPaddingTopValue() + getPaddingBottomValue());
+ Integer.valueOf(NONE.equals(getDisplay()) ? 0 : getPaddingTopValue() + getPaddingBottomValue());
}
return paddingVertical_.intValue();
}
@@ -1752,7 +1771,7 @@ public int getBorderBottomValue() {
private int getBorderHorizontal() {
if (borderHorizontal_ == null) {
borderHorizontal_ =
- Integer.valueOf("none".equals(getDisplay()) ? 0 : getBorderLeftValue() + getBorderRightValue());
+ Integer.valueOf(NONE.equals(getDisplay()) ? 0 : getBorderLeftValue() + getBorderRightValue());
}
return borderHorizontal_.intValue();
}
@@ -1760,7 +1779,7 @@ private int getBorderHorizontal() {
private int getBorderVertical() {
if (borderVertical_ == null) {
borderVertical_ =
- Integer.valueOf("none".equals(getDisplay()) ? 0 : getBorderTopValue() + getBorderBottomValue());
+ Integer.valueOf(NONE.equals(getDisplay()) ? 0 : getBorderTopValue() + getBorderBottomValue());
}
return borderVertical_.intValue();
}
@@ -1779,7 +1798,7 @@ public String getWordSpacing() {
@Override
public String getStyleAttribute(final Definition style, final boolean getDefaultValueIfEmpty) {
if (!getElement().getDomNodeOrDie().isAttachedToPage()
- && getBrowserVersion().hasFeature(CSS_COMPUTED_NO_Z_INDEX)) {
+ && getBrowserVersion().hasFeature(CSS_STYLE_PROP_DISCONNECTED_IS_EMPTY)) {
return EMPTY_FINAL;
}
String value = super.getStyleAttribute(style, getDefaultValueIfEmpty);
@@ -1830,7 +1849,7 @@ public String getPropertyValue(final String name) {
* @see #pixelString(Element, CSSStyleDeclaration.CssValue)
*/
protected String pixelString(final String value) {
- if (value == EMPTY_FINAL || value.endsWith("px")) {
+ if (EMPTY_FINAL == value || value.endsWith("px")) {
return value;
}
return pixelValue(value) + "px";
@@ -1852,5 +1871,4 @@ protected String pixelString(final Element element, final CssValue value) {
}
return pixelValue(element, value) + "px";
}
-
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedFont.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedFont.java
index 080d2cac57e..c30271e5a77 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedFont.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/ComputedFont.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
* A helper class for handling font attributes of {@link ComputedCSSStyleDeclaration}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
final class ComputedFont {
@@ -27,14 +28,15 @@ final class ComputedFont {
static final int LINE_HEIGHT_INDEX = 4;
static final int FONT_FAMILY_INDEX = 5;
- static String[] getDetails(String font, final boolean handleSpaceAfterSlash) {
- while (font.contains(" ")) {
- font = font.replace(" ", " ");
+ static String[] getDetails(final String font, final boolean handleSpaceAfterSlash) {
+ String fontName = font;
+ while (fontName.contains(" ")) {
+ fontName = fontName.replace(" ", " ");
}
- if (!handleSpaceAfterSlash && font.contains("/ ")) {
+ if (!handleSpaceAfterSlash && fontName.contains("/ ")) {
return null;
}
- final String[] tokens = font.split(" ");
+ final String[] tokens = fontName.split(" ");
if (tokens.length > 1) {
final String[] fontSizeDetails = getFontSizeDetails(tokens[tokens.length - 2]);
if (fontSizeDetails == null) {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/MediaQueryList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/MediaQueryList.java
index af135e43ccd..1df591238bb 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/MediaQueryList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/MediaQueryList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,11 +15,9 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import org.w3c.dom.stylesheets.MediaList;
-
+import com.gargoylesoftware.css.dom.MediaListImpl;
import com.gargoylesoftware.css.parser.CSSErrorHandler;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -31,6 +29,7 @@
* A JavaScript object for {@code MediaQueryList}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
@JsxClass
public class MediaQueryList extends EventTarget {
@@ -40,7 +39,7 @@ public class MediaQueryList extends EventTarget {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public MediaQueryList() {
}
@@ -69,7 +68,7 @@ public String getMedia() {
@JsxGetter
public boolean isMatches() {
final CSSErrorHandler errorHandler = getWindow().getWebWindow().getWebClient().getCssErrorHandler();
- final MediaList mediaList = CSSStyleSheet.parseMedia(errorHandler, media_);
+ final MediaListImpl mediaList = CSSStyleSheet.parseMedia(errorHandler, media_);
return CSSStyleSheet.isActive(this, mediaList);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleAttributes.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleAttributes.java
index c3ce2e84657..bdae408f1ee 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleAttributes.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleAttributes.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,8 @@
import static com.gargoylesoftware.htmlunit.javascript.host.css.BrowserConfiguration.chrome;
import static com.gargoylesoftware.htmlunit.javascript.host.css.BrowserConfiguration.ff;
-import static com.gargoylesoftware.htmlunit.javascript.host.css.BrowserConfiguration.ff52up;
-import static com.gargoylesoftware.htmlunit.javascript.host.css.BrowserConfiguration.ffBelow52;
+import static com.gargoylesoftware.htmlunit.javascript.host.css.BrowserConfiguration.ff68up;
+import static com.gargoylesoftware.htmlunit.javascript.host.css.BrowserConfiguration.ffBelow68;
import static com.gargoylesoftware.htmlunit.javascript.host.css.BrowserConfiguration.ie;
import java.util.ArrayList;
@@ -94,24 +94,24 @@ public enum Definition {
/** The style property {@code alignContent}. */
ALIGN_CONTENT("alignContent", "align-content", ie("stretch"),
- ffBelow52("auto"), ff52up("normal"), chrome("normal")),
+ ff("normal"), chrome("normal")),
/** The style property {@code align-content}. */
- ALIGN_CONTENT_("align-content", "align-content", ffBelow52("auto"), ff52up("normal")),
+ ALIGN_CONTENT_("align-content", "align-content", ff("normal")),
/** The style property {@code alignItems}. */
- ALIGN_ITEMS("alignItems", "align-items", ffBelow52("start"), ff52up("normal"),
+ ALIGN_ITEMS("alignItems", "align-items", ff("normal"),
ie("stretch"), chrome("normal")),
/** The style property {@code align-items}. */
- ALIGN_ITEMS_("align-items", "align-items", ffBelow52("start"), ff52up("normal")),
+ ALIGN_ITEMS_("align-items", "align-items", ff("normal")),
/** The style property {@code alignSelf}. */
- ALIGN_SELF("alignSelf", "align-self", ffBelow52("start"), ff52up("auto"),
+ ALIGN_SELF("alignSelf", "align-self", ff("auto"),
ie("auto"), chrome("auto")),
/** The style property {@code align-self}. */
- ALIGN_SELF_("align-self", "align-self", ffBelow52("start"), ff52up("auto")),
+ ALIGN_SELF_("align-self", "align-self", ff("auto")),
/** The style property {@code alignmentBaseline}. */
ALIGNMENT_BASELINE("alignmentBaseline", "alignment-baseline", ie("auto"), chrome("auto")),
@@ -180,6 +180,9 @@ public enum Definition {
/** The style property {@code azimuth}. */
AZIMUTH("azimuth", "azimuth"),
+ /** The style property {@code backdropFilter}. */
+ BACKDROP_FILTER("backdropFilter", "backdrop-filter", chrome("none")),
+
/** The style property {@code backfaceVisibility}. */
BACKFACE_VISIBILITY("backfaceVisibility", "backface-visibility",
ff("visible"), ie("visible"), chrome("visible")),
@@ -212,11 +215,12 @@ public enum Definition {
BACKGROUND_CLIP_("background-clip", "background-clip", ff("border-box")),
/** The style property {@code backgroundColor}. */
- BACKGROUND_COLOR("backgroundColor", "background-color", chrome("rgba(0, 0, 0, 0)"), ff("transparent"),
+ BACKGROUND_COLOR("backgroundColor", "background-color", chrome("rgba(0, 0, 0, 0)"),
+ ff("rgba(0, 0, 0, 0)"),
ie("transparent")),
/** The style property {@code background-color}. */
- BACKGROUND_COLOR_("background-color", "background-color", ff("transparent")),
+ BACKGROUND_COLOR_("background-color", "background-color", ff("rgba(0, 0, 0, 0)")),
/** The style property {@code backgroundImage}. */
BACKGROUND_IMAGE("backgroundImage", "background-image", chrome("none"), ff("none"), ie("none")),
@@ -239,17 +243,17 @@ public enum Definition {
/** The style property {@code backgroundPositionX}. */
BACKGROUND_POSITION_X("backgroundPositionX", "background-position-x",
- ie("undefined"), chrome("0%"), ff52up("0%")),
+ ie("undefined"), chrome("0%"), ff("0%")),
/** The style property {@code background-position-x}. */
- BACKGROUND_POSITION_X_("background-position-x", "background-position-x", ff52up("0%")),
+ BACKGROUND_POSITION_X_("background-position-x", "background-position-x", ff("0%")),
/** The style property {@code backgroundPositionY}. */
BACKGROUND_POSITION_Y("backgroundPositionY", "background-position-y",
- ie("undefined"), chrome("0%"), ff52up("0%")),
+ ie("undefined"), chrome("0%"), ff("0%")),
/** The style property {@code background-position-y}. */
- BACKGROUND_POSITION_Y_("background-position-y", "background-position-y", ff52up("0%")),
+ BACKGROUND_POSITION_Y_("background-position-y", "background-position-y", ff("0%")),
/** The style property {@code backgroundRepeat}. */
BACKGROUND_REPEAT("backgroundRepeat", "background-repeat", chrome("repeat"), ff("repeat"), ie("repeat")),
@@ -264,10 +268,11 @@ public enum Definition {
BACKGROUND_REPEAT_Y("backgroundRepeatY", "background-repeat-y", chrome("")),
/** The style property {@code backgroundSize}. */
- BACKGROUND_SIZE("backgroundSize", "background-size", ff("auto auto"), ie("auto"), chrome("auto")),
+ BACKGROUND_SIZE("backgroundSize", "background-size", ffBelow68("auto auto"), ff68up("auto"),
+ ie("auto"), chrome("auto")),
/** The style property {@code background-size}. */
- BACKGROUND_SIZE_("background-size", "background-size", ff("auto auto")),
+ BACKGROUND_SIZE_("background-size", "background-size", ffBelow68("auto auto"), ff68up("auto")),
/** The style property {@code baselineShift}. */
BASELINE_SHIFT("baselineShift", "baseline-shift", ie("baseline"), chrome("0px")),
@@ -276,61 +281,95 @@ public enum Definition {
BEHAVIOR("behavior", "behavior"),
/** The style property {@code blockSize}. */
- BLOCK_SIZE("blockSize", "block-size", ff(""), chrome("0px")),
+ BLOCK_SIZE("blockSize", "block-size", chrome("322px"), ffBelow68(""), ff68up("343px")),
/** The style property {@code block-size}. */
- BLOCK_SIZE_("block-size", "block-size", ff("")),
+ BLOCK_SIZE_("block-size", "block-size", ffBelow68(""), ff68up("343px")),
/** The style property {@code border}. */
BORDER("border", "border", chrome("0px none rgb(0, 0, 0)"), ff(""), ie("")),
+ /** The style property {@code borderBlock}. */
+ BORDER_BLOCK("borderBlock", "border-block", ff68up("")),
+
+ /** The style property {@code border-block}. */
+ BORDER_BLOCK_("border-block", "border-block", ff68up("")),
+
+ /** The style property {@code borderBlockColor}. */
+ BORDER_BLOCK_COLOR("borderBlockColor", "border-block-color", ff68up("")),
+
+ /** The style property {@code border-block-color}. */
+ BORDER_BLOCK_COLOR_("border-block-color", "border-block-color", ff68up("")),
+
/** The style property {@code borderBlockEnd}. */
- BORDER_BLOCK_END("borderBlockEnd", "border-block-end", ff("")),
+ BORDER_BLOCK_END("borderBlockEnd", "border-block-end", chrome("0px none rgb(0, 0, 0)"), ff("")),
/** The style property {@code border-block-end}. */
BORDER_BLOCK_END_("border-block-end", "border-block-end", ff("")),
/** The style property {@code borderBlockEndColor}. */
- BORDER_BLOCK_END_COLOR("borderBlockEndColor", "border-block-end-color", ff("")),
+ BORDER_BLOCK_END_COLOR("borderBlockEndColor", "border-block-end-color", chrome("rgb(0, 0, 0)"),
+ ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code border-block-end-color}. */
- BORDER_BLOCK_END_COLOR_("border-block-end-color", "border-block-end-color", ff("")),
+ BORDER_BLOCK_END_COLOR_("border-block-end-color", "border-block-end-color",
+ ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code borderBlockEndStyle}. */
- BORDER_BLOCK_END_STYLE("borderBlockEndStyle", "border-block-end-style", ff("")),
+ BORDER_BLOCK_END_STYLE("borderBlockEndStyle", "border-block-end-style", chrome("none"),
+ ffBelow68(""), ff68up("none")),
/** The style property {@code border-block-end-style}. */
- BORDER_BLOCK_END_STYLE_("border-block-end-style", "border-block-end-style", ff("")),
+ BORDER_BLOCK_END_STYLE_("border-block-end-style", "border-block-end-style", ffBelow68(""), ff68up("none")),
/** The style property {@code borderBlockEndWidth}. */
- BORDER_BLOCK_END_WIDTH("borderBlockEndWidth", "border-block-end-width", ff("")),
+ BORDER_BLOCK_END_WIDTH("borderBlockEndWidth", "border-block-end-width", chrome("0px"),
+ ffBelow68(""), ff68up("0px")),
/** The style property {@code border-block-end-width}. */
- BORDER_BLOCK_END_WIDTH_("border-block-end-width", "border-block-end-width", ff("")),
+ BORDER_BLOCK_END_WIDTH_("border-block-end-width", "border-block-end-width", ffBelow68(""), ff68up("0px")),
/** The style property {@code borderBlockStart}. */
- BORDER_BLOCK_START("borderBlockStart", "border-block-start", ff("")),
+ BORDER_BLOCK_START("borderBlockStart", "border-block-start", chrome("0px none rgb(0, 0, 0)"), ff("")),
/** The style property {@code border-block-start}. */
BORDER_BLOCK_START_("border-block-start", "border-block-start", ff("")),
/** The style property {@code borderBlockStartColor}. */
- BORDER_BLOCK_START_COLOR("borderBlockStartColor", "border-block-start-color", ff("")),
+ BORDER_BLOCK_START_COLOR("borderBlockStartColor", "border-block-start-color", chrome("rgb(0, 0, 0)"),
+ ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code border-block-start-color}. */
- BORDER_BLOCK_START_COLOR_("border-block-start-color", "border-block-start-color", ff("")),
+ BORDER_BLOCK_START_COLOR_("border-block-start-color", "border-block-start-color",
+ ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code borderBlockStartStyle}. */
- BORDER_BLOCK_START_STYLE("borderBlockStartStyle", "border-block-start-style", ff("")),
+ BORDER_BLOCK_START_STYLE("borderBlockStartStyle", "border-block-start-style", chrome("none"),
+ ffBelow68(""), ff68up("none")),
/** The style property {@code border-block-start-style}. */
- BORDER_BLOCK_START_STYLE_("border-block-start-style", "border-block-start-style", ff("")),
+ BORDER_BLOCK_START_STYLE_("border-block-start-style", "border-block-start-style",
+ ffBelow68(""), ff68up("none")),
/** The style property {@code borderBlockStartWidth}. */
- BORDER_BLOCK_START_WIDTH("borderBlockStartWidth", "border-block-start-width", ff("")),
+ BORDER_BLOCK_START_WIDTH("borderBlockStartWidth", "border-block-start-width", chrome("0px"),
+ ffBelow68(""), ff68up("0px")),
/** The style property {@code border-block-start-width}. */
- BORDER_BLOCK_START_WIDTH_("border-block-start-width", "border-block-start-width", ff("")),
+ BORDER_BLOCK_START_WIDTH_("border-block-start-width", "border-block-start-width",
+ ffBelow68(""), ff68up("0px")),
+
+ /** The style property {@code borderBlockStyle}. */
+ BORDER_BLOCK_STYLE("borderBlockStyle", "border-block-style", ff68up("")),
+
+ /** The style property {@code border-block-style}. */
+ BORDER_BLOCK_STYLE_("border-block-style", "border-block-style", ff68up("")),
+
+ /** The style property {@code borderBlockWidth}. */
+ BORDER_BLOCK_WIDTH("borderBlockWidth", "border-block-width", ff68up("")),
+
+ /** The style property {@code border-block-width}. */
+ BORDER_BLOCK_WIDTH_("border-block-width", "border-block-width", ff68up("")),
/** The style property {@code borderBottom}. */
BORDER_BOTTOM("borderBottom", "border-bottom", chrome("0px none rgb(0, 0, 0)"), ff(""), ie("")),
@@ -383,6 +422,18 @@ public enum Definition {
/** The style property {@code border-color}. */
BORDER_COLOR_("border-color", "border-color", ff("")),
+ /** The style property {@code borderEndEndRadius}. */
+ BORDER_END_END_RADIUS("borderEndEndRadius", "border-end-end-radius", ff68up("0px")),
+
+ /** The style property {@code border-end-end-radius}. */
+ BORDER_END_END_RADIUS_("border-end-end-radius", "border-end-end-radius", ff68up("0px")),
+
+ /** The style property {@code borderEndStartRadius}. */
+ BORDER_END_START_RADIUS("borderEndStartRadius", "border-end-start-radius", ff68up("0px")),
+
+ /** The style property {@code border-end-start-radius}. */
+ BORDER_END_START_RADIUS_("border-end-start-radius", "border-end-start-radius", ff68up("0px")),
+
/** The style property {@code borderImage}. */
BORDER_IMAGE("borderImage", "border-image", ff(""), ie(""), chrome("none")),
@@ -390,24 +441,27 @@ public enum Definition {
BORDER_IMAGE_("border-image", "border-image", ff("")),
/** The style property {@code borderImageOutset}. */
- BORDER_IMAGE_OUTSET("borderImageOutset", "border-image-outset", ff("0 0 0 0"), ie("0"), chrome("0px")),
+ BORDER_IMAGE_OUTSET("borderImageOutset", "border-image-outset", ie("0"), chrome("0px"),
+ ff("0")),
/** The style property {@code border-image-outset}. */
- BORDER_IMAGE_OUTSET_("border-image-outset", "border-image-outset", ff("0 0 0 0")),
+ BORDER_IMAGE_OUTSET_("border-image-outset", "border-image-outset", ff("0")),
/** The style property {@code borderImageRepeat}. */
BORDER_IMAGE_REPEAT("borderImageRepeat", "border-image-repeat",
- ff("stretch stretch"), ie("stretch"), chrome("stretch")),
+ ffBelow68("stretch stretch"), ff68up("stretch"), ie("stretch"), chrome("stretch")),
/** The style property {@code border-image-repeat}. */
- BORDER_IMAGE_REPEAT_("border-image-repeat", "border-image-repeat", ff("stretch stretch")),
+ BORDER_IMAGE_REPEAT_("border-image-repeat", "border-image-repeat",
+ ffBelow68("stretch stretch"), ff68up("stretch")),
/** The style property {@code borderImageSlice}. */
- BORDER_IMAGE_SLICE("borderImageSlice", "border-image-slice",
- ff("100% 100% 100% 100%"), ie("100%"), chrome("100%")),
+ BORDER_IMAGE_SLICE("borderImageSlice", "border-image-slice", ie("100%"), chrome("100%"),
+ ff("100%")),
/** The style property {@code border-image-slice}. */
- BORDER_IMAGE_SLICE_("border-image-slice", "border-image-slice", ff("100% 100% 100% 100%")),
+ BORDER_IMAGE_SLICE_("border-image-slice", "border-image-slice",
+ ff("100%")),
/** The style property {@code borderImageSource}. */
BORDER_IMAGE_SOURCE("borderImageSource", "border-image-source", ff("none"), ie("none"), chrome("none")),
@@ -416,58 +470,95 @@ public enum Definition {
BORDER_IMAGE_SOURCE_("border-image-source", "border-image-source", ff("none")),
/** The style property {@code borderImageWidth}. */
- BORDER_IMAGE_WIDTH("borderImageWidth", "border-image-width", ff("1 1 1 1"), ie("1"), chrome("1")),
+ BORDER_IMAGE_WIDTH("borderImageWidth", "border-image-width", ie("1"), chrome("1"),
+ ff("1")),
/** The style property {@code border-image-width}. */
- BORDER_IMAGE_WIDTH_("border-image-width", "border-image-width", ff("1 1 1 1")),
+ BORDER_IMAGE_WIDTH_("border-image-width", "border-image-width", ff("1")),
+
+ /** The style property {@code borderInline}. */
+ BORDER_INLINE("borderInline", "border-inline", ff68up("")),
+
+ /** The style property {@code border-inline}. */
+ BORDER_INLINE_("border-inline", "border-inline", ff68up("")),
+
+ /** The style property {@code borderInlineColor}. */
+ BORDER_INLINE_COLOR("borderInlineColor", "border-inline-color", ff68up("")),
+
+ /** The style property {@code border-inline-color}. */
+ BORDER_INLINE_COLOR_("border-inline-color", "border-inline-color", ff68up("")),
/** The style property {@code borderInlineEnd}. */
- BORDER_INLINE_END("borderInlineEnd", "border-inline-end", ff("")),
+ BORDER_INLINE_END("borderInlineEnd", "border-inline-end", chrome("0px none rgb(0, 0, 0)"), ff("")),
/** The style property {@code border-inline-end}. */
BORDER_INLINE_END_("border-inline-end", "border-inline-end", ff("")),
/** The style property {@code borderInlineEndColor}. */
- BORDER_INLINE_END_COLOR("borderInlineEndColor", "border-inline-end-color", ff("")),
+ BORDER_INLINE_END_COLOR("borderInlineEndColor", "border-inline-end-color", chrome("rgb(0, 0, 0)"),
+ ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code border-inline-end-color}. */
- BORDER_INLINE_END_COLOR_("border-inline-end-color", "border-inline-end-color", ff("")),
+ BORDER_INLINE_END_COLOR_("border-inline-end-color", "border-inline-end-color",
+ ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code borderInlineEndStyle}. */
- BORDER_INLINE_END_STYLE("borderInlineEndStyle", "border-inline-end-style", ff("")),
+ BORDER_INLINE_END_STYLE("borderInlineEndStyle", "border-inline-end-style", chrome("none"),
+ ffBelow68(""), ff68up("none")),
/** The style property {@code border-inline-end-style}. */
- BORDER_INLINE_END_STYLE_("border-inline-end-style", "border-inline-end-style", ff("")),
+ BORDER_INLINE_END_STYLE_("border-inline-end-style", "border-inline-end-style",
+ ffBelow68(""), ff68up("none")),
/** The style property {@code borderInlineEndWidth}. */
- BORDER_INLINE_END_WIDTH("borderInlineEndWidth", "border-inline-end-width", ff("")),
+ BORDER_INLINE_END_WIDTH("borderInlineEndWidth", "border-inline-end-width", chrome("0px"),
+ ffBelow68(""), ff68up("0px")),
/** The style property {@code border-inline-end-width}. */
- BORDER_INLINE_END_WIDTH_("border-inline-end-width", "border-inline-end-width", ff("")),
+ BORDER_INLINE_END_WIDTH_("border-inline-end-width", "border-inline-end-width",
+ ffBelow68(""), ff68up("0px")),
/** The style property {@code borderInlineStart}. */
- BORDER_INLINE_START("borderInlineStart", "border-inline-start", ff("")),
+ BORDER_INLINE_START("borderInlineStart", "border-inline-start", chrome("0px none rgb(0, 0, 0)"), ff("")),
/** The style property {@code border-inline-start}. */
BORDER_INLINE_START_("border-inline-start", "border-inline-start", ff("")),
/** The style property {@code borderInlineStartColor}. */
- BORDER_INLINE_START_COLOR("borderInlineStartColor", "border-inline-start-color", ff("")),
+ BORDER_INLINE_START_COLOR("borderInlineStartColor", "border-inline-start-color",
+ chrome("rgb(0, 0, 0)"), ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code border-inline-start-color}. */
- BORDER_INLINE_START_COLOR_("border-inline-start-color", "border-inline-start-color", ff("")),
+ BORDER_INLINE_START_COLOR_("border-inline-start-color", "border-inline-start-color",
+ ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code borderInlineStartStyle}. */
- BORDER_INLINE_START_STYLE("borderInlineStartStyle", "border-inline-start-style", ff("")),
+ BORDER_INLINE_START_STYLE("borderInlineStartStyle", "border-inline-start-style", chrome("none"),
+ ffBelow68(""), ff68up("none")),
/** The style property {@code border-inline-start-style}. */
- BORDER_INLINE_START_STYLE_("border-inline-start-style", "border-inline-start-style", ff("")),
+ BORDER_INLINE_START_STYLE_("border-inline-start-style", "border-inline-start-style",
+ ffBelow68(""), ff68up("none")),
/** The style property {@code borderInlineStartWidth}. */
- BORDER_INLINE_START_WIDTH("borderInlineStartWidth", "border-inline-start-width", ff("")),
+ BORDER_INLINE_START_WIDTH("borderInlineStartWidth", "border-inline-start-width", chrome("0px"),
+ ffBelow68(""), ff68up("0px")),
/** The style property {@code border-inline-start-width}. */
- BORDER_INLINE_START_WIDTH_("border-inline-start-width", "border-inline-start-width", ff("")),
+ BORDER_INLINE_START_WIDTH_("border-inline-start-width", "border-inline-start-width",
+ ffBelow68(""), ff68up("0px")),
+
+ /** The style property {@code borderInlineStyle}. */
+ BORDER_INLINE_STYLE("borderInlineStyle", "border-inline-style", ff68up("")),
+
+ /** The style property {@code border-inline-style}. */
+ BORDER_INLINE_STYLE_("border-inline-style", "border-inline-style", ff68up("")),
+
+ /** The style property {@code borderInlineWidth}. */
+ BORDER_INLINE_WIDTH("borderInlineWidth", "border-inline-color", ff68up("")),
+
+ /** The style property {@code border-inline-width}. */
+ BORDER_INLINE_WIDTH_("border-inline-width", "border-inline-color", ff68up("")),
/** The style property {@code borderLeft}. */
BORDER_LEFT("borderLeft", "border-left", chrome("0px none rgb(0, 0, 0)"), ff(""), ie("")),
@@ -530,6 +621,18 @@ public enum Definition {
/** The style property {@code border-spacing}. */
BORDER_SPACING_("border-spacing", "border-spacing", ff("0px 0px")),
+ /** The style property {@code borderStartEndRadius}. */
+ BORDER_START_END_RADIUS("borderStartEndRadius", "border-start-end-radius", ff68up("0px")),
+
+ /** The style property {@code border-start-end-radius}. */
+ BORDER_START_END_RADIUS_("border-start-end-radius", "border-start-end-radius", ff68up("0px")),
+
+ /** The style property {@code borderStartStartRadius}. */
+ BORDER_START_START_RADIUS("borderStartStartRadius", "border-start-start-radius", ff68up("0px")),
+
+ /** The style property {@code border-start-start-radius}. */
+ BORDER_START_START_RADIUS_("border-start-start-radius", "border-start-start-radius", ff68up("0px")),
+
/** The style property {@code borderStyle}. */
BORDER_STYLE("borderStyle", "border-style", chrome("none"), ff(""), ie("")),
@@ -602,13 +705,22 @@ public enum Definition {
BOX_SIZING_("box-sizing", "box-sizing", ff("content-box")),
/** The style property {@code breakAfter}. */
- BREAK_AFTER("breakAfter", "break-after", chrome("auto"), ie("auto")),
+ BREAK_AFTER("breakAfter", "break-after", chrome("auto"), ff68up("auto"), ie("auto")),
+
+ /** The style property {@code break-after}. */
+ BREAK_AFTER_("break-after", "break-after", ff68up("auto")),
/** The style property {@code breakBefore}. */
- BREAK_BEFORE("breakBefore", "break-before", chrome("auto"), ie("auto")),
+ BREAK_BEFORE("breakBefore", "break-before", chrome("auto"), ff68up("auto"), ie("auto")),
+
+ /** The style property {@code break-before}. */
+ BREAK_BEFORE_("break-before", "break-before", ff68up("auto")),
/** The style property {@code breakInside}. */
- BREAK_INSIDE("breakInside", "break-inside", chrome("auto"), ie("auto")),
+ BREAK_INSIDE("breakInside", "break-inside", chrome("auto"), ff68up("auto"), ie("auto")),
+
+ /** The style property {@code break-inside}. */
+ BREAK_INSIDE_("break-inside", "break-inside", ff68up("auto")),
/** The style property {@code bufferedRendering}. */
BUFFERED_RENDERING("bufferedRendering", "buffered-rendering", chrome("auto")),
@@ -620,7 +732,10 @@ public enum Definition {
CAPTION_SIDE_("caption-side", "caption-side", ff("top")),
/** The style property {@code caretColor}. */
- CARET_COLOR("caretColor", "caret-color", chrome("rgb(0, 0, 0)")),
+ CARET_COLOR("caretColor", "caret-color", chrome("rgb(0, 0, 0)"), ff("rgb(0, 0, 0)")),
+
+ /** The style property {@code caret-color}. */
+ CARET_COLOR_("caret-color", "caret-color", ff("rgb(0, 0, 0)")),
/** The style property {@code clear}. */
CLEAR("clear", "clear", chrome("none"), ff("none"), ie("none")),
@@ -644,20 +759,20 @@ public enum Definition {
COLOR("color", "color", chrome("rgb(0, 0, 0)"), ff(""), ie("")),
/** The style property {@code colorAdjust}. */
- COLOR_ADJUST("colorAdjust", "color-adjust", ff52up("economy")),
+ COLOR_ADJUST("colorAdjust", "color-adjust", ff("economy")),
/** The style property {@code color-adjust}. */
- COLOR_ADJUST_("color-adjust", "color-adjust", ff52up("economy")),
+ COLOR_ADJUST_("color-adjust", "color-adjust", ff("economy")),
/** The style property {@code colorInterpolation}. */
- COLOR_INTERPOLATION("colorInterpolation", "color-interpolation", ff("srgb"), chrome("sRGB")),
+ COLOR_INTERPOLATION("colorInterpolation", "color-interpolation", ff("srgb"), chrome("srgb")),
/** The style property {@code color-interpolation}. */
COLOR_INTERPOLATION_("color-interpolation", "color-interpolation", ff("srgb")),
/** The style property {@code colorInterpolationFilters}. */
COLOR_INTERPOLATION_FILTERS("colorInterpolationFilters",
- "color-interpolation-filters", ff("linearrgb"), ie(""), chrome("linearRGB")),
+ "color-interpolation-filters", ff("linearrgb"), ie(""), chrome("linearrgb")),
/** The style property {@code color-interpolation-filters}. */
COLOR_INTERPOLATION_FILTERS_("color-interpolation-filters", "color-interpolation-filters", ff("linearrgb")),
@@ -666,65 +781,65 @@ public enum Definition {
COLOR_RENDERING("colorRendering", "color-rendering", chrome("auto")),
/** The style property {@code columnCount}. */
- COLUMN_COUNT("columnCount", "column-count", chrome("auto"), ff52up("auto"), ie("auto")),
+ COLUMN_COUNT("columnCount", "column-count", chrome("auto"), ff("auto"), ie("auto")),
/** The style property {@code column-count}. */
- COLUMN_COUNT_("column-count", "column-count", ff52up("auto")),
+ COLUMN_COUNT_("column-count", "column-count", ff("auto")),
/** The style property {@code columnFill}. */
- COLUMN_FILL("columnFill", "column-fill", chrome("balance"), ff52up("balance"), ie("balance")),
+ COLUMN_FILL("columnFill", "column-fill", chrome("balance"), ff("balance"), ie("balance")),
/** The style property {@code column-fill}. */
- COLUMN_FILL_("column-fill", "column-fill", ff52up("balance")),
+ COLUMN_FILL_("column-fill", "column-fill", ff("balance")),
/** The style property {@code columnGap}. */
- COLUMN_GAP("columnGap", "column-gap", chrome("normal"), ff52up("16px"), ie("normal")),
+ COLUMN_GAP("columnGap", "column-gap", chrome("normal"), ie("normal"), ff("normal")),
/** The style property {@code column-gap}. */
- COLUMN_GAP_("column-gap", "column-gap", ff52up("16px")),
+ COLUMN_GAP_("column-gap", "column-gap", ff("normal")),
/** The style property {@code columnRule}. */
- COLUMN_RULE("columnRule", "column-rule", chrome("0px none rgb(0, 0, 0)"), ff52up(""), ie("")),
+ COLUMN_RULE("columnRule", "column-rule", chrome("0px none rgb(0, 0, 0)"), ff(""), ie("")),
/** The style property {@code column-rule}. */
- COLUMN_RULE_("column-rule", "column-rule", ff52up("")),
+ COLUMN_RULE_("column-rule", "column-rule", ff("")),
/** The style property {@code columnRuleColor}. */
COLUMN_RULE_COLOR("columnRuleColor", "column-rule-color",
- chrome("rgb(0, 0, 0)"), ff52up("rgb(0, 0, 0)"), ie("rgb(0, 0, 0)")),
+ chrome("rgb(0, 0, 0)"), ff("rgb(0, 0, 0)"), ie("rgb(0, 0, 0)")),
/** The style property {@code column-rule-color}. */
- COLUMN_RULE_COLOR_("column-rule-color", "column-rule-color", ff52up("rgb(0, 0, 0)")),
+ COLUMN_RULE_COLOR_("column-rule-color", "column-rule-color", ff("rgb(0, 0, 0)")),
/** The style property {@code columnRuleStyle}. */
- COLUMN_RULE_STYLE("columnRuleStyle", "column-rule-style", chrome("none"), ff52up("none"), ie("none")),
+ COLUMN_RULE_STYLE("columnRuleStyle", "column-rule-style", chrome("none"), ff("none"), ie("none")),
/** The style property {@code column-rule-style}. */
- COLUMN_RULE_STYLE_("column-rule-style", "column-rule-style", ff52up("none")),
+ COLUMN_RULE_STYLE_("column-rule-style", "column-rule-style", ff("none")),
/** The style property {@code columnRuleWidth}. */
- COLUMN_RULE_WIDTH("columnRuleWidth", "column-rule-width", chrome("0px"), ff52up("0px"), ie("medium")),
+ COLUMN_RULE_WIDTH("columnRuleWidth", "column-rule-width", chrome("0px"), ff("0px"), ie("medium")),
/** The style property {@code column-rule-width}. */
- COLUMN_RULE_WIDTH_("column-rule-width", "column-rule-width", ff52up("0px")),
+ COLUMN_RULE_WIDTH_("column-rule-width", "column-rule-width", ff("0px")),
/** The style property {@code columnSpan}. */
COLUMN_SPAN("columnSpan", "column-span", chrome("none"), ie("1")),
/** The style property {@code columnWidth}. */
- COLUMN_WIDTH("columnWidth", "column-width", chrome("auto"), ff52up("auto"), ie("auto")),
+ COLUMN_WIDTH("columnWidth", "column-width", chrome("auto"), ff("auto"), ie("auto")),
/** The style property {@code column-width}. */
- COLUMN_WIDTH_("column-width", "column-width", ff52up("auto")),
+ COLUMN_WIDTH_("column-width", "column-width", ff("auto")),
/** The style property {@code columns}. */
- COLUMNS("columns", "columns", chrome("auto auto"), ff52up(""), ie("")),
+ COLUMNS("columns", "columns", chrome("auto auto"), ff(""), ie("")),
/** The style property {@code contain}. */
CONTAIN("contain", "contain", chrome("none")),
/** The style property {@code content}. */
- CONTENT("content", "content", ie("normal"), chrome(""), ff("none")),
+ CONTENT("content", "content", ie("normal"), chrome("normal"), ff("none")),
/** The style property {@code counterIncrement}. */
COUNTER_INCREMENT("counterIncrement", "counter-increment", chrome("none"), ff("none"), ie("none")),
@@ -738,6 +853,12 @@ public enum Definition {
/** The style property {@code counter-reset}. */
COUNTER_RESET_("counter-reset", "counter-reset", ff("none")),
+ /** The style property {@code counterSet}. */
+ COUNTER_SET("counterSet", "counter-set", ff68up("none")),
+
+ /** The style property {@code counter-set}. */
+ COUNTER_SET_("counter-set", "counter-set", ff68up("none")),
+
/** The style property {@code cssFloat}. */
CSS_FLOAT("cssFloat", "css-float", chrome("none"), ff("none"), ie("none")),
@@ -864,7 +985,7 @@ public enum Definition {
FLOOD_OPACITY_("flood-opacity", "flood-opacity", ff("1")),
/** The style property {@code font}. */
- FONT("font", "font", chrome("normal normal 400 normal 16px / normal \"Times New Roman\""), ff(""), ie("")),
+ FONT("font", "font", chrome("16px \"Times New Roman\""), ff(""), ie("")),
/** The style property {@code fontDisplay}. */
FONT_DISPLAY("fontDisplay", "font-display", chrome("")),
@@ -894,6 +1015,9 @@ public enum Definition {
/** The style property {@code font-language-override}. */
FONT_LANGUAGE_OVERRIDE_("font-language-override", "font-language-override", ff("normal")),
+ /** The style property {@code fontOpticalSizing}. */
+ FONT_OPTICAL_SIZING("fontOpticalSizing", "font-optical-sizing", chrome("auto")),
+
/** The style property {@code fontSize}. */
FONT_SIZE("fontSize", "font-size", chrome("16px"), ff("16px"), ie("16px")),
@@ -907,10 +1031,11 @@ public enum Definition {
FONT_SIZE_ADJUST_("font-size-adjust", "font-size-adjust", ff("none")),
/** The style property {@code fontStretch}. */
- FONT_STRETCH("fontStretch", "font-stretch", chrome("100%"), ff("normal"), ie("normal")),
+ FONT_STRETCH("fontStretch", "font-stretch", chrome("100%"),
+ ffBelow68("normal"), ff68up("100%"), ie("normal")),
/** The style property {@code font-stretch}. */
- FONT_STRETCH_("font-stretch", "font-stretch", ff("normal")),
+ FONT_STRETCH_("font-stretch", "font-stretch", ffBelow68("normal"), ff68up("100%")),
/** The style property {@code fontStyle}. */
FONT_STYLE("fontStyle", "font-style", chrome("normal"), ff("normal"), ie("normal")),
@@ -976,7 +1101,7 @@ public enum Definition {
FONT_WEIGHT_("font-weight", "font-weight", ff("400")),
/** The style property {@code gap}. */
- GAP("gap", "gap", chrome("normal normal")),
+ GAP("gap", "gap", chrome("normal"), ff68up("")),
/** The style property {@code glyphOrientationHorizontal}. */
GLYPH_ORIENTATION_HORIZONTAL("glyphOrientationHorizontal", "glyph-orientation-horizontal",
@@ -988,109 +1113,111 @@ public enum Definition {
/** The style property {@code grid}. */
GRID("grid", "grid", chrome("none / none / none / row / auto / auto"),
- ff52up("")),
+ ff("")),
/** The style property {@code gridArea}. */
- GRID_AREA("gridArea", "grid-area", chrome("auto / auto / auto / auto"), ff52up("")),
+ GRID_AREA("gridArea", "grid-area", chrome("auto / auto / auto / auto"), ff("")),
/** The style property {@code grid-area}. */
- GRID_AREA_("grid-area", "grid-area", ff52up("")),
+ GRID_AREA_("grid-area", "grid-area", ff("")),
/** The style property {@code gridAutoColumns}. */
- GRID_AUTO_COLUMNS("gridAutoColumns", "grid-auto-columns", chrome("auto"), ff52up("auto")),
+ GRID_AUTO_COLUMNS("gridAutoColumns", "grid-auto-columns", chrome("auto"), ff("auto")),
/** The style property {@code grid-auto-columns}. */
- GRID_AUTO_COLUMNS_("grid-auto-columns", "grid-auto-columns", ff52up("auto")),
+ GRID_AUTO_COLUMNS_("grid-auto-columns", "grid-auto-columns", ff("auto")),
/** The style property {@code gridAutoFlow}. */
- GRID_AUTO_FLOW("gridAutoFlow", "grid-auto-flow", chrome("row"), ff52up("row")),
+ GRID_AUTO_FLOW("gridAutoFlow", "grid-auto-flow", chrome("row"), ff("row")),
/** The style property {@code grid-auto-flow}. */
- GRID_AUTO_FLOW_("grid-auto-flow", "grid-auto-flow", ff52up("row")),
+ GRID_AUTO_FLOW_("grid-auto-flow", "grid-auto-flow", ff("row")),
/** The style property {@code gridAutoRows}. */
- GRID_AUTO_ROWS("gridAutoRows", "grid-auto-rows", chrome("auto"), ff52up("auto")),
+ GRID_AUTO_ROWS("gridAutoRows", "grid-auto-rows", chrome("auto"), ff("auto")),
/** The style property {@code grid-auto-rows}. */
- GRID_AUTO_ROWS_("grid-auto-rows", "grid-auto-rows", ff52up("auto")),
+ GRID_AUTO_ROWS_("grid-auto-rows", "grid-auto-rows", ff("auto")),
/** The style property {@code gridColumn}. */
- GRID_COLUMN("gridColumn", "grid-column", chrome("auto / auto"), ff52up("")),
+ GRID_COLUMN("gridColumn", "grid-column", chrome("auto / auto"), ff("")),
/** The style property {@code grid-column}. */
- GRID_COLUMN_("grid-column", "grid-column", ff52up("")),
+ GRID_COLUMN_("grid-column", "grid-column", ff("")),
/** The style property {@code gridColumnEnd}. */
- GRID_COLUMN_END("gridColumnEnd", "grid-column-end", chrome("auto"), ff52up("auto")),
+ GRID_COLUMN_END("gridColumnEnd", "grid-column-end", chrome("auto"), ff("auto")),
/** The style property {@code grid-column-end}. */
- GRID_COLUMN_END_("grid-column-end", "grid-column-end", ff52up("auto")),
+ GRID_COLUMN_END_("grid-column-end", "grid-column-end", ff("auto")),
/** The style property {@code gridColumnGap}. */
- GRID_COLUMN_GAP("gridColumnGap", "grid-column-gap", chrome("normal"), ff52up("0px")),
+ GRID_COLUMN_GAP("gridColumnGap", "grid-column-gap", chrome("normal"), ffBelow68("0px"), ff68up("normal")),
/** The style property {@code grid-column-gap}. */
- GRID_COLUMN_GAP_("grid-column-gap", "grid-column-gap", ff52up("0px")),
+ GRID_COLUMN_GAP_("grid-column-gap", "grid-column-gap", ffBelow68("0px"), ff68up("normal")),
/** The style property {@code gridColumnStart}. */
- GRID_COLUMN_START("gridColumnStart", "grid-column-start", chrome("auto"), ff52up("auto")),
+ GRID_COLUMN_START("gridColumnStart", "grid-column-start", chrome("auto"), ff("auto")),
/** The style property {@code grid-column-start}. */
- GRID_COLUMN_START_("grid-column-start", "grid-column-start", ff52up("auto")),
+ GRID_COLUMN_START_("grid-column-start", "grid-column-start", ff("auto")),
/** The style property {@code gridGap}. */
- GRID_GAP("gridGap", "grid-gap", chrome("normal normal"), ff52up("")),
+ GRID_GAP("gridGap", "grid-gap", chrome("normal normal"), ff("")),
/** The style property {@code grid-gap}. */
- GRID_GAP_("grid-gap", "grid-gap", ff52up("")),
+ GRID_GAP_("grid-gap", "grid-gap", ff("")),
/** The style property {@code gridRow}. */
- GRID_ROW("gridRow", "grid-row", chrome("auto / auto"), ff52up("")),
+ GRID_ROW("gridRow", "grid-row", chrome("auto / auto"), ff("")),
/** The style property {@code grid-row}. */
- GRID_ROW_("grid-row", "grid-row", ff52up("")),
+ GRID_ROW_("grid-row", "grid-row", ff("")),
/** The style property {@code gridRowEnd}. */
- GRID_ROW_END("gridRowEnd", "grid-row-end", chrome("auto"), ff52up("auto")),
+ GRID_ROW_END("gridRowEnd", "grid-row-end", chrome("auto"), ff("auto")),
/** The style property {@code grid-row-end}. */
- GRID_ROW_END_("grid-row-end", "grid-row-end", ff52up("auto")),
+ GRID_ROW_END_("grid-row-end", "grid-row-end", ff("auto")),
/** The style property {@code gridRowGap}. */
- GRID_ROW_GAP("gridRowGap", "grid-row-gap", chrome("normal"), ff52up("0px")),
+ GRID_ROW_GAP("gridRowGap", "grid-row-gap", chrome("normal"), ffBelow68("0px"), ff68up("normal")),
/** The style property {@code grid-row-gap}. */
- GRID_ROW_GAP_("grid-row-gap", "grid-row-gap", ff52up("0px")),
+ GRID_ROW_GAP_("grid-row-gap", "grid-row-gap", ffBelow68("0px"), ff68up("normal")),
/** The style property {@code gridRowStart}. */
- GRID_ROW_START("gridRowStart", "grid-row-start", chrome("auto"), ff52up("auto")),
+ GRID_ROW_START("gridRowStart", "grid-row-start", chrome("auto"), ff("auto")),
/** The style property {@code grid-row-start}. */
- GRID_ROW_START_("grid-row-start", "grid-row-start", ff52up("auto")),
+ GRID_ROW_START_("grid-row-start", "grid-row-start", ff("auto")),
/** The style property {@code gridTemplate}. */
- GRID_TEMPLATE("gridTemplate", "grid-template", chrome("none / none / none"), ff52up("")),
+ GRID_TEMPLATE("gridTemplate", "grid-template", chrome("none / none / none"), ff("")),
/** The style property {@code grid-template}. */
- GRID_TEMPLATE_("grid-template", "grid-template", ff52up("")),
+ GRID_TEMPLATE_("grid-template", "grid-template", ff("")),
/** The style property {@code gridTemplateAreas}. */
- GRID_TEMPLATE_AREAS("gridTemplateAreas", "grid-template-areas", chrome("none"), ff52up("none")),
+ GRID_TEMPLATE_AREAS("gridTemplateAreas", "grid-template-areas", chrome("none"),
+ ff("none")),
/** The style property {@code grid-template-areas}. */
- GRID_TEMPLATE_AREAS_("grid-template-areas", "grid-template-areas", ff52up("none")),
+ GRID_TEMPLATE_AREAS_("grid-template-areas", "grid-template-areas",
+ ff("none")),
/** The style property {@code gridTemplateColumns}. */
- GRID_TEMPLATE_COLUMNS("gridTemplateColumns", "grid-template-columns", chrome("none"), ff52up("none")),
+ GRID_TEMPLATE_COLUMNS("gridTemplateColumns", "grid-template-columns", chrome("none"), ff("none")),
/** The style property {@code grid-template-columns}. */
- GRID_TEMPLATE_COLUMNS_("grid-template-columns", "grid-template-columns", ff52up("none")),
+ GRID_TEMPLATE_COLUMNS_("grid-template-columns", "grid-template-columns", ff("none")),
/** The style property {@code gridTemplateRows}. */
- GRID_TEMPLATE_ROWS("gridTemplateRows", "grid-template-rows", chrome("none"), ff52up("none")),
+ GRID_TEMPLATE_ROWS("gridTemplateRows", "grid-template-rows", chrome("none"), ff("none")),
/** The style property {@code grid-template-rows}. */
- GRID_TEMPLATE_ROWS_("grid-template-rows", "grid-template-rows", ff52up("none")),
+ GRID_TEMPLATE_ROWS_("grid-template-rows", "grid-template-rows", ff("none")),
/** The style property {@code height}. */
HEIGHT("height", "height", chrome(""), ff(""), ie("")),
@@ -1099,10 +1226,10 @@ public enum Definition {
HYPHENS("hyphens", "hyphens", ff("manual"), chrome("manual")),
/** The style property {@code imageOrientation}. */
- IMAGE_ORIENTATION("imageOrientation", "image-orientation", ff("0deg")),
+ IMAGE_ORIENTATION("imageOrientation", "image-orientation", ffBelow68("0deg"), ff68up("none")),
/** The style property {@code image-orientation}. */
- IMAGE_ORIENTATION_("image-orientation", "image-orientation", ff("0deg")),
+ IMAGE_ORIENTATION_("image-orientation", "image-orientation", ffBelow68("0deg"), ff68up("none")),
/** The style property {@code imageRendering}. */
IMAGE_RENDERING("imageRendering", "image-rendering", ff("auto"), chrome("auto")),
@@ -1117,33 +1244,72 @@ public enum Definition {
IME_MODE_("ime-mode", "ime-mode", ff("auto")),
/** The style property {@code inlineSize}. */
- INLINE_SIZE("inlineSize", "inline-size", ff(""), chrome("913px")),
+ INLINE_SIZE("inlineSize", "inline-size", ffBelow68(""), ff68up("1242px"), chrome("913px")),
/** The style property {@code inline-size}. */
- INLINE_SIZE_("inline-size", "inline-size", ff("")),
+ INLINE_SIZE_("inline-size", "inline-size", ffBelow68(""), ff68up("1242px")),
+
+ /** The style property {@code inset}. */
+ INSET("inset", "inset", ff68up("")),
+
+ /** The style property {@code insetBlock}. */
+ INSET_BLOCK("insetBlock", "inset-block", ff68up("")),
+
+ /** The style property {@code inset-block}. */
+ INSET_BLOCK_("inset-block", "inset-block", ff68up("")),
+
+ /** The style property {@code insetBlockEnd}. */
+ INSET_BLOCK_END("insetBlockEnd", "inset-block-end", ff68up("auto")),
+
+ /** The style property {@code inset-block-end}. */
+ INSET_BLOCK_END_("inset-block-end", "inset-block-end", ff68up("auto")),
+
+ /** The style property {@code insetBlockStart}. */
+ INSET_BLOCK_START("insetBlockStart", "inset-block-start", ff68up("auto")),
+
+ /** The style property {@code inset-block-start}. */
+ INSET_BLOCK_START_("inset-block-start", "inset-block-start", ff68up("auto")),
+
+ /** The style property {@code insetInline}. */
+ INSET_INLINE("insetInline", "inset-inline", ff68up("")),
+
+ /** The style property {@code inset-inline}. */
+ INSET_INLINE_("inset-inline", "inset-inline", ff68up("")),
+
+ /** The style property {@code insetInlineEnd}. */
+ INSET_INLINE_END("insetInlineEnd", "inset-inline-end", ff68up("auto")),
+
+ /** The style property {@code inset-inline-end}. */
+ INSET_INLINE_END_("inset-inline-end", "inset-inline-end", ff68up("auto")),
+
+ /** The style property {@code insetInlineStart}. */
+ INSET_INLINE_START("insetInlineStart", "inset-inline-start", ff68up("auto")),
+
+ /** The style property {@code inset-inline-start}. */
+ INSET_INLINE_START_("inset-inline-start", "inset-inline-start", ff68up("auto")),
/** The style property {@code isolation}. */
ISOLATION("isolation", "isolation", ff("auto"), chrome("auto")),
/** The style property {@code justifyContent}. */
JUSTIFY_CONTENT("justifyContent", "justify-content",
- ffBelow52("auto"), ff52up("normal"),
+ ff("normal"),
ie("flex-start"), chrome("normal")),
/** The style property {@code justify-content}. */
- JUSTIFY_CONTENT_("justify-content", "justify-content", ffBelow52("auto"), ff52up("normal")),
+ JUSTIFY_CONTENT_("justify-content", "justify-content", ff("normal")),
/** The style property {@code justifyItems}. */
- JUSTIFY_ITEMS("justifyItems", "justify-items", ffBelow52("start"), ff52up("normal"), chrome("normal")),
+ JUSTIFY_ITEMS("justifyItems", "justify-items", ff("normal"), chrome("normal")),
/** The style property {@code justify-items}. */
- JUSTIFY_ITEMS_("justify-items", "justify-items", ffBelow52("start"), ff52up("normal")),
+ JUSTIFY_ITEMS_("justify-items", "justify-items", ff("normal")),
/** The style property {@code justifySelf}. */
- JUSTIFY_SELF("justifySelf", "justify-self", ffBelow52("start"), ff52up("auto"), chrome("auto")),
+ JUSTIFY_SELF("justifySelf", "justify-self", ff("auto"), chrome("auto")),
/** The style property {@code justify-self}. */
- JUSTIFY_SELF_("justify-self", "justify-self", ffBelow52("start"), ff52up("auto")),
+ JUSTIFY_SELF_("justify-self", "justify-self", ff("auto")),
/** The style property {@code kerning}. */
KERNING("kerning", "kerning", ie("auto")),
@@ -1186,13 +1352,14 @@ public enum Definition {
LINE_BREAK("lineBreak", "line-break", ie("undefined"), chrome("auto")),
/** The style property {@code lineHeight}. */
- LINE_HEIGHT("lineHeight", "line-height", ff("20px"), ie("normal"), chrome("normal")),
+ LINE_HEIGHT("lineHeight", "line-height", ffBelow68("20px"), ff68up("18px"),
+ ie("normal"), chrome("normal")),
/** The style property {@code line-height}. */
- LINE_HEIGHT_("line-height", "line-height", ff("20px")),
+ LINE_HEIGHT_("line-height", "line-height", ffBelow68("20px"), ff68up("18px")),
/** The style property {@code listStyle}. */
- LIST_STYLE("listStyle", "list-style", chrome("disc outside none"), ff(""), ie("")),
+ LIST_STYLE("listStyle", "list-style", chrome("outside none disc"), ff(""), ie("")),
/** The style property {@code list-style}. */
LIST_STYLE_("list-style", "list-style", ff("")),
@@ -1219,17 +1386,23 @@ public enum Definition {
/** The style property {@code margin}. */
MARGIN("margin", "margin", chrome("0px"), ff(""), ie("")),
+ /** The style property {@code marginBlock}. */
+ MARGIN_BLOCK("marginBlock", "margin-block", ff68up("")),
+
+ /** The style property {@code margin-block}. */
+ MARGIN_BLOCK_("margin-block", "margin-block", ff68up("")),
+
/** The style property {@code marginBlockEnd}. */
- MARGIN_BLOCK_END("marginBlockEnd", "margin-block-end", ff("")),
+ MARGIN_BLOCK_END("marginBlockEnd", "margin-block-end", chrome("0px"), ffBelow68(""), ff68up("0px")),
/** The style property {@code margin-block-end}. */
- MARGIN_BLOCK_END_("margin-block-end", "margin-block-end", ff("")),
+ MARGIN_BLOCK_END_("margin-block-end", "margin-block-end", ffBelow68(""), ff68up("0px")),
/** The style property {@code marginBlockStart}. */
- MARGIN_BLOCK_START("marginBlockStart", "margin-block-start", ff("")),
+ MARGIN_BLOCK_START("marginBlockStart", "margin-block-start", chrome("0px"), ffBelow68(""), ff68up("0px")),
/** The style property {@code margin-block-start}. */
- MARGIN_BLOCK_START_("margin-block-start", "margin-block-start", ff("")),
+ MARGIN_BLOCK_START_("margin-block-start", "margin-block-start", ffBelow68(""), ff68up("0px")),
/** The style property {@code marginBottom}. */
MARGIN_BOTTOM("marginBottom", "margin-bottom", chrome("0px"), ff(""), ie("")),
@@ -1237,17 +1410,23 @@ public enum Definition {
/** The style property {@code margin-bottom}. */
MARGIN_BOTTOM_("margin-bottom", "margin-bottom", ff("0px")),
+ /** The style property {@code marginInline}. */
+ MARGIN_INLINE("marginInline", "margin-inline", ff68up("")),
+
+ /** The style property {@code margin-inline}. */
+ MARGIN_INLINE_("margin-inline", "margin-inline", ff68up("")),
+
/** The style property {@code marginInlineEnd}. */
- MARGIN_INLINE_END("marginInlineEnd", "margin-inline-end", ff("")),
+ MARGIN_INLINE_END("marginInlineEnd", "margin-inline-end", chrome("0px"), ffBelow68(""), ff68up("0px")),
/** The style property {@code margin-inline-end}. */
- MARGIN_INLINE_END_("margin-inline-end", "margin-inline-end", ff("")),
+ MARGIN_INLINE_END_("margin-inline-end", "margin-inline-end", ffBelow68(""), ff68up("0px")),
/** The style property {@code marginInlineStart}. */
- MARGIN_INLINE_START("marginInlineStart", "margin-inline-start", ff("")),
+ MARGIN_INLINE_START("marginInlineStart", "margin-inline-start", chrome("0px"), ffBelow68(""), ff68up("0px")),
/** The style property {@code margin-inline-start}. */
- MARGIN_INLINE_START_("margin-inline-start", "margin-inline-start", ff("")),
+ MARGIN_INLINE_START_("margin-inline-start", "margin-inline-start", ffBelow68(""), ff68up("0px")),
/** The style property {@code marginLeft}. */
MARGIN_LEFT("marginLeft", "margin-left", chrome("0px"), ff(""), ie("")),
@@ -1268,7 +1447,7 @@ public enum Definition {
MARGIN_TOP_("margin-top", "margin-top", ff("0px")),
/** The style property {@code marker}. */
- MARKER("marker", "marker", ff(""), ie("none"), chrome("")),
+ MARKER("marker", "marker", ff(""), ie("none"), chrome("none")),
/** The style property {@code markerEnd}. */
MARKER_END("markerEnd", "marker-end", ff("none"), ie("none"), chrome("none")),
@@ -1283,10 +1462,10 @@ public enum Definition {
MARKER_MID_("marker-mid", "marker-mid", ff("none")),
/** The style property {@code markerOffset}. */
- MARKER_OFFSET("markerOffset", "marker-offset", ffBelow52("auto")),
+ MARKER_OFFSET("markerOffset", "marker-offset"),
/** The style property {@code marker-offset}. */
- MARKER_OFFSET_("marker-offset", "marker-offset", ffBelow52("auto")),
+ MARKER_OFFSET_("marker-offset", "marker-offset"),
/** The style property {@code markerStart}. */
MARKER_START("markerStart", "marker-start", ff("none"), ie("none"), chrome("none")),
@@ -1297,6 +1476,66 @@ public enum Definition {
/** The style property {@code mask}. */
MASK("mask", "mask", ff("none"), ie("none"), chrome("none")),
+ /** The style property {@code maskClip}. */
+ MASK_CLIP("maskClip", "mask-clip", ff("border-box")),
+
+ /** The style property {@code mask-clip}. */
+ MASK_CLIP_("mask-clip", "mask-clip", ff("border-box")),
+
+ /** The style property {@code maskComposite}. */
+ MASK_COMPOSITE("maskComposite", "mask-composite", ff("add")),
+
+ /** The style property {@code mask-composite}. */
+ MASK_COMPOSITE_("mask-composite", "mask-composite", ff("add")),
+
+ /** The style property {@code maskImage}. */
+ MASK_IMAGE("maskImage", "mask-image", ff("none")),
+
+ /** The style property {@code mask-image}. */
+ MASK_IMAGE_("mask-image", "mask-image", ff("none")),
+
+ /** The style property {@code maskMode}. */
+ MASK_MODE("maskMode", "mask-mode", ff("match-source")),
+
+ /** The style property {@code mask-mode}. */
+ MASK_MODE_("mask-mode", "mask-mode", ff("match-source")),
+
+ /** The style property {@code maskOrigin}. */
+ MASK_ORIGIN("maskOrigin", "mask-origin", ff("border-box")),
+
+ /** The style property {@code mask-origin}. */
+ MASK_ORIGIN_("mask-origin", "mask-origin", ff("border-box")),
+
+ /** The style property {@code maskPosition}. */
+ MASK_POSITION("maskPosition", "mask-position", ff("0% 0%")),
+
+ /** The style property {@code mask-position}. */
+ MASK_POSITION_("mask-position", "mask-position", ff("0% 0%")),
+
+ /** The style property {@code maskPositionX}. */
+ MASK_POSITION_X("maskPositionX", "mask-position-x", ff("0%")),
+
+ /** The style property {@code mask-position-x}. */
+ MASK_POSITION_X_("mask-position-x", "mask-position-x", ff("0%")),
+
+ /** The style property {@code maskPositionY}. */
+ MASK_POSITION_Y("maskPositionY", "mask-position-y", ff("0%")),
+
+ /** The style property {@code mask-position-y}. */
+ MASK_POSITION_Y_("mask-position-y", "mask-position-y", ff("0%")),
+
+ /** The style property {@code maskRepeat}. */
+ MASK_REPEAT("maskRepeat", "mask-repeat", ff("repeat")),
+
+ /** The style property {@code mask-repeat}. */
+ MASK_REPEAT_("mask-repeat", "mask-repeat", ff("repeat")),
+
+ /** The style property {@code maskSize}. */
+ MASK_SIZE("maskSize", "mask-size", ffBelow68("auto auto"), ff68up("auto")),
+
+ /** The style property {@code mask-size}. */
+ MASK_SIZE_("mask-size", "mask-size", ffBelow68("auto auto"), ff68up("auto")),
+
/** The style property {@code maskType}. */
MASK_TYPE("maskType", "mask-type", ff("luminance"), chrome("luminance")),
@@ -1304,10 +1543,10 @@ public enum Definition {
MASK_TYPE_("mask-type", "mask-type", ff("luminance")),
/** The style property {@code maxBlockSize}. */
- MAX_BLOCK_SIZE("maxBlockSize", "max-block-size", ff(""), chrome("none")),
+ MAX_BLOCK_SIZE("maxBlockSize", "max-block-size", ffBelow68(""), ff68up("none"), chrome("none")),
/** The style property {@code max-block-size}. */
- MAX_BLOCK_SIZE_("max-block-size", "max-block-size", ff("")),
+ MAX_BLOCK_SIZE_("max-block-size", "max-block-size", ffBelow68(""), ff68up("none")),
/** The style property {@code maxHeight}. */
MAX_HEIGHT("maxHeight", "max-height", chrome("none"), ff(""), ie("")),
@@ -1316,10 +1555,10 @@ public enum Definition {
MAX_HEIGHT_("max-height", "max-height", ff("none")),
/** The style property {@code maxInlineSize}. */
- MAX_INLINE_SIZE("maxInlineSize", "max-inline-size", ff(""), chrome("none")),
+ MAX_INLINE_SIZE("maxInlineSize", "max-inline-size", ffBelow68(""), ff68up("none"), chrome("none")),
/** The style property {@code max-inline-size}. */
- MAX_INLINE_SIZE_("max-inline-size", "max-inline-size", ff("")),
+ MAX_INLINE_SIZE_("max-inline-size", "max-inline-size", ffBelow68(""), ff68up("none")),
/** The style property {@code maxWidth}. */
MAX_WIDTH("maxWidth", "max-width", chrome("none"), ff(""), ie("")),
@@ -1331,10 +1570,10 @@ public enum Definition {
MAX_ZOOM("maxZoom", "max-zoom", chrome("")),
/** The style property {@code minBlockSize}. */
- MIN_BLOCK_SIZE("minBlockSize", "min-block-size", ff(""), chrome("0px")),
+ MIN_BLOCK_SIZE("minBlockSize", "min-block-size", ffBelow68(""), ff68up("0px"), chrome("0px")),
/** The style property {@code min-block-size}. */
- MIN_BLOCK_SIZE_("min-block-size", "min-block-size", ff("")),
+ MIN_BLOCK_SIZE_("min-block-size", "min-block-size", ffBelow68(""), ff68up("0px")),
/** The style property {@code minHeight}. */
MIN_HEIGHT("minHeight", "min-height", chrome("0px"), ff(""), ie("")),
@@ -1343,10 +1582,10 @@ public enum Definition {
MIN_HEIGHT_("min-height", "min-height", ff("0px")),
/** The style property {@code minInlineSize}. */
- MIN_INLINE_SIZE("minInlineSize", "min-inline-size", ff(""), chrome("0px")),
+ MIN_INLINE_SIZE("minInlineSize", "min-inline-size", ffBelow68(""), ff68up("0px"), chrome("0px")),
/** The style property {@code min-inline-size}. */
- MIN_INLINE_SIZE_("min-inline-size", "min-inline-size", ff("")),
+ MIN_INLINE_SIZE_("min-inline-size", "min-inline-size", ffBelow68(""), ff68up("0px")),
/** The style property {@code minWidth}. */
MIN_WIDTH("minWidth", "min-width", chrome("0px"), ff(""), ie("")),
@@ -1367,50 +1606,50 @@ public enum Definition {
MOZ_ANIMATION("MozAnimation", "-moz-animation", ff("")),
/** The style property {@code -moz-animation}. */
- MOZ_ANIMATION__("-moz-animation", "-moz-animation", ff52up("")),
+ MOZ_ANIMATION__("-moz-animation", "-moz-animation", ff("")),
/** The style property {@code MozAnimationDelay}. */
MOZ_ANIMATION_DELAY("MozAnimationDelay", "-moz-animation-delay", ff("0s")),
/** The style property {@code -moz-animation-delay}. */
- MOZ_ANIMATION_DELAY__("-moz-animation-delay", "-moz-animation-delay", ff52up("0s")),
+ MOZ_ANIMATION_DELAY__("-moz-animation-delay", "-moz-animation-delay", ff("0s")),
/** The style property {@code MozAnimationDirection}. */
MOZ_ANIMATION_DIRECTION("MozAnimationDirection", "-moz-animation-direction", ff("normal")),
/** The style property {@code -moz-animation-direction}. */
- MOZ_ANIMATION_DIRECTION__("-moz-animation-direction", "-moz-animation-direction", ff52up("normal")),
+ MOZ_ANIMATION_DIRECTION__("-moz-animation-direction", "-moz-animation-direction", ff("normal")),
/** The style property {@code MozAnimationDuration}. */
MOZ_ANIMATION_DURATION("MozAnimationDuration", "-moz-animation-duration", ff("0s")),
/** The style property {@code -moz-animation-duration}. */
- MOZ_ANIMATION_DURATION__("-moz-animation-duration", "-moz-animation-duration", ff52up("0s")),
+ MOZ_ANIMATION_DURATION__("-moz-animation-duration", "-moz-animation-duration", ff("0s")),
/** The style property {@code MozAnimationFillMode}. */
MOZ_ANIMATION_FILL_MODE("MozAnimationFillMode", "-moz-animation-fill-mode", ff("none")),
/** The style property {@code -moz-animation-fill-mode}. */
- MOZ_ANIMATION_FILL_MODE__("-moz-animation-fill-mode", "-moz-animation-fill-mode", ff52up("none")),
+ MOZ_ANIMATION_FILL_MODE__("-moz-animation-fill-mode", "-moz-animation-fill-mode", ff("none")),
/** The style property {@code MozAnimationIterationCount}. */
MOZ_ANIMATION_ITERATION_COUNT("MozAnimationIterationCount", "-moz-animation-iteration-count", ff("1")),
/** The style property {@code -moz-animation-iteration-count}. */
MOZ_ANIMATION_ITERATION_COUNT__("-moz-animation-iteration-count", "-moz-animation-iteration-count",
- ff52up("1")),
+ ff("1")),
/** The style property {@code MozAnimationName}. */
MOZ_ANIMATION_NAME("MozAnimationName", "-moz-animation-name", ff("none")),
/** The style property {@code -moz-animation-name}. */
- MOZ_ANIMATION_NAME__("-moz-animation-name", "-moz-animation-name", ff52up("none")),
+ MOZ_ANIMATION_NAME__("-moz-animation-name", "-moz-animation-name", ff("none")),
/** The style property {@code MozAnimationPlayState}. */
MOZ_ANIMATION_PLAY_STATE("MozAnimationPlayState", "-moz-animation-play-state", ff("running")),
/** The style property {@code -moz-animation-play-state}. */
- MOZ_ANIMATION_PLAY_STATE__("-moz-animation-play-state", "-moz-animation-play-state", ff52up("running")),
+ MOZ_ANIMATION_PLAY_STATE__("-moz-animation-play-state", "-moz-animation-play-state", ff("running")),
/** The style property {@code MozAnimationTimingFunction}. */
MOZ_ANIMATION_TIMING_FUNCTION("MozAnimationTimingFunction", "-moz-animation-timing-function",
@@ -1418,19 +1657,19 @@ public enum Definition {
/** The style property {@code -moz-animation-timing-function}. */
MOZ_ANIMATION_TIMING_FUNCTION__("-moz-animation-timing-function", "-moz-animation-timing-function",
- ff52up("ease")),
+ ff("ease")),
/** The style property {@code MozAppearance}. */
MOZ_APPEARANCE("MozAppearance", "-moz-appearance", ff("none")),
/** The style property {@code -moz-appearance}. */
- MOZ_APPEARANCE__("-moz-appearance", "-moz-appearance", ff52up("none")),
+ MOZ_APPEARANCE__("-moz-appearance", "-moz-appearance", ff("none")),
/** The style property {@code MozBackfaceVisibility}. */
MOZ_BACKFACE_VISIBILITY("MozBackfaceVisibility", "-moz-backface-visibility", ff("visible")),
/** The style property {@code -moz-backface-visibility}. */
- MOZ_BACKFACE_VISIBILITY__("-moz-backface-visibility", "-moz-backface-visibility", ff52up("visible")),
+ MOZ_BACKFACE_VISIBILITY__("-moz-backface-visibility", "-moz-backface-visibility", ff("visible")),
/** The style property {@code MozBackgroundClip}. */
MOZ_BACKGROUND_CLIP("MozBackgroundClip", "-moz-background-clip"),
@@ -1442,53 +1681,56 @@ public enum Definition {
MOZ_BACKGROUND_SIZE("MozBackgroundSize", "-moz-background-size"),
/** The style property {@code MozBinding}. */
- MOZ_BINDING("MozBinding", "-moz-binding", ff("none")),
+ MOZ_BINDING("MozBinding", "-moz-binding", ffBelow68("none")),
/** The style property {@code -moz-binding}. */
- MOZ_BINDING__("-moz-binding", "-moz-binding", ff52up("none")),
+ MOZ_BINDING__("-moz-binding", "-moz-binding", ffBelow68("none")),
/** The style property {@code MozBorderBottomColors}. */
- MOZ_BORDER_BOTTOM_COLORS("MozBorderBottomColors", "-moz-border-bottom-colors", ff("none")),
+ MOZ_BORDER_BOTTOM_COLORS("MozBorderBottomColors", "-moz-border-bottom-colors",
+ ff("none").setIteratable(false)),
/** The style property {@code -moz-border-bottom-colors}. */
MOZ_BORDER_BOTTOM_COLORS__("-moz-border-bottom-colors", "-moz-border-bottom-colors",
- ff52up("none")),
+ ff("none").setIteratable(false)),
/** The style property {@code MozBorderEnd}. */
MOZ_BORDER_END("MozBorderEnd", "-moz-border-end", ff("")),
/** The style property {@code -moz-border-end}. */
- MOZ_BORDER_END__("-moz-border-end", "-moz-border-end", ff52up("")),
+ MOZ_BORDER_END__("-moz-border-end", "-moz-border-end", ff("")),
/** The style property {@code MozBorderEndColor}. */
- MOZ_BORDER_END_COLOR("MozBorderEndColor", "-moz-border-end-color", ff("")),
+ MOZ_BORDER_END_COLOR("MozBorderEndColor", "-moz-border-end-color", ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code -moz-border-end-color}. */
- MOZ_BORDER_END_COLOR__("-moz-border-end-color", "-moz-border-end-color", ff52up("")),
+ MOZ_BORDER_END_COLOR__("-moz-border-end-color", "-moz-border-end-color", ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code MozBorderEndStyle}. */
- MOZ_BORDER_END_STYLE("MozBorderEndStyle", "-moz-border-end-style", ff("")),
+ MOZ_BORDER_END_STYLE("MozBorderEndStyle", "-moz-border-end-style", ffBelow68(""), ff68up("none")),
/** The style property {@code -moz-border-end-style}. */
- MOZ_BORDER_END_STYLE__("-moz-border-end-style", "-moz-border-end-style", ff52up("")),
+ MOZ_BORDER_END_STYLE__("-moz-border-end-style", "-moz-border-end-style", ffBelow68(""), ff68up("none")),
/** The style property {@code MozBorderEndWidth}. */
- MOZ_BORDER_END_WIDTH("MozBorderEndWidth", "-moz-border-end-width", ff("")),
+ MOZ_BORDER_END_WIDTH("MozBorderEndWidth", "-moz-border-end-width", ffBelow68(""), ff68up("0px")),
/** The style property {@code -moz-border-end-width}. */
- MOZ_BORDER_END_WIDTH__("-moz-border-end-width", "-moz-border-end-width", ff52up("")),
+ MOZ_BORDER_END_WIDTH__("-moz-border-end-width", "-moz-border-end-width", ffBelow68(""), ff68up("0px")),
/** The style property {@code MozBorderImage}. */
MOZ_BORDER_IMAGE("MozBorderImage", "-moz-border-image", ff("")),
/** The style property {@code -moz-border-image}. */
- MOZ_BORDER_IMAGE__("-moz-border-image", "-moz-border-image", ff52up("")),
+ MOZ_BORDER_IMAGE__("-moz-border-image", "-moz-border-image", ff("")),
/** The style property {@code MozBorderLeftColors}. */
- MOZ_BORDER_LEFT_COLORS("MozBorderLeftColors", "-moz-border-left-colors", ff("none")),
+ MOZ_BORDER_LEFT_COLORS("MozBorderLeftColors", "-moz-border-left-colors",
+ ff("none").setIteratable(false)),
/** The style property {@code -moz-border-left-colors}. */
- MOZ_BORDER_LEFT_COLORS__("-moz-border-left-colors", "-moz-border-left-colors", ff52up("none")),
+ MOZ_BORDER_LEFT_COLORS__("-moz-border-left-colors", "-moz-border-left-colors",
+ ff("none").setIteratable(false)),
/** The style property {@code MozBorderRadius}. */
MOZ_BORDER_RADIUS("MozBorderRadius", "-moz-border-radius"),
@@ -1506,76 +1748,81 @@ public enum Definition {
MOZ_BORDER_RADIUS_TOPRIGHT("MozBorderRadiusTopright", "-moz-border-radius-topright"),
/** The style property {@code MozBorderRightColors}. */
- MOZ_BORDER_RIGHT_COLORS("MozBorderRightColors", "-moz-border-right-colors", ff("none")),
+ MOZ_BORDER_RIGHT_COLORS("MozBorderRightColors", "-moz-border-right-colors",
+ ff("none").setIteratable(false)),
/** The style property {@code -moz-border-right-colors}. */
- MOZ_BORDER_RIGHT_COLORS__("-moz-border-right-colors", "-moz-border-right-colors", ff52up("none")),
+ MOZ_BORDER_RIGHT_COLORS__("-moz-border-right-colors", "-moz-border-right-colors",
+ ff("none").setIteratable(false)),
/** The style property {@code MozBorderStart}. */
MOZ_BORDER_START("MozBorderStart", "-moz-border-start", ff("")),
/** The style property {@code -moz-border-start}. */
- MOZ_BORDER_START__("-moz-border-start", "-moz-border-start", ff52up("")),
+ MOZ_BORDER_START__("-moz-border-start", "-moz-border-start", ff("")),
/** The style property {@code MozBorderStartColor}. */
- MOZ_BORDER_START_COLOR("MozBorderStartColor", "-moz-border-start-color", ff("")),
+ MOZ_BORDER_START_COLOR("MozBorderStartColor", "-moz-border-start-color", ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code -moz-border-start-color}. */
- MOZ_BORDER_START_COLOR__("-moz-border-start-color", "-moz-border-start-color", ff52up("")),
+ MOZ_BORDER_START_COLOR__("-moz-border-start-color", "-moz-border-start-color",
+ ffBelow68(""), ff68up("rgb(0, 0, 0)")),
/** The style property {@code MozBorderStartStyle}. */
- MOZ_BORDER_START_STYLE("MozBorderStartStyle", "-moz-border-start-style", ff("")),
+ MOZ_BORDER_START_STYLE("MozBorderStartStyle", "-moz-border-start-style", ffBelow68(""), ff68up("none")),
/** The style property {@code -moz-border-start-style}. */
- MOZ_BORDER_START_STYLE__("-moz-border-start-style", "-moz-border-start-style", ff52up("")),
+ MOZ_BORDER_START_STYLE__("-moz-border-start-style", "-moz-border-start-style", ffBelow68(""), ff68up("none")),
/** The style property {@code MozBorderStartWidth}. */
- MOZ_BORDER_START_WIDTH("MozBorderStartWidth", "-moz-border-start-width", ff("")),
+ MOZ_BORDER_START_WIDTH("MozBorderStartWidth", "-moz-border-start-width", ffBelow68(""), ff68up("0px")),
/** The style property {@code -moz-border-start-width}. */
- MOZ_BORDER_START_WIDTH__("-moz-border-start-width", "-moz-border-start-width", ff52up("")),
+ MOZ_BORDER_START_WIDTH__("-moz-border-start-width", "-moz-border-start-width", ffBelow68(""), ff68up("0px")),
/** The style property {@code MozBorderTopColors}. */
- MOZ_BORDER_TOP_COLORS("MozBorderTopColors", "-moz-border-top-colors", ff("none")),
+ MOZ_BORDER_TOP_COLORS("MozBorderTopColors", "-moz-border-top-colors",
+ ff("none").setIteratable(false)),
/** The style property {@code -moz-border-top-colors}. */
- MOZ_BORDER_TOP_COLORS__("-moz-border-top-colors", "-moz-border-top-colors", ff52up("none")),
+ MOZ_BORDER_TOP_COLORS__("-moz-border-top-colors", "-moz-border-top-colors",
+ ff("none").setIteratable(false)),
/** The style property {@code MozBoxAlign}. */
MOZ_BOX_ALIGN("MozBoxAlign", "-moz-box-align", ff("stretch")),
/** The style property {@code -moz-box-align}. */
- MOZ_BOX_ALIGN__("-moz-box-align", "-moz-box-align", ff52up("stretch")),
+ MOZ_BOX_ALIGN__("-moz-box-align", "-moz-box-align", ff("stretch")),
/** The style property {@code MozBoxDirection}. */
MOZ_BOX_DIRECTION("MozBoxDirection", "-moz-box-direction", ff("normal")),
/** The style property {@code -moz-box-direction}. */
- MOZ_BOX_DIRECTION__("-moz-box-direction", "-moz-box-direction", ff52up("normal")),
+ MOZ_BOX_DIRECTION__("-moz-box-direction", "-moz-box-direction", ff("normal")),
/** The style property {@code MozBoxFlex}. */
MOZ_BOX_FLEX("MozBoxFlex", "-moz-box-flex", ff("0")),
/** The style property {@code -moz-box-flex}. */
- MOZ_BOX_FLEX__("-moz-box-flex", "-moz-box-flex", ff52up("0")),
+ MOZ_BOX_FLEX__("-moz-box-flex", "-moz-box-flex", ff("0")),
/** The style property {@code MozBoxOrdinalGroup}. */
MOZ_BOX_ORDINAL_GROUP("MozBoxOrdinalGroup", "-moz-box-ordinal-group", ff("1")),
/** The style property {@code -moz-box-ordinal-group}. */
- MOZ_BOX_ORDINAL_GROUP__("-moz-box-ordinal-group", "-moz-box-ordinal-group", ff52up("1")),
+ MOZ_BOX_ORDINAL_GROUP__("-moz-box-ordinal-group", "-moz-box-ordinal-group", ff("1")),
/** The style property {@code MozBoxOrient}. */
MOZ_BOX_ORIENT("MozBoxOrient", "-moz-box-orient", ff("horizontal")),
/** The style property {@code -moz-box-orient}. */
- MOZ_BOX_ORIENT__("-moz-box-orient", "-moz-box-orient", ff52up("horizontal")),
+ MOZ_BOX_ORIENT__("-moz-box-orient", "-moz-box-orient", ff("horizontal")),
/** The style property {@code MozBoxPack}. */
MOZ_BOX_PACK("MozBoxPack", "-moz-box-pack", ff("start")),
/** The style property {@code -moz-box-pack}. */
- MOZ_BOX_PACK__("-moz-box-pack", "-moz-box-pack", ff52up("start")),
+ MOZ_BOX_PACK__("-moz-box-pack", "-moz-box-pack", ff("start")),
/** The style property {@code MozBoxShadow}. */
MOZ_BOX_SHADOW("MozBoxShadow", "-moz-box-shadow"),
@@ -1584,31 +1831,31 @@ public enum Definition {
MOZ_BOX_SIZING("MozBoxSizing", "-moz-box-sizing", ff("content-box")),
/** The style property {@code -moz-box-sizing}. */
- MOZ_BOX_SIZING__("-moz-box-sizing", "-moz-box-sizing", ff52up("content-box")),
+ MOZ_BOX_SIZING__("-moz-box-sizing", "-moz-box-sizing", ff("content-box")),
/** The style property {@code MozColumnCount}. */
MOZ_COLUMN_COUNT("MozColumnCount", "-moz-column-count", ff("auto")),
/** The style property {@code -moz-column-count}. */
- MOZ_COLUMN_COUNT__("-moz-column-count", "-moz-column-count", ff52up("auto")),
+ MOZ_COLUMN_COUNT__("-moz-column-count", "-moz-column-count", ff("auto")),
/** The style property {@code MozColumnFill}. */
MOZ_COLUMN_FILL("MozColumnFill", "-moz-column-fill", ff("balance")),
/** The style property {@code -moz-column-fill}. */
- MOZ_COLUMN_FILL__("-moz-column-fill", "-moz-column-fill", ff52up("balance")),
+ MOZ_COLUMN_FILL__("-moz-column-fill", "-moz-column-fill", ff("balance")),
/** The style property {@code MozColumnGap}. */
- MOZ_COLUMN_GAP("MozColumnGap", "-moz-column-gap", ff("16px")),
+ MOZ_COLUMN_GAP("MozColumnGap", "-moz-column-gap", ff("normal")),
/** The style property {@code -moz-column-gap}. */
- MOZ_COLUMN_GAP__("-moz-column-gap", "-moz-column-gap", ff52up("16px")),
+ MOZ_COLUMN_GAP__("-moz-column-gap", "-moz-column-gap", ff("normal")),
/** The style property {@code MozColumnRule}. */
MOZ_COLUMN_RULE("MozColumnRule", "-moz-column-rule", ff("")),
/** The style property {@code -moz-column-rule}. */
- MOZ_COLUMN_RULE__("-moz-column-rule", "-moz-column-rule", ff52up("")),
+ MOZ_COLUMN_RULE__("-moz-column-rule", "-moz-column-rule", ff("")),
/** The style property {@code MozColumnRuleColor}. */
MOZ_COLUMN_RULE_COLOR("MozColumnRuleColor", "-moz-column-rule-color",
@@ -1616,7 +1863,7 @@ public enum Definition {
/** The style property {@code -moz-column-rule-color}. */
MOZ_COLUMN_RULE_COLOR__("-moz-column-rule-color", "-moz-column-rule-color",
- ff52up("rgb(0, 0, 0)")),
+ ff("rgb(0, 0, 0)")),
/** The style property {@code MozColumnRuleStyle}. */
MOZ_COLUMN_RULE_STYLE("MozColumnRuleStyle", "-moz-column-rule-style",
@@ -1624,7 +1871,7 @@ public enum Definition {
/** The style property {@code -moz-column-rule-style}. */
MOZ_COLUMN_RULE_STYLE__("-moz-column-rule-style", "-moz-column-rule-style",
- ff52up("none")),
+ ff("none")),
/** The style property {@code MozColumnRuleWidth}. */
MOZ_COLUMN_RULE_WIDTH("MozColumnRuleWidth", "-moz-column-rule-width",
@@ -1632,25 +1879,25 @@ public enum Definition {
/** The style property {@code -moz-column-rule-width}. */
MOZ_COLUMN_RULE_WIDTH__("-moz-column-rule-width", "-moz-column-rule-width",
- ff52up("0px")),
+ ff("0px")),
/** The style property {@code MozColumnWidth}. */
MOZ_COLUMN_WIDTH("MozColumnWidth", "-moz-column-width", ff("auto")),
/** The style property {@code -moz-column-width}. */
- MOZ_COLUMN_WIDTH__("-moz-column-width", "-moz-column-width", ff52up("auto")),
+ MOZ_COLUMN_WIDTH__("-moz-column-width", "-moz-column-width", ff("auto")),
/** The style property {@code MozColumns}. */
MOZ_COLUMNS("MozColumns", "-moz-columns", ff("")),
/** The style property {@code -moz-columns}. */
- MOZ_COLUMNS__("-moz-columns", "-moz-columns", ff52up("")),
+ MOZ_COLUMNS__("-moz-columns", "-moz-columns", ff("")),
/** The style property {@code MozFloatEdge}. */
MOZ_FLOAT_EDGE("MozFloatEdge", "-moz-float-edge", ff("content-box")),
/** The style property {@code -moz-float-edge}. */
- MOZ_FLOAT_EDGE__("-moz-float-edge", "-moz-float-edge", ff52up("content-box")),
+ MOZ_FLOAT_EDGE__("-moz-float-edge", "-moz-float-edge", ff("content-box")),
/** The style property {@code MozFontFeatureSettings}. */
MOZ_FONT_FEATURE_SETTINGS("MozFontFeatureSettings", "-moz-font-feature-settings",
@@ -1658,7 +1905,7 @@ public enum Definition {
/** The style property {@code -moz-font-feature-settings}. */
MOZ_FONT_FEATURE_SETTINGS__("-moz-font-feature-settings", "-moz-font-feature-settings",
- ff52up("normal")),
+ ff("normal")),
/** The style property {@code MozFontLanguageOverride}. */
MOZ_FONT_LANGUAGE_OVERRIDE("MozFontLanguageOverride", "-moz-font-language-override",
@@ -1666,7 +1913,7 @@ public enum Definition {
/** The style property {@code -moz-font-language-override}. */
MOZ_FONT_LANGUAGE_OVERRIDE__("-moz-font-language-override", "-moz-font-language-override",
- ff52up("normal")),
+ ff("normal")),
/** The style property {@code MozForceBrokenImageIcon}. */
MOZ_FORCE_BROKEN_IMAGE_ICON("MozForceBrokenImageIcon", "-moz-force-broken-image-icon",
@@ -1674,31 +1921,31 @@ public enum Definition {
/** The style property {@code -moz-force-broken-image-icon}. */
MOZ_FORCE_BROKEN_IMAGE_ICON__("-moz-force-broken-image-icon", "-moz-force-broken-image-icon",
- ff52up("0")),
+ ff("0")),
/** The style property {@code MozHyphens}. */
MOZ_HYPHENS("MozHyphens", "-moz-hyphens", ff("manual")),
/** The style property {@code -moz-hyphens}. */
- MOZ_HYPHENS__("-moz-hyphens", "-moz-hyphens", ff52up("manual")),
+ MOZ_HYPHENS__("-moz-hyphens", "-moz-hyphens", ff("manual")),
/** The style property {@code MozImageRegion}. */
MOZ_IMAGE_REGION("MozImageRegion", "-moz-image-region", ff("auto")),
/** The style property {@code -moz-image-region}. */
- MOZ_IMAGE_REGION__("-moz-image-region", "-moz-image-region", ff52up("auto")),
+ MOZ_IMAGE_REGION__("-moz-image-region", "-moz-image-region", ff("auto")),
/** The style property {@code MozMarginEnd}. */
- MOZ_MARGIN_END("MozMarginEnd", "-moz-margin-end", ff("")),
+ MOZ_MARGIN_END("MozMarginEnd", "-moz-margin-end", ffBelow68(""), ff68up("0px")),
/** The style property {@code -moz-margin-end}. */
- MOZ_MARGIN_END__("-moz-margin-end", "-moz-margin-end", ff52up("")),
+ MOZ_MARGIN_END__("-moz-margin-end", "-moz-margin-end", ffBelow68(""), ff68up("0px")),
/** The style property {@code MozMarginStart}. */
- MOZ_MARGIN_START("MozMarginStart", "-moz-margin-start", ff("")),
+ MOZ_MARGIN_START("MozMarginStart", "-moz-margin-start", ffBelow68(""), ff68up("0px")),
/** The style property {@code -moz-margin-start}. */
- MOZ_MARGIN_START__("-moz-margin-start", "-moz-margin-start", ff52up("")),
+ MOZ_MARGIN_START__("-moz-margin-start", "-moz-margin-start", ffBelow68(""), ff68up("0px")),
/** The style property {@code MozOpacity}. */
MOZ_OPACITY("MozOpacity", "-moz-opacity"),
@@ -1707,7 +1954,7 @@ public enum Definition {
MOZ_ORIENT("MozOrient", "-moz-orient", ff("inline")),
/** The style property {@code -moz-orient}. */
- MOZ_ORIENT__("-moz-orient", "-moz-orient", ff52up("inline")),
+ MOZ_ORIENT__("-moz-orient", "-moz-orient", ff("inline")),
/** The style property {@code MozOutline}. */
MOZ_OUTLINE("MozOutline", "-moz-outline"),
@@ -1722,7 +1969,7 @@ public enum Definition {
MOZ_OUTLINE_RADIUS("MozOutlineRadius", "-moz-outline-radius", ff("")),
/** The style property {@code -moz-outline-radius}. */
- MOZ_OUTLINE_RADIUS__("-moz-outline-radius", "-moz-outline-radius", ff52up("")),
+ MOZ_OUTLINE_RADIUS__("-moz-outline-radius", "-moz-outline-radius", ff("")),
/** The style property {@code MozOutlineRadiusBottomleft}. */
MOZ_OUTLINE_RADIUS_BOTTOMLEFT("MozOutlineRadiusBottomleft",
@@ -1730,7 +1977,7 @@ public enum Definition {
/** The style property {@code -moz-outline-radius-bottomleft}. */
MOZ_OUTLINE_RADIUS_BOTTOMLEFT__("-moz-outline-radius-bottomleft",
- "-moz-outline-radius-bottomleft", ff52up("0px")),
+ "-moz-outline-radius-bottomleft", ff("0px")),
/** The style property {@code MozOutlineRadiusBottomright}. */
MOZ_OUTLINE_RADIUS_BOTTOMRIGHT("MozOutlineRadiusBottomright",
@@ -1738,7 +1985,7 @@ public enum Definition {
/** The style property {@code -moz-outline-radius-bottomright}. */
MOZ_OUTLINE_RADIUS_BOTTOMRIGHT__("-moz-outline-radius-bottomright",
- "-moz-outline-radius-bottomright", ff52up("0px")),
+ "-moz-outline-radius-bottomright", ff("0px")),
/** The style property {@code MozOutlineRadiusTopleft}. */
MOZ_OUTLINE_RADIUS_TOPLEFT("MozOutlineRadiusTopleft",
@@ -1746,7 +1993,7 @@ public enum Definition {
/** The style property {@code -moz-outline-radius-topleft}. */
MOZ_OUTLINE_RADIUS_TOPLEFT__("-moz-outline-radius-topleft",
- "-moz-outline-radius-topleft", ff52up("0px")),
+ "-moz-outline-radius-topleft", ff("0px")),
/** The style property {@code MozOutlineRadiusTopright}. */
MOZ_OUTLINE_RADIUS_TOPRIGHT("MozOutlineRadiusTopright",
@@ -1754,7 +2001,7 @@ public enum Definition {
/** The style property {@code -moz-outline-radius-topright}. */
MOZ_OUTLINE_RADIUS_TOPRIGHT__("-moz-outline-radius-topright",
- "-moz-outline-radius-topright", ff52up("0px")),
+ "-moz-outline-radius-topright", ff("0px")),
/** The style property {@code MozOutlineStyle}. */
MOZ_OUTLINE_STYLE("MozOutlineStyle", "-moz-outline-style"),
@@ -1763,50 +2010,50 @@ public enum Definition {
MOZ_OUTLINE_WIDTH("MozOutlineWidth", "-moz-outline-width"),
/** The style property {@code MozPaddingEnd}. */
- MOZ_PADDING_END("MozPaddingEnd", "-moz-padding-end", ff("")),
+ MOZ_PADDING_END("MozPaddingEnd", "-moz-padding-end", ffBelow68(""), ff68up("0px")),
/** The style property {@code -moz-padding-end}. */
- MOZ_PADDING_END__("-moz-padding-end", "-moz-padding-end", ff52up("")),
+ MOZ_PADDING_END__("-moz-padding-end", "-moz-padding-end", ffBelow68(""), ff68up("0px")),
/** The style property {@code MozPaddingStart}. */
- MOZ_PADDING_START("MozPaddingStart", "-moz-padding-start", ff("")),
+ MOZ_PADDING_START("MozPaddingStart", "-moz-padding-start", ffBelow68(""), ff68up("0px")),
/** The style property {@code -moz-padding-start}. */
- MOZ_PADDING_START__("-moz-padding-start", "-moz-padding-start", ff52up("")),
+ MOZ_PADDING_START__("-moz-padding-start", "-moz-padding-start", ffBelow68(""), ff68up("0px")),
/** The style property {@code MozPerspective}. */
MOZ_PERSPECTIVE("MozPerspective", "-moz-perspective", ff("none")),
/** The style property {@code -moz-perspective}. */
- MOZ_PERSPECTIVE__("-moz-perspective", "-moz-perspective", ff52up("none")),
+ MOZ_PERSPECTIVE__("-moz-perspective", "-moz-perspective", ff("none")),
/** The style property {@code MozPerspectiveOrigin}. */
MOZ_PERSPECTIVE_ORIGIN("MozPerspectiveOrigin",
- "-moz-perspective-origin", ffBelow52("705px 172.5px"), ff52up("625px 172.5px")),
+ "-moz-perspective-origin", ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code -moz-perspective-origin}. */
MOZ_PERSPECTIVE_ORIGIN__("-moz-perspective-origin",
- "-moz-perspective-origin", ff52up("625px 172.5px")),
+ "-moz-perspective-origin", ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code MozStackSizing}. */
MOZ_STACK_SIZING("MozStackSizing", "-moz-stack-sizing", ff("stretch-to-fit")),
/** The style property {@code -moz-stack-sizing}. */
- MOZ_STACK_SIZING__("-moz-stack-sizing", "-moz-stack-sizing", ff52up("stretch-to-fit")),
+ MOZ_STACK_SIZING__("-moz-stack-sizing", "-moz-stack-sizing", ff("stretch-to-fit")),
/** The style property {@code MozTabSize}. */
MOZ_TAB_SIZE("MozTabSize", "-moz-tab-size", ff("8")),
/** The style property {@code -moz-tab-size}. */
- MOZ_TAB_SIZE__("-moz-tab-size", "-moz-tab-size", ff52up("8")),
+ MOZ_TAB_SIZE__("-moz-tab-size", "-moz-tab-size", ff("8")),
/** The style property {@code MozTextAlignLast}. */
MOZ_TEXT_ALIGN_LAST("MozTextAlignLast", "-moz-text-align-last",
- ff("auto")),
+ ff("auto").setIteratable(false)),
/** The style property {@code -moz-text-align-last}. */
MOZ_TEXT_ALIGN_LAST__("-moz-text-align-last", "-moz-text-align-last",
- ff52up("auto")),
+ ff("auto").setIteratable(false)),
/** The style property {@code MozTextSizeAdjust}. */
MOZ_TEXT_SIZE_ADJUST("MozTextSizeAdjust", "-moz-text-size-adjust",
@@ -1814,21 +2061,21 @@ public enum Definition {
/** The style property {@code -moz-text-size-adjust}. */
MOZ_TEXT_SIZE_ADJUST__("-moz-text-size-adjust", "-moz-text-size-adjust",
- ff52up("auto")),
+ ff("auto")),
/** The style property {@code MozTransform}. */
MOZ_TRANSFORM("MozTransform", "-moz-transform", ff("none")),
/** The style property {@code -moz-transform}. */
- MOZ_TRANSFORM__("-moz-transform", "-moz-transform", ff52up("none")),
+ MOZ_TRANSFORM__("-moz-transform", "-moz-transform", ff("none")),
/** The style property {@code MozTransformOrigin}. */
MOZ_TRANSFORM_ORIGIN("MozTransformOrigin", "-moz-transform-origin",
- ffBelow52("705px 172.5px"), ff52up("625px 172.5px")),
+ ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code -moz-transform-origin}. */
MOZ_TRANSFORM_ORIGIN__("-moz-transform-origin", "-moz-transform-origin",
- ff52up("625px 172.5px")),
+ ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code MozTransformStyle}. */
MOZ_TRANSFORM_STYLE("MozTransformStyle", "-moz-transform-style",
@@ -1836,13 +2083,13 @@ public enum Definition {
/** The style property {@code -moz-transform-style}. */
MOZ_TRANSFORM_STYLE__("-moz-transform-style", "-moz-transform-style",
- ff52up("flat")),
+ ff("flat")),
/** The style property {@code MozTransition}. */
MOZ_TRANSITION("MozTransition", "-moz-transition", ff("")),
/** The style property {@code -moz-transition}. */
- MOZ_TRANSITION__("-moz-transition", "-moz-transition", ff52up("")),
+ MOZ_TRANSITION__("-moz-transition", "-moz-transition", ff("")),
/** The style property {@code MozTransitionDelay}. */
MOZ_TRANSITION_DELAY("MozTransitionDelay", "-moz-transition-delay",
@@ -1850,7 +2097,7 @@ public enum Definition {
/** The style property {@code -moz-transition-delay}. */
MOZ_TRANSITION_DELAY__("-moz-transition-delay", "-moz-transition-delay",
- ff52up("0s")),
+ ff("0s")),
/** The style property {@code MozTransitionDuration}. */
MOZ_TRANSITION_DURATION("MozTransitionDuration", "-moz-transition-duration",
@@ -1858,7 +2105,7 @@ public enum Definition {
/** The style property {@code -moz-transition-duration}. */
MOZ_TRANSITION_DURATION__("-moz-transition-duration", "-moz-transition-duration",
- ff52up("0s")),
+ ff("0s")),
/** The style property {@code MozTransitionProperty}. */
MOZ_TRANSITION_PROPERTY("MozTransitionProperty", "-moz-transition-property",
@@ -1866,7 +2113,7 @@ public enum Definition {
/** The style property {@code -moz-transition-property}. */
MOZ_TRANSITION_PROPERTY__("-moz-transition-property", "-moz-transition-property",
- ff52up("all")),
+ ff("all")),
/** The style property {@code MozTransitionTimingFunction}. */
MOZ_TRANSITION_TIMING_FUNCTION("MozTransitionTimingFunction",
@@ -1874,37 +2121,37 @@ public enum Definition {
/** The style property {@code -moz-transition-timing-function}. */
MOZ_TRANSITION_TIMING_FUNCTION__("-moz-transition-timing-function",
- "-moz-transition-timing-function", ff52up("ease")),
+ "-moz-transition-timing-function", ff("ease")),
/** The style property {@code MozUserFocus}. */
MOZ_USER_FOCUS("MozUserFocus", "-moz-user-focus", ff("none")),
/** The style property {@code -moz-user-focus}. */
- MOZ_USER_FOCUS__("-moz-user-focus", "-moz-user-focus", ff52up("none")),
+ MOZ_USER_FOCUS__("-moz-user-focus", "-moz-user-focus", ff("none")),
/** The style property {@code MozUserInput}. */
MOZ_USER_INPUT("MozUserInput", "-moz-user-input", ff("auto")),
/** The style property {@code -moz-user-input}. */
- MOZ_USER_INPUT__("-moz-user-input", "-moz-user-input", ff52up("auto")),
+ MOZ_USER_INPUT__("-moz-user-input", "-moz-user-input", ff("auto")),
/** The style property {@code MozUserModify}. */
MOZ_USER_MODIFY("MozUserModify", "-moz-user-modify", ff("read-only")),
/** The style property {@code -moz-user-modify}. */
- MOZ_USER_MODIFY__("-moz-user-modify", "-moz-user-modify", ff52up("read-only")),
+ MOZ_USER_MODIFY__("-moz-user-modify", "-moz-user-modify", ff("read-only")),
/** The style property {@code MozUserSelect}. */
MOZ_USER_SELECT("MozUserSelect", "-moz-user-select", ff("auto")),
/** The style property {@code -moz-user-select}. */
- MOZ_USER_SELECT__("-moz-user-select", "-moz-user-select", ff52up("auto")),
+ MOZ_USER_SELECT__("-moz-user-select", "-moz-user-select", ff("auto")),
/** The style property {@code MozWindowDragging}. */
- MOZ_WINDOW_DRAGGING("MozWindowDragging", "-moz-window-dragging", ffBelow52("no-drag"), ff52up("default")),
+ MOZ_WINDOW_DRAGGING("MozWindowDragging", "-moz-window-dragging", ff("default")),
/** The style property {@code -moz-window-dragging}. */
- MOZ_WINDOW_DRAGGING__("-moz-window-dragging", "-moz-window-dragging", ff52up("default")),
+ MOZ_WINDOW_DRAGGING__("-moz-window-dragging", "-moz-window-dragging", ff("default")),
/** The style property {@code msAnimation}. */
MS_ANIMATION("msAnimation", "-ms-animation", ie("")),
@@ -2183,31 +2430,31 @@ public enum Definition {
OFFSET("offset", "offset", chrome("none 0px auto 0deg")),
/** The style property {@code offsetBlockEnd}. */
- OFFSET_BLOCK_END("offsetBlockEnd", "offset-block-end", ff("")),
+ OFFSET_BLOCK_END("offsetBlockEnd", "offset-block-end", ffBelow68("")),
/** The style property {@code offset-block-end}. */
- OFFSET_BLOCK_END_("offset-block-end", "offset-block-end", ff("")),
+ OFFSET_BLOCK_END_("offset-block-end", "offset-block-end", ffBelow68("")),
/** The style property {@code offsetBlockStart}. */
- OFFSET_BLOCK_START("offsetBlockStart", "offset-block-start", ff("")),
+ OFFSET_BLOCK_START("offsetBlockStart", "offset-block-start", ffBelow68("")),
/** The style property {@code offset-block-start}. */
- OFFSET_BLOCK_START_("offset-block-start", "offset-block-start", ff("")),
+ OFFSET_BLOCK_START_("offset-block-start", "offset-block-start", ffBelow68("")),
/** The style property {@code offsetDistance}. */
OFFSET_DISTANCE("offsetDistance", "offsetDistance", chrome("0px")),
/** The style property {@code offsetInlineEnd}. */
- OFFSET_INLINE_END("offsetInlineEnd", "offset-inline-end", ff("")),
+ OFFSET_INLINE_END("offsetInlineEnd", "offset-inline-end", ffBelow68("")),
/** The style property {@code offset-inline-end}. */
- OFFSET_INLINE_END_("offset-inline-end", "offset-inline-end", ff("")),
+ OFFSET_INLINE_END_("offset-inline-end", "offset-inline-end", ffBelow68("")),
/** The style property {@code offsetInlineStart}. */
- OFFSET_INLINE_START("offsetInlineStart", "offset-inline-start", ff("")),
+ OFFSET_INLINE_START("offsetInlineStart", "offset-inline-start", ffBelow68("")),
/** The style property {@code offset-inline-start}. */
- OFFSET_INLINE_START_("offset-inline-start", "offset-inline-start", ff("")),
+ OFFSET_INLINE_START_("offset-inline-start", "offset-inline-start", ffBelow68("")),
/** The style property {@code offsetPath}. */
OFFSET_PATH("offsetPath", "offsetPath", chrome("none")),
@@ -2259,13 +2506,16 @@ public enum Definition {
OVERFLOW("overflow", "overflow", chrome("visible"), ff("visible"), ie("visible")),
/** The style property {@code overflowAnchor}. */
- OVERFLOW_ANCHOR("overflowAnchor", "overflow-anchor", chrome("auto")),
+ OVERFLOW_ANCHOR("overflowAnchor", "overflow-anchor", chrome("auto"), ff68up("auto")),
+
+ /** The style property {@code overflow-anchor}. */
+ OVERFLOW_ANCHOR_("overflow-anchor", "overflow-anchor", ff68up("auto")),
/** The style property {@code overflowWrap}. */
- OVERFLOW_WRAP("overflowWrap", "overflow-wrap", chrome("normal"), ff52up("normal")),
+ OVERFLOW_WRAP("overflowWrap", "overflow-wrap", chrome("normal"), ff("normal")),
/** The style property {@code overflow-wrap}. */
- OVERFLOW_WRAP_("overflow-wrap", "overflow-wrap", ff52up("normal")),
+ OVERFLOW_WRAP_("overflow-wrap", "overflow-wrap", ff("normal")),
/** The style property {@code overflowX}. */
OVERFLOW_X("overflowX", "overflow-x", chrome("visible"), ff("visible"), ie("visible")),
@@ -2280,28 +2530,50 @@ public enum Definition {
OVERFLOW_Y_("overflow-y", "overflow-y", ff("visible")),
/** The style property {@code overscrollBehavior}. */
- OVERSCROLL_BEHAVIOR("overscrollBehavior", "overscroll-behavior", chrome("auto auto")),
+ OVERSCROLL_BEHAVIOR("overscrollBehavior", "overscroll-behavior", chrome("auto"), ff("")),
+
+ /** The style property {@code overscroll-behavior}. */
+ OVERSCROLL_BEHAVIOR_("overscroll-behavior", "overscroll-behavior", ff("")),
+
+ /** The style property {@code overscrollBehaviorBlock}. */
+ OVERSCROLL_BEHAVIOR_BLOCK("overscrollBehaviorBlock", "overscroll-behavior-block", chrome("auto")),
+
+ /** The style property {@code overscrollBehaviorInline}. */
+ OVERSCROLL_BEHAVIOR_INLINR("overscrollBehaviorInline", "overscroll-behavior-inline", chrome("auto")),
/** The style property {@code overscrollBehaviorX}. */
- OVERSCROLL_BEHAVIOR_X("overscrollBehaviorX", "overscroll-behavior_x", chrome("auto")),
+ OVERSCROLL_BEHAVIOR_X("overscrollBehaviorX", "overscroll-behavior-x", chrome("auto"), ff("auto")),
+
+ /** The style property {@code overscroll-behavior-x}. */
+ OVERSCROLL_BEHAVIOR_X_("overscroll-behavior-x", "overscroll-behavior-x", ff("auto")),
/** The style property {@code overscrollBehaviorY}. */
- OVERSCROLL_BEHAVIOR_Y("overscrollBehaviorY", "overscroll-behavior_y", chrome("auto")),
+ OVERSCROLL_BEHAVIOR_Y("overscrollBehaviorY", "overscroll-behavior-y", chrome("auto"), ff("auto")),
+
+ /** The style property {@code overscroll-behavior-y}. */
+ OVERSCROLL_BEHAVIOR_Y_("overscroll-behavior-y", "overscroll-behavior-y", ff("auto")),
/** The style property {@code padding}. */
PADDING("padding", "padding", chrome("0px"), ff(""), ie("")),
+ /** The style property {@code paddingBlock}. */
+ PADDING_BLOCK("paddingBlock", "padding-block", ff68up("")),
+
+ /** The style property {@code padding-block}. */
+ PADDING_BLOCK_("padding-block", "padding-block", ff68up("")),
+
/** The style property {@code paddingBlockEnd}. */
- PADDING_BLOCK_END("paddingBlockEnd", "padding-block-end", ff("")),
+ PADDING_BLOCK_END("paddingBlockEnd", "padding-block-end", chrome("0px"),
+ ffBelow68(""), ff68up("0px")),
/** The style property {@code padding-block-end}. */
- PADDING_BLOCK_END_("padding-block-end", "padding-block-end", ff("")),
+ PADDING_BLOCK_END_("padding-block-end", "padding-block-end", ffBelow68(""), ff68up("0px")),
/** The style property {@code paddingBlockStart}. */
- PADDING_BLOCK_START("paddingBlockStart", "padding-block-start", ff("")),
+ PADDING_BLOCK_START("paddingBlockStart", "padding-block-start", chrome("0px"), ffBelow68(""), ff68up("0px")),
/** The style property {@code padding-block-start}. */
- PADDING_BLOCK_START_("padding-block-start", "padding-block-start", ff("")),
+ PADDING_BLOCK_START_("padding-block-start", "padding-block-start", ffBelow68(""), ff68up("0px")),
/** The style property {@code paddingBottom}. */
PADDING_BOTTOM("paddingBottom", "padding-bottom", chrome("0px"), ff(""), ie("")),
@@ -2309,17 +2581,23 @@ public enum Definition {
/** The style property {@code padding-bottom}. */
PADDING_BOTTOM_("padding-bottom", "padding-bottom", ff("0px")),
+ /** The style property {@code paddingInline}. */
+ PADDING_INLINE("paddingInline", "padding-inline", ff68up("")),
+
+ /** The style property {@code padding-inline}. */
+ PADDING_INLINE_("padding-inline", "padding-inline", ff68up("")),
+
/** The style property {@code paddingInlineEnd}. */
- PADDING_INLINE_END("paddingInlineEnd", "padding-inline-end", ff("")),
+ PADDING_INLINE_END("paddingInlineEnd", "padding-inline-end", chrome("0px"), ffBelow68(""), ff68up("0px")),
/** The style property {@code padding-inline-end}. */
- PADDING_INLINE_END_("padding-inline-end", "padding-inline-end", ff("")),
+ PADDING_INLINE_END_("padding-inline-end", "padding-inline-end", ffBelow68(""), ff68up("0px")),
/** The style property {@code paddingInlineStart}. */
- PADDING_INLINE_START("paddingInlineStart", "padding-inline-start", ff("")),
+ PADDING_INLINE_START("paddingInlineStart", "padding-inline-start", chrome("0px"), ffBelow68(""), ff68up("0px")),
/** The style property {@code padding-inline-start}. */
- PADDING_INLINE_START_("padding-inline-start", "padding-inline-start", ff("")),
+ PADDING_INLINE_START_("padding-inline-start", "padding-inline-start", ffBelow68(""), ff68up("0px")),
/** The style property {@code paddingLeft}. */
PADDING_LEFT("paddingLeft", "padding-left", chrome("0px"), ff(""), ie("")),
@@ -2361,7 +2639,7 @@ public enum Definition {
PAGE_BREAK_INSIDE_("page-break-inside", "page-break-inside", ff("auto")),
/** The style property {@code paintOrder}. */
- PAINT_ORDER("paintOrder", "paint-order", ff("normal"), chrome("fill stroke markers")),
+ PAINT_ORDER("paintOrder", "paint-order", ff("normal"), chrome("normal")),
/** The style property {@code paint-order}. */
PAINT_ORDER_("paint-order", "paint-order", ff("normal")),
@@ -2380,11 +2658,11 @@ public enum Definition {
/** The style property {@code perspectiveOrigin}. */
PERSPECTIVE_ORIGIN("perspectiveOrigin", "perspective-origin",
- ffBelow52("705px 172.5px"), ff52up("625px 172.5px"), ie("620px 163.2px"), chrome("456.5px 161px")),
+ ffBelow68("625px 172.5px"), ff68up("621px 171.5px"), ie("620px 163.2px"), chrome("456.5px 161px")),
/** The style property {@code perspective-origin}. */
PERSPECTIVE_ORIGIN_("perspective-origin", "perspective-origin",
- ffBelow52("705px 172.5px"), ff52up("625px 172.5px")),
+ ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code pitch}. */
PITCH("pitch", "pitch"),
@@ -2393,40 +2671,40 @@ public enum Definition {
PITCH_RANGE("pitchRange", "pitch-range"),
/** The style property {@code pixelBottom}. */
- PIXEL_BOTTOM("pixelBottom", "pixel-bottom", ie("").setIteratable(false)),
+ PIXEL_BOTTOM("pixelBottom", "pixel-bottom", ie("")),
/** The style property {@code pixelHeight}. */
- PIXEL_HEIGHT("pixelHeight", "pixel-height", ie("").setIteratable(false)),
+ PIXEL_HEIGHT("pixelHeight", "pixel-height", ie("")),
/** The style property {@code pixelLeft}. */
- PIXEL_LEFT("pixelLeft", "pixel-left", ie("").setIteratable(false)),
+ PIXEL_LEFT("pixelLeft", "pixel-left", ie("")),
/** The style property {@code pixelRight}. */
- PIXEL_RIGHT("pixelRight", "pixel-right", ie("").setIteratable(false)),
+ PIXEL_RIGHT("pixelRight", "pixel-right", ie("")),
/** The style property {@code pixelTop}. */
- PIXEL_TOP("pixelTop", "pixel-top", ie("").setIteratable(false)),
+ PIXEL_TOP("pixelTop", "pixel-top", ie("")),
/** The style property {@code pixelWidth}. */
- PIXEL_WIDTH("pixelWidth", "pixel-width", ie("").setIteratable(false)),
+ PIXEL_WIDTH("pixelWidth", "pixel-width", ie("")),
/** The style property {@code placeContent}. */
- PLACE_CONTENT("placeContent", "place-content", chrome("normal normal"), ff52up("")),
+ PLACE_CONTENT("placeContent", "place-content", chrome("normal"), ff("")),
/** The style property {@code place-content}. */
- PLACE_CONTENT_("place-content", "place-content", ff52up("")),
+ PLACE_CONTENT_("place-content", "place-content", ff("")),
/** The style property {@code placeItems}. */
- PLACE_ITEMS("placeItems", "place-items", chrome("normal normal"), ff52up("")),
+ PLACE_ITEMS("placeItems", "place-items", chrome("normal"), ff("")),
/** The style property {@code place-items}. */
- PLACE_ITEMS_("place-items", "place-items", ff52up("")),
+ PLACE_ITEMS_("place-items", "place-items", ff("")),
/** The style property {@code placeSelf}. */
- PLACE_SELF("placeSelf", "place-self", chrome("auto auto"), ff52up("")),
+ PLACE_SELF("placeSelf", "place-self", chrome("auto"), ff("")),
/** The style property {@code place-self}. */
- PLACE_SELF_("place-self", "place-self", ff52up("")),
+ PLACE_SELF_("place-self", "place-self", ff("")),
/** The style property {@code pointerEvents}. */
POINTER_EVENTS("pointerEvents", "pointer-events", ie("visiblePainted"), chrome("auto"), ff("auto")),
@@ -2435,22 +2713,22 @@ public enum Definition {
POINTER_EVENTS_("pointer-events", "pointer-events", ff("auto")),
/** The style property {@code posBottom}. */
- POS_BOTTOM("posBottom", "pos-bottom", ie("").setIteratable(false)),
+ POS_BOTTOM("posBottom", "pos-bottom", ie("")),
/** The style property {@code posHeight}. */
- POS_HEIGHT("posHeight", "pos-height", ie("").setIteratable(false)),
+ POS_HEIGHT("posHeight", "pos-height", ie("")),
/** The style property {@code posLeft}. */
- POS_LEFT("posLeft", "pos-left", ie("").setIteratable(false)),
+ POS_LEFT("posLeft", "pos-left", ie("")),
/** The style property {@code posRight}. */
- POS_RIGHT("posRight", "pos-right", ie("").setIteratable(false)),
+ POS_RIGHT("posRight", "pos-right", ie("")),
/** The style property {@code posTop}. */
- POS_TOP("posTop", "pos-top", ie("").setIteratable(false)),
+ POS_TOP("posTop", "pos-top", ie("")),
/** The style property {@code posWidth}. */
- POS_WIDTH("posWidth", "pos-width", ie("").setIteratable(false)),
+ POS_WIDTH("posWidth", "pos-width", ie("")),
/** The style property {@code position}. */
POSITION("position", "position", chrome("static"), ff("static"), ie("static")),
@@ -2471,7 +2749,10 @@ public enum Definition {
RIGHT("right", "right", chrome("auto"), ff(""), ie("")),
/** The style property {@code rowGap}. */
- ROW_GAP("rowGap", "rowGap", chrome("normal")),
+ ROW_GAP("rowGap", "row-gap", chrome("normal"), ff68up("normal")),
+
+ /** The style property {@code row-gap}. */
+ ROW_GAP_("row-gap", "row-gap", ff68up("normal")),
/** The style property {@code rubyAlign}. */
RUBY_ALIGN("rubyAlign", "ruby-align", ff("space-around"), ie("")),
@@ -2500,47 +2781,194 @@ public enum Definition {
/** The style property {@code scroll-behavior}. */
SCROLL_BEHAVIOR_("scroll-behavior", "scroll-behavior", ff("auto")),
+ /** The style property {@code scrollMargin}. */
+ SCROLL_MARGIN("scrollMargin", "scroll-margin", chrome("0px"), ff68up("")),
+
+ /** The style property {@code scroll-margin}. */
+ SCROLL_MARGIN_("scroll-margin", "scroll-margin", ff68up("")),
+
+ /** The style property {@code scrollMarginBlock}. */
+ SCROLL_MARGIN_BLOCK("scrollMarginBlock", "scroll-margin-block", chrome("0px"), ff68up("")),
+
+ /** The style property {@code scroll-margin-block}. */
+ SCROLL_MARGIN_BLOCK_("scroll-margin-block", "scroll-margin-block", ff68up("")),
+
+ /** The style property {@code scrollMarginBlockEnd}. */
+ SCROLL_MARGIN_BLOCK_END("scrollMarginBlockEnd", "scroll-margin-block-end", chrome("0px"), ff68up("0px")),
+
+ /** The style property {@code scroll-margin-block-end}. */
+ SCROLL_MARGIN_BLOCK_END_("scroll-margin-block-end", "scroll-margin-block-end", ff68up("0px")),
+
+ /** The style property {@code scrollMarginBlockStart}. */
+ SCROLL_MARGIN_BLOCK_START("scrollMarginBlockStart", "scroll-margin-block-start", chrome("0px"), ff68up("0px")),
+
+ /** The style property {@code scroll-margin-block-start}. */
+ SCROLL_MARGIN_BLOCK_START_("scroll-margin-block-start", "scroll-margin-block-start", ff68up("0px")),
+
+ /** The style property {@code scrollMarginBottom}. */
+ SCROLL_MARGIN_BOTTOM("scrollMarginBottom", "scroll-margin-bottom", chrome("0px"), ff68up("0px")),
+
+ /** The style property {@code scroll-margin-bottom}. */
+ SCROLL_MARGIN_BOTTOM_("scroll-margin-bottom", "scroll-margin-bottom", ff68up("0px")),
+
+ /** The style property {@code scrollMarginInline}. */
+ SCROLL_MARGIN_INLINE("scrollMarginInline", "scroll-margin-inline", chrome("0px"), ff68up("")),
+
+ /** The style property {@code scroll-margin-inline}. */
+ SCROLL_MARGIN_INLINE_("scroll-margin-inline", "scroll-margin-inline", ff68up("")),
+
+ /** The style property {@code scrollMarginInlineEnd}. */
+ SCROLL_MARGIN_INLINE_END("scrollMarginInlineEnd", "scroll-margin-inline-end", chrome("0px"), ff68up("0px")),
+
+ /** The style property {@code scroll-margin-inline-end}. */
+ SCROLL_MARGIN_INLINE_END_("scroll-margin-inline-end", "scroll-margin-inline-end", ff68up("0px")),
+
+ /** The style property {@code scrollMarginInlineStart}. */
+ SCROLL_MARGIN_INLINE_START("scrollMarginInlineStart", "scroll-margin-inline-start",
+ chrome("0px"), ff68up("0px")),
+
+ /** The style property {@code scroll-margin-inline-start}. */
+ SCROLL_MARGIN_INLINE_START_("scroll-margin-inline-start", "scroll-margin-inline-start", ff68up("0px")),
+
+ /** The style property {@code scrollMarginLeft}. */
+ SCROLL_MARGIN_LEFT("scrollMarginLeft", "scroll-margin-left", chrome("0px"), ff68up("0px")),
+
+ /** The style property {@code scroll-margin-left}. */
+ SCROLL_MARGIN_LEFT_("scroll-margin-left", "scroll-margin-left", ff68up("0px")),
+
+ /** The style property {@code scrollMarginRight}. */
+ SCROLL_MARGIN_RIGHT("scrollMarginRight", "scroll-margin-right", chrome("0px"), ff68up("0px")),
+
+ /** The style property {@code scroll-margin-right}. */
+ SCROLL_MARGIN_RIGHT_("scroll-margin-right", "scroll-margin-right", ff68up("0px")),
+
+ /** The style property {@code scrollMarginTop}. */
+ SCROLL_MARGIN_TOP("scrollMarginTop", "scroll-margin-top", chrome("0px"), ff68up("0px")),
+
+ /** The style property {@code scroll-margin-top}. */
+ SCROLL_MARGIN_TOP_("scroll-margin-top", "scroll-margin-top", ff68up("0px")),
+
+ /** The style property {@code scrollPadding}. */
+ SCROLL_PADDING("scrollPadding", "scroll-padding", chrome("auto"), ff68up("")),
+
+ /** The style property {@code scroll-padding}. */
+ SCROLL_PADDING_("scroll-padding", "scroll-padding", ff68up("")),
+
+ /** The style property {@code scrollPaddingBlock}. */
+ SCROLL_PADDING_BLOCK("scrollPaddingBlock", "scroll-padding-block",
+ chrome("auto"), ff68up("")),
+
+ /** The style property {@code scroll-padding-block}. */
+ SCROLL_PADDING_BLOCK_("scroll-padding-block", "scroll-padding-block", ff68up("")),
+
+ /** The style property {@code scrollPaddingBlockEnd}. */
+ SCROLL_PADDING_BLOCK_END("scrollPaddingBlockEnd", "scroll-padding-block-end",
+ chrome("auto"), ff68up("auto")),
+
+ /** The style property {@code scroll-padding-block-end}. */
+ SCROLL_PADDING_BLOCK_END_("scroll-padding-block-end", "scroll-padding-block-end", ff68up("auto")),
+
+ /** The style property {@code scrollPaddingBlockStart}. */
+ SCROLL_PADDING_BLOCK_START("scrollPaddingBlockStart", "scroll-padding-block-start",
+ chrome("auto"), ff68up("auto")),
+
+ /** The style property {@code scroll-padding-block-start}. */
+ SCROLL_PADDING_BLOCK_START_("scroll-padding-block-start", "scroll-padding-block-start", ff68up("auto")),
+
+ /** The style property {@code scrollPaddingBottom}. */
+ SCROLL_PADDING_BOTTOM("scrollPaddingBottom", "scroll-padding-bottom", chrome("auto"), ff68up("auto")),
+
+ /** The style property {@code scroll-padding-bottom}. */
+ SCROLL_PADDING_BOTTOM_("scroll-padding-bottom", "scroll-padding-bottom", ff68up("auto")),
+
+ /** The style property {@code scrollPaddingInline}. */
+ SCROLL_PADDING_INLINE("scrollPaddingInline", "scroll-padding-inline", chrome("auto"), ff68up("")),
+
+ /** The style property {@code scroll-padding-inline}. */
+ SCROLL_PADDING_INLINE_("scroll-padding-inline", "scroll-padding-inline", ff68up("")),
+
+ /** The style property {@code scrollPaddingInlineEnd}. */
+ SCROLL_PADDING_INLINE_END("scrollPaddingInlineEnd", "scroll-padding-inline-end",
+ chrome("auto"), ff68up("auto")),
+
+ /** The style property {@code scroll-padding-inline-end}. */
+ SCROLL_PADDING_INLINE_END_("scroll-padding-inline-end", "scroll-padding-inline-end", ff68up("auto")),
+
+ /** The style property {@code scrollPaddingInlineStart}. */
+ SCROLL_PADDING_INLINE_START("scrollPaddingInlineStart", "scroll-padding-inline-start",
+ chrome("auto"), ff68up("auto")),
+
+ /** The style property {@code scroll-padding-inline-start}. */
+ SCROLL_PADDING_INLINE_START_("scroll-padding-inline-start", "scroll-padding-inline-start", ff68up("auto")),
+
+ /** The style property {@code scrollPaddingLeft}. */
+ SCROLL_PADDING_LEFT("scrollPaddingLeft", "scroll-padding-left", chrome("auto"), ff68up("auto")),
+
+ /** The style property {@code scroll-padding-left}. */
+ SCROLL_PADDING_LEFT_("scroll-padding-left", "scroll-padding-left", ff68up("auto")),
+
+ /** The style property {@code scrollPaddingRight}. */
+ SCROLL_PADDING_RIGHT("scrollPaddingRight", "scroll-padding-right", chrome("auto"), ff68up("auto")),
+
+ /** The style property {@code scroll-padding-right}. */
+ SCROLL_PADDING_RIGHT_("scroll-padding-right", "scroll-padding-right", ff68up("auto")),
+
+ /** The style property {@code scrollPaddingTop}. */
+ SCROLL_PADDING_TOP("scrollPaddingTop", "scroll-padding-top", chrome("auto"), ff68up("auto")),
+
+ /** The style property {@code scroll-padding-top}. */
+ SCROLL_PADDING_TOP_("scroll-padding-top", "scroll-padding-top", ff68up("auto")),
+
+ /** The style property {@code scrollSnapAlign}. */
+ SCROLL_SNAP_ALIGN("scrollSnapAlign", "scroll-snap-align", chrome("none"), ff68up("none")),
+
+ /** The style property {@code scroll-snap-align}. */
+ SCROLL_SNAP_ALIGN_("scroll-snap-align", "scroll-snap-align", ff68up("none")),
+
/** The style property {@code scrollSnapCoordinate}. */
- SCROLL_SNAP_COORDINATE("scrollSnapCoordinate", "scroll-snap-coordinate", ff("none")),
+ SCROLL_SNAP_COORDINATE("scrollSnapCoordinate", "scroll-snap-coordinate", ffBelow68("none")),
/** The style property {@code scroll-snap-coordinate}. */
- SCROLL_SNAP_COORDINATE_("scroll-snap-coordinate", "scroll-snap-coordinate", ff("none")),
+ SCROLL_SNAP_COORDINATE_("scroll-snap-coordinate", "scroll-snap-coordinate", ffBelow68("none")),
/** The style property {@code scrollSnapDestination}. */
- SCROLL_SNAP_DESTINATION("scrollSnapDestination", "scroll-snap-destination", ff("0px 0px")),
+ SCROLL_SNAP_DESTINATION("scrollSnapDestination", "scroll-snap-destination", ffBelow68("0px 0px")),
/** The style property {@code scroll-snap-destination}. */
- SCROLL_SNAP_DESTINATION_("scroll-snap-destination", "scroll-snap-destination", ff("0px 0px")),
+ SCROLL_SNAP_DESTINATION_("scroll-snap-destination", "scroll-snap-destination", ffBelow68("0px 0px")),
/** The style property {@code scrollSnapPointsX}. */
- SCROLL_SNAP_POINTS_X("scrollSnapPointsX", "scroll-snap-points-x", ff("none")),
+ SCROLL_SNAP_POINTS_X("scrollSnapPointsX", "scroll-snap-points-x", ffBelow68("none")),
/** The style property {@code scroll-snap-points-x}. */
- SCROLL_SNAP_POINTS_X_("scroll-snap-points-x", "scroll-snap-points-x", ff("none")),
+ SCROLL_SNAP_POINTS_X_("scroll-snap-points-x", "scroll-snap-points-x", ffBelow68("none")),
/** The style property {@code scrollSnapPointsY}. */
- SCROLL_SNAP_POINTS_Y("scrollSnapPointsY", "scroll-snap-points-y", ff("none")),
+ SCROLL_SNAP_POINTS_Y("scrollSnapPointsY", "scroll-snap-points-y", ffBelow68("none")),
/** The style property {@code scroll-snap-points-y}. */
- SCROLL_SNAP_POINTS_Y_("scroll-snap-points-y", "scroll-snap-points-y", ff("none")),
+ SCROLL_SNAP_POINTS_Y_("scroll-snap-points-y", "scroll-snap-points-y", ffBelow68("none")),
+
+ /** The style property {@code scrollSnapStop}. */
+ SCROLL_SNAP_STOP("scrollSnapStop", "scroll-snap-stop", chrome("normal")),
/** The style property {@code scrollSnapType}. */
- SCROLL_SNAP_TYPE("scrollSnapType", "scroll-snap-type", ff("")),
+ SCROLL_SNAP_TYPE("scrollSnapType", "scroll-snap-type", chrome("none"), ffBelow68(""), ff68up("none")),
/** The style property {@code scroll-snap-type}. */
- SCROLL_SNAP_TYPE_("scroll-snap-type", "scroll-snap-type", ff("")),
+ SCROLL_SNAP_TYPE_("scroll-snap-type", "scroll-snap-type", ffBelow68(""), ff68up("none")),
/** The style property {@code scrollSnapTypeX}. */
- SCROLL_SNAP_TYPE_X("scrollSnapTypeX", "scroll-snap-type-x", ff("none")),
+ SCROLL_SNAP_TYPE_X("scrollSnapTypeX", "scroll-snap-type-x", ffBelow68("none")),
/** The style property {@code scroll-snap-type-x}. */
- SCROLL_SNAP_TYPE_X_("scroll-snap-type-x", "scroll-snap-type-x", ff("none")),
+ SCROLL_SNAP_TYPE_X_("scroll-snap-type-x", "scroll-snap-type-x", ffBelow68("none")),
/** The style property {@code scrollSnapTypeY}. */
- SCROLL_SNAP_TYPE_Y("scrollSnapTypeY", "scroll-snap-type-y", ff("none")),
+ SCROLL_SNAP_TYPE_Y("scrollSnapTypeY", "scroll-snap-type-y", ffBelow68("none")),
/** The style property {@code scroll-snap-type-y}. */
- SCROLL_SNAP_TYPE_Y_("scroll-snap-type-y", "scroll-snap-type-y", ff("none")),
+ SCROLL_SNAP_TYPE_Y_("scroll-snap-type-y", "scroll-snap-type-y", ffBelow68("none")),
/** The style property {@code scrollbar3dLightColor}. */
SCROLLBAR_3DLIGHT_COLOR("scrollbar3dLightColor", "scrollbar-3dlight-color", ie("undefined")),
@@ -2551,6 +2979,12 @@ public enum Definition {
/** The style property {@code scrollbarBaseColor}. */
SCROLLBAR_BASE_COLOR("scrollbarBaseColor", "scrollbar-base-color", ie("undefined")),
+ /** The style property {@code scrollbarColor}. */
+ SCROLLBAR_COLOR("scrollbarColor", "scrollbar-color", ff68up("auto")),
+
+ /** The style property {@code scrollbar-color}. */
+ SCROLLBAR_COLOR_("scrollbar-color", "scrollbar-color", ff68up("auto")),
+
/** The style property {@code scrollbarDarkShadowColor}. */
SCROLLBAR_DARKSHADOW_COLOR("scrollbarDarkShadowColor", "scrollbar-darkshadow-color", ie("undefined")),
@@ -2566,14 +3000,29 @@ public enum Definition {
/** The style property {@code scrollbarTrackColor}. */
SCROLLBAR_TRACK_COLOR("scrollbarTrackColor", "scrollbar-track-color", ie("undefined")),
+ /** The style property {@code scrollbarWidth}. */
+ SCROLLBAR_WIDTH("scrollbarWidth", "scrollbar-width", ff68up("auto")),
+
+ /** The style property {@code scrollbar-width}. */
+ SCROLLBAR_WIDTH_("scrollbar-width", "scrollbar-width", ff68up("auto")),
+
/** The style property {@code shapeImageThreshold}. */
- SHAPE_IMAGE_THRESHOLD("shapeImageThreshold", "shape-image-threshold", chrome("0")),
+ SHAPE_IMAGE_THRESHOLD("shapeImageThreshold", "shape-image-threshold", chrome("0"), ff68up("0")),
+
+ /** The style property {@code shape-image-threshold}. */
+ SHAPE_IMAGE_THRESHOLD_("shape-image-threshold", "shape-image-threshold", ff68up("0")),
/** The style property {@code shapeMargin}. */
- SHAPE_MARGIN("shapeMargin", "shape-margin", chrome("0px")),
+ SHAPE_MARGIN("shapeMargin", "shape-margin", chrome("0px"), ff68up("0px")),
+
+ /** The style property {@code shape-margin}. */
+ SHAPE_MARGIN_("shape-margin", "shape-margin", ff68up("0px")),
/** The style property {@code shapeOutside}. */
- SHAPE_OUTSIDE("shapeOutside", "shape-outside", chrome("none")),
+ SHAPE_OUTSIDE("shapeOutside", "shape-outside", chrome("none"), ff68up("none")),
+
+ /** The style property {@code shape-outside}. */
+ SHAPE_OUTSIDE_("shape-outside", "shape-outside", ff68up("none")),
/** The style property {@code shapeRendering}. */
SHAPE_RENDERING("shapeRendering", "shape-rendering", ff("auto"), chrome("auto")),
@@ -2681,10 +3130,10 @@ public enum Definition {
TEXT_ALIGN_("text-align", "text-align", ff("start")),
/** The style property {@code textAlignLast}. */
- TEXT_ALIGN_LAST("textAlignLast", "text-align-last", ie("auto"), chrome("auto"), ff52up("auto")),
+ TEXT_ALIGN_LAST("textAlignLast", "text-align-last", ie("auto"), chrome("auto"), ff("auto")),
/** The style property {@code text-align-last}. */
- TEXT_ALIGN_LAST_("text-align-last", "text-align-last", ff52up("auto")),
+ TEXT_ALIGN_LAST_("text-align-last", "text-align-last", ff("auto")),
/** The style property {@code textAnchor}. */
TEXT_ANCHOR("textAnchor", "text-anchor", ff("start"), ie("start"), chrome("start")),
@@ -2696,10 +3145,10 @@ public enum Definition {
TEXT_AUTOSPACE("textAutospace", "text-autospace", ie("undefined")),
/** The style property {@code textCombineUpright}. */
- TEXT_COMBINE_UPRIGHT("textCombineUpright", "text-combine-upright", chrome("none"), ff52up("none")),
+ TEXT_COMBINE_UPRIGHT("textCombineUpright", "text-combine-upright", chrome("none"), ff("none")),
/** The style property {@code text-combine-upright}. */
- TEXT_COMBINE_UPRIGHT_("text-combine-upright", "text-combine-upright", ff52up("none")),
+ TEXT_COMBINE_UPRIGHT_("text-combine-upright", "text-combine-upright", ff("none")),
/** The style property {@code textDecoration}. */
TEXT_DECORATION("textDecoration", "text-decoration", chrome("none solid rgb(0, 0, 0)"), ff("none"), ie("none")),
@@ -2708,7 +3157,7 @@ public enum Definition {
TEXT_DECORATION_("text-decoration", "text-decoration", ff("none")),
/** The style property {@code textDecorationBlink}. */
- TEXT_DECORATION_BLINK("textDecorationBlink", "text-decoration-blink", ie("false").setIteratable(false)),
+ TEXT_DECORATION_BLINK("textDecorationBlink", "text-decoration-blink", ie("false")),
/** The style property {@code textDecorationColor}. */
TEXT_DECORATION_COLOR("textDecorationColor", "text-decoration-color",
@@ -2725,14 +3174,14 @@ public enum Definition {
/** The style property {@code textDecorationLineThrough}. */
TEXT_DECORATION_LINE_THROUGH("textDecorationLineThrough", "text-decoration-line-through",
- ie("false").setIteratable(false)),
+ ie("false")),
/** The style property {@code textDecorationNone}. */
- TEXT_DECORATION_NONE("textDecorationNone", "text-decoration-none", ie("false").setIteratable(false)),
+ TEXT_DECORATION_NONE("textDecorationNone", "text-decoration-none", ie("false")),
/** The style property {@code textDecorationOverline}. */
TEXT_DECORATION_OVERLINE("textDecorationOverline", "text-decoration-overline",
- ie("false").setIteratable(false)),
+ ie("false")),
/** The style property {@code textDecorationSkipInk}. */
TEXT_DECORATION_SKIP("textDecorationSkipInk", "text-decoration-skip-ink", chrome("auto")),
@@ -2745,31 +3194,31 @@ public enum Definition {
/** The style property {@code textDecorationUnderline}. */
TEXT_DECORATION_UNDERLINE("textDecorationUnderline", "text-decoration-underline",
- ie("false").setIteratable(false)),
+ ie("false")),
/** The style property {@code textEmphasis}. */
- TEXT_EMPHASIS("textEmphasis", "text-emphasis", ff52up("")),
+ TEXT_EMPHASIS("textEmphasis", "text-emphasis", ff("")),
/** The style property {@code text-emphasis}. */
- TEXT_EMPHASIS_("text-emphasis", "text-emphasis", ff52up("")),
+ TEXT_EMPHASIS_("text-emphasis", "text-emphasis", ff("")),
/** The style property {@code textEmphasisColor}. */
- TEXT_EMPHASIS_COLOR("textEmphasisColor", "text-emphasis-color", ff52up("rgb(0, 0, 0)")),
+ TEXT_EMPHASIS_COLOR("textEmphasisColor", "text-emphasis-color", ff("rgb(0, 0, 0)")),
/** The style property {@code text-emphasis-color}. */
- TEXT_EMPHASIS_COLOR_("text-emphasis-color", "text-emphasis-color", ff52up("rgb(0, 0, 0)")),
+ TEXT_EMPHASIS_COLOR_("text-emphasis-color", "text-emphasis-color", ff("rgb(0, 0, 0)")),
/** The style property {@code textEmphasisPosition}. */
- TEXT_EMPHASIS_POSITION("textEmphasisPosition", "text-emphasis-position", ff52up("over right")),
+ TEXT_EMPHASIS_POSITION("textEmphasisPosition", "text-emphasis-position", ff("over right")),
/** The style property {@code text-emphasis-position}. */
- TEXT_EMPHASIS_POSITION_("text-emphasis-position", "text-emphasis-position", ff52up("over right")),
+ TEXT_EMPHASIS_POSITION_("text-emphasis-position", "text-emphasis-position", ff("over right")),
/** The style property {@code textEmphasisStyle}. */
- TEXT_EMPHASIS_STYLE("textEmphasisStyle", "text-emphasis-style", ff52up("none")),
+ TEXT_EMPHASIS_STYLE("textEmphasisStyle", "text-emphasis-style", ff("none")),
/** The style property {@code text-emphasis-style}. */
- TEXT_EMPHASIS_STYLE_("text-emphasis-style", "text-emphasis-style", ff52up("none")),
+ TEXT_EMPHASIS_STYLE_("text-emphasis-style", "text-emphasis-style", ff("none")),
/** The style property {@code textIndent}. */
TEXT_INDENT("textIndent", "text-indent", chrome("0px"), ff(""), ie("")),
@@ -2778,7 +3227,10 @@ public enum Definition {
TEXT_INDENT_("text-indent", "text-indent", ff("0px")),
/** The style property {@code textJustify}. */
- TEXT_JUSTIFY("textJustify", "text-justify", ie("auto")),
+ TEXT_JUSTIFY("textJustify", "text-justify", ie("auto"), ff("auto")),
+
+ /** The style property {@code text-justify}. */
+ TEXT_JUSTIFY_("text-justify", "text-justify", ff("auto")),
/** The style property {@code textJustifyTrim}. */
TEXT_JUSTIFY_TRIM("textJustifyTrim", "text-justify-trim", ie("undefined")),
@@ -2829,23 +3281,26 @@ public enum Definition {
TOP("top", "top", ff("auto"), ie("auto"), chrome("auto")),
/** The style property {@code touchAction}. */
- TOUCH_ACTION("touchAction", "touch-action", ie("auto"), chrome("auto"), ff52up("auto")),
+ TOUCH_ACTION("touchAction", "touch-action", ie("auto"), chrome("auto"), ff("auto")),
/** The style property {@code touch-action}. */
- TOUCH_ACTION_("touch-action", "touch-action", ff52up("auto")),
+ TOUCH_ACTION_("touch-action", "touch-action", ff("auto")),
/** The style property {@code transform}. */
TRANSFORM("transform", "transform", ff("none"), ie("none"), chrome("none")),
/** The style property {@code transformBox}. */
- TRANSFORM_BOX("transformBox", "transform-box", chrome("view-box")),
+ TRANSFORM_BOX("transformBox", "transform-box", chrome("view-box"), ff("border-box")),
+
+ /** The style property {@code transform-box}. */
+ TRANSFORM_BOX_("transform-box", "transform-box", ff("border-box")),
/** The style property {@code transformOrigin}. */
TRANSFORM_ORIGIN("transformOrigin", "transform-origin",
- ffBelow52("705px 172.5px"), ff52up("625px 172.5px"), ie("620px 163.2px"), chrome("456.5px 161px")),
+ ffBelow68("625px 172.5px"), ff68up("621px 171.5px"), ie("620px 163.2px"), chrome("456.5px 161px")),
/** The style property {@code transform-origin}. */
- TRANSFORM_ORIGIN_("transform-origin", "transform-origin", ffBelow52("705px 172.5px"), ff52up("625px 172.5px")),
+ TRANSFORM_ORIGIN_("transform-origin", "transform-origin", ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code transformStyle}. */
TRANSFORM_STYLE("transformStyle", "transform-style", ff("flat"), ie("flat"), chrome("flat")),
@@ -2887,10 +3342,10 @@ public enum Definition {
/** The style property {@code unicodeBidi}. */
UNICODE_BIDI("unicodeBidi", "unicode-bidi",
- ffBelow52("-moz-isolate"), ff52up("isolate"), ie("normal"), chrome("normal")),
+ ff("isolate"), ie("normal"), chrome("normal")),
/** The style property {@code unicode-bidi}. */
- UNICODE_BIDI_("unicode-bidi", "unicode-bidi", ffBelow52("-moz-isolate"), ff52up("isolate")),
+ UNICODE_BIDI_("unicode-bidi", "unicode-bidi", ff("isolate")),
/** The style property {@code unicodeRange}. */
UNICODE_RANGE("unicodeRange", "unicode-range", chrome("")),
@@ -2923,163 +3378,177 @@ public enum Definition {
VOLUME("volume", "volume"),
/** The style property {@code webkitAlignContent}. */
- WEBKIT_ALIGN_CONTENT("webkitAlignContent", "webkit-align-content", ff52up("normal")),
+ WEBKIT_ALIGN_CONTENT("webkitAlignContent", "webkit-align-content", chrome("normal"), ff("normal")),
/** The style property {@code WebkitAlignContent}. */
- WEBKIT_ALIGN_CONTENT_("WebkitAlignContent", "webkit-align-content", ff52up("normal")),
+ WEBKIT_ALIGN_CONTENT_("WebkitAlignContent", "webkit-align-content", ff("normal")),
/** The style property {@code -webkit-align-content}. */
- WEBKIT_ALIGN_CONTENT__("-webkit-align-content", "webkit-align-content", ff52up("normal")),
+ WEBKIT_ALIGN_CONTENT__("-webkit-align-content", "webkit-align-content", ff("normal")),
/** The style property {@code webkitAlignItems}. */
- WEBKIT_ALIGN_ITEMS("webkitAlignItems", "webkit-align-items", ff52up("normal")),
+ WEBKIT_ALIGN_ITEMS("webkitAlignItems", "webkit-align-items", chrome("normal"), ff("normal")),
/** The style property {@code WebkitAlignItems}. */
- WEBKIT_ALIGN_ITEMS_("WebkitAlignItems", "webkit-align-items", ff52up("normal")),
+ WEBKIT_ALIGN_ITEMS_("WebkitAlignItems", "webkit-align-items", ff("normal")),
/** The style property {@code -webkit-align-items}. */
- WEBKIT_ALIGN_ITEMS__("-webkit-align-items", "webkit-align-items", ff52up("normal")),
+ WEBKIT_ALIGN_ITEMS__("-webkit-align-items", "webkit-align-items", ff("normal")),
/** The style property {@code webkitAlignSelf}. */
- WEBKIT_ALIGN_SELF("webkitAlignSelf", "webkit-align-self", ff52up("auto")),
+ WEBKIT_ALIGN_SELF("webkitAlignSelf", "webkit-align-self", chrome("auto"), ff("auto")),
/** The style property {@code WebkitAlignSelf}. */
- WEBKIT_ALIGN_SELF_("WebkitAlignSelf", "webkit-align-self", ff52up("auto")),
+ WEBKIT_ALIGN_SELF_("WebkitAlignSelf", "webkit-align-self", ff("auto")),
/** The style property {@code -webkit-align-self}. */
- WEBKIT_ALIGN_SELF__("-webkit-align-self", "webkit-align-self", ff52up("auto")),
+ WEBKIT_ALIGN_SELF__("-webkit-align-self", "webkit-align-self", ff("auto")),
/** The style property {@code webkitAnimation}. */
- WEBKIT_ANIMATION("webkitAnimation", "webkit-animation", ff52up("")),
+ WEBKIT_ANIMATION("webkitAnimation", "webkit-animation",
+ chrome("none 0s ease 0s 1 normal none running"), ff("")),
/** The style property {@code WebkitAnimation}. */
- WEBKIT_ANIMATION_("WebkitAnimation", "webkit-animation", ff52up("")),
+ WEBKIT_ANIMATION_("WebkitAnimation", "webkit-animation", ff("")),
/** The style property {@code -webkit-animation}. */
- WEBKIT_ANIMATION__("-webkit-animation", "webkit-animation", ff52up("")),
+ WEBKIT_ANIMATION__("-webkit-animation", "webkit-animation", ff("")),
/** The style property {@code webkitAnimationDelay}. */
- WEBKIT_ANIMATION_DELAY("webkitAnimationDelay", "webkit-animation-delay", ff52up("0s")),
+ WEBKIT_ANIMATION_DELAY("webkitAnimationDelay", "webkit-animation-delay", chrome("0s"), ff("0s")),
/** The style property {@code WebkitAnimationDelay}. */
- WEBKIT_ANIMATION_DELAY_("WebkitAnimationDelay", "webkit-animation-delay", ff52up("0s")),
+ WEBKIT_ANIMATION_DELAY_("WebkitAnimationDelay", "webkit-animation-delay", ff("0s")),
/** The style property {@code -webkit-animation-delay}. */
- WEBKIT_ANIMATION_DELAY__("-webkit-animation-delay", "webkit-animation-delay", ff52up("0s")),
+ WEBKIT_ANIMATION_DELAY__("-webkit-animation-delay", "webkit-animation-delay", ff("0s")),
/** The style property {@code webkitAnimationDirection}. */
- WEBKIT_ANIMATION_DIRECTION("webkitAnimationDirection", "webkit-animation-direction", ff52up("normal")),
+ WEBKIT_ANIMATION_DIRECTION("webkitAnimationDirection", "webkit-animation-direction",
+ chrome("normal"), ff("normal")),
/** The style property {@code WebkitAnimationDirection}. */
- WEBKIT_ANIMATION_DIRECTION_("WebkitAnimationDirection", "webkit-animation-direction", ff52up("normal")),
+ WEBKIT_ANIMATION_DIRECTION_("WebkitAnimationDirection", "webkit-animation-direction", ff("normal")),
/** The style property {@code -webkit-animation-direction}. */
- WEBKIT_ANIMATION_DIRECTION__("-webkit-animation-direction", "webkit-animation-direction", ff52up("normal")),
+ WEBKIT_ANIMATION_DIRECTION__("-webkit-animation-direction", "webkit-animation-direction", ff("normal")),
/** The style property {@code webkitAnimationDuration}. */
- WEBKIT_ANIMATION_DURATION("webkitAnimationDuration", "webkit-animation-duration", ff52up("0s")),
+ WEBKIT_ANIMATION_DURATION("webkitAnimationDuration", "webkit-animation-duration", chrome("0s"), ff("0s")),
/** The style property {@code WebkitAnimationDuration}. */
- WEBKIT_ANIMATION_DURATION_("WebkitAnimationDuration", "webkit-animation-duration", ff52up("0s")),
+ WEBKIT_ANIMATION_DURATION_("WebkitAnimationDuration", "webkit-animation-duration", ff("0s")),
/** The style property {@code -webkit-animation-duration}. */
- WEBKIT_ANIMATION_DURATION__("-webkit-animation-duration", "webkit-animation-duration", ff52up("0s")),
+ WEBKIT_ANIMATION_DURATION__("-webkit-animation-duration", "webkit-animation-duration", ff("0s")),
/** The style property {@code webkitAnimationFillMode}. */
- WEBKIT_ANIMATION_FILL_MODE("webkitAnimationFillMode", "webkit-animation-fill-mode", ff52up("none")),
+ WEBKIT_ANIMATION_FILL_MODE("webkitAnimationFillMode", "webkit-animation-fill-mode", chrome("none"), ff("none")),
/** The style property {@code WebkitAnimationFillMode}. */
- WEBKIT_ANIMATION_FILL_MODE_("WebkitAnimationFillMode", "webkit-animation-fill-mode", ff52up("none")),
+ WEBKIT_ANIMATION_FILL_MODE_("WebkitAnimationFillMode", "webkit-animation-fill-mode", ff("none")),
/** The style property {@code -webkit-animation-fill-mode}. */
- WEBKIT_ANIMATION_FILL_MODE__("-webkit-animation-fill-mode", "webkit-animation-fill-mode", ff52up("none")),
+ WEBKIT_ANIMATION_FILL_MODE__("-webkit-animation-fill-mode", "webkit-animation-fill-mode", ff("none")),
/** The style property {@code webkitAnimationIterationCount}. */
WEBKIT_ANIMATION_ITERATION_COUNT("webkitAnimationIterationCount", "webkit-animation-iteration-count",
- ff52up("1")),
+ chrome("1"), ff("1")),
/** The style property {@code WebkitAnimationIterationCount}. */
WEBKIT_ANIMATION_ITERATION_COUNT_("WebkitAnimationIterationCount", "webkit-animation-iteration-count",
- ff52up("1")),
+ ff("1")),
/** The style property {@code -webkit-animation-iteration-count}. */
WEBKIT_ANIMATION_ITERATION_COUNT__("-webkit-animation-iteration-count", "webkit-animation-iteration-count",
- ff52up("1")),
+ ff("1")),
/** The style property {@code webkitAnimationName}. */
- WEBKIT_ANIMATION_NAME("webkitAnimationName", "webkit-animation-name", ff52up("none")),
+ WEBKIT_ANIMATION_NAME("webkitAnimationName", "webkit-animation-name", chrome("none"), ff("none")),
/** The style property {@code WebkitAnimationName}. */
- WEBKIT_ANIMATION_NAME_("WebkitAnimationName", "webkit-animation-name", ff52up("none")),
+ WEBKIT_ANIMATION_NAME_("WebkitAnimationName", "webkit-animation-name", ff("none")),
/** The style property {@code -webkit-animation-name}. */
- WEBKIT_ANIMATION_NAME__("-webkit-animation-name", "webkit-animation-name", ff52up("none")),
+ WEBKIT_ANIMATION_NAME__("-webkit-animation-name", "webkit-animation-name", ff("none")),
/** The style property {@code webkitAnimationPlayState}. */
- WEBKIT_ANIMATION_PLAY_STATE("webkitAnimationPlayState", "webkit-animation-play-state", ff52up("running")),
+ WEBKIT_ANIMATION_PLAY_STATE("webkitAnimationPlayState", "webkit-animation-play-state",
+ chrome("running"), ff("running")),
/** The style property {@code WebkitAnimationPlayState}. */
- WEBKIT_ANIMATION_PLAY_STATE_("WebkitAnimationPlayState", "webkit-animation-play-state", ff52up("running")),
+ WEBKIT_ANIMATION_PLAY_STATE_("WebkitAnimationPlayState", "webkit-animation-play-state", ff("running")),
/** The style property {@code -webkit-animation-play-state}. */
- WEBKIT_ANIMATION_PLAY_STATE__("-webkit-animation-play-state", "webkit-animation-play-state", ff52up("running")),
+ WEBKIT_ANIMATION_PLAY_STATE__("-webkit-animation-play-state", "webkit-animation-play-state", ff("running")),
/** The style property {@code webkitAnimationTimingFunction}. */
WEBKIT_ANIMATION_TIMING_FUNCTION("webkitAnimationTimingFunction", "webkit-animation-timing-function",
- ff52up("ease")),
+ chrome("ease"), ff("ease")),
/** The style property {@code WebkitAnimationTimingFunction}. */
WEBKIT_ANIMATION_TIMING_FUNCTION_("WebkitAnimationTimingFunction", "webkit-animation-timing-function",
- ff52up("ease")),
+ ff("ease")),
/** The style property {@code -webkit-animation-timing-function}. */
WEBKIT_ANIMATION_TIMING_FUNCTION__("-webkit-animation-timing-function", "webkit-animation-timing-function",
- ff52up("ease")),
+ ff("ease")),
/** The style property {@code webkitAppRegion}. */
- WEBKIT_APP_REGION("webkitAppRegion", "webkit-app-region", chrome("no-drag")),
+ WEBKIT_APP_REGION("webkitAppRegion", "webkit-app-region", chrome("none")),
/** The style property {@code webkitAppearance}. */
- WEBKIT_APPEARANCE("webkitAppearance", "webkit-appearance", chrome("none")),
+ WEBKIT_APPEARANCE("webkitAppearance", "webkit-appearance", chrome("none"), ff68up("none")),
+
+ /** The style property {@code WebkitAppearance}. */
+ WEBKIT_APPEARANCE_("WebkitAppearance", "webkit-appearance", ff68up("none")),
+
+ /** The style property {@code -webkit-appearance}. */
+ WEBKIT_APPEARANCE__("-webkit-appearance", "webkit-appearance", ff68up("none")),
/** The style property {@code webkitBackfaceVisibility}. */
WEBKIT_BACKFACE_VISIBILITY("webkitBackfaceVisibility", "webkit-backface-visibility",
- ff52up("visible")),
+ chrome("visible"), ff("visible")),
/** The style property {@code WebkitBackfaceVisibility}. */
WEBKIT_BACKFACE_VISIBILITY_("WebkitBackfaceVisibility", "webkit-backface-visibility",
- ff52up("visible")),
+ ff("visible")),
/** The style property {@code -webkit-backface-visibility}. */
WEBKIT_BACKFACE_VISIBILITY__("-webkit-backface-visibility", "webkit-backface-visibility",
- ff52up("visible")),
+ ff("visible")),
/** The style property {@code webkitBackgroundClip}. */
- WEBKIT_BACKGROUND_CLIP("webkitBackgroundClip", "webkit-background-clip", ff52up("border-box")),
+ WEBKIT_BACKGROUND_CLIP("webkitBackgroundClip", "webkit-background-clip",
+ chrome("border-box"), ff("border-box")),
/** The style property {@code WebkitBackgroundClip}. */
- WEBKIT_BACKGROUND_CLIP_("WebkitBackgroundClip", "webkit-background-clip", ff52up("border-box")),
+ WEBKIT_BACKGROUND_CLIP_("WebkitBackgroundClip", "webkit-background-clip", ff("border-box")),
/** The style property {@code -webkit-background-clip}. */
- WEBKIT_BACKGROUND_CLIP__("-webkit-background-clip", "webkit-background-clip", ff52up("border-box")),
+ WEBKIT_BACKGROUND_CLIP__("-webkit-background-clip", "webkit-background-clip", ff("border-box")),
/** The style property {@code webkitBackgroundOrigin}. */
- WEBKIT_BACKGROUND_ORIGIN("webkitBackgroundOrigin", "webkit-background-origin", ff52up("padding-box")),
+ WEBKIT_BACKGROUND_ORIGIN("webkitBackgroundOrigin", "webkit-background-origin",
+ chrome("padding-box"), ff("padding-box")),
/** The style property {@code WebkitBackgroundOrigin}. */
- WEBKIT_BACKGROUND_ORIGIN_("WebkitBackgroundOrigin", "webkit-background-origin", ff52up("padding-box")),
+ WEBKIT_BACKGROUND_ORIGIN_("WebkitBackgroundOrigin", "webkit-background-origin", ff("padding-box")),
/** The style property {@code -webkit-background-origin}. */
- WEBKIT_BACKGROUND_ORIGIN__("-webkit-background-origin", "webkit-background-origin", ff52up("padding-box")),
+ WEBKIT_BACKGROUND_ORIGIN__("-webkit-background-origin", "webkit-background-origin", ff("padding-box")),
/** The style property {@code webkitBackgroundSize}. */
- WEBKIT_BACKGROUND_SIZE("webkitBackgroundSize", "webkit-background-size", ff52up("auto auto")),
+ WEBKIT_BACKGROUND_SIZE("webkitBackgroundSize", "webkit-background-size", chrome("auto"),
+ ffBelow68("auto auto"), ff68up("auto")),
/** The style property {@code WebkitBackgroundSize}. */
- WEBKIT_BACKGROUND_SIZE_("WebkitBackgroundSize", "webkit-background-size", ff52up("auto auto")),
+ WEBKIT_BACKGROUND_SIZE_("WebkitBackgroundSize", "webkit-background-size",
+ ffBelow68("auto auto"), ff68up("auto")),
/** The style property {@code -webkit-background-size}. */
- WEBKIT_BACKGROUND_SIZE__("-webkit-background-size", "webkit-background-size", ff52up("auto auto")),
+ WEBKIT_BACKGROUND_SIZE__("-webkit-background-size", "webkit-background-size",
+ ffBelow68("auto auto"), ff68up("auto")),
/** The style property {@code webkitBorderAfter}. */
WEBKIT_BORDER_AFTER("webkitBorderAfter", "webkit-border-after", chrome("0px none rgb(0, 0, 0)")),
@@ -3107,27 +3576,27 @@ public enum Definition {
/** The style property {@code webkitBorderBottomLeftRadius}. */
WEBKIT_BORDER_BOTTOM_LEFT_RADIUS("webkitBorderBottomLeftRadius", "webkit-border-bottom-left-radius",
- ff52up("0px")),
+ chrome("0px"), ff("0px")),
/** The style property {@code WebkitBorderBottomLeftRadius}. */
WEBKIT_BORDER_BOTTOM_LEFT_RADIUS_("WebkitBorderBottomLeftRadius", "webkit-border-bottom-left-radius",
- ff52up("0px")),
+ ff("0px")),
/** The style property {@code -webkit-border-bottom-left-radius}. */
WEBKIT_BORDER_BOTTOM_LEFT_RADIUS__("-webkit-border-bottom-left-radius", "webkit-border-bottom-left-radius",
- ff52up("0px")),
+ ff("0px")),
/** The style property {@code webkitBorderBottomRightRadius}. */
WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS("webkitBorderBottomRightRadius", "webkit-border-bottom-right-radius",
- ff52up("0px")),
+ chrome("0px"), ff("0px")),
/** The style property {@code WebkitBorderBottomRightRadius}. */
WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS_("WebkitBorderBottomRightRadius", "webkit-border-bottom-right-radius",
- ff52up("0px")),
+ ff("0px")),
/** The style property {@code -webkit-border-bottom-right-radius}. */
WEBKIT_BORDER_BOTTOM_RIGHT_RADIUS__("-webkit-border-bottom-right-radius", "webkit-border-bottom-right-radius",
- ff52up("0px")),
+ ff("0px")),
/** The style property {@code webkitBorderEnd}. */
WEBKIT_BORDER_END("webkitBorderEnd", "webkit-border-end", chrome("0px none rgb(0, 0, 0)")),
@@ -3146,22 +3615,22 @@ public enum Definition {
chrome("0px")),
/** The style property {@code webkitBorderImage}. */
- WEBKIT_BORDER_IMAGE("webkitBorderImage", "webkit-border-image", chrome("none"), ff52up("")),
+ WEBKIT_BORDER_IMAGE("webkitBorderImage", "webkit-border-image", chrome("none"), ff("")),
/** The style property {@code WebkitBorderImage}. */
- WEBKIT_BORDER_IMAGE_("WebkitBorderImage", "webkit-border-image", ff52up("")),
+ WEBKIT_BORDER_IMAGE_("WebkitBorderImage", "webkit-border-image", ff("")),
/** The style property {@code -webkit-border-image}. */
- WEBKIT_BORDER_IMAGE__("-webkit-border-image", "webkit-border-image", ff52up("")),
+ WEBKIT_BORDER_IMAGE__("-webkit-border-image", "webkit-border-image", ff("")),
/** The style property {@code webkitBorderRadius}. */
- WEBKIT_BORDER_RADIUS("webkitBorderRadius", "webkit-border-radius", ff52up("")),
+ WEBKIT_BORDER_RADIUS("webkitBorderRadius", "webkit-border-radius", chrome("0px"), ff("")),
/** The style property {@code WebkitBorderRadius}. */
- WEBKIT_BORDER_RADIUS_("WebkitBorderRadius", "webkit-border-radius", ff52up("")),
+ WEBKIT_BORDER_RADIUS_("WebkitBorderRadius", "webkit-border-radius", ff("")),
/** The style property {@code -webkit-border-radius}. */
- WEBKIT_BORDER_RADIUS__("-webkit-border-radius", "webkit-border-radius", ff52up("")),
+ WEBKIT_BORDER_RADIUS__("-webkit-border-radius", "webkit-border-radius", ff("")),
/** The style property {@code webkitBorderStart}. */
WEBKIT_BORDER_START("webkitBorderStart", "webkit-border-start", chrome("0px none rgb(0, 0, 0)")),
@@ -3176,111 +3645,116 @@ public enum Definition {
WEBKIT_BORDER_START_WIDTH("webkitBorderStartWidth", "webkit-border-start-width", chrome("0px")),
/** The style property {@code webkitBorderTopLeftRadius}. */
- WEBKIT_BORDER_TOP_LEFT_RADIUS("webkitBorderTopLeftRadius", "webkit-border-top-left-radius", ff52up("0px")),
+ WEBKIT_BORDER_TOP_LEFT_RADIUS("webkitBorderTopLeftRadius", "webkit-border-top-left-radius",
+ chrome("0px"), ff("0px")),
/** The style property {@code WebkitBorderTopLeftRadius}. */
- WEBKIT_BORDER_TOP_LEFT_RADIUS_("WebkitBorderTopLeftRadius", "webkit-border-top-left-radius", ff52up("0px")),
+ WEBKIT_BORDER_TOP_LEFT_RADIUS_("WebkitBorderTopLeftRadius", "webkit-border-top-left-radius", ff("0px")),
/** The style property {@code -webkit-border-top-left-radius}. */
WEBKIT_BORDER_TOP_LEFT_RADIUS__("-webkit-border-top-left-radius", "webkit-border-top-left-radius",
- ff52up("0px")),
+ ff("0px")),
/** The style property {@code webkitBorderTopRightRadius}. */
- WEBKIT_BORDER_TOP_RIGHT_RADIUS("webkitBorderTopRightRadius", "webkit-border-top-right-radius", ff52up("0px")),
+ WEBKIT_BORDER_TOP_RIGHT_RADIUS("webkitBorderTopRightRadius", "webkit-border-top-right-radius",
+ chrome("0px"), ff("0px")),
/** The style property {@code WebkitBorderTopRightRadius}. */
- WEBKIT_BORDER_TOP_RIGHT_RADIUS_("WebkitBorderTopRightRadius", "webkit-border-top-right-radius", ff52up("0px")),
+ WEBKIT_BORDER_TOP_RIGHT_RADIUS_("WebkitBorderTopRightRadius", "webkit-border-top-right-radius", ff("0px")),
/** The style property {@code -webkit-border-top-right-radius}. */
WEBKIT_BORDER_TOP_RIGHT_RADIUS__("-webkit-border-top-right-radius", "webkit-border-top-right-radius",
- ff52up("0px")),
+ ff("0px")),
/** The style property {@code webkitBorderVerticalSpacing}. */
WEBKIT_BORDER_VERTICAL_SPACING("webkitBorderVerticalSpacing", "webkit-border-vertical-spacing", chrome("0px")),
/** The style property {@code webkitBoxAlign}. */
- WEBKIT_BOX_ALIGN("webkitBoxAlign", "webkit-box-align", chrome("stretch"), ff52up("stretch")),
+ WEBKIT_BOX_ALIGN("webkitBoxAlign", "webkit-box-align", chrome("stretch"), ff("stretch")),
/** The style property {@code WebkitBoxAlign}. */
- WEBKIT_BOX_ALIGN_("WebkitBoxAlign", "webkit-box-align", ff52up("stretch")),
+ WEBKIT_BOX_ALIGN_("WebkitBoxAlign", "webkit-box-align", ff("stretch")),
/** The style property {@code -webkit-box-align}. */
- WEBKIT_BOX_ALIGN__("-webkit-box-align", "webkit-box-align", ff52up("stretch")),
+ WEBKIT_BOX_ALIGN__("-webkit-box-align", "webkit-box-align", ff("stretch")),
/** The style property {@code webkitBoxDecorationBreak}. */
WEBKIT_BOX_DECORATION_BREAK("webkitBoxDecorationBreak", "webkit-box-decoration-break", chrome("slice")),
/** The style property {@code webkitBoxDirection}. */
- WEBKIT_BOX_DIRECTION("webkitBoxDirection", "webkit-box-direction", chrome("normal"), ff52up("normal")),
+ WEBKIT_BOX_DIRECTION("webkitBoxDirection", "webkit-box-direction", chrome("normal"), ff("normal")),
/** The style property {@code WebkitBoxDirection}. */
- WEBKIT_BOX_DIRECTION_("WebkitBoxDirection", "webkit-box-direction", ff52up("normal")),
+ WEBKIT_BOX_DIRECTION_("WebkitBoxDirection", "webkit-box-direction", ff("normal")),
/** The style property {@code -webkit-box-direction}. */
- WEBKIT_BOX_DIRECTION__("-webkit-box-direction", "webkit-box-direction", ff52up("normal")),
+ WEBKIT_BOX_DIRECTION__("-webkit-box-direction", "webkit-box-direction", ff("normal")),
/** The style property {@code webkitBoxFlex}. */
- WEBKIT_BOX_FLEX("webkitBoxFlex", "webkit-box-flex", chrome("0"), ff52up("0")),
+ WEBKIT_BOX_FLEX("webkitBoxFlex", "webkit-box-flex", chrome("0"), ff("0")),
/** The style property {@code WebkitBoxFlex}. */
- WEBKIT_BOX_FLEX_("WebkitBoxFlex", "webkit-box-flex", ff52up("0")),
+ WEBKIT_BOX_FLEX_("WebkitBoxFlex", "webkit-box-flex", ff("0")),
/** The style property {@code -webkit-box-flex}. */
- WEBKIT_BOX_FLEX__("-webkit-box-flex", "webkit-box-flex", ff52up("0")),
+ WEBKIT_BOX_FLEX__("-webkit-box-flex", "webkit-box-flex", ff("0")),
/** The style property {@code webkitBoxFlexGroup}. */
- WEBKIT_BOX_FLEX_GROUP("webkitBoxFlexGroup", "webkit-box-flex-group", chrome("1")),
+ WEBKIT_BOX_FLEX_GROUP("webkitBoxFlexGroup", "webkit-box-flex-group", chrome("1").setIteratable(false)),
/** The style property {@code webkitBoxLines}. */
- WEBKIT_BOX_LINES("webkitBoxLines", "webkit-box-lines", chrome("single")),
+ WEBKIT_BOX_LINES("webkitBoxLines", "webkit-box-lines", chrome("single").setIteratable(false)),
/** The style property {@code webkitBoxOrdinalGroup}. */
- WEBKIT_BOX_ORDINAL_GROUP("webkitBoxOrdinalGroup", "webkit-box-ordinal-group", chrome("1"), ff52up("1")),
+ WEBKIT_BOX_ORDINAL_GROUP("webkitBoxOrdinalGroup", "webkit-box-ordinal-group", chrome("1"), ff("1")),
/** The style property {@code WebkitBoxOrdinalGroup}. */
- WEBKIT_BOX_ORDINAL_GROUP_("WebkitBoxOrdinalGroup", "webkit-box-ordinal-group", ff52up("1")),
+ WEBKIT_BOX_ORDINAL_GROUP_("WebkitBoxOrdinalGroup", "webkit-box-ordinal-group", ff("1")),
/** The style property {@code -webkit-box-ordinal-group}. */
- WEBKIT_BOX_ORDINAL_GROUP__("-webkit-box-ordinal-group", "webkit-box-ordinal-group", ff52up("1")),
+ WEBKIT_BOX_ORDINAL_GROUP__("-webkit-box-ordinal-group", "webkit-box-ordinal-group", ff("1")),
/** The style property {@code webkitBoxOrient}. */
- WEBKIT_BOX_ORIENT("webkitBoxOrient", "webkit-box-orient", chrome("horizontal"), ff52up("horizontal")),
+ WEBKIT_BOX_ORIENT("webkitBoxOrient", "webkit-box-orient", chrome("horizontal"), ff("horizontal")),
/** The style property {@code WebkitBoxOrient}. */
- WEBKIT_BOX_ORIENT_("WebkitBoxOrient", "webkit-box-orient", ff52up("horizontal")),
+ WEBKIT_BOX_ORIENT_("WebkitBoxOrient", "webkit-box-orient", ff("horizontal")),
/** The style property {@code -webkit-box-orient}. */
- WEBKIT_BOX_ORIENT__("-webkit-box-orient", "webkit-box-orient", ff52up("horizontal")),
+ WEBKIT_BOX_ORIENT__("-webkit-box-orient", "webkit-box-orient", ff("horizontal")),
/** The style property {@code webkitBoxPack}. */
- WEBKIT_BOX_PACK("webkitBoxPack", "webkit-box-pack", chrome("start"), ff52up("start")),
+ WEBKIT_BOX_PACK("webkitBoxPack", "webkit-box-pack", chrome("start"), ff("start")),
/** The style property {@code WebkitBoxPack}. */
- WEBKIT_BOX_PACK_("WebkitBoxPack", "webkit-box-pack", ff52up("start")),
+ WEBKIT_BOX_PACK_("WebkitBoxPack", "webkit-box-pack", ff("start")),
/** The style property {@code -webkit-box-pack}. */
- WEBKIT_BOX_PACK__("-webkit-box-pack", "webkit-box-pack", ff52up("start")),
+ WEBKIT_BOX_PACK__("-webkit-box-pack", "webkit-box-pack", ff("start")),
/** The style property {@code webkitBoxReflect}. */
WEBKIT_BOX_REFLECT("webkitBoxReflect", "webkit-box-reflect", chrome("none")),
/** The style property {@code webkitBoxShadow}. */
- WEBKIT_BOX_SHADOW("webkitBoxShadow", "webkit-box-shadow", ff52up("none")),
+ WEBKIT_BOX_SHADOW("webkitBoxShadow", "webkit-box-shadow", chrome("none"), ff("none")),
/** The style property {@code WebkitBoxShadow}. */
- WEBKIT_BOX_SHADOW_("WebkitBoxShadow", "webkit-box-shadow", ff52up("none")),
+ WEBKIT_BOX_SHADOW_("WebkitBoxShadow", "webkit-box-shadow", ff("none")),
/** The style property {@code -webkit-box-shadow}. */
- WEBKIT_BOX_SHADOW__("-webkit-box-shadow", "webkit-box-shadow", ff52up("none")),
+ WEBKIT_BOX_SHADOW__("-webkit-box-shadow", "webkit-box-shadow", ff("none")),
/** The style property {@code webkitBoxSizing}. */
- WEBKIT_BOX_SIZING("webkitBoxSizing", "webkit-box-sizing", ff52up("content-box")),
+ WEBKIT_BOX_SIZING("webkitBoxSizing", "webkit-box-sizing", chrome("content-box"), ff("content-box")),
/** The style property {@code WebkitBoxSizing}. */
- WEBKIT_BOX_SIZING_("WebkitBoxSizing", "webkit-box-sizing", ff52up("content-box")),
+ WEBKIT_BOX_SIZING_("WebkitBoxSizing", "webkit-box-sizing", ff("content-box")),
/** The style property {@code -webkit-box-sizing}. */
- WEBKIT_BOX_SIZING__("-webkit-box-sizing", "webkit-box-sizing", ff52up("content-box")),
+ WEBKIT_BOX_SIZING__("-webkit-box-sizing", "webkit-box-sizing", ff("content-box")),
+
+ /** The style property {@code webkitClipPath}. */
+ WEBKIT_CLIP_PATH("webkitClipPath", "webkit-clip-path", chrome("none")),
/** The style property {@code webkitColumnBreakAfter}. */
WEBKIT_COLUMN_BREAK_AFTER("webkitColumnBreakAfter", "webkit-column-break-after", chrome("auto")),
@@ -3291,77 +3765,107 @@ public enum Definition {
/** The style property {@code webkitColumnBreakInside}. */
WEBKIT_COLUMN_BREAK_INSIDE("webkitColumnBreakInside", "webkit-column-break-inside", chrome("auto")),
+ /** The style property {@code webkitColumnCount}. */
+ WEBKIT_COLUMN_COUNT("webkitColumnCount", "webkit-column-count", chrome("auto")),
+
+ /** The style property {@code webkitColumnGap}. */
+ WEBKIT_COLUMN_GAP("webkitColumnGap", "webkit-column-gap", chrome("normal")),
+
+ /** The style property {@code webkitColumnRule}. */
+ WEBKIT_COLUMN_RULE("webkitColumnRule", "webkit-column-rule", chrome("0px none rgb(0, 0, 0)")),
+
+ /** The style property {@code webkitColumnRuleColor}. */
+ WEBKIT_COLUMN_RULE_COLOR("webkitColumnRuleColor", "webkit-column-rule-color", chrome("rgb(0, 0, 0)")),
+
+ /** The style property {@code webkitColumnRuleStyle}. */
+ WEBKIT_COLUMN_RULE_STYLE("webkitColumnRuleStyle", "webkit-column-rule-style", chrome("none")),
+
+ /** The style property {@code webkitColumnRuleWidth}. */
+ WEBKIT_COLUMN_RULE_WIDTH("webkitColumnRuleWidth", "webkit-column-rule-width", chrome("0px")),
+
+ /** The style property {@code webkitColumnSpan}. */
+ WEBKIT_COLUMN_SPAN("webkitColumnSpan", "webkit-column-rule-span", chrome("none")),
+
+ /** The style property {@code webkitColumnWidth}. */
+ WEBKIT_COLUMN_WIDTH("webkitColumnWidth", "webkit-column-width", chrome("auto")),
+
+ /** The style property {@code webkitColumns}. */
+ WEBKIT_COLUMNS("webkitColumns", "webkit-columns", chrome("auto auto")),
+
/** The style property {@code webkitFilter}. */
- WEBKIT_FILTER("webkitFilter", "webkit-filter", ff52up("none")),
+ WEBKIT_FILTER("webkitFilter", "webkit-filter", chrome("none"), ff("none")),
/** The style property {@code WebkitFilter}. */
- WEBKIT_FILTER_("WebkitFilter", "webkit-filter", ff52up("none")),
+ WEBKIT_FILTER_("WebkitFilter", "webkit-filter", ff("none")),
/** The style property {@code -webkit-filter}. */
- WEBKIT_FILTER__("-webkit-filter", "webkit-filter", ff52up("none")),
+ WEBKIT_FILTER__("-webkit-filter", "webkit-filter", ff("none")),
/** The style property {@code webkitFlex}. */
- WEBKIT_FLEX("webkitFlex", "webkit-flex", ff52up("")),
+ WEBKIT_FLEX("webkitFlex", "webkit-flex", chrome("0 1 auto"), ff("")),
/** The style property {@code WebkitFlex}. */
- WEBKIT_FLEX_("WebkitFlex", "webkit-flex", ff52up("")),
+ WEBKIT_FLEX_("WebkitFlex", "webkit-flex", ff("")),
/** The style property {@code -webkit-flex}. */
- WEBKIT_FLEX__("-webkit-flex", "webkit-flex", ff52up("")),
+ WEBKIT_FLEX__("-webkit-flex", "webkit-flex", ff("")),
/** The style property {@code webkitFlexBasis}. */
- WEBKIT_FLEX_BASIS("webkitFlexBasis", "webkit-flex-basis", ff52up("auto")),
+ WEBKIT_FLEX_BASIS("webkitFlexBasis", "webkit-flex-basis", chrome("auto"), ff("auto")),
/** The style property {@code WebkitFlexBasis}. */
- WEBKIT_FLEX_BASIS_("WebkitFlexBasis", "webkit-flex-basis", ff52up("auto")),
+ WEBKIT_FLEX_BASIS_("WebkitFlexBasis", "webkit-flex-basis", ff("auto")),
/** The style property {@code -webkit-flex-basis}. */
- WEBKIT_FLEX_BASIS__("-webkit-flex-basis", "webkit-flex-basis", ff52up("auto")),
+ WEBKIT_FLEX_BASIS__("-webkit-flex-basis", "webkit-flex-basis", ff("auto")),
/** The style property {@code webkitFlexDirection}. */
- WEBKIT_FLEX_DIRECTION("webkitFlexDirection", "webkit-flex-direction", ff52up("row")),
+ WEBKIT_FLEX_DIRECTION("webkitFlexDirection", "webkit-flex-direction", chrome("row"), ff("row")),
/** The style property {@code WebkitFlexDirection}. */
- WEBKIT_FLEX_DIRECTION_("WebkitFlexDirection", "webkit-flex-direction", ff52up("row")),
+ WEBKIT_FLEX_DIRECTION_("WebkitFlexDirection", "webkit-flex-direction", ff("row")),
/** The style property {@code -webkit-flex-direction}. */
- WEBKIT_FLEX_DIRECTION__("-webkit-flex-direction", "webkit-flex-direction", ff52up("row")),
+ WEBKIT_FLEX_DIRECTION__("-webkit-flex-direction", "webkit-flex-direction", ff("row")),
/** The style property {@code webkitFlexFlow}. */
- WEBKIT_FLEX_FLOW("webkitFlexFlow", "webkit-flex-flow", ff52up("")),
+ WEBKIT_FLEX_FLOW("webkitFlexFlow", "webkit-flex-flow", chrome("row nowrap"), ff("")),
/** The style property {@code WebkitFlexFlow}. */
- WEBKIT_FLEX_FLOW_("WebkitFlexFlow", "webkit-flex-flow", ff52up("")),
+ WEBKIT_FLEX_FLOW_("WebkitFlexFlow", "webkit-flex-flow", ff("")),
/** The style property {@code -webkit-flex-flow}. */
- WEBKIT_FLEX_FLOW__("-webkit-flex-flow", "webkit-flex-flow", ff52up("")),
+ WEBKIT_FLEX_FLOW__("-webkit-flex-flow", "webkit-flex-flow", ff("")),
/** The style property {@code webkitFlexGrow}. */
- WEBKIT_FLEX_GROW("webkitFlexGrow", "webkit-flex-grow", ff52up("0")),
+ WEBKIT_FLEX_GROW("webkitFlexGrow", "webkit-flex-grow", chrome("0"), ff("0")),
/** The style property {@code WebkitFlexGrow}. */
- WEBKIT_FLEX_GROW_("WebkitFlexGrow", "webkit-flex-grow", ff52up("0")),
+ WEBKIT_FLEX_GROW_("WebkitFlexGrow", "webkit-flex-grow", ff("0")),
/** The style property {@code -webkit-flex-grow}. */
- WEBKIT_FLEX_GROW__("-webkit-flex-grow", "webkit-flex-grow", ff52up("0")),
+ WEBKIT_FLEX_GROW__("-webkit-flex-grow", "webkit-flex-grow", ff("0")),
/** The style property {@code webkitFlexShrink}. */
- WEBKIT_FLEX_SHRINK("webkitFlexShrink", "webkit-flex-shrink", ff52up("1")),
+ WEBKIT_FLEX_SHRINK("webkitFlexShrink", "webkit-flex-shrink", chrome("1"), ff("1")),
/** The style property {@code WebkitFlexShrink}. */
- WEBKIT_FLEX_SHRINK_("WebkitFlexShrink", "webkit-flex-shrink", ff52up("1")),
+ WEBKIT_FLEX_SHRINK_("WebkitFlexShrink", "webkit-flex-shrink", ff("1")),
/** The style property {@code -webkit-flex-shrink}. */
- WEBKIT_FLEX_SHRINK__("-webkit-flex-shrink", "webkit-flex-shrink", ff52up("1")),
+ WEBKIT_FLEX_SHRINK__("-webkit-flex-shrink", "webkit-flex-shrink", ff("1")),
/** The style property {@code webkitFlexWrap}. */
- WEBKIT_FLEX_WRAP("webkitFlexWrap", "webkit-flex-wrap", ff52up("nowrap")),
+ WEBKIT_FLEX_WRAP("webkitFlexWrap", "webkit-flex-wrap", chrome("nowrap"), ff("nowrap")),
/** The style property {@code WebkitFlexWrap}. */
- WEBKIT_FLEX_WRAP_("WebkitFlexWrap", "webkit-flex-wrap", ff52up("nowrap")),
+ WEBKIT_FLEX_WRAP_("WebkitFlexWrap", "webkit-flex-wrap", ff("nowrap")),
/** The style property {@code -webkit-flex-wrap}. */
- WEBKIT_FLEX_WRAP__("-webkit-flex-wrap", "webkit-flex-wrap", ff52up("nowrap")),
+ WEBKIT_FLEX_WRAP__("-webkit-flex-wrap", "webkit-flex-wrap", ff("nowrap")),
+
+ /** The style property {@code webkitFontFeatureSettings}. */
+ WEBKIT_FONT_FEATURE_SETTINGS("webkitFontFeatureSettings", "webkit-font-feature-settings", chrome("normal")),
/** The style property {@code webkitFontSizeDelta}. */
WEBKIT_FONT_SIZE_DELTA("webkitFontSizeDelta", "webkit-font-size-delta", chrome("")),
@@ -3376,19 +3880,25 @@ public enum Definition {
WEBKIT_HYPHENATE_CHARACTER("webkitHyphenateCharacter", "webkit-hyphenate-character", chrome("auto")),
/** The style property {@code webkitJustifyContent}. */
- WEBKIT_JUSTIFY_CONTENT("webkitJustifyContent", "webkit-justify-content", ff52up("normal")),
+ WEBKIT_JUSTIFY_CONTENT("webkitJustifyContent", "webkit-justify-content", chrome("normal"), ff("normal")),
/** The style property {@code WebkitJustifyContent}. */
- WEBKIT_JUSTIFY_CONTENT_("WebkitJustifyContent", "webkit-justify-content", ff52up("normal")),
+ WEBKIT_JUSTIFY_CONTENT_("WebkitJustifyContent", "webkit-justify-content", ff("normal")),
/** The style property {@code -webkit-justify-content}. */
- WEBKIT_JUSTIFY_CONTENT__("-webkit-justify-content", "webkit-justify-content", ff52up("normal")),
+ WEBKIT_JUSTIFY_CONTENT__("-webkit-justify-content", "webkit-justify-content", ff("normal")),
/** The style property {@code webkitLineBreak}. */
WEBKIT_LINE_BREAK("webkitLineBreak", "webkit-line-break", chrome("auto")),
/** The style property {@code webkitLineClamp}. */
- WEBKIT_LINE_CLAMP("webkitLineClamp", "webkit-line-clamp", chrome("none")),
+ WEBKIT_LINE_CLAMP("webkitLineClamp", "webkit-line-clamp", chrome("none"), ff68up("none")),
+
+ /** The style property {@code WebkitLineClamp}. */
+ WEBKIT_LINE_CLAMP_("WebkitLineClamp", "webkit-line-clamp", ff68up("none")),
+
+ /** The style property {@code -webkit-line-clamp}. */
+ WEBKIT_LINE_CLAMP__("-webkit-line-clamp", "webkit-line-clamp", ff68up("none")),
/** The style property {@code webkitLocale}. */
WEBKIT_LOCALE("webkitLocale", "webkit-locale", chrome("auto")),
@@ -3429,7 +3939,13 @@ public enum Definition {
WEBKIT_MARGIN_TOP_COLLAPSE("webkitMarginTopCollapse", "webkit-margin-top-collapse", chrome("collapse")),
/** The style property {@code webkitMask}. */
- WEBKIT_MASK("webkitMask", "webkit-mask", chrome("")),
+ WEBKIT_MASK("webkitMask", "webkit-mask", chrome(""), ff("none")),
+
+ /** The style property {@code WebkitMask}. */
+ WEBKIT_MASK_("WebkitMask", "webkit-mask", ff("none")),
+
+ /** The style property {@code -webkit-mask}. */
+ WEBKIT_MASK__("-webkit-mask", "webkit-mask", ff("none")),
/** The style property {@code webkitMaskBoxImage}. */
WEBKIT_MASK_BOX_IMAGE("webkitMaskBoxImage", "webkit-mask-box-image", chrome("none")),
@@ -3450,28 +3966,76 @@ public enum Definition {
WEBKIT_MASK_BOX_IMAGE_WIDTH("webkitMaskBoxImageWidth", "webkit-mask-box-image-width", chrome("auto")),
/** The style property {@code webkitMaskClip}. */
- WEBKIT_MASK_CLIP("webkitMaskClip", "webkit-mask-clip", chrome("border-box")),
+ WEBKIT_MASK_CLIP("webkitMaskClip", "webkit-mask-clip", chrome("border-box"), ff("border-box")),
+
+ /** The style property {@code WebkitMaskClip}. */
+ WEBKIT_MASK_CLIP_("WebkitMaskClip", "webkit-mask-clip", ff("border-box")),
+
+ /** The style property {@code -webkit-mask-clip}. */
+ WEBKIT_MASK_CLIP__("-webkit-mask-clip", "webkit-mask-clip", ff("border-box")),
/** The style property {@code webkitMaskComposite}. */
- WEBKIT_MASK_COMPOSITE("webkitMaskComposite", "webkit-mask-composite", chrome("source-over")),
+ WEBKIT_MASK_COMPOSITE("webkitMaskComposite", "webkit-mask-composite", chrome("source-over"), ff("add")),
+
+ /** The style property {@code WebkitMaskComposite}. */
+ WEBKIT_MASK_COMPOSITE_("WebkitMaskComposite", "webkit-mask-composite", ff("add")),
+
+ /** The style property {@code -webkit-mask-composite}. */
+ WEBKIT_MASK_COMPOSITE__("-webkit-mask-composite", "webkit-mask-composite", ff("add")),
/** The style property {@code webkitMaskImage}. */
- WEBKIT_MASK_IMAGE("webkitMaskImage", "webkit-mask-image", chrome("none")),
+ WEBKIT_MASK_IMAGE("webkitMaskImage", "webkit-mask-image", chrome("none"), ff("none")),
+
+ /** The style property {@code WebkitMaskImage}. */
+ WEBKIT_MASK_IMAGE_("WebkitMaskImage", "webkit-mask-image", ff("none")),
+
+ /** The style property {@code -webkit-mask-image}. */
+ WEBKIT_MASK_IMAGE__("-webkit-mask-image", "webkit-mask-image", ff("none")),
/** The style property {@code webkitMaskOrigin}. */
- WEBKIT_MASK_ORIGIN("webkitMaskOrigin", "webkit-mask-origin", chrome("border-box")),
+ WEBKIT_MASK_ORIGIN("webkitMaskOrigin", "webkit-mask-origin", chrome("border-box"), ff("border-box")),
+
+ /** The style property {@code WebkitMaskOrigin}. */
+ WEBKIT_MASK_ORIGIN_("WebkitMaskOrigin", "webkit-mask-origin", ff("border-box")),
+
+ /** The style property {@code -webkit-mask-origin}. */
+ WEBKIT_MASK_ORIGIN__("-webkit-mask-origin", "webkit-mask-origin", ff("border-box")),
/** The style property {@code webkitMaskPosition}. */
- WEBKIT_MASK_POSITION("webkitMaskPosition", "webkit-mask-position", chrome("0% 0%")),
+ WEBKIT_MASK_POSITION("webkitMaskPosition", "webkit-mask-position", chrome("0% 0%"), ff("0% 0%")),
+
+ /** The style property {@code WebkitMaskPosition}. */
+ WEBKIT_MASK_POSITION_("WebkitMaskPosition", "webkit-mask-position", ff("0% 0%")),
+
+ /** The style property {@code -webkit-mask-position}. */
+ WEBKIT_MASK_POSITION__("-webkit-mask-position", "webkit-mask-position", ff("0% 0%")),
/** The style property {@code webkitMaskPositionX}. */
- WEBKIT_MASK_POSITION_X("webkitMaskPositionX", "webkit-mask-position-x", chrome("0%")),
+ WEBKIT_MASK_POSITION_X("webkitMaskPositionX", "webkit-mask-position-x", chrome("0%"), ff("0%")),
+
+ /** The style property {@code WebkitMaskPositionX}. */
+ WEBKIT_MASK_POSITION_X_("WebkitMaskPositionX", "webkit-mask-position-x", ff("0%")),
+
+ /** The style property {@code -webkit-mask-position-x}. */
+ WEBKIT_MASK_POSITION_X__("-webkit-mask-position-x", "webkit-mask-position-x", ff("0%")),
/** The style property {@code webkitMaskPositionY}. */
- WEBKIT_MASK_POSITION_Y("webkitMaskPositionY", "webkit-mask-position-y", chrome("0%")),
+ WEBKIT_MASK_POSITION_Y("webkitMaskPositionY", "webkit-mask-position-y", chrome("0%"), ff("0%")),
+
+ /** The style property {@code WebkitMaskPositionY}. */
+ WEBKIT_MASK_POSITION_Y_("WebkitMaskPositionY", "webkit-mask-position-y", ff("0%")),
+
+ /** The style property {@code -webkit-mask-position-y}. */
+ WEBKIT_MASK_POSITION_Y__("-webkit-mask-position-y", "webkit-mask-position-y", ff("0%")),
/** The style property {@code webkitMaskRepeat}. */
- WEBKIT_MASK_REPEAT("webkitMaskRepeat", "webkit-mask-repeat", chrome("repeat")),
+ WEBKIT_MASK_REPEAT("webkitMaskRepeat", "webkit-mask-repeat", chrome("repeat"), ff("repeat")),
+
+ /** The style property {@code WebkitMaskRepeat}. */
+ WEBKIT_MASK_REPEAT_("WebkitMaskRepeat", "webkit-mask-repeat", ff("repeat")),
+
+ /** The style property {@code -webkit-mask-repeat}. */
+ WEBKIT_MASK_REPEAT__("-webkit-mask-repeat", "webkit-mask-repeat", ff("repeat")),
/** The style property {@code webkitMaskRepeatX}. */
WEBKIT_MASK_REPEAT_X("webkitMaskRepeatX", "webkit-mask-repeat-x", chrome("")),
@@ -3480,7 +4044,13 @@ public enum Definition {
WEBKIT_MASK_REPEAT_Y("webkitMaskRepeatY", "webkit-mask-repeat-y", chrome("")),
/** The style property {@code webkitMaskSize}. */
- WEBKIT_MASK_SIZE("webkitMaskSize", "webkit-mask-size", chrome("auto")),
+ WEBKIT_MASK_SIZE("webkitMaskSize", "webkit-mask-size", chrome("auto"), ffBelow68("auto auto"), ff68up("auto")),
+
+ /** The style property {@code WebkitMaskSize}. */
+ WEBKIT_MASK_SIZE_("WebkitMaskSize", "webkit-mask-size", ffBelow68("auto auto"), ff68up("auto")),
+
+ /** The style property {@code -webkit-mask-size}. */
+ WEBKIT_MASK_SIZE__("-webkit-mask-size", "webkit-mask-size", ffBelow68("auto auto"), ff68up("auto")),
/** The style property {@code webkitMaxLogicalHeight}. */
WEBKIT_MAX_LOGICAL_HEIGHT("webkitMaxLogicalHeight", "webkit-max-logical-height", chrome("none")),
@@ -3494,14 +4064,17 @@ public enum Definition {
/** The style property {@code webkitMinLogicalWidth}. */
WEBKIT_MIN_LOGICAL_WIDTH("webkitMinLogicalWidth", "webkit-min-logical-width", chrome("0px")),
+ /** The style property {@code webkitOpacity}. */
+ WEBKIT_OPACITY("webkitOpacity", "webkit-opacity", chrome("1")),
+
/** The style property {@code webkitOrder}. */
- WEBKIT_ORDER("webkitOrder", "webkit-order", ff52up("0")),
+ WEBKIT_ORDER("webkitOrder", "webkit-order", chrome("0"), ff("0")),
/** The style property {@code WebkitOrder}. */
- WEBKIT_ORDER_("WebkitOrder", "webkit-order", ff52up("0")),
+ WEBKIT_ORDER_("WebkitOrder", "webkit-order", ff("0")),
/** The style property {@code -webkit-order}. */
- WEBKIT_ORDER__("-webkit-order", "webkit-order", ff52up("0")),
+ WEBKIT_ORDER__("-webkit-order", "webkit-order", ff("0")),
/** The style property {@code webkitPaddingAfter}. */
WEBKIT_PADDING_AFTER("webkitPaddingAfter", "webkit-padding-after", chrome("0px")),
@@ -3516,22 +4089,25 @@ public enum Definition {
WEBKIT_PADDING_START("webkitPaddingStart", "webkit-padding-start", chrome("0px")),
/** The style property {@code webkitPerspective}. */
- WEBKIT_PERSPECTIVE("webkitPerspective", "webkit-perspective", ff52up("none")),
+ WEBKIT_PERSPECTIVE("webkitPerspective", "webkit-perspective", chrome("none"), ff("none")),
/** The style property {@code WebkitPerspective}. */
- WEBKIT_PERSPECTIVE_("WebkitPerspective", "webkit-perspective", ff52up("none")),
+ WEBKIT_PERSPECTIVE_("WebkitPerspective", "webkit-perspective", ff("none")),
/** The style property {@code -webkit-perspective}. */
- WEBKIT_PERSPECTIVE__("-webkit-perspective", "webkit-perspective", ff52up("none")),
+ WEBKIT_PERSPECTIVE__("-webkit-perspective", "webkit-perspective", ff("none")),
/** The style property {@code webkitPerspectiveOrigin}. */
- WEBKIT_PERSPECTIVE_ORIGIN("webkitPerspectiveOrigin", "webkit-perspective-origin", ff52up("625px 172.5px")),
+ WEBKIT_PERSPECTIVE_ORIGIN("webkitPerspectiveOrigin", "webkit-perspective-origin",
+ chrome("456.5px 161px"), ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code WebkitPerspectiveOrigin}. */
- WEBKIT_PERSPECTIVE_ORIGIN_("WebkitPerspectiveOrigin", "webkit-perspective-origin", ff52up("625px 172.5px")),
+ WEBKIT_PERSPECTIVE_ORIGIN_("WebkitPerspectiveOrigin", "webkit-perspective-origin",
+ ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code -webkit-perspective-origin}. */
- WEBKIT_PERSPECTIVE_ORIGIN__("-webkit-perspective-origin", "webkit-perspective-origin", ff52up("625px 172.5px")),
+ WEBKIT_PERSPECTIVE_ORIGIN__("-webkit-perspective-origin", "webkit-perspective-origin",
+ ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code webkitPerspectiveOriginX}. */
WEBKIT_PERSPECTIVE_ORIGIN_X("webkitPerspectiveOriginX", "webkit-perspective-origin-x", chrome("")),
@@ -3548,6 +4124,15 @@ public enum Definition {
/** The style property {@code webkitRubyPosition}. */
WEBKIT_RUBY_POSITION("webkitRubyPosition", "webkit-ruby-position", chrome("before")),
+ /** The style property {@code webkitShapeImageThreshold}. */
+ WEBKIT_SHAPE_IMAGE_THRESHOLD("webkitShapeImageThreshold", "webkit-shape-image-threshold", chrome("0")),
+
+ /** The style property {@code webkitShapeMargin}. */
+ WEBKIT_SHAPE_MARGIN("webkitShapeMargin", "webkit-shape-margin", chrome("0px")),
+
+ /** The style property {@code webkitShapeOutside}. */
+ WEBKIT_SHAPE_OUTSIDE("webkitShapeOutside", "webkit-shape-outside", chrome("none")),
+
/** The style property {@code webkitTapHighlightColor}. */
WEBKIT_TAP_HIGHLIGHT_COLOR("webkitTapHighlightColor", "webkit-tap-highlight-color",
chrome("rgba(0, 0, 0, 0.18)")),
@@ -3576,15 +4161,15 @@ public enum Definition {
/** The style property {@code webkitTextFillColor}. */
WEBKIT_TEXT_FILL_COLOR("webkitTextFillColor", "webkit-text-fill-color",
- chrome("rgb(0, 0, 0)"), ff52up("rgb(0, 0, 0)")),
+ chrome("rgb(0, 0, 0)"), ff("rgb(0, 0, 0)")),
/** The style property {@code WebkitTextFillColor}. */
WEBKIT_TEXT_FILL_COLOR_("WebkitTextFillColor", "webkit-text-fill-color",
- ff52up("rgb(0, 0, 0)")),
+ ff("rgb(0, 0, 0)")),
/** The style property {@code -webkit-text-fill-color}. */
WEBKIT_TEXT_FILL_COLOR__("-webkit-text-fill-color", "webkit-text-fill-color",
- ff52up("rgb(0, 0, 0)")),
+ ff("rgb(0, 0, 0)")),
/** The style property {@code webkitTextOrientation}. */
WEBKIT_TEXT_ORIENTATION("webkitTextOrientation", "webkit-text-orientation", chrome("vertical-right")),
@@ -3593,61 +4178,64 @@ public enum Definition {
WEBKIT_TEXT_SECURITY("webkitTextSecurity", "webkit-text-security", chrome("none")),
/** The style property {@code webkitTextSizeAdjust}. */
- WEBKIT_TEXT_SIZE_ADJUST("webkitTextSizeAdjust", "webkit-text-size-adjust", ff52up("auto")),
+ WEBKIT_TEXT_SIZE_ADJUST("webkitTextSizeAdjust", "webkit-text-size-adjust", chrome("auto"), ff("auto")),
/** The style property {@code WebkitTextSizeAdjust}. */
- WEBKIT_TEXT_SIZE_ADJUST_("WebkitTextSizeAdjust", "webkit-text-size-adjust", ff52up("auto")),
+ WEBKIT_TEXT_SIZE_ADJUST_("WebkitTextSizeAdjust", "webkit-text-size-adjust", ff("auto")),
/** The style property {@code -webkit-text-size-adjust}. */
- WEBKIT_TEXT_SIZE_ADJUST__("-webkit-text-size-adjust", "webkit-text-size-adjust", ff52up("auto")),
+ WEBKIT_TEXT_SIZE_ADJUST__("-webkit-text-size-adjust", "webkit-text-size-adjust", ff("auto")),
/** The style property {@code webkitTextStroke}. */
- WEBKIT_TEXT_STROKE("webkitTextStroke", "webkit-text-stroke", chrome(""), ff52up("")),
+ WEBKIT_TEXT_STROKE("webkitTextStroke", "webkit-text-stroke", chrome(""), ff("")),
/** The style property {@code WebkitTextStroke}. */
- WEBKIT_TEXT_STROKE_("WebkitTextStroke", "webkit-text-stroke", ff52up("")),
+ WEBKIT_TEXT_STROKE_("WebkitTextStroke", "webkit-text-stroke", ff("")),
/** The style property {@code -webkit-text-stroke}. */
- WEBKIT_TEXT_STROKE__("-webkit-text-stroke", "webkit-text-stroke", ff52up("")),
+ WEBKIT_TEXT_STROKE__("-webkit-text-stroke", "webkit-text-stroke", ff("")),
/** The style property {@code webkitTextStrokeColor}. */
WEBKIT_TEXT_STROKE_COLOR("webkitTextStrokeColor", "webkit-text-stroke-color",
- chrome("rgb(0, 0, 0)"), ff52up("rgb(0, 0, 0)")),
+ chrome("rgb(0, 0, 0)"), ff("rgb(0, 0, 0)")),
/** The style property {@code WebkitTextStrokeColor}. */
WEBKIT_TEXT_STROKE_COLOR_("WebkitTextStrokeColor", "webkit-text-stroke-color",
- ff52up("rgb(0, 0, 0)")),
+ ff("rgb(0, 0, 0)")),
/** The style property {@code -webkit-text-stroke-color}. */
WEBKIT_TEXT_STROKE_COLOR__("-webkit-text-stroke-color", "webkit-text-stroke-color",
- ff52up("rgb(0, 0, 0)")),
+ ff("rgb(0, 0, 0)")),
/** The style property {@code webkitTextStrokeWidth}. */
- WEBKIT_TEXT_STROKE_WIDTH("webkitTextStrokeWidth", "webkit-text-stroke-width", chrome("0px"), ff52up("0px")),
+ WEBKIT_TEXT_STROKE_WIDTH("webkitTextStrokeWidth", "webkit-text-stroke-width", chrome("0px"), ff("0px")),
/** The style property {@code WebkitTextStrokeWidth}. */
- WEBKIT_TEXT_STROKE_WIDTH_("WebkitTextStrokeWidth", "webkit-text-stroke-width", ff52up("0px")),
+ WEBKIT_TEXT_STROKE_WIDTH_("WebkitTextStrokeWidth", "webkit-text-stroke-width", ff("0px")),
/** The style property {@code -webkit-text-stroke-width}. */
- WEBKIT_TEXT_STROKE_WIDTH__("-webkit-text-stroke-width", "webkit-text-stroke-width", ff52up("0px")),
+ WEBKIT_TEXT_STROKE_WIDTH__("-webkit-text-stroke-width", "webkit-text-stroke-width", ff("0px")),
/** The style property {@code webkitTransform}. */
- WEBKIT_TRANSFORM("webkitTransform", "webkit-transform", ff52up("none")),
+ WEBKIT_TRANSFORM("webkitTransform", "webkit-transform", chrome("none"), ff("none")),
/** The style property {@code WebkitTransform}. */
- WEBKIT_TRANSFORM_("WebkitTransform", "webkit-transform", ff52up("none")),
+ WEBKIT_TRANSFORM_("WebkitTransform", "webkit-transform", ff("none")),
/** The style property {@code -webkit-transform}. */
- WEBKIT_TRANSFORM__("-webkit-transform", "webkit-transform", ff52up("none")),
+ WEBKIT_TRANSFORM__("-webkit-transform", "webkit-transform", ff("none")),
/** The style property {@code webkitTransformOrigin}. */
- WEBKIT_TRANSFORM_ORIGIN("webkitTransformOrigin", "webkit-transform-origin", ff52up("625px 172.5px")),
+ WEBKIT_TRANSFORM_ORIGIN("webkitTransformOrigin", "webkit-transform-origin",
+ chrome("620px 161px"), ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code WebkitTransformOrigin}. */
- WEBKIT_TRANSFORM_ORIGIN_("WebkitTransformOrigin", "webkit-transform-origin", ff52up("625px 172.5px")),
+ WEBKIT_TRANSFORM_ORIGIN_("WebkitTransformOrigin", "webkit-transform-origin",
+ ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code -webkit-transform-origin}. */
- WEBKIT_TRANSFORM_ORIGIN__("-webkit-transform-origin", "webkit-transform-origin", ff52up("625px 172.5px")),
+ WEBKIT_TRANSFORM_ORIGIN__("-webkit-transform-origin", "webkit-transform-origin",
+ ffBelow68("625px 172.5px"), ff68up("621px 171.5px")),
/** The style property {@code webkitTransformOriginX}. */
WEBKIT_TRANSFORM_ORIGIN_X("webkitTransformOriginX", "webkit-transform-origin-x", chrome("")),
@@ -3659,61 +4247,61 @@ public enum Definition {
WEBKIT_TRANSFORM_ORIGIN_Z("webkitTransformOriginZ", "webkit-transform-origin-z", chrome("")),
/** The style property {@code webkitTransformStyle}. */
- WEBKIT_TRANSFORM_STYLE("webkitTransformStyle", "webkit-transform-style", ff52up("flat")),
+ WEBKIT_TRANSFORM_STYLE("webkitTransformStyle", "webkit-transform-style", chrome("flat"), ff("flat")),
/** The style property {@code WebkitTransformStyle}. */
- WEBKIT_TRANSFORM_STYLE_("WebkitTransformStyle", "webkit-transform-style", ff52up("flat")),
+ WEBKIT_TRANSFORM_STYLE_("WebkitTransformStyle", "webkit-transform-style", ff("flat")),
/** The style property {@code -webkit-transform-style}. */
- WEBKIT_TRANSFORM_STYLE__("-webkit-transform-style", "webkit-transform-style", ff52up("flat")),
+ WEBKIT_TRANSFORM_STYLE__("-webkit-transform-style", "webkit-transform-style", ff("flat")),
/** The style property {@code webkitTransition}. */
- WEBKIT_TRANSITION("webkitTransition", "webkit-transition", ff52up("")),
+ WEBKIT_TRANSITION("webkitTransition", "webkit-transition", chrome("all 0s ease 0s"), ff("")),
/** The style property {@code WebkitTransition}. */
- WEBKIT_TRANSITION_("WebkitTransition", "webkit-transition", ff52up("")),
+ WEBKIT_TRANSITION_("WebkitTransition", "webkit-transition", ff("")),
/** The style property {@code -webkit-transition}. */
- WEBKIT_TRANSITION__("-webkit-transition", "webkit-transition", ff52up("")),
+ WEBKIT_TRANSITION__("-webkit-transition", "webkit-transition", ff("")),
/** The style property {@code webkitTransitionDelay}. */
- WEBKIT_TRANSITION_DELAY("webkitTransitionDelay", "webkit-transition-delay", ff52up("0s")),
+ WEBKIT_TRANSITION_DELAY("webkitTransitionDelay", "webkit-transition-delay", chrome("0s"), ff("0s")),
/** The style property {@code WebkitTransitionDelay}. */
- WEBKIT_TRANSITION_DELAY_("WebkitTransitionDelay", "webkit-transition-delay", ff52up("0s")),
+ WEBKIT_TRANSITION_DELAY_("WebkitTransitionDelay", "webkit-transition-delay", ff("0s")),
/** The style property {@code -webkit-transition-delay}. */
- WEBKIT_TRANSITION_DELAY__("-webkit-transition-delay", "webkit-transition-delay", ff52up("0s")),
+ WEBKIT_TRANSITION_DELAY__("-webkit-transition-delay", "webkit-transition-delay", ff("0s")),
/** The style property {@code webkitTransitionDuration}. */
- WEBKIT_TRANSITION_DURATION("webkitTransitionDuration", "webkit-transition-duration", ff52up("0s")),
+ WEBKIT_TRANSITION_DURATION("webkitTransitionDuration", "webkit-transition-duration", chrome("0s"), ff("0s")),
/** The style property {@code WebkitTransitionDuration}. */
- WEBKIT_TRANSITION_DURATION_("WebkitTransitionDuration", "webkit-transition-duration", ff52up("0s")),
+ WEBKIT_TRANSITION_DURATION_("WebkitTransitionDuration", "webkit-transition-duration", ff("0s")),
/** The style property {@code -webkit-transition-duration}. */
- WEBKIT_TRANSITION_DURATION__("-webkit-transition-duration", "webkit-transition-duration", ff52up("0s")),
+ WEBKIT_TRANSITION_DURATION__("-webkit-transition-duration", "webkit-transition-duration", ff("0s")),
/** The style property {@code webkitTransitionProperty}. */
- WEBKIT_TRANSITION_PROPERTY("webkitTransitionProperty", "webkit-transition-property", ff52up("all")),
+ WEBKIT_TRANSITION_PROPERTY("webkitTransitionProperty", "webkit-transition-property", chrome("all"), ff("all")),
/** The style property {@code WebkitTransitionProperty}. */
- WEBKIT_TRANSITION_PROPERTY_("WebkitTransitionProperty", "webkit-transition-property", ff52up("all")),
+ WEBKIT_TRANSITION_PROPERTY_("WebkitTransitionProperty", "webkit-transition-property", ff("all")),
/** The style property {@code -webkit-transition-property}. */
- WEBKIT_TRANSITION_PROPERTY__("-webkit-transition-property", "webkit-transition-property", ff52up("all")),
+ WEBKIT_TRANSITION_PROPERTY__("-webkit-transition-property", "webkit-transition-property", ff("all")),
/** The style property {@code webkitTransitionTimingFunction}. */
WEBKIT_TRANSITION_TIMING_FUNCTION("webkitTransitionTimingFunction", "webkit-transition-timing-function",
- ff52up("ease")),
+ chrome("ease"), ff("ease")),
/** The style property {@code WebkitTransitionTimingFunction}. */
WEBKIT_TRANSITION_TIMING_FUNCTION_("WebkitTransitionTimingFunction", "webkit-transition-timing-function",
- ff52up("ease")),
+ ff("ease")),
/** The style property {@code -webkit-transition-timing-function}. */
WEBKIT_TRANSITION_TIMING_FUNCTION__("-webkit-transition-timing-function", "webkit-transition-timing-function",
- ff52up("ease")),
+ ff("ease")),
/** The style property {@code webkitUserDrag}. */
WEBKIT_USER_DRAG("webkitUserDrag", "webkit-user-drag", chrome("auto")),
@@ -3722,13 +4310,13 @@ public enum Definition {
WEBKIT_USER_MODIFY("webkitUserModify", "webkit-user-modify", chrome("read-only")),
/** The style property {@code webkitUserSelect}. */
- WEBKIT_USER_SELECT("webkitUserSelect", "webkit-user-select", ff52up("auto")),
+ WEBKIT_USER_SELECT("webkitUserSelect", "webkit-user-select", chrome("auto"), ff("auto")),
/** The style property {@code WebkitUserSelect}. */
- WEBKIT_USER_SELECT_("WebkitUserSelect", "webkit-user-select", ff52up("auto")),
+ WEBKIT_USER_SELECT_("WebkitUserSelect", "webkit-user-select", ff("auto")),
/** The style property {@code -webkit-user-select}. */
- WEBKIT_USER_SELECT__("-webkit-user-select", "webkit-user-select", ff52up("auto")),
+ WEBKIT_USER_SELECT__("-webkit-user-select", "webkit-user-select", ff("auto")),
/** The style property {@code webkitWritingMode}. */
WEBKIT_WRITING_MODE("webkitWritingMode", "webkit-writing-mode", chrome("horizontal-tb")),
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleMedia.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleMedia.java
index e760a8bf6fa..36b4da58632 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleMedia.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleMedia.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,15 +15,12 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
-import org.w3c.dom.stylesheets.MediaList;
-
+import com.gargoylesoftware.css.dom.MediaListImpl;
import com.gargoylesoftware.css.parser.CSSErrorHandler;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxGetter;
@@ -31,15 +28,15 @@
* A JavaScript object for {@code StyleMedia}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
@JsxClass(isJSObject = false, value = CHROME)
-@JsxClass({IE, EDGE})
+@JsxClass(IE)
public class StyleMedia extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor(EDGE)
public StyleMedia() {
}
@@ -60,7 +57,7 @@ public String getType() {
@JsxFunction
public boolean matchMedium(final String media) {
final CSSErrorHandler errorHandler = getWindow().getWebWindow().getWebClient().getCssErrorHandler();
- final MediaList mediaList = CSSStyleSheet.parseMedia(errorHandler, media);
+ final MediaListImpl mediaList = CSSStyleSheet.parseMedia(errorHandler, media);
return CSSStyleSheet.isActive(this, mediaList);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheet.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheet.java
index c71ab5a4f8f..118a868b8f3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheet.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheet.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class StyleSheet extends SimpleScriptable {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public StyleSheet() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheetList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheetList.java
index 74a12d9bd94..ec5db8d7812 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheetList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/StyleSheetList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,12 +16,11 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_STYLESHEETLIST_ACTIVE_ONLY;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import org.apache.commons.lang3.StringUtils;
-import org.w3c.dom.stylesheets.MediaList;
+import com.gargoylesoftware.css.dom.MediaListImpl;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.HtmlAttributeChangeEvent;
@@ -103,7 +102,7 @@ public boolean isActiveStyleSheetLink(final DomNode domNode) {
return true;
}
final WebClient webClient = getWindow().getWebWindow().getWebClient();
- final MediaList mediaList = CSSStyleSheet.parseMedia(webClient.getCssErrorHandler(), media);
+ final MediaListImpl mediaList = CSSStyleSheet.parseMedia(webClient.getCssErrorHandler(), media);
return CSSStyleSheet.isActive(this, mediaList);
}
}
@@ -113,7 +112,7 @@ public boolean isActiveStyleSheetLink(final DomNode domNode) {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public StyleSheetList() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/WebKitCSSMatrix.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/WebKitCSSMatrix.java
index 3b6f0f241a5..44b71c81c9a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/WebKitCSSMatrix.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/WebKitCSSMatrix.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,20 +15,20 @@
package com.gargoylesoftware.htmlunit.javascript.host.css;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
+import com.gargoylesoftware.htmlunit.javascript.host.dom.DOMMatrix;
/**
* A JavaScript object for {@code WebKitCSSMatrix}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({CHROME, EDGE, FF52})
-public class WebKitCSSMatrix extends SimpleScriptable {
+@JsxClass({CHROME, FF})
+public class WebKitCSSMatrix extends DOMMatrix {
/**
* Creates an instance.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/package-info.java
index dbbf720281e..c1821a6ab14 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/css/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/AbstractList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/AbstractList.java
index 417e839ee66..43bdaad061d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/AbstractList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/AbstractList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Attr.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Attr.java
index d0e3cfdaf58..aeae85f6330 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Attr.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Attr.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_ATTR_FIRST_LAST_CHILD_RETURNS_NULL;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -49,7 +48,7 @@ public class Attr extends Node {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Attr() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CDATASection.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CDATASection.java
index 8d222417ba9..ddb9a0cb10d 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CDATASection.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CDATASection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.html.DomCDataSection;
@@ -33,7 +32,7 @@ public class CDATASection extends Text {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public CDATASection() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CharacterData.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CharacterData.java
index 1f31d0425c7..76b99c4ef19 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CharacterData.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CharacterData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOM_CDATA_DELETE_THROWS_NEGATIVE_COUNT;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.html.DomCharacterData;
@@ -45,7 +44,7 @@ public class CharacterData extends Node {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public CharacterData() {
}
@@ -183,7 +182,7 @@ public Element getPreviousElementSibling() {
* {@inheritDoc}
*/
@Override
- @JsxFunction({CHROME, FF, EDGE})
+ @JsxFunction({CHROME, FF})
public void remove() {
super.remove();
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Comment.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Comment.java
index 4cc19d6d158..b0c1d2cc68b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Comment.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Comment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -42,7 +41,7 @@ public class Comment extends CharacterData {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Comment() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CustomElementRegistry.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CustomElementRegistry.java
index dbd2e54cf36..fcb59fe3773 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CustomElementRegistry.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/CustomElementRegistry.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF68;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -24,8 +25,9 @@
* A JavaScript object for {@code CustomElementRegistry}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(CHROME)
+@JsxClass({CHROME, FF68})
public class CustomElementRegistry extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMCursor.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMCursor.java
index 54cfe3f0deb..ffcbfdd47ef 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMCursor.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMCursor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.dom;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -24,8 +24,9 @@
* A JavaScript object for {@code DOMCursor}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(FF)
+@JsxClass(FF60)
public class DOMCursor extends EventTarget {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMError.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMError.java
index 0b384daec15..5b250e16732 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMError.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMError.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class DOMError extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public DOMError() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMException.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMException.java
index c6c0794e3c4..51ee0e9b19c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMException.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMException.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -128,7 +127,7 @@ public class DOMException extends SimpleScriptable {
/**
* Default constructor used to build the prototype.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public DOMException() {
code_ = -1;
message_ = null;
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMImplementation.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMImplementation.java
index e355285fe81..74231378ea0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMImplementation.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMImplementation.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,7 +39,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOMIMPLEMENTATION_FEATURE_VIEWS_3;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOMIMPLEMENTATION_FEATURE_XPATH;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.StringWebResponse;
@@ -78,7 +77,7 @@ public class DOMImplementation extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public DOMImplementation() {
}
@@ -262,7 +261,7 @@ public XMLDocument createDocument(final String namespaceURI, final String qualif
*/
@JsxFunction
public HTMLDocument createHTMLDocument(final Object titleObj) {
- if (titleObj == Undefined.instance
+ if (Undefined.isUndefined(titleObj)
&& getBrowserVersion().hasFeature(JS_DOMIMPLEMENTATION_CREATE_HTMLDOCOMENT_REQUIRES_TITLE)) {
throw Context.reportRuntimeError("Title is required");
}
@@ -284,7 +283,7 @@ && getBrowserVersion().hasFeature(JS_DOMIMPLEMENTATION_CREATE_HTMLDOCOMENT_REQUI
final HTMLHeadElement head = (HTMLHeadElement) document.createElement("head");
html.appendChild(head);
- if (titleObj != Undefined.instance) {
+ if (!Undefined.isUndefined(titleObj)) {
final HTMLTitleElement title = (HTMLTitleElement) document.createElement("title");
head.appendChild(title);
title.setTextContent(Context.toString(titleObj));
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMMatrix.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMMatrix.java
index 13aa18b5a4b..0d06f12f72a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMMatrix.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMMatrix.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMMatrixReadOnly.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMMatrixReadOnly.java
index b5f1fc675c6..8dbcb20fee2 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMMatrixReadOnly.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMMatrixReadOnly.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMParser.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMParser.java
index af94cbda324..40d1cfc6791 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMParser.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
import com.gargoylesoftware.htmlunit.javascript.host.xml.XMLDocument;
+import com.gargoylesoftware.htmlunit.util.MimeType;
import net.sourceforge.htmlunit.corejs.javascript.Context;
import net.sourceforge.htmlunit.corejs.javascript.Undefined;
@@ -55,11 +56,11 @@ public DOMParser() {
*/
@JsxFunction
public XMLDocument parseFromString(final String str, final Object type) {
- if (type == null || Undefined.instance == type) {
+ if (type == null || Undefined.isUndefined(type)) {
throw Context.reportRuntimeError("Missing 'type' parameter");
}
- if (!"text/html".equals(type) && !"text/xml".equals(type) && !"application/xml".equals(type)
- && !"application/xhtml+xml".equals(type) && !"image/svg+xml".equals(type)) {
+ if (!MimeType.TEXT_HTML.equals(type) && !MimeType.TEXT_XML.equals(type) && !"application/xml".equals(type)
+ && !MimeType.APPLICATION_XHTML.equals(type) && !"image/svg+xml".equals(type)) {
throw Context.reportRuntimeError("Invalid 'type' parameter: " + type);
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMPoint.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMPoint.java
index ac4e6778c9f..3861bcb4e96 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMPoint.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMPoint.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMPointReadOnly.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMPointReadOnly.java
index 4e041001116..e29de1013aa 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMPointReadOnly.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMPointReadOnly.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMRectReadOnly.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMRectReadOnly.java
index 4323805a64b..8a19da2dbd2 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMRectReadOnly.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMRectReadOnly.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMRequest.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMRequest.java
index 5070c7e4095..c48e5a3a701 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMRequest.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMRequest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMSettableTokenList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMSettableTokenList.java
index 203319d777b..c00301c0a09 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMSettableTokenList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMSettableTokenList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,26 +14,22 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.dom;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
/**
* A JavaScript object for {@code DOMSettableTokenList}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass({FF45, IE, EDGE})
+@JsxClass(IE)
public class DOMSettableTokenList extends DOMTokenList {
/**
* Creates an instance.
*/
- @JsxConstructor({FF, EDGE})
public DOMSettableTokenList() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMStringList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMStringList.java
index 17c25219fbd..8da1582d2fd 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMStringList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMStringList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -33,7 +32,7 @@ public class DOMStringList extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public DOMStringList() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMStringMap.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMStringMap.java
index cef4a456da0..a4ea5da6b12 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMStringMap.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMStringMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.html.DomElement;
@@ -40,7 +39,7 @@ public final class DOMStringMap extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public DOMStringMap() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMTokenList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMTokenList.java
index 3585e2d818a..3504b397d4c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMTokenList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DOMTokenList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,10 +19,8 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOMTOKENLIST_GET_NULL_IF_OUTSIDE;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOMTOKENLIST_LENGTH_IGNORES_DUPLICATES;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOMTOKENLIST_REMOVE_WHITESPACE_CHARS_ON_ADD;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOMTOKENLIST_REMOVE_WHITESPACE_CHARS_ON_EDIT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOMTOKENLIST_REMOVE_WHITESPACE_CHARS_ON_REMOVE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.util.HashSet;
@@ -60,7 +58,7 @@ public class DOMTokenList extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public DOMTokenList() {
}
@@ -86,8 +84,8 @@ public int getLength() {
final String[] parts = StringUtils.split(value, whitespaceChars());
if (getBrowserVersion().hasFeature(JS_DOMTOKENLIST_LENGTH_IGNORES_DUPLICATES)) {
final HashSet elements = new HashSet<>(parts.length);
- for (int i = 0; i < parts.length; i++) {
- elements.add(parts[i]);
+ for (String part : parts) {
+ elements.add(part);
}
return elements.size();
}
@@ -106,11 +104,7 @@ public String getDefaultValue(final Class> hint) {
if (node != null) {
final DomAttr attr = (DomAttr) node.getAttributes().getNamedItem(attributeName_);
if (attr != null) {
- String value = attr.getValue();
- if (getBrowserVersion().hasFeature(JS_DOMTOKENLIST_REMOVE_WHITESPACE_CHARS_ON_EDIT)) {
- value = String.join(" ", StringUtils.split(value, whitespaceChars()));
- }
- return value;
+ return String.join(" ", StringUtils.split(attr.getValue(), whitespaceChars()));
}
}
return "";
@@ -179,7 +173,7 @@ public void remove(final String token) {
if (from > 0) {
result.append(value, 0, from);
if (to < value.length()) {
- result.append(" ");
+ result.append(' ');
}
}
result.append(value, to, value.length());
@@ -270,9 +264,9 @@ private void updateAttribute(final String value) {
DomAttr attr = (DomAttr) domNode.getAttributes().getNamedItem(attributeName_);
if (null == attr) {
attr = domNode.getPage().createAttribute(attributeName_);
- domNode.setAttributeNode(attr);
}
attr.setValue(value);
+ domNode.setAttributeNode(attr);
}
private int position(final String value, final String token) {
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Document.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Document.java
index 8d487d7d54d..b99022a7607 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Document.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Document.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,27 +15,28 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_ONCLOSE_DOCUMENT_CREATE_NOT_SUPPORTED;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_ONPOPSTATE_DOCUMENT_CREATE_NOT_SUPPORTED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_TYPE_BEFOREUNLOADEVENT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_TYPE_HASHCHANGEEVENT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_TYPE_KEY_EVENTS;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_TYPE_MOUSEWHEELEVENT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_TYPE_POINTEREVENT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_TYPE_PROGRESSEVENT;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_TYPE_WHEELEVENT;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLDOCUMENT_APPLETS_NODELIST;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLDOCUMENT_CHARSET_LOWERCASE;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_ANCHORS_REQUIRES_NAME_OR_ID;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_CREATE_ELEMENT_STRICT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_DESIGN_MODE_INHERIT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_FORMS_FUNCTION_SUPPORTED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_SELECTION_RANGE_COUNT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_SETTING_DOMAIN_THROWS_FOR_ABOUT_BLANK;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOCUMENT_SET_LOCATION_EXECUTED_IN_ANCHOR;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_TREEWALKER_EXPAND_ENTITY_REFERENCES_FALSE;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_TREEWALKER_FILTER_FUNCTION_ONLY;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_XML_GET_ELEMENT_BY_ID__ANY_ELEMENT;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.QUERYSELECTORALL_NOT_IN_QUIRKS;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import static com.gargoylesoftware.htmlunit.util.StringUtils.parseHttpDate;
@@ -52,14 +53,17 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xml.utils.PrefixResolver;
+import org.w3c.dom.CDATASection;
import org.w3c.dom.DOMException;
import org.w3c.dom.DocumentType;
+import org.w3c.dom.ProcessingInstruction;
import com.gargoylesoftware.css.parser.CSSException;
import com.gargoylesoftware.htmlunit.BrowserVersion;
@@ -77,7 +81,7 @@
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.DomText;
import com.gargoylesoftware.htmlunit.html.FrameWindow;
-import com.gargoylesoftware.htmlunit.html.HTMLParser;
+import com.gargoylesoftware.htmlunit.html.Html;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlApplet;
import com.gargoylesoftware.htmlunit.html.HtmlArea;
@@ -96,8 +100,6 @@
import com.gargoylesoftware.htmlunit.html.UnknownElementFactory;
import com.gargoylesoftware.htmlunit.html.impl.SimpleRange;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
-import com.gargoylesoftware.htmlunit.javascript.configuration.CanSetReadOnly;
-import com.gargoylesoftware.htmlunit.javascript.configuration.CanSetReadOnlyStatus;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
@@ -111,23 +113,31 @@
import com.gargoylesoftware.htmlunit.javascript.host.css.StyleSheetList;
import com.gargoylesoftware.htmlunit.javascript.host.event.BeforeUnloadEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.CloseEvent;
+import com.gargoylesoftware.htmlunit.javascript.host.event.CompositionEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.CustomEvent;
+import com.gargoylesoftware.htmlunit.javascript.host.event.DragEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
+import com.gargoylesoftware.htmlunit.javascript.host.event.FocusEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.HashChangeEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.KeyboardEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.MessageEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.MouseEvent;
+import com.gargoylesoftware.htmlunit.javascript.host.event.MouseWheelEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.MutationEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.PointerEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.PopStateEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.ProgressEvent;
+import com.gargoylesoftware.htmlunit.javascript.host.event.SVGZoomEvent;
+import com.gargoylesoftware.htmlunit.javascript.host.event.TextEvent;
import com.gargoylesoftware.htmlunit.javascript.host.event.UIEvent;
+import com.gargoylesoftware.htmlunit.javascript.host.event.WheelEvent;
import com.gargoylesoftware.htmlunit.javascript.host.html.DocumentProxy;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLAnchorElement;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLCollection;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLElement;
import com.gargoylesoftware.htmlunit.util.EncodingSniffer;
+import com.gargoylesoftware.htmlunit.xml.XmlPage;
import net.sourceforge.htmlunit.corejs.javascript.Callable;
import net.sourceforge.htmlunit.corejs.javascript.Context;
@@ -204,6 +214,9 @@ public class Document extends Node {
dom3EventMap.put("UIEvent", UIEvent.class);
dom3EventMap.put("CustomEvent", CustomEvent.class);
dom3EventMap.put("CloseEvent", CloseEvent.class);
+ dom3EventMap.put("CompositionEvent", CompositionEvent.class);
+ dom3EventMap.put("DragEvent", DragEvent.class);
+ dom3EventMap.put("TextEvent", TextEvent.class);
SUPPORTED_DOM3_EVENT_TYPE_MAP = Collections.unmodifiableMap(dom3EventMap);
final Map> additionalEventMap = new HashMap<>();
@@ -214,13 +227,17 @@ public class Document extends Node {
additionalEventMap.put("PointerEvent", PointerEvent.class);
additionalEventMap.put("PopStateEvent", PopStateEvent.class);
additionalEventMap.put("ProgressEvent", ProgressEvent.class);
+ additionalEventMap.put("MouseWheelEvent", MouseWheelEvent.class);
+ additionalEventMap.put("FocusEvent", FocusEvent.class);
+ additionalEventMap.put("WheelEvent", WheelEvent.class);
+ additionalEventMap.put("SVGZoomEvent", SVGZoomEvent.class);
SUPPORTED_VENDOR_EVENT_TYPE_MAP = Collections.unmodifiableMap(additionalEventMap);
}
/**
* Static counter for {@link #uniqueID_}.
*/
- private static int UniqueID_Counter_ = 1;
+ private static AtomicInteger UniqueID_Counter_ = new AtomicInteger(1);
private Window window_;
private DOMImplementation implementation_;
@@ -300,7 +317,7 @@ public class Document extends Node {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Document() {
}
@@ -335,20 +352,13 @@ public Location getLocation() {
@JsxSetter
public void setLocation(final String location) throws IOException {
final Object event = getWindow().getEvent();
- boolean setLocation = true;
if (event instanceof UIEvent) {
final Object target = ((UIEvent) event).getTarget();
if (target instanceof HTMLAnchorElement) {
final String href = ((HTMLAnchorElement) target).getHref();
- if (!href.isEmpty()
- && !getBrowserVersion().hasFeature(JS_DOCUMENT_SET_LOCATION_EXECUTED_IN_ANCHOR)) {
- setLocation = false;
- }
}
}
- if (setLocation) {
- window_.setLocation(location);
- }
+ window_.setLocation(location);
}
/**
@@ -386,7 +396,7 @@ public Element getDocumentElement() {
* Gets the JavaScript property {@code rootElement}.
* @return the root node for the document
*/
- @JsxGetter({CHROME, FF52, IE})
+ @JsxGetter
public Element getRootElement() {
return null;
}
@@ -651,20 +661,21 @@ else if (resolver instanceof PrefixResolver) {
public Object createElement(String tagName) {
Object result = NOT_FOUND;
try {
- final BrowserVersion browserVersion = getBrowserVersion();
-
- if (browserVersion.hasFeature(JS_DOCUMENT_CREATE_ELEMENT_STRICT)
- && (tagName.contains("<") || tagName.contains(">"))) {
- LOG.info("createElement: Provided string '"
- + tagName + "' contains an invalid character; '<' and '>' are not allowed");
+ if (tagName.contains("<") || tagName.contains(">")) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("createElement: Provided string '"
+ + tagName + "' contains an invalid character; '<' and '>' are not allowed");
+ }
throw Context.reportRuntimeError("String contains an invalid character");
}
- else if (tagName.startsWith("<") && tagName.endsWith(">")) {
+ else if (tagName.length() > 0 && tagName.charAt(0) == '<' && tagName.endsWith(">")) {
tagName = tagName.substring(1, tagName.length() - 1);
final Matcher matcher = TAG_NAME_PATTERN.matcher(tagName);
if (!matcher.matches()) {
- LOG.info("createElement: Provided string '" + tagName + "' contains an invalid character");
+ if (LOG.isInfoEnabled()) {
+ LOG.info("createElement: Provided string '" + tagName + "' contains an invalid character");
+ }
throw Context.reportRuntimeError("String contains an invalid character");
}
}
@@ -730,8 +741,8 @@ public Object createElementNS(final String namespaceURI, final String qualifiedN
throw Context.reportRuntimeError("XUL not available");
}
- if (HTMLParser.XHTML_NAMESPACE.equals(namespaceURI)
- || HTMLParser.SVG_NAMESPACE.equals(namespaceURI)) {
+ if (Html.XHTML_NAMESPACE.equals(namespaceURI)
+ || Html.SVG_NAMESPACE.equals(namespaceURI)) {
element = getPage().createElementNS(namespaceURI, qualifiedName);
}
else {
@@ -880,6 +891,14 @@ protected EffectOnCache getEffectOnCache(final HtmlAttributeChangeEvent event) {
*/
@JsxGetter({CHROME, IE})
public Object getApplets() {
+ if (getBrowserVersion().hasFeature(HTMLDOCUMENT_APPLETS_NODELIST)) {
+ return new NodeList(getDomNodeOrDie(), false) {
+ @Override
+ protected boolean isMatching(final DomNode node) {
+ return node instanceof HtmlApplet;
+ }
+ };
+ }
return new HTMLCollection(getDomNodeOrDie(), false) {
@Override
protected boolean isMatching(final DomNode node) {
@@ -892,8 +911,7 @@ protected boolean isMatching(final DomNode node) {
* Returns this document's {@code body} element.
* @return this document's {@code body} element
*/
- @JsxGetter({CHROME, IE, EDGE})
- @CanSetReadOnly(CanSetReadOnlyStatus.EXCEPTION)
+ @JsxGetter({CHROME, IE})
public HTMLElement getBody() {
final Page page = getPage();
if (page instanceof HtmlPage) {
@@ -1076,7 +1094,9 @@ public boolean execCommand(final String cmd, final boolean userInterface, final
if (!hasCommand(cmd, false)) {
return false;
}
- LOG.warn("Nothing done for execCommand(" + cmd + ", ...) (feature not implemented)");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("Nothing done for execCommand(" + cmd + ", ...) (feature not implemented)");
+ }
return true;
}
@@ -1088,7 +1108,7 @@ public boolean execCommand(final String cmd, final boolean userInterface, final
@JsxGetter(IE)
public String getUniqueID() {
if (uniqueID_ == null) {
- uniqueID_ = "ms__id" + UniqueID_Counter_++;
+ uniqueID_ = "ms__id" + Document.UniqueID_Counter_.getAndIncrement();
}
return uniqueID_;
}
@@ -1099,10 +1119,6 @@ public String getUniqueID() {
*/
@JsxGetter(propertyName = "URL")
public String getURL() {
- if (!(getPage() instanceof HtmlPage)) {
- // TODO: implement XmlPage.getUrl
- return "";
- }
return getPage().getUrl().toExternalForm();
}
@@ -1190,15 +1206,25 @@ && getBrowserVersion().hasFeature(EVENT_ONCLOSE_DOCUMENT_CREATE_NOT_SUPPORTED))
&& ("Events".equals(eventType)
|| "KeyEvents".equals(eventType) && getBrowserVersion().hasFeature(EVENT_TYPE_KEY_EVENTS)
|| "HashChangeEvent".equals(eventType)
- && getBrowserVersion().hasFeature(EVENT_TYPE_HASHCHANGEEVENT)
+ && getBrowserVersion().hasFeature(EVENT_TYPE_HASHCHANGEEVENT)
|| "BeforeUnloadEvent".equals(eventType)
- && getBrowserVersion().hasFeature(EVENT_TYPE_BEFOREUNLOADEVENT)
+ && getBrowserVersion().hasFeature(EVENT_TYPE_BEFOREUNLOADEVENT)
+ || "MouseWheelEvent".equals(eventType)
+ && getBrowserVersion().hasFeature(EVENT_TYPE_MOUSEWHEELEVENT)
|| "PointerEvent".equals(eventType)
- && getBrowserVersion().hasFeature(EVENT_TYPE_POINTEREVENT)
+ && getBrowserVersion().hasFeature(EVENT_TYPE_POINTEREVENT)
|| "PopStateEvent".equals(eventType)
|| "ProgressEvent".equals(eventType)
- && getBrowserVersion().hasFeature(EVENT_TYPE_PROGRESSEVENT))) {
+ && getBrowserVersion().hasFeature(EVENT_TYPE_PROGRESSEVENT)
+ || "FocusEvent".equals(eventType)
+ || "WheelEvent".equals(eventType)
+ && getBrowserVersion().hasFeature(EVENT_TYPE_WHEELEVENT))) {
clazz = SUPPORTED_VENDOR_EVENT_TYPE_MAP.get(eventType);
+
+ if (PopStateEvent.class == clazz
+ && getBrowserVersion().hasFeature(EVENT_ONPOPSTATE_DOCUMENT_CREATE_NOT_SUPPORTED)) {
+ clazz = null;
+ }
}
if (clazz == null) {
Context.throwAsScriptRuntimeEx(new DOMException(DOMException.NOT_SUPPORTED_ERR,
@@ -1968,7 +1994,7 @@ public void setTitle(final String title) {
* {@inheritDoc}
*/
@Override
- @JsxGetter({CHROME, FF, EDGE})
+ @JsxGetter({CHROME, FF})
public HTMLCollection getChildren() {
return super.getChildren();
}
@@ -2987,7 +3013,7 @@ public void setOnpointerleave(final Object onpointerleave) {
* Returns the {@code onpointerlockchange} event handler for this element.
* @return the {@code onpointerlockchange} event handler for this element
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOnpointerlockchange() {
return getEventHandler("pointerlockchange");
}
@@ -2996,7 +3022,7 @@ public Function getOnpointerlockchange() {
* Sets the {@code onpointerlockchange} event handler for this element.
* @param onpointerlockchange the {@code onpointerlockchange} event handler for this element
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOnpointerlockchange(final Object onpointerlockchange) {
setEventHandler("pointerlockchange", onpointerlockchange);
}
@@ -3005,7 +3031,7 @@ public void setOnpointerlockchange(final Object onpointerlockchange) {
* Returns the {@code onpointerlockerror} event handler for this element.
* @return the {@code onpointerlockerror} event handler for this element
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOnpointerlockerror() {
return getEventHandler("pointerlockerror");
}
@@ -3014,7 +3040,7 @@ public Function getOnpointerlockerror() {
* Sets the {@code onpointerlockerror} event handler for this element.
* @param onpointerlockerror the {@code onpointerlockerror} event handler for this element
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOnpointerlockerror(final Object onpointerlockerror) {
setEventHandler("pointerlockerror", onpointerlockerror);
}
@@ -3257,7 +3283,7 @@ public void setOnselect(final Object onselect) {
* Returns the {@code onselectionchange} event handler for this element.
* @return the {@code onselectionchange} event handler for this element
*/
- @JsxGetter({CHROME, IE, FF52})
+ @JsxGetter({CHROME, IE})
public Function getOnselectionchange() {
return getEventHandler("selectionchange");
}
@@ -3266,7 +3292,7 @@ public Function getOnselectionchange() {
* Sets the {@code onselectionchange} event handler for this element.
* @param onselectionchange the {@code onselectionchange} event handler for this element
*/
- @JsxSetter({CHROME, IE, FF52})
+ @JsxSetter({CHROME, IE})
public void setOnselectionchange(final Object onselectionchange) {
setEventHandler("selectionchange", onselectionchange);
}
@@ -3275,7 +3301,7 @@ public void setOnselectionchange(final Object onselectionchange) {
* Returns the {@code onselectstart} event handler for this element.
* @return the {@code onselectstart} event handler for this element
*/
- @JsxGetter({CHROME, IE, FF52})
+ @JsxGetter({CHROME, IE})
public Function getOnselectstart() {
return getEventHandler("selectstart");
}
@@ -3284,7 +3310,7 @@ public Function getOnselectstart() {
* Sets the {@code onselectstart} event handler for this element.
* @param onselectstart the {@code onselectstart} event handler for this element
*/
- @JsxSetter({CHROME, IE, FF52})
+ @JsxSetter({CHROME, IE})
public void setOnselectstart(final Object onselectstart) {
setEventHandler("selectstart", onselectstart);
}
@@ -3383,7 +3409,7 @@ public void setOntimeupdate(final Object ontimeupdate) {
* Returns the {@code ontoggle} event handler for this element.
* @return the {@code ontoggle} event handler for this element
*/
- @JsxGetter({CHROME, FF52})
+ @JsxGetter(CHROME)
public Function getOntoggle() {
return getEventHandler("toggle");
}
@@ -3392,7 +3418,7 @@ public Function getOntoggle() {
* Sets the {@code ontoggle} event handler for this element.
* @param ontoggle the {@code ontoggle} event handler for this element
*/
- @JsxSetter({CHROME, FF52})
+ @JsxSetter(CHROME)
public void setOntoggle(final Object ontoggle) {
setEventHandler("toggle", ontoggle);
}
@@ -3563,7 +3589,7 @@ public void setOnmozfullscreenerror(final Object onmozfullscreenerror) {
* Returns the {@code onmozpointerlockchange} event handler for this element.
* @return the {@code onmozpointerlockchange} event handler for this element
*/
- @JsxGetter(FF45)
+ @JsxGetter(FF60)
public Function getOnmozpointerlockchange() {
return getEventHandler("mozpointerlockchange");
}
@@ -3572,7 +3598,7 @@ public Function getOnmozpointerlockchange() {
* Sets the {@code onmozpointerlockchange} event handler for this element.
* @param onmozpointerlockchange the {@code onmozpointerlockchange} event handler for this element
*/
- @JsxSetter(FF45)
+ @JsxSetter(FF60)
public void setOnmozpointerlockchange(final Object onmozpointerlockchange) {
setEventHandler("mozpointerlockchange", onmozpointerlockchange);
}
@@ -3581,7 +3607,7 @@ public void setOnmozpointerlockchange(final Object onmozpointerlockchange) {
* Returns the {@code onmozpointerlockerror} event handler for this element.
* @return the {@code onmozpointerlockerror} event handler for this element
*/
- @JsxGetter(FF45)
+ @JsxGetter(FF60)
public Function getOnmozpointerlockerror() {
return getEventHandler("mozpointerlockerror");
}
@@ -3590,7 +3616,7 @@ public Function getOnmozpointerlockerror() {
* Sets the {@code onmozpointerlockerror} event handler for this element.
* @param onmozpointerlockerror the {@code onmozpointerlockerror} event handler for this element
*/
- @JsxSetter(FF45)
+ @JsxSetter(FF60)
public void setOnmozpointerlockerror(final Object onmozpointerlockerror) {
setEventHandler("mozpointerlockerror", onmozpointerlockerror);
}
@@ -4099,186 +4125,6 @@ public void setOndeactivate(final Object ondeactivate) {
setEventHandler("deactivate", ondeactivate);
}
- /**
- * Returns the {@code onanimationend} event handler.
- * @return the {@code onanimationend} event handler
- */
- @JsxGetter(FF52)
- public Function getOnanimationend() {
- return getEventHandler("animationend");
- }
-
- /**
- * Sets the {@code onanimationend} event handler.
- * @param animationend the {@code onanimationend} event handler
- */
- @JsxSetter(FF52)
- public void setOnanimationend(final Object animationend) {
- setEventHandler("animationend", animationend);
- }
-
- /**
- * Returns the {@code onanimationiteration} event handler.
- * @return the {@code onanimationiteration} event handler
- */
- @JsxGetter(FF52)
- public Function getOnanimationiteration() {
- return getEventHandler("animationiteration");
- }
-
- /**
- * Sets the {@code onanimationiteration} event handler.
- * @param animationiteration the {@code onanimationiteration} event handler
- */
- @JsxSetter(FF52)
- public void setOnanimationiteration(final Object animationiteration) {
- setEventHandler("animationiteration", animationiteration);
- }
-
- /**
- * Returns the {@code onanimationstart} event handler.
- * @return the {@code onanimationstart} event handler
- */
- @JsxGetter(FF52)
- public Function getOnanimationstart() {
- return getEventHandler("animationstart");
- }
-
- /**
- * Sets the {@code onanimationstart} event handler.
- * @param animationstart the {@code onanimationstart} event handler
- */
- @JsxSetter(FF52)
- public void setOnanimationstart(final Object animationstart) {
- setEventHandler("animationstart", animationstart);
- }
-
- /**
- * Returns the {@code ondragexit} event handler.
- * @return the {@code ondragexit} event handler
- */
- @JsxGetter(FF52)
- public Function getOndragexit() {
- return getEventHandler("dragexit");
- }
-
- /**
- * Sets the {@code ondragexit} event handler.
- * @param dragexit the {@code ondragexit} event handler
- */
- @JsxSetter(FF52)
- public void setOndragexit(final Object dragexit) {
- setEventHandler("dragexit", dragexit);
- }
-
- /**
- * Returns the {@code onloadend} event handler.
- * @return the {@code onloadend} event handler
- */
- @JsxGetter(FF52)
- public Function getOnloadend() {
- return getEventHandler("loadend");
- }
-
- /**
- * Sets the {@code onloadend} event handler.
- * @param loadend the {@code onloadend} event handler
- */
- @JsxSetter(FF52)
- public void setOnloadend(final Object loadend) {
- setEventHandler("loadend", loadend);
- }
-
- /**
- * Returns the {@code ontransitionend} event handler.
- * @return the {@code ontransitionend} event handler
- */
- @JsxGetter(FF52)
- public Function getOntransitionend() {
- return getEventHandler("transitionend");
- }
-
- /**
- * Sets the {@code ontransitionend} event handler.
- * @param transitionend the {@code ontransitionend} event handler
- */
- @JsxSetter(FF52)
- public void setOntransitionend(final Object transitionend) {
- setEventHandler("transitionend", transitionend);
- }
-
- /**
- * Returns the {@code onwebkitanimationend} event handler.
- * @return the {@code onwebkitanimationend} event handler
- */
- @JsxGetter(FF52)
- public Function getOnwebkitanimationend() {
- return getEventHandler("webkitanimationend");
- }
-
- /**
- * Sets the {@code onwebkitanimationend} event handler.
- * @param webkitanimationend the {@code onwebkitanimationend} event handler
- */
- @JsxSetter(FF52)
- public void setOnwebkitanimationend(final Object webkitanimationend) {
- setEventHandler("webkitanimationend", webkitanimationend);
- }
-
- /**
- * Returns the {@code onwebkitanimationiteration} event handler.
- * @return the {@code onwebkitanimationiteration} event handler
- */
- @JsxGetter(FF52)
- public Function getOnwebkitanimationiteration() {
- return getEventHandler("webkitanimationiteration");
- }
-
- /**
- * Sets the {@code onwebkitanimationiteration} event handler.
- * @param webkitanimationiteration the {@code onwebkitanimationiteration} event handler
- */
- @JsxSetter(FF52)
- public void setOnwebkitanimationiteration(final Object webkitanimationiteration) {
- setEventHandler("webkitanimationiteration", webkitanimationiteration);
- }
-
- /**
- * Returns the {@code onwebkitanimationstart} event handler.
- * @return the {@code onwebkitanimationstart} event handler
- */
- @JsxGetter(FF52)
- public Function getOnwebkitanimationstart() {
- return getEventHandler("webkitanimationstart");
- }
-
- /**
- * Sets the {@code onwebkitanimationstart} event handler.
- * @param webkitanimationstart the {@code onwebkitanimationstart} event handler
- */
- @JsxSetter(FF52)
- public void setOnwebkitanimationstart(final Object webkitanimationstart) {
- setEventHandler("webkitanimationstart", webkitanimationstart);
- }
-
- /**
- * Returns the {@code onwebkittransitionend} event handler.
- * @return the {@code onwebkittransitionend} event handler
- */
- @JsxGetter(FF52)
- public Function getOnwebkittransitionend() {
- return getEventHandler("webkittransitionend");
- }
-
- /**
- * Sets the {@code onwebkittransitionend} event handler.
- * @param webkittransitionend the {@code onwebkittransitionend} event handler
- */
- @JsxSetter(FF52)
- public void setOnwebkittransitionend(final Object webkittransitionend) {
- setEventHandler("webkittransitionend", webkittransitionend);
- }
-
/**
* @return the {@code currentScript}
*/
@@ -4307,4 +4153,56 @@ public ScriptableObject getFonts() {
}
return fonts_;
}
+
+ @Override
+ protected boolean isReadOnlySettable(final String name, final Object value) {
+ if ("body".equals(name)) {
+ throw ScriptRuntime.typeError3("msg.set.prop.no.setter", name, getClassName(), Context.toString(value));
+ }
+ return super.isReadOnlySettable(name, value);
+ }
+
+ /**
+ * Returns the element with the specified ID, as long as it is an HTML element; {@code null} otherwise.
+ * @param id the ID to search for
+ * @return the element with the specified ID, as long as it is an HTML element; {@code null} otherwise
+ */
+ @JsxFunction
+ public Object getElementById(final String id) {
+ final DomNode domNode = getDomNodeOrDie();
+ final Object domElement = domNode.getFirstByXPath("//*[@id = \"" + id + "\"]");
+ if (domElement != null) {
+ if (!(domNode instanceof XmlPage) || domElement instanceof HtmlElement
+ || getBrowserVersion().hasFeature(JS_XML_GET_ELEMENT_BY_ID__ANY_ELEMENT)) {
+ return ((DomElement) domElement).getScriptableObject();
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("getElementById(" + id + "): no HTML DOM node found with this ID");
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Creates a new ProcessingInstruction.
+ * @param target the target
+ * @param data the data
+ * @return the new ProcessingInstruction
+ */
+ @JsxFunction
+ public Object createProcessingInstruction(final String target, final String data) {
+ final ProcessingInstruction node = getPage().createProcessingInstruction(target, data);
+ return getScriptableFor(node);
+ }
+
+ /**
+ * Creates a new createCDATASection.
+ * @param data the data
+ * @return the new CDATASection
+ */
+ @JsxFunction
+ public Object createCDATASection(final String data) {
+ final CDATASection node = getPage().createCDATASection(data);
+ return getScriptableFor(node);
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentFragment.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentFragment.java
index 7100dfddbd0..00a36782a85 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentFragment.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentFragment.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,10 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import java.util.Iterator;
+
import com.gargoylesoftware.css.parser.CSSException;
import com.gargoylesoftware.htmlunit.html.DomDocumentFragment;
import com.gargoylesoftware.htmlunit.html.DomNode;
@@ -29,6 +30,8 @@
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLCollection;
import net.sourceforge.htmlunit.corejs.javascript.Context;
+import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
+import net.sourceforge.htmlunit.corejs.javascript.Undefined;
/**
* A JavaScript object for {@code DocumentFragment}.
@@ -45,7 +48,7 @@ public class DocumentFragment extends Node {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public DocumentFragment() {
}
@@ -104,7 +107,13 @@ public Object getDefaultValue(final Class> hint) {
@Override
@JsxGetter({CHROME, FF})
public int getChildElementCount() {
- return super.getChildElementCount();
+ int counter = 0;
+ final Iterator iterator = getDomNodeOrDie().getChildren().iterator();
+ while (iterator.hasNext()) {
+ iterator.next();
+ counter++;
+ }
+ return counter;
}
/**
@@ -113,7 +122,10 @@ public int getChildElementCount() {
@Override
@JsxGetter({CHROME, FF})
public Element getFirstElementChild() {
- return super.getFirstElementChild();
+ for (DomNode child : getDomNodeOrDie().getChildren()) {
+ return (Element) child.getScriptableObject();
+ }
+ return null;
}
/**
@@ -122,16 +134,46 @@ public Element getFirstElementChild() {
@Override
@JsxGetter({CHROME, FF})
public Element getLastElementChild() {
- return super.getLastElementChild();
+ DomNode lastChild = null;
+ for (DomNode child : getDomNodeOrDie().getChildren()) {
+ lastChild = child;
+ }
+
+ if (lastChild != null) {
+ return (Element) lastChild.getScriptableObject();
+ }
+ return null;
}
/**
* {@inheritDoc}
*/
@Override
- @JsxGetter({CHROME, FF, EDGE})
+ @JsxGetter({CHROME, FF})
public HTMLCollection getChildren() {
return super.getChildren();
}
+ /**
+ * Returns the element with the specified ID, or {@code null} if that element could not be found.
+ * @param id the ID to search for
+ * @return the element, or {@code null} if it could not be found
+ */
+ @JsxFunction({CHROME, FF})
+ public Object getElementById(final Object id) {
+ if (id == null || Undefined.isUndefined(id)) {
+ return null;
+ }
+ final String idString = ScriptRuntime.toString(id);
+ if (idString == null || idString.length() == 0) {
+ return null;
+ }
+ for (DomNode child : getDomNodeOrDie().getChildren()) {
+ final Element elem = (Element) child.getScriptableObject();
+ if (idString.equals(elem.getId())) {
+ return elem;
+ }
+ }
+ return null;
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentType.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentType.java
index 0f985afb7f1..c6d0fe2b3d9 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentType.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/DocumentType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,7 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOCTYPE_ENTITIES_NULL;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_DOCTYPE_NOTATIONS_NULL;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import org.apache.commons.lang3.StringUtils;
@@ -50,7 +48,7 @@ public class DocumentType extends Node {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public DocumentType() {
}
@@ -141,34 +139,7 @@ public Object getNotations() {
* {@inheritDoc}
*/
@Override
- @JsxGetter(FF45)
- public Object getPrefix() {
- return super.getPrefix();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxGetter(FF45)
- public Object getLocalName() {
- return super.getLocalName();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxGetter(FF45)
- public Object getNamespaceURI() {
- return super.getNamespaceURI();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- @JsxFunction({CHROME, FF, EDGE})
+ @JsxFunction({CHROME, FF})
public void remove() {
super.remove();
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/IdleDeadline.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/IdleDeadline.java
index c8124dc9c85..7751fbd9b22 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/IdleDeadline.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/IdleDeadline.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -24,8 +25,9 @@
* A JavaScript object for {@code IdleDeadline}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(CHROME)
+@JsxClass({CHROME, FF})
public class IdleDeadline extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MediaList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MediaList.java
index 81019b4747b..71dbc337020 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MediaList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MediaList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_MEDIA_LIST_ALL;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_MEDIA_LIST_EMPTY_STRING;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.css.dom.MediaListImpl;
@@ -40,12 +39,12 @@
@JsxClass
public class MediaList extends SimpleScriptable {
- private final org.w3c.dom.stylesheets.MediaList wrappedList_;
+ private final MediaListImpl wrappedList_;
/**
* Creates a new instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public MediaList() {
wrappedList_ = null;
}
@@ -55,7 +54,7 @@ public MediaList() {
* @param parent the parent style
* @param wrappedList the wrapped media list that this host object exposes
*/
- public MediaList(final CSSStyleSheet parent, final org.w3c.dom.stylesheets.MediaList wrappedList) {
+ public MediaList(final CSSStyleSheet parent, final MediaListImpl wrappedList) {
wrappedList_ = wrappedList;
setParentScope(parent);
setPrototype(getPrototype(getClass()));
@@ -71,7 +70,7 @@ public String item(final int index) {
if (index < 0 || index >= getLength()) {
return null;
}
- final MediaQuery mq = ((MediaListImpl) wrappedList_).mediaQuery(index);
+ final MediaQuery mq = wrappedList_.mediaQuery(index);
return mq.toString();
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MutationObserver.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MutationObserver.java
index 9047fd5a448..57a2a4ca8d0 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MutationObserver.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MutationObserver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,7 +50,6 @@ public class MutationObserver extends SimpleScriptable implements HtmlAttributeC
private Function function_;
private Node node_;
- private boolean childList_;
private boolean attaributes_;
private boolean attributeOldValue_;
private NativeArray attributeFilter_;
@@ -90,13 +89,14 @@ public void observe(final Node node, final NativeObject options) {
node_ = node;
attaributes_ = Boolean.TRUE.equals(options.get("attributes"));
attributeOldValue_ = Boolean.TRUE.equals(options.get("attributeOldValue"));
- childList_ = Boolean.TRUE.equals(options.get("childList"));
characterData_ = Boolean.TRUE.equals(options.get("characterData"));
characterDataOldValue_ = Boolean.TRUE.equals(options.get("characterDataOldValue"));
subtree_ = Boolean.TRUE.equals(options.get("subtree"));
attributeFilter_ = (NativeArray) options.get("attributeFilter");
- if (!attaributes_ && !childList_ && !characterData_) {
+ final boolean childList = Boolean.TRUE.equals(options.get("childList"));
+
+ if (!attaributes_ && !childList && !characterData_) {
throw Context.throwAsScriptRuntimeEx(new IllegalArgumentException(
"One of childList, attributes, od characterData must be set"));
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MutationRecord.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MutationRecord.java
index 6334d837a96..e41039e879a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MutationRecord.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/MutationRecord.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -41,7 +40,7 @@ public class MutationRecord extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public MutationRecord() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Node.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Node.java
index 987d2b6ce49..cdc663300f3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Node.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Node.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,10 +17,7 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_NODE_CONTAINS_RETURNS_FALSE_FOR_INVALID_ARG;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.JS_NODE_INSERT_BEFORE_REF_OPTIONAL;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF45;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
import java.util.ArrayList;
@@ -151,7 +148,7 @@ public class Node extends EventTarget {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Node() {
// Empty.
}
@@ -333,7 +330,7 @@ protected Object insertBeforeImpl(final Object[] args) {
// extract refChild
final DomNode refChildNode;
- if (refChildObject == Undefined.instance) {
+ if (Undefined.isUndefined(refChildObject)) {
if (args.length == 2 || getBrowserVersion().hasFeature(JS_NODE_INSERT_BEFORE_REF_OPTIONAL)) {
refChildNode = null;
}
@@ -479,7 +476,7 @@ public Object cloneNode(final boolean deep) {
*
* @return whether this node is the same node as the given one
*/
- @JsxFunction({CHROME, FF52, IE})
+ @JsxFunction
public boolean isSameNode(final Object other) {
return other == this;
}
@@ -703,7 +700,7 @@ public boolean contains(final Object element) {
* Returns the Base URI as a string.
* @return the Base URI as a string
*/
- @JsxGetter({CHROME, FF, EDGE})
+ @JsxGetter({CHROME, FF})
public String getBaseURI() {
return getDomNodeOrDie().getBaseURI();
}
@@ -721,7 +718,7 @@ public boolean hasAttributes() {
* Returns the namespace prefix.
* @return the namespace prefix
*/
- @JsxGetter({FF45, IE})
+ @JsxGetter(IE)
public Object getPrefix() {
return getDomNodeOrDie().getPrefix();
}
@@ -730,7 +727,7 @@ public Object getPrefix() {
* Returns the local name of this attribute.
* @return the local name of this attribute
*/
- @JsxGetter({FF45, IE})
+ @JsxGetter(IE)
public Object getLocalName() {
return getDomNodeOrDie().getLocalName();
}
@@ -739,7 +736,7 @@ public Object getLocalName() {
* Returns the URI that identifies an XML namespace.
* @return the URI that identifies an XML namespace
*/
- @JsxGetter({FF45, IE})
+ @JsxGetter(IE)
public Object getNamespaceURI() {
return getDomNodeOrDie().getNamespaceURI();
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeFilter.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeFilter.java
index 1bc6bfc20be..c89b33d335e 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeFilter.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
@@ -112,7 +111,7 @@ public class NodeFilter extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public NodeFilter() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeIterator.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeIterator.java
index f2889852d15..697a36f3559 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeIterator.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeIterator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.SgmlPage;
@@ -40,7 +39,7 @@ public class NodeIterator extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public NodeIterator() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeList.java
index 1d26ebf898d..d0bc4816d8f 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/NodeList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,21 +15,23 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF52;
import java.util.ArrayList;
import java.util.List;
+import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomNode;
+import com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory;
import com.gargoylesoftware.htmlunit.javascript.HtmlUnitScriptable;
+import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
import com.gargoylesoftware.htmlunit.javascript.host.Iterator;
import net.sourceforge.htmlunit.corejs.javascript.Context;
+import net.sourceforge.htmlunit.corejs.javascript.ContextAction;
import net.sourceforge.htmlunit.corejs.javascript.Function;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
@@ -56,7 +58,7 @@ public class NodeList extends AbstractList {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public NodeList() {
}
@@ -109,7 +111,7 @@ public List getElements() {
* Returns an {@link Iterator} allowing to go through all keys contained in this object.
* @return an {@link Iterator}
*/
- @JsxFunction({CHROME, FF52})
+ @JsxFunction({CHROME, FF})
public Iterator keys() {
final int length = getElements().size();
final List list = new ArrayList<>();
@@ -126,7 +128,7 @@ public Iterator keys() {
* Returns an {@link Iterator} allowing to go through all keys contained in this object.
* @return an {@link Iterator}
*/
- @JsxFunction({CHROME, FF52})
+ @JsxFunction({CHROME, FF})
public Iterator values() {
final List list = getElements();
final Iterator object = new Iterator(ITERATOR_NAME, list.iterator());
@@ -139,7 +141,7 @@ public Iterator values() {
* Returns an {@link Iterator} allowing to go through all key/value pairs contained in this object.
* @return an {@link Iterator}
*/
- @JsxFunction({CHROME, FF52})
+ @JsxFunction({CHROME, FF})
public Iterator entries() {
final List elements = getElements();
final Context context = Context.getCurrentContext();
@@ -167,20 +169,25 @@ private static void setIteratorPrototype(final Scriptable scriptable) {
* Calls the {@code callback} given in parameter once for each value pair in the list, in insertion order.
* @param callback function to execute for each element
*/
- @JsxFunction({CHROME, FF52})
+ @JsxFunction({CHROME, FF})
public void forEach(final Object callback) {
final List nodes = getElements();
- final Context context = Context.enter();
- try {
- final Function function = (Function) callback;
- final Scriptable scope = getParentScope();
- for (int i = 0; i < nodes.size(); i++) {
- function.call(context, scope, this, new Object[] {
- nodes.get(i).getScriptableObject(), i, this});
+
+ final WebClient client = getWindow().getWebWindow().getWebClient();
+ final HtmlUnitContextFactory cf = ((JavaScriptEngine) client.getJavaScriptEngine()).getContextFactory();
+
+ final ContextAction contextAction = new ContextAction() {
+ @Override
+ public Object run(final Context cx) {
+ final Function function = (Function) callback;
+ final Scriptable scope = getParentScope();
+ for (int i = 0; i < nodes.size(); i++) {
+ function.call(cx, scope, NodeList.this, new Object[] {
+ nodes.get(i).getScriptableObject(), i, NodeList.this});
+ }
+ return null;
}
- }
- finally {
- Context.exit();
- }
+ };
+ cf.call(contextAction);
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/ProcessingInstruction.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/ProcessingInstruction.java
index 988f68d99c7..3f7e8ac51df 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/ProcessingInstruction.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/ProcessingInstruction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.html.DomProcessingInstruction;
@@ -35,7 +34,7 @@ public class ProcessingInstruction extends CharacterData {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public ProcessingInstruction() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/RadioNodeList.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/RadioNodeList.java
index 70faf56b07e..bbb5f22878c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/RadioNodeList.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/RadioNodeList.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Range.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Range.java
index d78e452595a..f3ea96653ff 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Range.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Range.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.util.HashSet;
@@ -25,7 +24,6 @@
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.html.DomDocumentFragment;
import com.gargoylesoftware.htmlunit.html.DomNode;
-import com.gargoylesoftware.htmlunit.html.HTMLParser;
import com.gargoylesoftware.htmlunit.html.impl.SimpleRange;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -72,13 +70,15 @@ public class Range extends SimpleScriptable {
@JsxConstant
public static final short END_TO_START = 3;
- private Node startContainer_, endContainer_;
- private int startOffset_, endOffset_;
+ private Node startContainer_;
+ private Node endContainer_;
+ private int startOffset_;
+ private int endOffset_;
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Range() {
}
@@ -327,7 +327,8 @@ public Object createContextualFragment(final String valueAsString) {
final SgmlPage page = startContainer_.getDomNodeOrDie().getPage();
final DomDocumentFragment fragment = new DomDocumentFragment(page);
try {
- HTMLParser.parseFragment(fragment, startContainer_.getDomNodeOrDie(), valueAsString);
+ page.getWebClient().getPageCreator().getHtmlParser()
+ .parseFragment(fragment, startContainer_.getDomNodeOrDie(), valueAsString);
}
catch (final Exception e) {
LogFactory.getLog(Range.class).error("Unexpected exception occurred in createContextualFragment", e);
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Selection.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Selection.java
index 9bba8a0bec1..601c56bad11 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Selection.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Selection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.util.ArrayList;
@@ -41,6 +40,7 @@
* @author Ahmed Ashour
* @author Daniel Gredler
* @author Frank Danek
+ * @author Ronald Brill
*/
@JsxClass
public class Selection extends SimpleScriptable {
@@ -53,7 +53,7 @@ public class Selection extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Selection() {
}
@@ -147,7 +147,7 @@ public int getRangeCount() {
* Returns the type of selection (IE only).
* @return the type of selection
*/
- @JsxGetter(CHROME)
+ @JsxGetter({CHROME, FF})
public String getType() {
return type_;
}
@@ -260,7 +260,7 @@ public void collapseToStart() {
/**
* Cancels the current selection, sets the selection type to none.
*/
- @JsxFunction(CHROME)
+ @JsxFunction({CHROME, FF})
public void empty() {
removeAllRanges();
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/ShadowRoot.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/ShadowRoot.java
index 70dd3b240d6..bff5afdb8de 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/ShadowRoot.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/ShadowRoot.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF68;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -23,8 +24,9 @@
* A JavaScript object for {@code ShadowRoot}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(CHROME)
+@JsxClass({CHROME, FF68})
public class ShadowRoot extends DocumentFragment {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Text.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Text.java
index 603ed72bca4..35c5a512686 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Text.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/Text.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -45,7 +44,7 @@ public class Text extends CharacterData {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public Text() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/TextRange.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/TextRange.java
index 3b4b377c0d2..a677186cf37 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/TextRange.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/TextRange.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -185,11 +185,13 @@ public void select() {
@JsxFunction
public int moveStart(final String unit, final Object count) {
if (!"character".equals(unit)) {
- LOG.warn("moveStart('" + unit + "') is not yet supported");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("moveStart('" + unit + "') is not yet supported");
+ }
return 0;
}
int c = 1;
- if (count != Undefined.instance) {
+ if (!Undefined.isUndefined(count)) {
c = (int) Context.toNumber(count);
}
if (range_.getStartContainer() == range_.getEndContainer()
@@ -222,11 +224,13 @@ public int move(final String unit, final Object count) {
@JsxFunction
public int moveEnd(final String unit, final Object count) {
if (!"character".equals(unit)) {
- LOG.warn("moveEnd('" + unit + "') is not yet supported");
+ if (LOG.isWarnEnabled()) {
+ LOG.warn("moveEnd('" + unit + "') is not yet supported");
+ }
return 0;
}
int c = 1;
- if (count != Undefined.instance) {
+ if (!Undefined.isUndefined(count)) {
c = (int) Context.toNumber(count);
}
if (range_.getStartContainer() == range_.getEndContainer()
@@ -319,13 +323,13 @@ public void setEndPoint(final String type, final TextRange other) {
* @param textLength the text length
* @return the moveBy amount constrained to the text length
*/
- protected int constrainMoveBy(int moveBy, final int current, final int textLength) {
+ private static int constrainMoveBy(final int moveBy, final int current, final int textLength) {
final int to = current + moveBy;
if (to < 0) {
- moveBy -= to;
+ return moveBy - to;
}
- else if (to >= textLength) {
- moveBy -= to - textLength;
+ if (to >= textLength) {
+ return moveBy - (to - textLength);
}
return moveBy;
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/TreeWalker.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/TreeWalker.java
index 58b3af9716e..369dd146ba6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/TreeWalker.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/TreeWalker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -50,7 +49,7 @@ public class TreeWalker extends SimpleScriptable {
/**
* Creates an instance.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public TreeWalker() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/WebKitMutationObserver.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/WebKitMutationObserver.java
index e90d2607b63..9602f25249b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/WebKitMutationObserver.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/WebKitMutationObserver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathEvaluator.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathEvaluator.java
index 56a03119860..5fadbe2b1b6 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathEvaluator.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathEvaluator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import org.apache.xml.utils.PrefixResolver;
@@ -36,7 +35,7 @@
* @author Chuck Dumont
* @author Ronald Brill
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class XPathEvaluator extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathNSResolver.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathNSResolver.java
index 5a41db6c5f0..68919e72d5c 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathNSResolver.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathNSResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,16 +15,15 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import org.apache.xml.utils.PrefixResolver;
import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
-import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction;
-import com.gargoylesoftware.htmlunit.xml.XmlUtil;
+import com.gargoylesoftware.htmlunit.util.XmlUtils;
/**
* A JavaScript object for {@code XPathNSResolver}.
@@ -32,8 +31,7 @@
* @author Ahmed Ashour
* @author Chuck Dumont
*/
-@JsxClass(EDGE)
-@JsxClass(isJSObject = false, value = CHROME)
+@JsxClass(isJSObject = false, value = {CHROME, FF})
public class XPathNSResolver extends SimpleScriptable implements PrefixResolver {
private Node element_;
@@ -41,7 +39,6 @@ public class XPathNSResolver extends SimpleScriptable implements PrefixResolver
/**
* Default constructor.
*/
- @JsxConstructor(EDGE)
public XPathNSResolver() {
}
@@ -61,7 +58,7 @@ public void setElement(final Node element) {
*/
@JsxFunction
public String lookupNamespaceURI(final String prefix) {
- return XmlUtil.lookupNamespaceURI((DomElement) element_.getDomNodeOrDie(), prefix);
+ return XmlUtils.lookupNamespaceURI((DomElement) element_.getDomNodeOrDie(), prefix);
}
/**
@@ -69,7 +66,7 @@ public String lookupNamespaceURI(final String prefix) {
*/
@Override
public String getBaseIdentifier() {
- return XmlUtil.lookupNamespaceURI((DomElement) element_.getDomNodeOrDie(), "");
+ return XmlUtils.lookupNamespaceURI((DomElement) element_.getDomNodeOrDie(), "");
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathResult.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathResult.java
index 7f22904d79e..f9b59a9656a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathResult.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/XPathResult.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.dom;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import java.util.List;
@@ -38,7 +37,7 @@
* @author Chuck Dumont
* @author Ronald Brill
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class XPathResult extends SimpleScriptable {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/package-info.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/package-info.java
index 6b932d2c268..7a43f0a86ca 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/package-info.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/dom/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ApplicationCacheErrorEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ApplicationCacheErrorEvent.java
index 19a7fc3bd16..ad363164014 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ApplicationCacheErrorEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ApplicationCacheErrorEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/AudioProcessingEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/AudioProcessingEvent.java
index 82775a4a719..5327ba2a668 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/AudioProcessingEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/AudioProcessingEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.event;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -26,7 +25,7 @@
*
* @author Ahmed Ashour
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class AudioProcessingEvent extends Event {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BeforeInstallPromptEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BeforeInstallPromptEvent.java
index c50c73151c7..780aabc756b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BeforeInstallPromptEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BeforeInstallPromptEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BeforeUnloadEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BeforeUnloadEvent.java
index 600694a67e6..4ca8a5a5349 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BeforeUnloadEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BeforeUnloadEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,10 +14,12 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.event;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_BEFORE_UNLOAD_RETURN_VALUE_IS_HTML5_LIKE;
+import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_HANDLER_NULL_RETURN_IS_MEANINGFUL;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -34,22 +36,25 @@
*
* @author Frank Danek
* @author Ahmed Ashour
+ * @author Ronald Brill
+ * @author Atsushi Nakagawa
*/
@JsxClass
public class BeforeUnloadEvent extends Event {
+ private Object returnValue_;
/**
* Creates a new event instance.
*/
public BeforeUnloadEvent() {
- setEventType("");
- setReturnValue("");
+ setType("");
+ returnValue_ = "";
}
/**
* The JavaScript constructor. It seems it is not possible to do it from JavaScript code.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public void jConstructor() {
Context.throwAsScriptRuntimeEx(new IllegalArgumentException("Illegal Constructor"));
}
@@ -64,26 +69,63 @@ public BeforeUnloadEvent(final DomNode domNode, final String type) {
super(domNode, type);
setBubbles(false);
- setReturnValue(Undefined.instance);
+ setReturnValue(getReturnValueDefault(getBrowserVersion()));
+ }
+
+ @Override
+ public void initEvent(final String type, final boolean bubbles, final boolean cancelable) {
+ super.initEvent(type, bubbles, cancelable);
+ setReturnValue(getReturnValueDefault(getBrowserVersion()));
+ }
+
+ private static Object getReturnValueDefault(final BrowserVersion browserVersion) {
+ if (browserVersion.hasFeature(EVENT_BEFORE_UNLOAD_RETURN_VALUE_IS_HTML5_LIKE)) {
+ // Empty string default is specified by HTML5
+ // https://www.w3.org/TR/html5/browsers.html#the-beforeunloadevent-interface
+ return "";
+ }
+ return Undefined.instance;
+ }
+
+ /**
+ * @return {@code true} if returnValue holds the beforeunload message
+ */
+ public boolean isBeforeUnloadMessageSet() {
+ return !getReturnValueDefault(getBrowserVersion()).equals(getReturnValue());
}
/**
- * Returns the return value associated with the event.
* @return the return value associated with the event
*/
- @Override
@JsxGetter
+ @Override
public Object getReturnValue() {
- return super.getReturnValue();
+ return returnValue_;
}
/**
* Sets the return value associated with the event.
* @param returnValue the return value associated with the event
*/
- @Override
@JsxSetter
+ @Override
public void setReturnValue(final Object returnValue) {
- super.setReturnValue(returnValue);
+ returnValue_ = returnValue;
+ }
+
+ @Override
+ void handlePropertyHandlerReturnValue(final Object returnValue) {
+ super.handlePropertyHandlerReturnValue(returnValue);
+
+ final BrowserVersion browserVersion = getBrowserVersion();
+
+ // Most browsers ignore null return values of property handlers
+ if (returnValue != null || browserVersion.hasFeature(EVENT_HANDLER_NULL_RETURN_IS_MEANINGFUL)) {
+ // Chrome/Firefox only accept the return value if returnValue is equal to default
+ if (!browserVersion.hasFeature(EVENT_BEFORE_UNLOAD_RETURN_VALUE_IS_HTML5_LIKE)
+ || getReturnValueDefault(browserVersion).equals(getReturnValue())) {
+ setReturnValue(returnValue);
+ }
+ }
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BlobEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BlobEvent.java
index a9484fa95ad..c5364d9bb64 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BlobEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/BlobEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ClipboardEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ClipboardEvent.java
index 80d56f814bf..0d545ab9c35 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ClipboardEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ClipboardEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.event;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -26,7 +25,7 @@
*
* @author Ahmed Ashour
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class ClipboardEvent extends Event {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CloseEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CloseEvent.java
index 68aabbfdb75..57a86e57a88 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CloseEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CloseEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_ONCLOSE_INIT_CLOSE_EVENT_THROWS;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
@@ -66,7 +65,7 @@ public void eventCreated() {
* @param details the event details (optional)
*/
@Override
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public void jsConstructor(final String type, final ScriptableObject details) {
super.jsConstructor(type, details);
@@ -74,7 +73,7 @@ public void jsConstructor(final String type, final ScriptableObject details) {
String reason = "";
boolean wasClean = false;
- if (details != null && details != Undefined.instance) {
+ if (details != null && !Undefined.isUndefined(details)) {
final Double detailCode = (Double) details.get("code");
if (detailCode != null) {
code = detailCode.intValue();
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CompositionEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CompositionEvent.java
index 9320c9124be..4946276af36 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CompositionEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CompositionEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.event;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -32,7 +31,7 @@ public class CompositionEvent extends UIEvent {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public CompositionEvent() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CustomEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CustomEvent.java
index 4f36d4d649a..d686439fbc3 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CustomEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/CustomEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.event;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -37,7 +36,7 @@ public class CustomEvent extends Event {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public CustomEvent() {
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceLightEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceLightEvent.java
index 3998e729763..e0846a6d97a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceLightEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceLightEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.event;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -23,8 +23,9 @@
* A JavaScript object for {@code DeviceLightEvent}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(FF)
+@JsxClass(FF60)
public class DeviceLightEvent extends Event {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceMotionEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceMotionEvent.java
index 276937d0900..86c6af2d096 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceMotionEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceMotionEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.event;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -26,7 +25,7 @@
*
* @author Ahmed Ashour
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class DeviceMotionEvent extends Event {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceOrientationEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceOrientationEvent.java
index 488949ac0f6..b8e3757315a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceOrientationEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceOrientationEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.event;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -26,7 +25,7 @@
*
* @author Ahmed Ashour
*/
-@JsxClass({CHROME, FF, EDGE})
+@JsxClass({CHROME, FF})
public class DeviceOrientationEvent extends Event {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceProximityEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceProximityEvent.java
index 8d9944952ab..d35375d8a10 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceProximityEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DeviceProximityEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.event;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF60;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxConstructor;
@@ -23,8 +23,9 @@
* A JavaScript object for {@code DeviceProximityEvent}.
*
* @author Ahmed Ashour
+ * @author Ronald Brill
*/
-@JsxClass(FF)
+@JsxClass(FF60)
public class DeviceProximityEvent extends Event {
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DragEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DragEvent.java
index e5d90bdbd78..7459262974a 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DragEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/DragEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.event;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -32,7 +31,7 @@ public class DragEvent extends MouseEvent {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public DragEvent() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ErrorEvent.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ErrorEvent.java
index f9a30507385..e55408f9ff2 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ErrorEvent.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/ErrorEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
package com.gargoylesoftware.htmlunit.javascript.host.event;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass;
@@ -32,7 +31,7 @@ public class ErrorEvent extends Event {
/**
* Default constructor.
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public ErrorEvent() {
}
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/Event.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/Event.java
index b00cafd44ed..b462d43261b 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/Event.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/Event.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,14 +14,11 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.event;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_FOCUS_FOCUS_IN_BLUR_OUT;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_ONLOAD_CANCELABLE_FALSE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
-import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF;
+import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF68;
import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.IE;
-import java.lang.reflect.Method;
import java.util.LinkedList;
import com.gargoylesoftware.htmlunit.ScriptResult;
@@ -35,6 +32,7 @@
import com.gargoylesoftware.htmlunit.javascript.configuration.JsxSetter;
import net.sourceforge.htmlunit.corejs.javascript.Context;
+import net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime;
import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
import net.sourceforge.htmlunit.corejs.javascript.Undefined;
@@ -57,6 +55,7 @@
* @author Rob Di Marco
* @author Ronald Brill
* @author Frank Danek
+ * @author Atsushi Nakagawa
*/
@JsxClass
public class Event extends SimpleScriptable {
@@ -179,7 +178,6 @@ public class Event extends SimpleScriptable {
private String propertyName_;
private boolean stopPropagation_;
private boolean stopImmediatePropagation_;
- private Object returnValue_;
private boolean preventDefault_;
/**
@@ -229,6 +227,7 @@ public Event(final EventTarget target, final String type) {
target_ = target;
currentTarget_ = target;
type_ = type;
+
setParentScope(target);
setPrototype(getPrototype(getClass()));
@@ -237,9 +236,11 @@ public Event(final EventTarget target, final String type) {
}
else if (TYPE_LOAD.equals(type)) {
bubbles_ = false;
- if (getBrowserVersion().hasFeature(EVENT_ONLOAD_CANCELABLE_FALSE)) {
- cancelable_ = false;
- }
+ cancelable_ = false;
+ }
+ else if (TYPE_ERROR.equals(type)) {
+ // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-error
+ bubbles_ = false;
}
}
@@ -276,12 +277,12 @@ public void eventCreated() {
* @param type the event type
* @param details the event details (optional)
*/
- @JsxConstructor({CHROME, FF, EDGE})
+ @JsxConstructor({CHROME, FF})
public void jsConstructor(final String type, final ScriptableObject details) {
boolean bubbles = false;
boolean cancelable = false;
- if (details != null && details != Undefined.instance) {
+ if (details != null && !Undefined.isUndefined(details)) {
final Boolean detailBubbles = (Boolean) details.get("bubbles");
if (detailBubbles != null) {
bubbles = detailBubbles.booleanValue();
@@ -321,7 +322,7 @@ public void endFire() {
* Returns the object that fired the event.
* @return the object that fired the event
*/
- @JsxGetter({IE, CHROME, EDGE})
+ @JsxGetter({IE, CHROME, FF68})
public Object getSrcElement() {
return srcElement_;
}
@@ -526,7 +527,7 @@ protected void setCancelable(final boolean cancelable) {
* called for this event. Otherwise this attribute must return {@code false}.
* @return {@code true} if this event has been cancelled or not
*/
- @JsxGetter({FF, IE, EDGE})
+ @JsxGetter
public boolean isDefaultPrevented() {
return cancelable_ && preventDefault_;
}
@@ -534,7 +535,7 @@ public boolean isDefaultPrevented() {
/**
* @return indicates if event propagation is stopped
*/
- @JsxGetter(IE)
+ @JsxGetter
public boolean isCancelBubble() {
return stopPropagation_;
}
@@ -542,7 +543,7 @@ public boolean isCancelBubble() {
/**
* @param newValue indicates if event propagation is stopped
*/
- @JsxSetter(IE)
+ @JsxSetter
public void setCancelBubble(final boolean newValue) {
stopPropagation_ = newValue;
}
@@ -581,19 +582,13 @@ public boolean isImmediatePropagationStopped() {
}
/**
- * Returns the return value associated with the event.
- * @return the return value associated with the event
+ * Handles the return values of property handlers.
+ * @param returnValue the return value returned by the property handler
*/
- public Object getReturnValue() {
- return returnValue_;
- }
-
- /**
- * Sets the return value associated with the event.
- * @param returnValue the return value associated with the event
- */
- public void setReturnValue(final Object returnValue) {
- returnValue_ = returnValue;
+ void handlePropertyHandlerReturnValue(final Object returnValue) {
+ if (Boolean.FALSE.equals(returnValue)) {
+ preventDefault();
+ }
}
/**
@@ -615,20 +610,6 @@ public void initEvent(final String type, final boolean bubbles, final boolean ca
type_ = type;
bubbles_ = bubbles;
cancelable_ = cancelable;
- if (TYPE_BEFORE_UNLOAD.equals(type) && getBrowserVersion().hasFeature(EVENT_FOCUS_FOCUS_IN_BLUR_OUT)) {
- try {
- final Class> klass = getClass();
- final Method readMethod = klass.getMethod("getReturnValue");
- final Method writeMethod = klass.getMethod("setReturnValue", Object.class);
- defineProperty("returnValue", null, readMethod, writeMethod, ScriptableObject.EMPTY);
- if ("Event".equals(klass.getSimpleName())) {
- setReturnValue(Boolean.TRUE);
- }
- }
- catch (final Exception e) {
- throw Context.throwAsScriptRuntimeEx(e);
- }
- }
}
/**
@@ -638,7 +619,9 @@ public void initEvent(final String type, final boolean bubbles, final boolean ca
*/
@JsxFunction
public void preventDefault() {
- preventDefault_ = true;
+ if (isCancelable()) {
+ preventDefault_ = true;
+ }
}
/**
@@ -658,12 +641,13 @@ public boolean isAborted(final ScriptResult result) {
*/
@Override
public String toString() {
- final StringBuilder builder = new StringBuilder("Event ");
- builder.append(getType());
- builder.append(" (");
- builder.append("Current Target: ");
- builder.append(currentTarget_);
- builder.append(");");
+ final StringBuilder builder = new StringBuilder(40);
+ builder.append("Event ")
+ .append(getType())
+ .append(" (")
+ .append("Current Target: ")
+ .append(currentTarget_)
+ .append(");");
return builder.toString();
}
@@ -677,4 +661,25 @@ public String toString() {
public boolean processLabelAfterBubbling() {
return false;
}
+
+ /**
+ * @return the return value property
+ */
+ @JsxGetter({CHROME, FF68})
+ public Object getReturnValue() {
+ return !preventDefault_;
+ }
+
+ /**
+ * @param newValue the new return value
+ */
+ @JsxSetter({CHROME, FF68})
+ public void setReturnValue(final Object newValue) {
+ if (isCancelable()) {
+ final boolean bool = !ScriptRuntime.toBoolean(newValue);
+ if (bool) {
+ preventDefault_ = bool;
+ }
+ }
+ }
}
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/EventHandler.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/EventHandler.java
index baaf0c80623..5c4ad59e0f1 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/EventHandler.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/EventHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,9 +47,7 @@ public EventHandler(final DomNode node, final String eventName, final String jsS
jsSnippet_ = "function on" + eventName + "(event) {" + jsSnippet + "\n}";
- final ScriptableObject w = node.getPage().getEnclosingWindow().getScriptableObject();
- final Scriptable function = (Scriptable) w.get("Function", w);
- setPrototype(function.getPrototype());
+ setPrototype(ScriptableObject.getClassPrototype(node.getScriptableObject(), "Function"));
}
/**
diff --git a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/EventListenersContainer.java b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/EventListenersContainer.java
index a121c8bab3a..2e6d55c2dee 100644
--- a/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/EventListenersContainer.java
+++ b/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/event/EventListenersContainer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2018 Gargoyle Software Inc.
+ * Copyright (c) 2002-2020 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,22 +14,19 @@
*/
package com.gargoylesoftware.htmlunit.javascript.host.event;
-import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_FALSE_RESULT;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.html.DomNode;
-import com.gargoylesoftware.htmlunit.html.HtmlBody;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.javascript.host.Window;
import com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument;
@@ -49,40 +46,93 @@
* @author Ahmed Ashour
* @author Frank Danek
* @author Ronald Brill
+ * @author Atsushi Nakagawa
*/
public class EventListenersContainer implements Serializable {
private static final Log LOG = LogFactory.getLog(EventListenersContainer.class);
- static class TypeContainer implements Serializable {
- private List capturingListeners_;
- private List bubblingListeners_;
- private Object handler_;
+ // Refactoring note: This seems ad-hoc.. Shouldn't synchronization be orchestrated between
+ // JS thread and main thread at a much higher layer? Anyways, to preserve behaviour of prior
+ // coding where 'synchronized' was used more explicitly, we're using a ConcurrentHashMap here
+ // and using ConcurrentMap.compute() to mutate below so that mutations are atomic. This for
+ // example avoids the case where two concurrent addListener()s can result in either being lost.
+ private final ConcurrentMap typeContainers_ = new ConcurrentHashMap<>();
+ private final EventTarget jsNode_;
+
+ private static class TypeContainer implements Serializable {
+ public static final TypeContainer EMPTY = new TypeContainer();
+
+ // This sentinel value could be some singleton instance but null
+ // isn't used for anything else so why not.
+ private static final Scriptable EVENT_HANDLER_PLACEHOLDER = null;
+
+ private final List capturingListeners_;
+ private final List bubblingListeners_;
+ private final List atTargetListeners_;
+ private final Function handler_;
TypeContainer() {
- capturingListeners_ = Collections.unmodifiableList(new ArrayList());
- bubblingListeners_ = Collections.unmodifiableList(new ArrayList());
+ capturingListeners_ = Collections.emptyList();
+ bubblingListeners_ = Collections.emptyList();
+ atTargetListeners_ = Collections.emptyList();
+ handler_ = null;
}
private TypeContainer(final List capturingListeners,
- final List bubblingListeners, final Object handler) {
- capturingListeners_ = Collections.unmodifiableList(new ArrayList<>(capturingListeners));
- bubblingListeners_ = Collections.unmodifiableList(new ArrayList<>(bubblingListeners));
+ final List bubblingListeners, final List atTargetListeners,
+ final Function handler) {
+ capturingListeners_ = capturingListeners;
+ bubblingListeners_ = bubblingListeners;
+ atTargetListeners_ = atTargetListeners;
handler_ = handler;
}
- private List getListeners(final boolean useCapture) {
- if (useCapture) {
- return capturingListeners_;
+ private List getListeners(final int eventPhase) {
+ switch (eventPhase) {
+ case Event.CAPTURING_PHASE:
+ return capturingListeners_;
+ case Event.AT_TARGET:
+ return atTargetListeners_;
+ case Event.BUBBLING_PHASE:
+ return bubblingListeners_;
+ default:
+ throw new UnsupportedOperationException("eventPhase: " + eventPhase);
}
- return bubblingListeners_;
}
- private synchronized boolean addListener(final Scriptable listener, final boolean useCapture) {
- final List listeners = getListeners(useCapture);
+ public TypeContainer setPropertyHandler(final Function propertyHandler) {
+ if (propertyHandler != null) {
+ // If we already have a handler then the position of the existing
+ // placeholder should not be changed so just change the handler
+ if (handler_ != null) {
+ if (propertyHandler == handler_) {
+ return this;
+ }
+ return withPropertyHandler(propertyHandler);
+ }
+
+ // Insert the placeholder and set the handler
+ return withPropertyHandler(propertyHandler).addListener(EVENT_HANDLER_PLACEHOLDER, false);
+ }
+ if (handler_ == null) {
+ return this;
+ }
+ return removeListener(EVENT_HANDLER_PLACEHOLDER, false).withPropertyHandler(null);
+ }
+
+ private TypeContainer withPropertyHandler(final Function propertyHandler) {
+ return new TypeContainer(capturingListeners_, bubblingListeners_, atTargetListeners_, propertyHandler);
+ }
+
+ public TypeContainer addListener(final Scriptable listener, final boolean useCapture) {
+
+ List capturingListeners = capturingListeners_;
+ List bubblingListeners = bubblingListeners_;
+ final List listeners = useCapture ? capturingListeners : bubblingListeners;
if (listeners.contains(listener)) {
- return false;
+ return this;
}
List newListeners = new ArrayList<>(listeners.size() + 1);
@@ -91,21 +141,29 @@ private synchronized boolean addListener(final Scriptable listener, final boolea
newListeners = Collections.unmodifiableList(newListeners);
if (useCapture) {
- capturingListeners_ = newListeners;
+ capturingListeners = newListeners;
}
else {
- bubblingListeners_ = newListeners;
+ bubblingListeners = newListeners;
}
- return true;
+ List atTargetListeners = new ArrayList<>(atTargetListeners_.size() + 1);
+ atTargetListeners.addAll(atTargetListeners_);
+ atTargetListeners.add(listener);
+ atTargetListeners = Collections.unmodifiableList(atTargetListeners);
+
+ return new TypeContainer(capturingListeners, bubblingListeners, atTargetListeners, handler_);
}
- private synchronized void removeListener(final Scriptable listener, final boolean useCapture) {
- final List