Menu

#60 Precedence of stylesheets

closed
nobody
None
1
2015-02-11
2014-11-14
mercury
No

When multiple stylesheets are passed to this constructor:

public DirectAnalyzer(List<StyleSheet> sheets)

The precedence of stylesheets doesn't appear to be respected.

For example, if I pass two stylesheets:

#target { background : red }

and

#target { background : green }

in that order, then the background of #target should be green, but it is being computed as red.

I am using the latest version of jStyleParser (1.19)

Discussion

  • mercury

    mercury - 2014-11-14

    The rendering in SF.net has a bug if a line begins with #, and I can't edit the previous post. Hence, posting again.

    The first stylesheet:

     #target {background: red }
    

    The second stylesheet:

     #target {background: green }
    
     
  • Radek Burget

    Radek Burget - 2014-11-14

    Hi,
    I am unable to reproduce the buggy behavior. Do you have any test case? My testing code is the following (based on some of your previous tests :-)

        public static void main(String[] args)
        {
            String css1 = "#d1 { background : red; }";
            String css2 = "#d1 { background : green; }";
            String html = "<html>" + "<head>" + "<style>" + css1 + css2 + "</style>" + "</head>" + "<body>" + "<div>"+ "<div id='d1'>Green text</div>"   + "</div>" + "</body>" + "</html>";
    
            try {
                InputStream is = new ByteArrayInputStream(html.getBytes());
                DocumentSource docSrc = new StreamDocumentSource(is, new URL("http://localhost"), "text/html");
                DOMSource domSrc = new DefaultDOMSource(docSrc);
                Document doc = domSrc.parse();
    
                NodeList childrens = doc.getChildNodes();
                // gives the innermost div
                Element div = (Element) childrens.item(0).getChildNodes().item(1).getChildNodes().item(0).getChildNodes().item(0);
                // this is to verify that we got the correct div
                System.out.println("Element " + div.getNodeName() + " #" + div.getAttribute("id"));
    
                StyleSheet ss[] = new StyleSheet[2];
                ss[0] = CSSFactory.parseString(css1, null);
                ss[1] = CSSFactory.parseString(css2, null);
                DirectAnalyzer directAnalyser = new cz.vutbr.web.domassign.DirectAnalyzer(Arrays.asList(ss));
                NodeData nd = directAnalyser.getElementStyle(div, null, "screen");
    
                System.out.println("Style Sheet1 " + ss[0]);
                System.out.println("Style Sheet1 " + ss[1]);
                System.out.println("\n--------");
                System.out.println("NodeData: " + nd);
    
                Term<?> zterm = nd.getValue("background-color", true);
                String s = zterm.toString();
                System.out.println(s);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
     
  • mercury

    mercury - 2014-11-14

    In the above testing code, you are concatenating the two rules inside a single stylesheet.

    Can you try creating two different stylesheets (two different <style> elements)?

     
  • mercury

    mercury - 2014-11-14

    Oops, never mind! The <style> element is not being actually used in the above code. I will try to create a test case.

     
  • mercury

    mercury - 2014-11-15

    There seems to be some race condition involved here. Not sure if it is in our code or jStyleParser. Will investigate and confirm later.

    Thanks again for your quick responses!

     
  • mercury

    mercury - 2014-12-11

    I was able to reproduce the problem and also trace the root cause.

    The priority of every ruleset is being set during parsing stage. And the rules are sorted based on this priority in DirectAnalyser.getDeclarationsForElement().

    Now, in our application, the order of parsing is not necessarily the same as the document order. This was causing the problem in our case.

    As a workaround, there are two changes I did:
    1. Used a LinkedHashSet instead of a HashSet to store candidates in getDeclarationsForElement(). This preserves the order of the rulesets and yet removes duplicates.
    2. Implemented a new priority strategy that simply returns a zero priority everytime.

    With these changes, I am seeing perfect behavior.

    The first change is simple. For the second change, it would be good if the priority strategy was configurable. If you are okay, I will make a PR for it.

     
  • Radek Burget

    Radek Burget - 2015-01-10
    • status: open --> accepted
     
  • Radek Burget

    Radek Burget - 2015-01-10

    Solved on GitHub.

     
  • Radek Burget

    Radek Burget - 2015-02-11
    • status: accepted --> closed
     
  • Radek Burget

    Radek Burget - 2015-02-11

    Closed in 1.20

     

Anonymous
Anonymous

Add attachments
Cancel