Skip to content

Commit

Permalink
make the impl more explicit
Browse files Browse the repository at this point in the history
  • Loading branch information
rbri committed Nov 12, 2024
1 parent 2939142 commit 899ea14
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 46 deletions.
28 changes: 26 additions & 2 deletions src/main/java/org/htmlunit/html/HtmlScript.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,23 @@ public class HtmlScript extends HtmlElement implements ScriptElement {
super(qualifiedName, page, attributes);
}

/**
* Returns the value of the attribute {@code charset}. Refer to the
* <a href="http://www.w3.org/TR/html401/">HTML 4.01</a>
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code charset}
* or an empty string if that attribute isn't defined.
*/
public final String getCharsetAttribute() {
return getAttributeDirect("charset");
}

/**
* {@inheritDoc}
*/
@Override
public final String getCharsetAttribute() {
public final String getScriptCharset() {
return getAttributeDirect("charset");
}

Expand Down Expand Up @@ -98,11 +110,23 @@ public final String getLanguageAttribute() {
return getAttributeDirect("language");
}

/**
* Returns the value of the attribute {@code src}. Refer to the
* <a href="http://www.w3.org/TR/html401/">HTML 4.01</a>
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code src}
* or an empty string if that attribute isn't defined.
*/
public final String getSrcAttribute() {
return getSrcAttributeNormalized();
}

/**
* {@inheritDoc}
*/
@Override
public final String getSrcAttribute() {
public final String getScriptSource() {
return getSrcAttributeNormalized();
}

Expand Down
19 changes: 5 additions & 14 deletions src/main/java/org/htmlunit/html/ScriptElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* An element which can handle scripts.
*
* @author Ahmed Ashour
* @author Ronald Brill
*/
public interface ScriptElement {

Expand All @@ -40,24 +41,14 @@ public interface ScriptElement {
void setExecuted(boolean executed);

/**
* Returns the value of the attribute {@code src}. Refer to the
* <a href="http://www.w3.org/TR/html401/">HTML 4.01</a>
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code src}
* or an empty string if that attribute isn't defined.
* @return the script source url
*/
String getSrcAttribute();
String getScriptSource();

/**
* Returns the value of the attribute {@code charset}. Refer to the
* <a href="http://www.w3.org/TR/html401/">HTML 4.01</a>
* documentation for details on the use of this attribute.
*
* @return the value of the attribute {@code charset}
* or an empty string if that attribute isn't defined.
* @return the charset used for the script encoding
*/
String getCharsetAttribute();
String getScriptCharset();

/**
* <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br>
Expand Down
57 changes: 27 additions & 30 deletions src/main/java/org/htmlunit/html/ScriptElementSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,13 @@ private ScriptElementSupport() {
}

/**
* Lifecycle method invoked after a node and all its children have been added to a page, during
* parsing of the HTML. Intended to be overridden by nodes which need to perform custom logic
* after they and all their child nodes have been processed by the HTML parser. This method is
* not recursive, and the default implementation is empty, so there is no need to call
* <code>super.onAllChildrenAddedToPage()</code> if you implement this method.
* @param element the element
* Support method that is called from the (html or svg) script and the link tag.
*
* @param script the ScriptElement to work for
* @param postponed whether to use {@link org.htmlunit.javascript.PostponedAction} or no
*/
public static void onAllChildrenAddedToPage(final DomElement element, final boolean postponed) {
public static void onAllChildrenAddedToPage(final ScriptElement script, final boolean postponed) {
final DomElement element = (DomElement) script;
if (element.getOwnerDocument() instanceof XmlPage) {
return;
}
Expand All @@ -80,8 +78,7 @@ public static void onAllChildrenAddedToPage(final DomElement element, final bool
return;
}

final ScriptElement script = (ScriptElement) element;
final String srcAttrib = script.getSrcAttribute();
final String srcAttrib = script.getScriptSource();
final boolean hasNoSrcAttrib = ATTRIBUTE_NOT_DEFINED == srcAttrib;
if (!hasNoSrcAttrib && script.isDeferred()) {
return;
Expand Down Expand Up @@ -109,7 +106,7 @@ public void execute() {
&& ATTRIBUTE_NOT_DEFINED != srcAttrib);
}
try {
executeScriptIfNeeded(element, false, false);
executeScriptIfNeeded(script, false, false);
}
finally {
if (jsDoc != null) {
Expand Down Expand Up @@ -151,19 +148,19 @@ else if (engine != null
* <span style="color:red">INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.</span><br>
*
* Executes this script node if necessary and/or possible.
* @param element the element
*
* @param script the ScriptElement to work for
* @param ignoreAttachedToPage don't do the isAttachedToPage check
* @param ignorePageIsAncestor don't do the element.getPage().isAncestorOf(element) check
*/
public static void executeScriptIfNeeded(final DomElement element, final boolean ignoreAttachedToPage,
public static void executeScriptIfNeeded(final ScriptElement script, final boolean ignoreAttachedToPage,
final boolean ignorePageIsAncestor) {
if (!isExecutionNeeded(element, ignoreAttachedToPage, ignorePageIsAncestor)) {
if (!isExecutionNeeded(script, ignoreAttachedToPage, ignorePageIsAncestor)) {
return;
}

final ScriptElement scriptElement = (ScriptElement) element;

final String src = scriptElement.getSrcAttribute();
final String src = script.getScriptSource();
final DomElement element = (DomElement) script;
if (SLASH_SLASH_COLON.equals(src)) {
executeEvent(element, Event.TYPE_ERROR);
return;
Expand All @@ -177,8 +174,8 @@ public static void executeScriptIfNeeded(final DomElement element, final boolean
LOG.debug("Loading external JavaScript: " + src);
}
try {
scriptElement.setExecuted(true);
Charset charset = EncodingSniffer.toCharset(scriptElement.getCharsetAttribute());
script.setExecuted(true);
Charset charset = EncodingSniffer.toCharset(script.getScriptCharset());
if (charset == null) {
charset = page.getCharset();
}
Expand Down Expand Up @@ -216,7 +213,7 @@ else if (element.getFirstChild() != null) {
final Document doc = win.getDocument();
try {
doc.setCurrentScript(element.getScriptableObject());
executeInlineScriptIfNeeded(element);
executeInlineScriptIfNeeded(script);
}
finally {
doc.setCurrentScript(null);
Expand All @@ -227,18 +224,18 @@ else if (element.getFirstChild() != null) {
/**
* Indicates if script execution is necessary and/or possible.
*
* @param element the element
* @param script the ScriptElement to work for
* @param ignoreAttachedToPage don't do the isAttachedToPage check
* @param ignorePageIsAncestor don't do the element.getPage().isAncestorOf(element) check
* @return {@code true} if the script should be executed
*/
private static boolean isExecutionNeeded(final DomElement element, final boolean ignoreAttachedToPage,
private static boolean isExecutionNeeded(final ScriptElement script, final boolean ignoreAttachedToPage,
final boolean ignorePageIsAncestor) {
final ScriptElement script = (ScriptElement) element;
if (script.isExecuted() || script.wasCreatedByDomParser()) {
return false;
}

final DomElement element = (DomElement) script;
if (!ignoreAttachedToPage && !element.isAttachedToPage()) {
return false;
}
Expand Down Expand Up @@ -271,7 +268,7 @@ private static boolean isExecutionNeeded(final DomElement element, final boolean
// If the script language is not JavaScript, we can't execute.
final String t = element.getAttributeDirect("type");
final String l = element.getAttributeDirect("language");
if (!isJavaScript(element, t, l)) {
if (!isJavaScript(t, l)) {
// Was at warn level before 2.46 but other types or tricky implementations with unsupported types
// are common out there and too many peoples out there thinking the is the root of problems.
// Browsers are also not warning about this.
Expand All @@ -290,12 +287,12 @@ private static boolean isExecutionNeeded(final DomElement element, final boolean
* Returns true if a script with the specified type and language attributes is actually JavaScript.
* According to <a href="http://www.w3.org/TR/REC-html40/types.html#h-6.7">W3C recommendation</a>
* are content types case insensitive.<br>
* @param element the element
*
* @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
*/
public static boolean isJavaScript(final DomElement element, String typeAttribute, final String languageAttribute) {
public static boolean isJavaScript(String typeAttribute, final String languageAttribute) {
typeAttribute = typeAttribute.trim();

if (StringUtils.isNotEmpty(typeAttribute)) {
Expand All @@ -317,17 +314,17 @@ private static void executeEvent(final DomElement element, final String type) {
/**
* Executes this script node as inline script if necessary and/or possible.
*/
private static void executeInlineScriptIfNeeded(final DomElement element) {
if (!isExecutionNeeded(element, false, false)) {
private static void executeInlineScriptIfNeeded(final ScriptElement script) {
if (!isExecutionNeeded(script, false, false)) {
return;
}

final ScriptElement scriptElement = (ScriptElement) element;
final String src = scriptElement.getSrcAttribute();
final String src = script.getScriptSource();
if (src != ATTRIBUTE_NOT_DEFINED) {
return;
}

final DomElement element = (DomElement) script;
final String forr = element.getAttributeDirect("for");
String event = element.getAttributeDirect("event");
// The event name can be like "onload" or "onload()".
Expand All @@ -345,7 +342,7 @@ private static void executeInlineScriptIfNeeded(final DomElement element) {
final String desc = "script in " + url + " from (" + line1 + ", " + col1
+ ") to (" + line2 + ", " + col2 + ")";

scriptElement.setExecuted(true);
script.setExecuted(true);
((HtmlPage) element.getPage()).executeJavaScript(scriptCode, desc, line1);
}
}
Expand Down

0 comments on commit 899ea14

Please sign in to comment.