Seeing additional closing/end tags for img and br tags when using the latest version of Jsoup parser (1.15.3) - xml-parsing

Seeing additional closing/end tags for img and br tags when using the latest version of Jsoup parser (1.15.3).
With the latest jsoup version 1.15.3 it is observed that additional end tags for br and img tags are getting added after parsing, for the below input html:
<html>
<body>
<div>
<span><img src="flower.jpg"><br>This is a sampletext</span>
</div>
</body>
</html>
Below is the output after parsing using xml parser:
<html>
<body>
<div>
<span><img src="flower.jpeg"><br>text**</br></img>**</span>
</div>
</body>
</html>
For the same input with version 1.11.3 of jsoup the br and img tags were having a self closing tag:
<html>
<body>
<div>
<span><img src="flower.jpg"**/><br/>**This is a sampletext</span>
</div>
</body>
</html>
As per the below changes on the jsoup code the output settings if set to xml should have a self closing tag for img:
https://github.com/jhy/jsoup/commit/6c4f16f233cdfd7aedef33374609e9aa4ede255c#diff-2039a2cc0acb457fb17a4cc6640fb3815d9d753a39fa59cfaedd9d4e155b43ddR1080
We wanted to understand the reason behind this change on the latest version of Jsoup? Is there any specific intention on this change to add the end tags explicitly on the br and img tags?

Related

Rails insert automatically my code into body tag not into head tag

I did it in application.html.erb
<html>
<head>
<%if #hasAdsense == true%>
<script data-ad-client="ca-pub-64xxxxxxxxxxx" async
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<%end%>
</head>
<body>
<%= yield %>
</body>
</html>
but when I see a page with chrome developer tools ,it's automtically inserted in body not in head.
so html code of page where #hasAdsense==true looks like this.
<html>
<head>
</head>
<body>
<script data-ad-client="ca-pub-64xxxxxxxxxxx"
async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
</body>
</html>
I don't know why this happens, but google bot inspect Adsense script in head tag,
so I think this can cause problem so that I can't use Adsense script in my website.
is there a way let rails not insert automatically adsense script into body tag?
do you have
<%if #hasAdsense == true%>
<script data-ad-client="ca-pub-64xxxxxxxxxxx" async
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<%end%>
in any other views, because it might come from the yield.
We probs need a little more info here, is #hasAdsense a boolean value (can you confirm by showing your controller or checking on the page directly)? does this happen with other content? so if you made a if statement with <title>Hello World</title> does that render in the body as well?

&nbsp dispalyed as "Â" in html template in angular 7

I have a angular 7 project in that I have many html templates. In html templates where and I have inserted   its displayed as space along with another character "Â". This issue is not coming when I test in my local environment. When deployed in tomcat in my QA environment I am facing.
HTML Code
<!doctype html>
<html class="no-js" lang="en" dir="ltr">
<head>
<base href="/">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Test</title>
<meta name="description" content="Description">
</head>
<body>
<jhi-root></jhi-root>
</body>
</html>
Next code snippet is one of the template I use in my project.
<div class="d-flex" id="wrapper">
<jhi-sidebar></jhi-sidebar>
<div id="page-content-wrapper">
<jhi-header></jhi-header>
<div class="inner-page">
<div class="container-fluid">
<div class="row">
<div class="col-12">
<h3 class="card-title text-left">Widgets</h3>
</div>
</div>
</div>
<p> Link1 </p>
<p> Link2 </p>
<p> Link3 </p>
</div>
</div>
</div>
Below is the output that is displayed when the above template is rendered. We can see that space is created but with extra special character not sure.
Link1 Â
Link2 Â
Link3 Â
I have checked encoding type its UTF-8 but still I didnt understand why a weird character is displayed when rendered. Please help
That'd be encoding to UTF-8 then, not ISO-8859-1. The non-breaking space character is byte 0xA0 in ISO-8859-1; when encoded to UTF-8 it'd be 0xC2,0xA0, which, if you (incorrectly) view it as ISO-8859-1 comes out as " "
Ref
Use
<meta charset="utf-8">

Define and insert Thymeleaf fragments in TEXT templates

I'm trying to create email templates in both plain text and HTML with Thymeleaf. Because I don't want to duplicate the common parts I want to define these parts separately and insert them into the more specific templates.
It works for HTML, but for plain text variables in the common parts are not replaced:
HTML
common.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div th:fragment="header">
<p>
Hello, [( ${name} )]
</p>
</div>
<div th:fragment="footer">
<p>
Bye.
</p>
</div>
</body>
</html>
specific.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div th:replace="html/common::header"></div>
<p>
<a th:href="${myLink}">[( ${myLink} )]</a>
</p>
<div th:replace="html/common::footer"></div>
</body>
</html>
Plain text
header.txt
Hello ${name}
footer.txt
Bye
specific.txt
[( ~{text/header} )]
[( ${myLink} )]
[( ~{text/footer} )]
Result
It all works well for HTML but for the plain text version the ${name} variable from the inserted header.txt template is not replaced:
Hello, [#th:block th:utext="${name}"][/th:block]
http://example.com
Bye.
The HTML result looks correct:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<p>
Hello, name-value
</p>
</div>
<p>
http://example.com
</p>
<div>
<p>
Bye.
</p>
</div>
</body>
</html>
My questions
Is there an elegant solution for the plain text version?
Is there a way to define and use fragments also for textual Thymeleaf templates?
Any general recommendations, as I'm only starting to use Thymeleaf?
Variables in the Plain Text Version
For the plain text issue, you can use the [#th:block] syntax.
Specifically, instead of using this in your specific.txt:
[( ~{text/header} )]
you can use this:
[#th:block th:replace="text/header"][/th:block]
Also, in the header.txt file, instead of using this:
Hello ${name}
you need to use this:
Hello [( ${name} )]
This is expression inlining - which you have already used - and is presented here, for reference.
Some additional examples of the [#th:block] syntax are presented here.
Defining and Using Fragments for Text
You might think that the [#th:block] syntax would now allow us to use fragments, in a similar way to the HTML approach. For example, something like this:
DOES NOT WORK:
[#th:block th:replace="text/common :: header"][/th:block]
together with a common.txt fragment like this:
ALSO DOES NOT WORK:
[#th:block th:fragment="header"]
Hello, [( ${name} )]
[/th:block]
If you try this, you will get the following error:
java.lang.IllegalArgumentException: Template selectors cannot be specified for a template using a TEXT template mode: template insertion operations must be always performed on whole template files, not fragments
General Comments
The only other thing I would mention here, if you have not already seen or used it, is parameterized fragments. They can make HTML fragments more flexible and re-usable.

Bootstrap date picker not working on on my form using Grails site mesh main.gsp - but works for standalone form

I'm trying to see if I can get the Bootstrap datePicker (datePicker)to work in Grails v3.3.9/fields plugin 2.2.10
I've done a standalone page, that is I create a controller, and give it an action called 'ldt'.
I create grails view called ldt.gsp like this. When I hit trigger my controller in the browser - this simple page renders fine and datePicker works
<!DOCTYPE html>
<html>
<head>
<title>Bootstrap datepicket demo</title>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script type='text/javascript' src='//code.jquery.com/jquery-1.8.3.js'></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker3.min.css">
<script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js"></script>
<script type='text/javascript'>
$(function(){
//$('.input-group.date').datepicker({
$('#datepicker').datepicker({
calendarWeeks: true,
todayHighlight: true,
autoclose: true
});
});
</script>
</head>
<body>
<div class="container">
<h1>Bootstrap datepicker</h1>
<div class="input-group date" id="datepicker">
<input type="text" class="form-control">
<span class="input-group-addon">
<i class="glyphicon glyphicon-calendar"></i>
</span>
</div>
</div>
</body>
</html>
You can see that here. This is not using normal Grails site mesh etc
So I tried to put the same into views/layouts/main.gsp
So here is the head section of my revised main.gsp. (I've not included Bootstrap nor jQuery as them come with grails application.js).
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>
<g:layoutTitle default="Grails"/>
</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<asset:link rel="icon" href="favicon.ico" type="image/x-ico"/>
<asset:stylesheet src="application.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker3.min.css">
<script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js"></script>
<script type='text/javascript'>
$(function(){
$('#datepicker').datepicker({
calendarWeeks: true,
todayHighlight: true,
autoclose: true
});
});
</script>
<g:layoutHead/>
<%-- header assets --%>
</head>....
Now I am trying to render a specific field in the domain class - which is of type LocalDateTime. To try and do this I have created a _fields/localDateTime/_wrapper.gsp that looks like this in which I setup the input control (as I did for the standalone page), but I give the input a start date time for now.
localDateTime/_wrapper.gsp
<%# page import="java.time.LocalDateTime; java.time.format.DateTimeFormatter" %>
<g:set var="localDateTimePattern" value="${message(code: 'default.localDateTime.format',default: 'yyyy-MM-dd HH:mm')}"/>
<div class="fieldcontain" >
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class="input-group date" id='datetimepicker1' >
<label for=${this.pageScope.property}> ${this.pageScope.getVariable("label")} </label>
<input type='text' class="form-control" value="${java.time.LocalDateTime.now().toString()}"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
When I go this page in the browser it gets rendered, but the clickable field behaviour etc does not fire and the field has no calendar icon on the right hand side (this may be because Grails is loading Bootstrap 4, and when I tried the standalone with v4.3.1 the icon didn't render - but the click event still worked).
See rendered form here - using the 'edit' action which in turn is using standard scaffolds with <f:all which calls my _wrapper.gsp.
The string value of the date gets rendered fine (not formatted), but I get no click action and calendar doesn't pop up - no action at all. I've included a snip of the browser page inspection in the browser opened for the contractSignedDate property.
So if a standalone page gsp works just fine (albeit with Bootstrap 4 as loaded by Grails bau) does my click action not fire
So why can't the gsp action action fire when using the main.gsp/normal fields plugin/and _wrapper.gsp for java LocalDateTime? It worked for standalone gsp example so I know the datePicker works
How can I get the Bootstrap datepicker as described here working in a Grails scaffolded form?
PS it's not missing jqueryUI library - I've included 1.12.1 in both standalone and main.gsp see this image from inspector. Works fine on standalone but not using main.gsp and scaffolded forms
PS if I click into the scaffolded form property as shown in the _widget.gsp, the outer text box is highlighted in blue (which the bau grails rendered elements don't - so some form of click action is happening - just not getting a calendar to pop up.
This is very odd. When referenced on standalone gsp and link JS/CSS from CDN, the page worked.
If I add <meta name="layout" content="main" /> and had the page rendered via site mesh in main.gsp it would fail.
I tried many different combinations in the standalone page <head>, and basically the date picker doesn't seem to need the bootstrap js to work - but it does need the jQuery and it must be in the head section.
If you want the styles you need to include the bootstrap.css and the bootstrap-datepicker3 CSS.
<head>
<%--<meta name="layout" content="main" />--%>
<title>Bootstrap datepicket demo</title>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<%--<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script> --%>
<script type='text/javascript' src='//code.jquery.com/jquery-3.3.1.js'></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker3.min.css">
<script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js"></script>
</head>
However if you uncommented the meta tag it would all stop. In the end to get this to work I had to edit the /assets/application.js and remove the entries for Bootstrap and jQuery using the local copies in /assets/javascripts, and instead reference these directly from the cdn in main.gsp.
So my working application.js looks like this - where I include my own LCM-app JS:
// This is a manifest file that'll be compiled into application.js.
//
// Any JavaScript file within this directory can be referenced here using a relative path.
//
// You're free to add application-wide JavaScript to this file, but it's generally better
// to create separate JavaScript files as needed.
//= require LCM-app
//= require popper.min
//= require_self
My LCM-app js just looks like this where my selector is using class selector - note you seem to have add the dot between group and date '.input-group.date' - but that becomes a space in your markup
// used by bootstrap date picker - matching class selector is for class class='.input-group date'
$(function(){
$('.input-group.date').datepicker({
calendarWeeks: true,
todayHighlight: true,
autoclose: true
});
});
I then went to main.gsp and edited in the cdn references that I had in the standlone page (asset plugin is now disabled for jQuery and Bootstrap)
main.gsp (head section) - you dont need jqueryUI for this to work
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>
<g:layoutTitle default="Grails"/>
</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<asset:link rel="icon" href="favicon.ico" type="image/x-ico"/>
<asset:stylesheet src="application.css"/>
<%-- <script type='text/javascript' src='//code.jquery.com/jquery-1.12.1.js'></script>--%>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script type='text/javascript' src='//code.jquery.com/jquery-3.3.1.js'></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker3.min.css">
<script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js"></script>
<g:layoutHead/>
<%-- header assets --%>
</head>
Now when you uncomment out the <meta> tag in the standalone page and remove the direct refs - then the main.gsp site mesh adds these back exactly as they were in the standalone page
Point your browser at the test page and it all works as normal.
It even works when I put the basic code into a taglib (you have to stop the escaping using the static encodeAsForTags and set to 'none' for your tag).
JdtDateTimeTagLib
class JavaDateTimeTagLib {
static defaultEncodeAs = [taglib:'html']
//static encodeAsForTags = [tagName: [taglib:'html'], otherTagName: [taglib:'none']]
static encodeAsForTags = [ jdtScaffoldField:'none']
static namespace = "jdt" //java8 date time name space for tags
GrailsNameUtils grailsNameUtils = new GrailsNameUtils()
def jdtScaffoldField = {attrs, body ->
assert grailsNameUtils
String propertyName = attrs.propertyName ?: "unknown"
String property = attrs.property ?: "unknown"
String value = attrs.value
String naturalName = grailsNameUtils.getNaturalName(propertyName)
String label = attrs.label ?: 'unknown'
String ldtStr = attrs.ldt
String page = """
<g:set var="localDateTimePattern" value="${message(code: 'default.localDateTime.format',default: 'yyyy-MM-dd HH:mm')}"/>
<div class="fieldcontain" >
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group form-inline">
<label class='control-label' for="$propertyName"> ${label} </label>
<div class="input-group date" >
<input type='text' class="form-control" value="${ldtStr?.toString()}"/>
<span class="input-group-addon">
<i class="glyphicon glyphicon-calendar"></i>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
"""
out << page
}
}
I can then simplify the _fields/localDateTime/_wrapper.gsp to use that tag like so
<%# page import="java.time.LocalDateTime; java.time.format.DateTimeFormatter" %>
<g:set var="localDateTimePattern" value="${message(code: 'default.localDateTime.format',default: 'yyyy-MM-dd HH:mm')}"/>
<jdt:jdtScaffoldField propertyName="xyc" label="my label"></jdt:jdtScaffoldField>
Now when you go to a normal grails edit action my field is rendered and the calendar actions.
I've lost variables in this version as I'm not getting the values passed to the wrapper and putting them forward into my tag - but I think that's not too hard. See working screen shot 'as-is'
Sadly the lest of the Grails scaffolding is using its own rendering so the CSS styles don't match, alignment is a bit out etc - but its an improvement if I can just get the submit action etc to take the selected date and convert pack to LocalDateTime to persist in the database.
Basically it would be better if the grails <g:datePicker could be 'fixed' to work with new Java time formats and use the Bootstrap picker - because the fields plugin invokes the <g:datePicker for ordinary Java Date but completely doesn't handle the Java 8 temporal stuff.
I have tried to 'find' where the grails <g: taglib is implemented (thought it was going to be in the GSP plugin or core projects - but I can't find it in either.
However whilst it's not ideal - its good enough for the mini demo using scaffolds I was going to show people - just looks a little clunky as it's not consistent.

What type of operation and syntax for them are possible on Thymeleaf 3 fragment expression?

With Thymeleaf 3 it is possible to pass fragment from page to template via ~{:: selector} syntax.
What kind of operation are possible on that object?
Fragment can be used inside expression:
<div th:fragment="name(arg)">
<div th:replace="${arg} :? _"></div>
</div>
Can I extract only part of fragment inside fragment with something like (following is incorrect syntax!!):
<div th:fragment="name(arg)">
<div th:replace="${arg :: script} :? _"></div>
<div th:replace="${arg}.filter('script'} :? _"></div>
<div th:replace="${xpath(${arg},'script')} :? _"></div>
</div>
UPDATE I introspected to what fragment expression is resolved with:
<th:block th:text="${bodyContent.class}" />
which is org.thymeleaf.standard.expression.Fragment. It has:
<th:block th:text="${bodyContent.templateModel.class}" />
TemplateModel which can be rendered via toString() or write(Writer writer). I don't see easy way to filter Fragment content...
I saw Thymeleaf templates - Is there a way to decorate a template instead of including a template fragment? technique which I tried to employ.
Thymeleaf v2.1 and 3 allows referencing templates/fragment mix to itself.
Lets look to template:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<nav></nav>
<div th:replace="this :: body"/>
</body>
</html>
and to page:
<html lang="en" xmlns:th="http://www.thymeleaf.org"
th:replace="thymeleaf/layout/default :: html">
<body>
XXX
</body>
</html>
Above code produces infinite sequence of <body><nav></nav> as CSS selector referenced from template to body's template.
To move reference to page I added more complicated CSS style selector:
<html lang="en" xmlns:th="http://www.thymeleaf.org" class="htmlFrag">
<body>
<nav></nav>
<div th:replace="this :: html[!class]/body"/>
</body>
</html>
I am not sure how it is possible to have template and page in same scope for selector matching but it works...
Advanced templating with CSS/JS handling can be represented as:
<html lang="en" xmlns:th="http://www.thymeleaf.org" class="htmlFrag">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title th:text="~{::html[!class]/head/title/text()}"></title>
<link rel='stylesheet' href='/webjars/...">
<div th:replace="this :: html[!class]/head/link"/>
<script src="/webjars/..."></script>
<div th:replace="this :: html[!class]/head/script"/>
</head>
<body>
<nav></nav>
<div th:replace="this :: html[!class]/body"/>
</body>
</html>
UPDATE I've got responce from developers https://github.com/thymeleaf/thymeleaf/issues/626
Thymeleaf uses pull-based or fragment-inclusion-based layout architecture or by default.
With Layout Dialect it is possible to use hierarchical layout style and it is preferred to do this.

Resources