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;
}
Aggregations