Search in sources :

Example 1 with SACMediaList

use of org.w3c.css.sac.SACMediaList in project CodenameOne by codenameone.

the class CSSTheme method load.

public static CSSTheme load(URL uri) throws IOException {
    try {
        System.setProperty("org.w3c.css.sac.parser", "org.w3c.flute.parser.Parser");
        InputSource source = new InputSource();
        InputStream stream = uri.openStream();
        String stringContents = Util.readToString(stream);
        // The flute parser chokes on properties beginning with -- so we need to replace these with cn1 prefix
        // for CSS variable support.
        stringContents = stringContents.replaceAll("([\\(\\W])(--[a-zA-Z0-9\\-]+)", "$1cn1$2");
        // Flute chokes on embedded var() functions inside an rgb or rgba function.  Hoping to support it by changing the
        // function name to cn1rgb() and cn1rgba() respectively.
        stringContents = stringContents.replaceAll("\\brgb\\(", "cn1rgb(");
        stringContents = stringContents.replaceAll("\\brgba\\(", "cn1rgba(");
        source.setCharacterStream(new CharArrayReader(stringContents.toCharArray()));
        source.setURI(uri.toString());
        source.setEncoding("UTF-8");
        ParserFactory parserFactory = new ParserFactory();
        Parser parser = parserFactory.makeParser();
        final CSSTheme theme = new CSSTheme();
        theme.baseURL = uri;
        parser.setErrorHandler(new ErrorHandler() {

            @Override
            public void warning(CSSParseException csspe) throws CSSException {
                System.out.println("CSS Warning: " + csspe.getLocalizedMessage() + " on line " + csspe.getLineNumber() + " col: " + csspe.getColumnNumber() + " of file " + csspe.getURI());
            }

            @Override
            public void error(CSSParseException csspe) throws CSSException {
                System.out.println("CSS Error: " + csspe.getLocalizedMessage() + " on line " + csspe.getLineNumber() + " col: " + csspe.getColumnNumber() + " of file " + csspe.getURI());
            }

            @Override
            public void fatalError(CSSParseException csspe) throws CSSException {
                System.out.println("CSS Fatal Error: " + csspe.getLocalizedMessage() + " on line " + csspe.getLineNumber() + " col: " + csspe.getColumnNumber() + " of file " + csspe.getURI());
            }
        });
        // parser.setLocale(Locale.getDefault());
        parser.setDocumentHandler(new DocumentHandler() {

            Map<String, LexicalUnit> variables = new LinkedHashMap<>();

            SelectorList currSelectors;

            FontFace currFontFace;

            SACMediaList currMediaList;

            // double currentTargetDpi = 320;
            // double currentMinDpi = 120;
            // double currentMaxDpi = 640;
            // int currentScreenWidth = 1280;
            // int currentScreenHeight = 1920;
            @Override
            public void startDocument(InputSource is) throws CSSException {
            // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void endDocument(InputSource is) throws CSSException {
            // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void comment(String string) throws CSSException {
            }

            @Override
            public void ignorableAtRule(String string) throws CSSException {
            // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void namespaceDeclaration(String string, String string1) throws CSSException {
            // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void importStyle(String string, SACMediaList sacml, String string1) throws CSSException {
            // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void startMedia(SACMediaList sacml) throws CSSException {
                currMediaList = sacml;
            }

            @Override
            public void endMedia(SACMediaList sacml) throws CSSException {
                currMediaList = null;
            }

            @Override
            public void startPage(String string, String string1) throws CSSException {
            // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void endPage(String string, String string1) throws CSSException {
            // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void startFontFace() throws CSSException {
                currFontFace = theme.createFontFace();
            }

            @Override
            public void endFontFace() throws CSSException {
                currFontFace = null;
            }

            @Override
            public void startSelector(SelectorList sl) throws CSSException {
                // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                currSelectors = sl;
            }

            @Override
            public void endSelector(SelectorList sl) throws CSSException {
                currSelectors = null;
            }

            @Override
            public void property(String string, LexicalUnit lu, boolean bln) throws CSSException {
                try {
                    property_(string, lu, bln);
                } catch (Throwable t) {
                    if (t instanceof CSSException) {
                        throw (CSSException) t;
                    } else {
                        System.out.println("Exception occurred while parsing property " + string + " " + lu);
                        t.printStackTrace();
                        throw new ParseException(t.getMessage());
                    }
                }
            }

            private ScaledUnit last(LexicalUnit lu) {
                while (lu.getNextLexicalUnit() != null) {
                    lu = lu.getNextLexicalUnit();
                }
                return (lu instanceof ScaledUnit) ? (ScaledUnit) lu : new ScaledUnit(lu, theme.currentDpi, theme.getPreviewScreenWidth(), theme.getPreviewScreenHeight());
            }

            /**
             * Evaluates a LexicalUnit in the current parser position.  This will expand any variables.  It will
             * continue to evaluate the next lexical unit, until it reaches the end of the current lexical unit chain.
             * @param lu The lexical unit to evaluate.
             * @return
             * @throws CSSException
             */
            private ScaledUnit evaluate(LexicalUnit lu) throws CSSException {
                if (lu.getLexicalUnitType() == LexicalUnit.SAC_FUNCTION && "var".equals(lu.getFunctionName())) {
                    LexicalUnit parameters = lu.getParameters();
                    String varname = parameters.getStringValue();
                    LexicalUnit varVal = variables.get(varname);
                    ScaledUnit su;
                    if (varVal == null && parameters.getNextLexicalUnit() != null) {
                        varVal = parameters.getNextLexicalUnit();
                        su = evaluate(new ScaledUnit(varVal, theme.currentDpi, theme.getPreviewScreenWidth(), theme.getPreviewScreenHeight()));
                    } else if (varVal == null) {
                        su = new ScaledUnit(lu, theme.currentDpi, theme.getPreviewScreenWidth(), theme.getPreviewScreenHeight());
                    } else {
                        su = evaluate(new ScaledUnit(varVal, theme.currentDpi, theme.getPreviewScreenWidth(), theme.getPreviewScreenHeight()));
                    }
                    // Evaluate the variable value in case it also includes other variables that need to be evaluated.
                    // ScaledUnit su = evaluate(new ScaledUnit(varVal, theme.currentDpi, theme.getPreviewScreenWidth(), theme.getPreviewScreenHeight()));
                    LexicalUnit toAppend = lu.getNextLexicalUnit();
                    ScaledUnit last = last(su);
                    if (toAppend != null) {
                        toAppend = evaluate(toAppend);
                        last.setNextLexicalUnit(toAppend);
                        ((ScaledUnit) toAppend).setPrevLexicalUnit(last);
                    } else {
                        last.setNextLexicalUnit(null);
                    }
                    return su;
                } else {
                    ScaledUnit su = new ScaledUnit(lu, theme.currentDpi, theme.getPreviewScreenWidth(), theme.getPreviewScreenHeight());
                    LexicalUnit nex = su.getNextLexicalUnit();
                    if (su.getParameters() != null) {
                        su.setParameters(evaluate(su.getParameters()));
                    }
                    if (nex != null) {
                        ScaledUnit snex = evaluate(nex);
                        su.setNextLexicalUnit(snex);
                        snex.setPrevLexicalUnit(su);
                    }
                    return su;
                }
            }

            private void property_(String string, LexicalUnit _lu, boolean bln) throws CSSException {
                if (string.startsWith("cn1--")) {
                    variables.put(string, _lu);
                    return;
                }
                ScaledUnit su = evaluate(_lu);
                if (currFontFace != null) {
                    switch(string) {
                        case "font-family":
                            currFontFace.fontFamily = su;
                            break;
                        case "font-style":
                            currFontFace.fontStyle = su;
                            break;
                        case "font-stretch":
                            currFontFace.fontStretch = su;
                            break;
                        case "src":
                            currFontFace.src = su;
                            break;
                        case "font-weight":
                            currFontFace.fontWeight = su;
                            break;
                    }
                } else {
                    int len = currSelectors.getLength();
                    for (int i = 0; i < len; i++) {
                        Selector sel = currSelectors.item(i);
                        if (currMediaList != null) {
                            for (String mediaPrefix : getMediaPrefixes(currMediaList)) {
                                theme.apply(mediaPrefix, sel, string, su);
                            }
                        } else {
                            theme.apply(null, sel, string, su);
                        }
                    }
                }
            }
        });
        parser.parseStyleSheet(source);
        stream.close();
        return theme;
    } catch (ClassNotFoundException ex) {
        Logger.getLogger(CSSTheme.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        Logger.getLogger(CSSTheme.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        Logger.getLogger(CSSTheme.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NullPointerException ex) {
        if (ex.getMessage().contains("encoding properties")) {
        // This error always happens and there doesn't seem to be a way to fix it... so let's just hide
        // it .  Doesn't seem to hurt anything.
        } else {
        // Logger.getLogger(CSSTheme.class.getName()).log(Level.SEVERE, null, ex);
        }
    } catch (ClassCastException ex) {
        Logger.getLogger(CSSTheme.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}
Also used : InputSource(org.w3c.css.sac.InputSource) SACMediaList(org.w3c.css.sac.SACMediaList) ParserFactory(org.w3c.css.sac.helpers.ParserFactory) LinkedHashMap(java.util.LinkedHashMap) DocumentHandler(org.w3c.css.sac.DocumentHandler) CSSException(org.w3c.css.sac.CSSException) LexicalUnit(org.w3c.css.sac.LexicalUnit) ConditionalSelector(org.w3c.css.sac.ConditionalSelector) ElementSelector(org.w3c.css.sac.ElementSelector) Selector(org.w3c.css.sac.Selector) SimpleSelector(org.w3c.css.sac.SimpleSelector) ErrorHandler(org.w3c.css.sac.ErrorHandler) ObjectInputStream(java.io.ObjectInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) ImageInputStream(javax.imageio.stream.ImageInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) Parser(org.w3c.css.sac.Parser) JSONParser(com.codename1.io.JSONParser) CharArrayReader(java.io.CharArrayReader) CSSParseException(org.w3c.css.sac.CSSParseException) SelectorList(org.w3c.css.sac.SelectorList) CSSParseException(org.w3c.css.sac.CSSParseException) ParseException(org.w3c.flute.parser.ParseException)

Aggregations

JSONParser (com.codename1.io.JSONParser)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 CharArrayReader (java.io.CharArrayReader)1 FileInputStream (java.io.FileInputStream)1 InputStream (java.io.InputStream)1 ObjectInputStream (java.io.ObjectInputStream)1 LinkedHashMap (java.util.LinkedHashMap)1 ImageInputStream (javax.imageio.stream.ImageInputStream)1 CSSException (org.w3c.css.sac.CSSException)1 CSSParseException (org.w3c.css.sac.CSSParseException)1 ConditionalSelector (org.w3c.css.sac.ConditionalSelector)1 DocumentHandler (org.w3c.css.sac.DocumentHandler)1 ElementSelector (org.w3c.css.sac.ElementSelector)1 ErrorHandler (org.w3c.css.sac.ErrorHandler)1 InputSource (org.w3c.css.sac.InputSource)1 LexicalUnit (org.w3c.css.sac.LexicalUnit)1 Parser (org.w3c.css.sac.Parser)1 SACMediaList (org.w3c.css.sac.SACMediaList)1 Selector (org.w3c.css.sac.Selector)1 SelectorList (org.w3c.css.sac.SelectorList)1