radkovo / jStyleParser

jStyleParser is a CSS parser written in Java. It has its own application interface that is designed to allow an efficient CSS processing in Java and mapping the values to the Java data types. It parses CSS 2.1 style sheets into structures that can be efficiently assigned to DOM elements. It is intended be the primary CSS parser for the CSSBox library. While handling errors, it is user agent conforming according to the CSS specification.
http://cssbox.sourceforge.net/jstyleparser/
GNU Lesser General Public License v3.0
92 stars 49 forks source link

NPE errors when assigning CSS to DOM elements #106

Closed jmak35 closed 4 years ago

jmak35 commented 4 years ago

Hi there,

I'm very interested in using your library for a pet project of mine. I'm running version 4.17 of CSSBox and therefore version 3.5 of jStyleParser.

My aim is to retrieve all the styles for each element in the websites contentful.com and sportingnews.com/au/nba. My code is below.

public static void main(String[] args)
{
    try {
        MediaSpec media = new MediaSpecAll();

        //Open the network connection 
        DocumentSource docSource = new DefaultDocumentSource("https://www.contentful.com");

        //Parse the input document
        DOMSource parser = new DefaultDOMSource(docSource);
        Document doc = parser.parse();

        //Create the CSS analyzer
        DOMAnalyzer da = new DOMAnalyzer(doc, docSource.getURL());
        da.setMediaSpec(media);
        da.getStyleSheets(); //load the author style sheets
        da.stylesToDomInherited();

        docSource.close();

    } catch (Exception e) {
        System.err.println("Error: "+e.getMessage());
        e.printStackTrace();
    }
}

It comes back with this NPE though when da.getStyleSheets() is called:

Error: null
java.lang.NullPointerException
        at cz.vutbr.web.csskit.fn.TranslateYImpl.setValue(TranslateYImpl.java:29)
        at cz.vutbr.web.csskit.fn.TranslateYImpl.setValue(TranslateYImpl.java:11)
        at cz.vutbr.web.csskit.TermFactoryImpl.createFunctionByName(TermFactoryImpl.java:569)
        at cz.vutbr.web.csskit.TermFactoryImpl.createFunction(TermFactoryImpl.java:165)
        at cz.vutbr.web.csskit.antlr4.CSSParserVisitorImpl.visitFunct(CSSParserVisitorImpl.java:1069)
        at cz.vutbr.web.csskit.antlr4.CSSParserVisitorImpl.visitValuepart(CSSParserVisitorImpl.java:1151)
        at cz.vutbr.web.csskit.antlr4.CSSParserVisitorImpl.visitTermValuePart(CSSParserVisitorImpl.java:1024)
        at cz.vutbr.web.csskit.antlr4.CSSParserVisitorImpl.visitTerms(CSSParserVisitorImpl.java:989)
        at cz.vutbr.web.csskit.antlr4.CSSParserVisitorImpl.visitDeclaration(CSSParserVisitorImpl.java:888)
        at cz.vutbr.web.csskit.antlr4.CSSParserVisitorImpl.visitDeclarations(CSSParserVisitorImpl.java:845)
        at cz.vutbr.web.csskit.antlr4.CSSParserVisitorImpl.visitRuleset(CSSParserVisitorImpl.java:820)
        at cz.vutbr.web.csskit.antlr4.CSSParserVisitorImpl.visitMedia_rule(CSSParserVisitorImpl.java:707)
        at cz.vutbr.web.csskit.antlr4.CSSParserVisitorImpl.visitAtstatement(CSSParserVisitorImpl.java:415)
        at cz.vutbr.web.csskit.antlr4.CSSParserVisitorImpl.visitStatement(CSSParserVisitorImpl.java:327)
        at cz.vutbr.web.csskit.antlr4.CSSParserVisitorImpl.visitStylesheet(CSSParserVisitorImpl.java:281)
        at cz.vutbr.web.csskit.antlr4.CSSParserFactory.parse(CSSParserFactory.java:206)
        at cz.vutbr.web.csskit.antlr4.CSSParserFactory.parseAndImport(CSSParserFactory.java:147)
        at cz.vutbr.web.csskit.antlr4.CSSParserFactory.append(CSSParserFactory.java:114)
        at cz.vutbr.web.csskit.antlr4.CSSParserFactory.append(CSSParserFactory.java:136)
        at cz.vutbr.web.css.CSSFactory$CSSAssignTraversal.processNode(CSSFactory.java:816)
        at cz.vutbr.web.css.CSSFactory$CSSAssignTraversal.processNode(CSSFactory.java:790)
        at cz.vutbr.web.domassign.Traversal.listTraversal(Traversal.java:43)
        at cz.vutbr.web.css.CSSFactory.getUsedStyles(CSSFactory.java:578)
        at cz.vutbr.web.css.CSSFactory.getUsedStyles(CSSFactory.java:598)
        at org.fit.cssbox.css.DOMAnalyzer.getStyleSheets(DOMAnalyzer.java:385)
        at org.fit.cssbox.css.DOMAnalyzer.getStyleSheets(DOMAnalyzer.java:397)

The same happens if I run the following code after following your readme:

public static void main(String[] args)
        throws ParserConfigurationException, IOException, SAXException, CSSException
{
    DocumentSource src = new DefaultDocumentSource(new URL("https://www.contentful.com"));
    //Parse the input document (replace this with your own parser if desired)
    DOMSource parser = new DefaultDOMSource(src);
    Document doc = parser.parse(); //doc represents the obtained DOM

    MediaSpec media = new MediaSpecAll(); //use styles for all media
    StyleMap map = CSSFactory.assignDOM(doc, "UTF-8", new URL("https://www.contentful.com"), media, true);
    System.out.println(map);
}

I tried running the above code with the URL sportingnews.com/au/nba instead and get an NPE iff I run in debug mode, in the DeclarationTransformerImpl class. When !property.equalsInherit() is called, property is null. The rule is a transition of "top 0.3s ease-in-out" and it is trying to set top as a transition duration in my understanding since term is set to "top" and type is set to "cz.vutbr.web.css.CSSProperty$TransitionDuration"

protected <T extends CSSProperty> boolean genericTime(
            Class<T> type, T integerIdentification, ValueRange range,
            Declaration d, Map<String, CSSProperty> properties,
            Map<String, Term<?>> values) {
        if (d.size() != 1)
            return false;

        Term<?> term = d.get(0);
        if (term instanceof TermIdent) {
            T property = genericPropertyRaw(type, null, (TermIdent) term);
            if (!property.equalsInherit())
                return false;
            else
            {
                properties.put(d.getProperty(), property);
                return true;
            }
        }
        return genericTerm(TermTime.class, term, d.getProperty(), integerIdentification, range, properties, values);
    }

Could you please let me know if these NPEs can be fixed at all? I see so much promise with this library, I would hate to pass on it as I really want to continue with java instead of trying another approach with javascript.

Thank you in advance.

radkovo commented 4 years ago

Thanks for reporting this. There was a problem in function argument validation. Now, the NPE issue should be fixed. But please note that the website you mention uses custom CSS properties (var(--xxx)), which is not yet supported by jStyleParser.

jmak35 commented 4 years ago

Thank you for addressing this swiftly. I'll try again and check this out soon.