Hello, I'm tring to use jStyleParser as css parser for my Java project.
IMHO, the documentation is a little lazy.
For example:
In CssFactory class, the method parse(String fileName, String encoding) is
ambiguos: fileName rappresent the HTML file's Url or the Css file's Url?
How should I parse the css declaration included inside a <style> tag?
In Analyzer class, the method assingDeclarationsToDOM(Document doc, String
media, boolean inherit) is obscure: what rapresent "media?" Maybe the "media"
attribute inside the <link> tag?
After binding Css to the DOM throught the evaluateDOM method, is there a way
to get the related CSS properties passing an org.w3c.dom Node ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am aware that the API documentation is too brief or missing in some points
but I am improving it slowly. Since I am the only active developer now, the
time I can give to it is limited. Any help is greatly appreciated.
jStyleParser is primarily a CSS parser. That means, all the parse() methods
parse CSS code. There is also a parse(String) variant, that means you may
parse CSS code obtained from any source (even from the <style> tag).
The assignDOM method obtains the referenced stylesheets and assigns the styles
to the nodes of a DOM tree that you have obtained anyhow (usually by using a
HTML DOM parser). The typical usage is:
//assign the styles
StyleMap map = CSSFactory.assignDOM(doc, url, "screen", true);
//get the style for a node
NodeData nodeStyle = map.get(node);
[code]
That means, the resulting style is not part of the DOM but it can be obtained from the map. The media corresponds exactly to the CSS media specification, i.e. it tells which media should be used during evaluation (e.g. screen, print, etc.)
For details, I recommend taking a look at the unit tests located in src/test, mainly DOMAssign.java.
Regards
Radek
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
1) According to w3school (http://www.w3schools.com/tags/tag_link.asp), the media attribute can assume 9
different values (screen, tty, tv, projection, handheld, print, braille,
aural, all). It would be nice , inside assignDOM method, to parse a subset of
this 9 values, and not just one of them.
2) It's still not clear to me the class of variable node insisde the statement
NodeData nodeStyle = map.get(node);
It should be an org.w3c.dom.Node?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Property of tag body : background-image : url(\'[http://img3.iol.it/c/hf/8.2.1
2/themes/default/img/bg02.jpg](http://img3.iol.it/c/hf/8.2.12/themes/default/
img/bg02.jpg%5C)')
Property of tag body : padding-right : 0.0px
Property of tag body : min-height : 1000.0px
Property of tag body : padding-bottom : 0.0px
Property of tag body : margin-left : null
Property of tag body : margin-top : 33.0px
Property of tag body : background-repeat : null
Property of tag body : text-align : null
Property of tag body : margin-right : null
Property of tag body : font-size : 12.0px
Property of tag body : padding-left : 0.0px
Property of tag body : padding-top : 0.0px
Property of tag body : margin-bottom : 0.0
Property of tag body : color : #000000
Property of tag body : font-family : \'Arial\' , \'helvetica\' , sans-serif
I focused on the properties with null value (margin-left, margin-right, text-
align).
Inspecting the same css code with Firebug, I found these definitions:
margin: 33px auto 0;
text-align: center;
So it seems that jStyleParser doesn\'t recognize the value \"auto\" in margin
property, and it also doesn\'t catch the right value in property text-align;
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi, I am sorry for a late answer, I have been offline this week. I will answer
your questions one by one.
1) According to w3school (http://www.w3schools.com/tags/tag_link.asp), the media attribute can assume
9 different values (screen, tty, tv, projection, handheld, print, braille,
aural, all). It would be nice , inside assignDOM method, to parse a subset of
this 9 values, and not just one of them.
According the W3C specs:
Media types are mutually exclusive in the sense that a user agent can only
support one media type when rendering a document. That means, the parser must
choose one media type that should be used.
2) It's still not clear to me the class of variable node insisde the
statement
NodeData nodeStyle = map.get(node);
It should be an org.w3c.dom.Node?
Yes, it should be a DOM Node (or usually org.w3c.dom.Element which is a
special case of Node) from the same DOM tree that has been analyzed,
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I often find 2 or more media type declared inside a css link (for example:
<link media="screen, projection" type="text/css" href="<a class=" "="" href="http://www.mysite.net/lib/css/screen.css">http://www.mysite.net/klzzwxh:0000lib/css/screen.css"
rel="stylesheet">), so i thought they weren't mutually exclusive. i was wrong.
:(
What about my remarks on "auto"/"baseline"/"inherit" values (posts number
4-5-6) ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
regarding the "margin: auto" issue (and similar properties). The problem is,
that the margin (and many other properties) may have the values of different
types (e.g. length, auto, inherit, etc.). Therefore, it is good to first use
the getProperty() method to check the type. If you obtain "auto", "inherit",
etc., then there is no point in reading the value. If you obtain "length", you
may use the getValue() method to obtain the exact length:
CSSProperty.Margin mm = style.getProperty("margin-top");
System.out.println("margin-top="+mm);
if (mm == Margin.length)
{
TermLength mleft = style.getValue(TermLength.class, "margin-left");
System.out.println("value="+mleft);
}
The possible values of all the properties may be found in
cz.vutbr.web.css.CSSProperty interface and they should correspond to the CSS
2.1 specification. This affect probably the "inherit" and "baseline" values as
well.
Regarding the default values - jStyleParser just provides the properties that
are explicitly defined in the style sheets. It's just a parser. If something
is not defined in the style sheet, the decision is up to your application,
i.e. you should provide the missing default values by yourself if required.
Radek
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello, I'm tring to use jStyleParser as css parser for my Java project.
IMHO, the documentation is a little lazy.
For example:
In CssFactory class, the method parse(String fileName, String encoding) is
ambiguos: fileName rappresent the HTML file's Url or the Css file's Url?
How should I parse the css declaration included inside a <style> tag?
In Analyzer class, the method assingDeclarationsToDOM(Document doc, String
media, boolean inherit) is obscure: what rapresent "media?" Maybe the "media"
attribute inside the <link> tag?
After binding Css to the DOM throught the evaluateDOM method, is there a way
to get the related CSS properties passing an org.w3c.dom Node ?
Hello,
I am aware that the API documentation is too brief or missing in some points
but I am improving it slowly. Since I am the only active developer now, the
time I can give to it is limited. Any help is greatly appreciated.
jStyleParser is primarily a CSS parser. That means, all the parse() methods
parse CSS code. There is also a parse(String) variant, that means you may
parse CSS code obtained from any source (even from the <style> tag).
The assignDOM method obtains the referenced stylesheets and assigns the styles
to the nodes of a DOM tree that you have obtained anyhow (usually by using a
HTML DOM parser). The typical usage is:
Thank you for your reply, Radek .
Just few thoughts:
1) According to w3school (http://www.w3schools.com/tags/tag_link.asp), the media attribute can assume 9
different values (screen, tty, tv, projection, handheld, print, braille,
aural, all). It would be nice , inside assignDOM method, to parse a subset of
this 9 values, and not just one of them.
2) It's still not clear to me the class of variable node insisde the statement
NodeData nodeStyle = map.get(node);
It should be an org.w3c.dom.Node?
Errors in properties\\'s values
I wrote a simple project to test JStyleParser
package jstyleparsertest;
import cz.vutbr.web.css.CSSFactory;
import cz.vutbr.web.css.NodeData;
import cz.vutbr.web.css.Term;
import cz.vutbr.web.domassign.StyleMap;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class JStyleParserTest {
/**
*/
public static void main(String args) throws MalformedURLException
{
if(args.length != 2)
{
System.out.println(\\"Usage : JStyleParserTest <url> <tag to="" analyze="">\\");
}
else
{
String url = args;
String tagtoanalyze = args;
URI UriPageToCheck;
try
{
System.out.println(\\"Analyzing tag \\"+tagtoanalyze+\\" inside \\"+url);
UriPageToCheck = new URI(url);
Document DOM = new Myhtmlparser().parse(UriPageToCheck);
System.out.println(\\"HTTPFile
\\"+uriManager.getHTTPFile().getAbsolutePath() );
//assign the styles
StyleMap map = CSSFactory.assignDOM(DOM, UriPageToCheck .toURL(),
\\"screen\\", true);
System.out.println(\\" Map size \\"+ map.size());
//get the style for a node
NodeList childNodes = DOM.getElementsByTagName(tagtoanalyze);
for (int i = 0; i < childNodes.getLength(); i++ )
{
Node node = childNodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE)
{
Element el = (Element) node;
NodeData nodeStyle = map.get(el);
Iterator<String> iterator = nodeStyle.getPropertyNames().iterator();
while (iterator.hasNext())
{
String PropertyName = iterator.next();
Term<?> value = nodeStyle.getValue(PropertyName, true);
if (value != null) System.out.println(\\" Property of tag
\\"+el.getNodeName()+\\" : \\"+PropertyName+\\" : \\"+value.toString());
else System.out.println(\\" Property of tag \\"+el.getNodeName()+\\" :
\\"+PropertyName+\\" : null\\");
}
}
}
}
catch (URISyntaxException ex)
{
Logger.getLogger(JStyleParserTest.class.getName()).log(Level.SEVERE, null,
ex);
}
}
}
}
I applied this project to 2 website:
1) http://www.libero.it/
2) http://www.5avi.net/
Analyzing them for the tag <body>
For the first website I had this results:
Property of tag body : background-image : url(\'[http://img3.iol.it/c/hf/8.2.1
2/themes/default/img/bg02.jpg](http://img3.iol.it/c/hf/8.2.12/themes/default/
img/bg02.jpg%5C)')
Property of tag body : padding-right : 0.0px
Property of tag body : min-height : 1000.0px
Property of tag body : padding-bottom : 0.0px
Property of tag body : margin-left : null
Property of tag body : margin-top : 33.0px
Property of tag body : background-repeat : null
Property of tag body : text-align : null
Property of tag body : margin-right : null
Property of tag body : font-size : 12.0px
Property of tag body : padding-left : 0.0px
Property of tag body : padding-top : 0.0px
Property of tag body : margin-bottom : 0.0
Property of tag body : color : #000000
Property of tag body : font-family : \'Arial\' , \'helvetica\' , sans-serif
I focused on the properties with null value (margin-left, margin-right, text-
align).
Inspecting the same css code with Firebug, I found these definitions:
margin: 33px auto 0;
text-align: center;
So it seems that jStyleParser doesn\'t recognize the value \"auto\" in margin
property, and it also doesn\'t catch the right value in property text-align;
For the second website I had this results:
Property of tag body : border-bottom-width : 0.0
Property of tag body : font-weight : null
Property of tag body : border-right-width : 0.0
Property of tag body : background-image : url(\'images/background.png\')
Property of tag body : padding-right : 0.0
Property of tag body : background-color : #ffffff
Property of tag body : padding-bottom : 0.0
Property of tag body : vertical-align : null
Property of tag body : margin-left : 0.0
Property of tag body : margin-top : 0.0
Property of tag body : line-height : 1.5
Property of tag body : margin-right : 0.0
Property of tag body : font-size : 75.0%
Property of tag body : border-left-width : 0.0
Property of tag body : padding-left : 0.0
Property of tag body : padding-top : 0.0
Property of tag body : font-style : null
Property of tag body : margin-bottom : 0.0
Property of tag body : border-top-width : 0.0
Property of tag body : color : #444444
Property of tag body : font-family : \'Helvetica Neue\' , \'Arial\' ,
\'Helvetica\' , sans-serif
Again, I focused on the properties with null value (font-weight, vertical-
align, font-style).
Inspecting the same css code with Firebug, I found these definitions:
vertical-align: baseline;
font-weight : inherit;
font-style : inherit;
So it seems that jStyleParser doesn\'t recognize the value \"baseline\" in
vertical-align property.
Regarding font-weight and font-style, they have the value \"inherit\", even if
there are no definitions to ineherit.
According to w3schools.com (http://www.w3schools.com/cssref/pr_font_weight.as
p -
http://www.w3schools.com/cssref/pr_font_font-
style.asp),
both the font-weight and font-style properties have a default value
\"normal\".
IMHO all the properties, that for any reason haven\'t a defined value, should
be set to their default value (if they have one).
I hope my remarks are useful
Hi, I am sorry for a late answer, I have been offline this week. I will answer
your questions one by one.
According the W3C specs:
Media types are mutually exclusive in the sense that a user agent can only
support one media type when rendering a document. That means, the parser must
choose one media type that should be used.
NodeData nodeStyle = map.get(node);
It should be an org.w3c.dom.Node?
Yes, it should be a DOM Node (or usually org.w3c.dom.Element which is a
special case of Node) from the same DOM tree that has been analyzed,
Thank you Radek.
I often find 2 or more media type declared inside a css link (for example:
<link media="screen, projection" type="text/css" href="<a class=" "="" href="http://www.mysite.net/lib/css/screen.css">http://www.mysite.net/klzzwxh:0000lib/css/screen.css" rel="stylesheet">), so i thought they weren't mutually exclusive. i was wrong.
:(
What about my remarks on "auto"/"baseline"/"inherit" values (posts number
4-5-6) ?
Hi,
regarding the "margin: auto" issue (and similar properties). The problem is,
that the margin (and many other properties) may have the values of different
types (e.g. length, auto, inherit, etc.). Therefore, it is good to first use
the getProperty() method to check the type. If you obtain "auto", "inherit",
etc., then there is no point in reading the value. If you obtain "length", you
may use the getValue() method to obtain the exact length:
The possible values of all the properties may be found in
cz.vutbr.web.css.CSSProperty interface and they should correspond to the CSS
2.1 specification. This affect probably the "inherit" and "baseline" values as
well.
Regarding the default values - jStyleParser just provides the properties that
are explicitly defined in the style sheets. It's just a parser. If something
is not defined in the style sheet, the decision is up to your application,
i.e. you should provide the missing default values by yourself if required.
Radek
Just a note: please replace all the margin-top in the code above with margin-
left (or any other, it should be consistent).