Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setIndented(false) also removes new lines from text in views #104

Closed
shimikano opened this issue Dec 23, 2023 · 3 comments
Closed

setIndented(false) also removes new lines from text in views #104

shimikano opened this issue Dec 23, 2023 · 3 comments

Comments

@shimikano
Copy link

shimikano commented Dec 23, 2023

Similarly to #46, I tried to disable indentation in conjunction with a <textarea> element to avoid unwanted whitespace.

However, I noticed that setIndented(false) for views also removes new lines in text() blocks. This is problematic, e.g., for <script> tags. The following test fails, with the rendered view containing no new lines at all:

  @Test
  public void viewWithNoIndent() {
    var view = HtmlFlow.view(page -> {
      page
        .div()
          .textarea()
            .text("Sample text\nfoo\nbar")
          .__()
          .script()
            .text("""
              // some comment
              console.log('Hello world');""")
          .__()
        .__();
    }).setIndented(false);

    var actual = view.render();

    var expected = """
      <div><textarea>Sample text
      foo
      bar</textarea><script>// some comment
      console.log('Hello world');</script></div>""";

    assertEquals(expected, actual);
  }

For docs, this seems not to be the case (the test passes):

  @Test
  public void docWithNoIndent() {
    var stringBuilder = new StringBuilder();
    HtmlFlow.doc(stringBuilder).setIndented(false)
      .div()
        .textarea()
          .text("Sample text\nfoo\nbar")
        .__()
        .script()
          .text("""
            // some comment
            console.log('Hello world');""")
          .__()
      .__();

    var actual = stringBuilder.toString();

    var expected = """
      <div><textarea>Sample text
      foo
      bar</textarea><script>// some comment
      console.log('Hello world');</script></div>""";

    assertEquals(expected, actual);
  }

Is the view behavior a bug or is there another way to preserve the new lines in text() blocks?

Thank you very much.

@fmcarvalho
Copy link
Member

Well, it seems the way we are providing the setIndentation for HtmView is not correct. The way HtmlDoc and HtmView work are completely different. Indentation in HtmlDoc is made though the oldest newlineAndIndent():

public final void newlineAndIndent(){

Whereas HtmView is always built with indentation set to true, and later on render we decide wether we want to remove it. The bug is on the following lines from HtmlContinuationSyncStatic class:

String block = v.isIndented
    ? staticHtmlBlock
    : stream(staticHtmlBlock.split(lineSeparator())).map(String::trim).collect(joining());

We are wrongly removing all line separators. To fix that we have to remove this code. Also we have to change the way we were building an HtmlView. Basically, whenever we call setIndent(...)we have to run the preprocessing(...) from the scratch with the correct indentation flag. And to do it we need to keep the HtmTemplate function associated with the HtmlView.

Is not very complicated and I think it has no impact on performance because all that will be made to run on preprocessing. Moreover I never liked that if/else (i.e ternary) on HtmlContinuationSyncStatic.

However this refactoring includes a couple of steps and I need to review all this again. I hope to dedicate some time to it at the end of this week.

Thank you,
Miguel

@shimikano
Copy link
Author

Thank you, Miguel, for your efforts 🙏

@fmcarvalho
Copy link
Member

Solved on new release 4.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants