Skip to content

OffsetHeight not calculated properly #124

Description

@dvinihan

Running version 2.36.0.

When I build an HTMLUnit page using the following HTML, the offsetHeight is not properly calculated. It resolves to the height of the inner "title-sizer" element, rather than the full height rendered by the long text in the "title" element.

This code works correctly in the Chrome browser when opened from an .html file.

<!DOCTYPE html>
<html>
  <head>
    <title>ESS Template Generator</title>
    <meta charset="UTF-8" content="" />
    <style>
      .title-box {
        position: absolute;
        top: 430px;
        left: 75px;
        width: 960px;
        margin-top: 6px;
        font-size: 60px;
      }
      .title-sizer {
        height: 300px;
      }
    </style>
  </head>
  <body>
    <div class="title-box">
      <span class="title-sizer"
        ><span class="title"
          >8oz steak from Good and Gather. 8oz steak from Good and Gather. 8oz
          steak from Good and Gather. 8oz steak from Good and Gather. 8oz steak
          from Good and Gather. 8oz steak from Good and Gather. 8oz steak from
          Good and Gather. 8oz steak from Good and Gather.</span
        ></span
      >
    </div>
  </body>
  <script>
    function getAttributeValue(element, attribute) {
      if (element) {
        return window.getComputedStyle(element)[attribute].split("px")[0];
      }
      return 0;
    }

    var titleBox = document.querySelector(".title-sizer");
    var title = document.querySelector(".title");

    if (titleBox) {
      var titleHeight = titleBox.offsetHeight;
      alert(titleHeight);
      var titleFontSize = getAttributeValue(titleBox, "fontSize");
      var titleHeightGoal = getAttributeValue(titleBox, "height");

      while (titleHeight > titleHeightGoal) {
        titleFontSize -= 1;

        if (title) {
          title.style.fontSize = titleFontSize + "px";
        }

        titleHeight = titleBox.offsetHeight;
      }
    }
  </script>
</html>

Activity

rbri commented on Jan 28, 2020

@rbri
Member

Thanks for the report. Will have a look and try to improve the implementation. But keep in mind HtmlUnit is a headless renderer, there is no layout engine inside.

dvinihan commented on Jan 29, 2020

@dvinihan
Author

Thanks @rbri - what exactly does that mean? When HtmlUnit renders my page, it does seem like it takes into account the styles I provide in my CSS. Maybe I'm just inferring that, but are you saying it doesn't evaluate the CSS?

The reason I'm slightly confused is because when I do a similar task to the above code using the offsetWidth property, it does function exactly like I want it to.

rbri commented on Feb 10, 2020

@rbri
Member

When HtmlUnit renders my page

HtmlUnit never renders your page. HtmlUnit is headless - there is no rendering step. The whole processing is done on the dom. But we try to simulate also some of the layout related properties.

In your case HtmlUnit will use only the font size to calculate the offsetHeight, but will NOT do any line breaks to fit into the box.
Is this your problem?

dvinihan commented on Feb 11, 2020

@dvinihan
Author

That's exactly right- I was expecting the line breaks to be taken into account, but if they're not, it makes sense. Thanks.

dvinihan commented on Aug 12, 2020

@dvinihan
Author

@rbri Still dealing with this issue and wondering if there is any workaround you can provide. Essentially I have a

of set dimensions, say 1000px by 500px. And I have a dynamic text string which I want to shrink to fit into this div if it would overflow. Ideally, I would calculate the height of the text div, and if it's greater than my set max-height (500px), I would incrementally shrink the font until the height is less than or equal to 500. The only way to do this is to calculate the actual height at any given time of the div, which is not possible if line wrapping is not taken into account.

rbri commented on Aug 19, 2020

@rbri
Member

Have spent some more days on this, now we do word wrapping.
Some other minor fixes are also done.

Of course you still not get the correct values because we do no rendering but the height is now adjusted in every loop.
Will make a new snapshot build available as soon as all the unit tests have passed (check twitter).

Hope that helps.

dvinihan commented on Aug 19, 2020

@dvinihan
Author

Wow! That's wonderful! I'll keep an eye out for the new release. Thank you so much for your time and energy on this- it will really help us out!

rbri commented on Aug 19, 2020

@rbri
Member

A new snapshot build is available - please try and provide feedback.

dvinihan commented on Aug 19, 2020

@dvinihan
Author

@rbri What's the version number that I should include in my gradle build? I don't see any such releases on the github page or the website.

rbri commented on Aug 19, 2020

@rbri
Member

for maven you need

<dependency>
    <groupId>net.sourceforge.htmlunit</groupId>
    <artifactId>htmlunit</artifactId>
    <version>2.44.0-SNAPSHOT</version>
</dependency>

and maybe

<snapshotRepository>
    <id>sonatype-nexus-snapshots</id>
    <url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>

I guess you are able to translate this into gradle :-)

dvinihan commented on Aug 19, 2020

@dvinihan
Author

Hi @rbri - I am able to import the snapshot properly, but I see there is a new "parse" method to parse an HTML string onto the page. Would you mind providing a code snippet for how to implement this? I can only find the past version on your FAQ using the parseHtml and parseXhtml methods.

I did attempt to use the new parse method, but I'm getting this error: java.lang.NoSuchMethodError: 'void com.gargoylesoftware.htmlunit.html.parser.HTMLParser.parse(com.gargoylesoftware.htmlunit.WebResponse, com.gargoylesoftware.htmlunit.html.HtmlPage, boolean)'

dvinihan commented on Aug 19, 2020

@dvinihan
Author

Looks like the HtmlUnitNekoHtmlParser from version 2.40.0 is being used somehow, which is why the parse method is not found. Not sure what the fix is, but that's the cause.

rbri commented on Aug 20, 2020

@rbri
Member

Maybe you have different versions of an lib in your classpath.

dvinihan commented on Aug 20, 2020

@dvinihan
Author

I believe HtmlUnit is the package that is pulling in an older version of itself. When I remove the HtmlUnit dependency, I see all HtmlUnit packages disappear. When I put HtmlUnit back in, I see different versions all at once:
Screen Shot 2020-08-20 at 11 37 49 AM

rbri commented on Aug 20, 2020

@rbri
Member

Nearly impossible - do you have an (old) htmlunit driver also in your project?

Please try to have a look at the dependency tree (https://docs.gradle.org/current/userguide/viewing_debugging_dependencies.html)

dvinihan commented on Aug 20, 2020

@dvinihan
Author

I was able to figure out how to exclude the older version from library imports. However, once I do that, I get error messages like this:
java.lang.ClassNotFoundException: com.gargoylesoftware.htmlunit.AlertHandler
and
java.lang.ClassNotFoundException: com.gargoylesoftware.htmlunit.WebResponse

So it's either those errors, or if I do let the project include version 2.40.0 like in the screenshot above, then I still get this:
java.lang.NoSuchMethodError: 'void com.gargoylesoftware.htmlunit.html.parser.HTMLParser.parse(com.gargoylesoftware.htmlunit.WebResponse, com.gargoylesoftware.htmlunit.html.HtmlPage, boolean)'

rbri commented on Aug 21, 2020

@rbri
Member

Please make sure you only have the lastest versions of all the dependent lib in the classpath

    <htmlunitcssparser.version>1.5.0</htmlunitcssparser.version>
    <htmlunitneko.version>2.44.0-SNAPSHOT</htmlunitneko.version>
    <htmlunitcorejs.version>2.43.0</htmlunitcorejs.version>

dvinihan commented on Aug 24, 2020

@dvinihan
Author

@rbri I was able to get the classpath issues fixed, and it looks like the new updates are working great! Thank you so much for you work on this, it's really wonderful. Any idea when 2.44.0 will be released?

rbri commented on Aug 31, 2020

@rbri
Member

Thanks for the feedback - enjoy using HtmlUnit

dvinihan commented on Oct 5, 2020

@dvinihan
Author

@rbri After updating to the new 2.44.0 release, I'm having problems parsing HTML. Here's what I had prior to this update:

val client = new WebClient()
val response = new StringWebResponse(html, new URL(s"file:$resourcePath/static/css"))
val page = client.getPageCreator.getHtmlParser.parseHtml(response, client.getCurrentWindow)

and here's what I've been trying with the new release, since parseHtml method doesn't exist anymore:

val client = new WebClient()
val response = new StringWebResponse(html, new URL(s"file:$resourcePath/static/css"))
val page = new XHtmlPage(response, client.getCurrentWindow)
client.getPageCreator.getHtmlParser.parse(response, page, true)

I get this error thrown at the last line: java.lang.IllegalStateException: No script object associated with the Page. class: 'com.gargoylesoftware.htmlunit.html.XHtmlPage' url: 'file:../sign-templates/src/main/resources/static/css' content: <!DOCTYPE > .......

I even tried adding this before the final line: page.setScriptableObject(client.getCurrentWindow.getScriptableObject)

Could you please provide an updated example of how to parse HTML to the page?

rbri commented on Oct 5, 2020

@rbri
Member

rbri commented on Oct 6, 2020

@rbri
Member

Sorry for breaking the backward compatibility. Have updated the FAQ to make the sample code working again.

dvinihan commented on Oct 6, 2020

@dvinihan
Author

Perfect, thanks so much! And thank you for all the work you do on the library!

dvinihan commented on Oct 6, 2020

@dvinihan
Author

Hi @rbri -
After upgrading to 2.44.0 and attempting to calculate the offsetHeight on an element, I am still not seeing a value that takes text wrapping into account. Should I be seeing it in this case? When I tested with the snapshot, it did work correctly.

rbri commented on Oct 12, 2020

@rbri
Member

Sorry but there is no change regarding this between the snapshots and the release. Strange...
Please reopen if you still have this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions