package com.vaadin.sass; | |||||
import java.io.File; | |||||
import java.io.FileWriter; | |||||
import java.io.IOException; | |||||
public class SassCompiler { | |||||
public static void main(String[] args) throws Exception { | |||||
String input = null; | |||||
String output = null; | |||||
if (args.length == 0) { | |||||
System.out | |||||
.println("usage: SassCompile <scss file to compile> <css file to write>"); | |||||
return; | |||||
} else if (args.length == 1) { | |||||
input = args[0]; | |||||
} else { | |||||
input = args[0]; | |||||
output = args[1]; | |||||
} | |||||
File inputFile = new File(input); | |||||
ScssStylesheet scss = ScssStylesheet.get(inputFile); | |||||
scss.compile(); | |||||
if (output == null) { | |||||
System.out.println(scss.toString()); | |||||
} else { | |||||
writeFile(output, scss.toString()); | |||||
} | |||||
} | |||||
public static void writeFile(String filename, String output) | |||||
throws IOException { | |||||
File file = new File(filename); | |||||
FileWriter writer = new FileWriter(file); | |||||
writer.write(output); | |||||
writer.close(); | |||||
} | |||||
} |
package com.vaadin.sass; | |||||
import java.io.BufferedOutputStream; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.io.OutputStream; | |||||
import java.io.OutputStreamWriter; | |||||
import javax.servlet.ServletException; | |||||
import javax.servlet.http.HttpServlet; | |||||
import javax.servlet.http.HttpServletRequest; | |||||
import javax.servlet.http.HttpServletResponse; | |||||
public class ScssServlet extends HttpServlet { | |||||
@Override | |||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) | |||||
throws ServletException, IOException { | |||||
String cssPath = req.getRequestURI(); | |||||
if (cssPath.endsWith(".css")) { | |||||
File cssFile = new File(cssPath); | |||||
if (cssFile.exists()) { | |||||
} else { | |||||
String scssPath = cssPath.replace(".css", ".scss"); | |||||
File scssFile = new File(scssPath); | |||||
if (scssFile.exists()) { | |||||
ScssStylesheet scss = ScssStylesheet.get(new File(cssPath)); | |||||
try { | |||||
scss.compile(); | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
} | |||||
resp.setContentType("text/css"); | |||||
OutputStream fout = resp.getOutputStream(); | |||||
OutputStream bos = new BufferedOutputStream(fout); | |||||
OutputStreamWriter outputwriter = new OutputStreamWriter( | |||||
bos); | |||||
outputwriter.write(scss.toString()); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
package com.vaadin.sass; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import org.w3c.css.sac.CSSException; | |||||
import com.vaadin.sass.handler.SCSSDocumentHandler; | |||||
import com.vaadin.sass.handler.SCSSDocumentHandlerImpl; | |||||
import com.vaadin.sass.parser.Parser; | |||||
import com.vaadin.sass.tree.Node; | |||||
import com.vaadin.sass.visitor.BlockVisitor; | |||||
import com.vaadin.sass.visitor.ExtendVisitor; | |||||
import com.vaadin.sass.visitor.ImportVisitor; | |||||
import com.vaadin.sass.visitor.MixinVisitor; | |||||
import com.vaadin.sass.visitor.NestPropertiesVisitor; | |||||
import com.vaadin.sass.visitor.ParentSelectorVisitor; | |||||
import com.vaadin.sass.visitor.VariableVisitor; | |||||
import com.vaadin.sass.visitor.Visitor; | |||||
public class ScssStylesheet extends Node { | |||||
private static final long serialVersionUID = 3849790204404961608L; | |||||
/** | |||||
* Read in a file SCSS and parse it into a ScssStylesheet | |||||
* | |||||
* @param file | |||||
* @throws IOException | |||||
*/ | |||||
public ScssStylesheet() { | |||||
super(); | |||||
} | |||||
/** | |||||
* Main entry point for the SASS compiler. Takes in a file and builds upp a | |||||
* ScssStylesheet tree out of it. Calling compile() on it will transform | |||||
* SASS into CSS. Calling toString() will print out the SCSS/CSS. | |||||
* | |||||
* @param file | |||||
* @return | |||||
* @throws CSSException | |||||
* @throws IOException | |||||
*/ | |||||
public static ScssStylesheet get(File file) throws CSSException, | |||||
IOException { | |||||
Parser parser = new Parser(); | |||||
SCSSDocumentHandler handler = new SCSSDocumentHandlerImpl(); | |||||
file = file.getCanonicalFile(); | |||||
handler.getStyleSheet().setFileName(file.getAbsoluteFile().getParent()); | |||||
parser.setDocumentHandler(handler); | |||||
parser.parseStyleSheet(file.getAbsolutePath()); | |||||
return handler.getStyleSheet(); | |||||
} | |||||
/** | |||||
* Applies all the visitors and compiles SCSS into Css. | |||||
* | |||||
* @throws Exception | |||||
*/ | |||||
public void compile() throws Exception { | |||||
List<Visitor> visitors = new ArrayList<Visitor>(); | |||||
visitors.add(new ImportVisitor()); | |||||
visitors.add(new MixinVisitor()); | |||||
visitors.add(new VariableVisitor()); | |||||
visitors.add(new ParentSelectorVisitor()); | |||||
visitors.add(new BlockVisitor()); | |||||
visitors.add(new NestPropertiesVisitor()); | |||||
visitors.add(new ExtendVisitor()); | |||||
for (Visitor visitor : visitors) { | |||||
visitor.traverse(this); | |||||
} | |||||
} | |||||
/** | |||||
* Prints out the current state of the node tree. Will return SCSS before | |||||
* compile and CSS after. | |||||
* | |||||
* For now this is an own method with it's own implementation that most node | |||||
* types will implement themselves. | |||||
*/ | |||||
@Override | |||||
public String toString() { | |||||
StringBuilder string = new StringBuilder(""); | |||||
if (children.size() > 0) { | |||||
string.append(children.get(0).toString()); | |||||
} | |||||
String delimeter = "\n\n"; | |||||
if (children.size() > 1) { | |||||
for (int i = 1; i < children.size(); i++) { | |||||
String childString = children.get(i).toString(); | |||||
if (childString != null) { | |||||
string.append(delimeter).append(childString); | |||||
} | |||||
} | |||||
} | |||||
String output = string.toString(); | |||||
return output; | |||||
} | |||||
} |
package com.vaadin.sass.handler; | |||||
import java.util.Collection; | |||||
import org.w3c.css.sac.DocumentHandler; | |||||
import org.w3c.css.sac.LexicalUnit; | |||||
import org.w3c.css.sac.SACMediaList; | |||||
import org.w3c.css.sac.SelectorList; | |||||
import com.vaadin.sass.ScssStylesheet; | |||||
import com.vaadin.sass.tree.EachNode; | |||||
import com.vaadin.sass.tree.ForNode; | |||||
import com.vaadin.sass.tree.IfNode; | |||||
import com.vaadin.sass.tree.MixinDefNode; | |||||
import com.vaadin.sass.tree.VariableNode; | |||||
import com.vaadin.sass.tree.WhileNode; | |||||
public interface SCSSDocumentHandler extends DocumentHandler { | |||||
ScssStylesheet getStyleSheet(); | |||||
void variable(String name, LexicalUnit value, boolean guarded); | |||||
void startMixinDirective(String name, Collection<VariableNode> args); | |||||
void endMixinDirective(String name, Collection<VariableNode> args); | |||||
MixinDefNode mixinDirective(String name, String args, String body); | |||||
void debugDirective(); | |||||
ForNode forDirective(String var, String from, String to, boolean exclusive, | |||||
String body); | |||||
EachNode eachDirective(String var, String list, String body); | |||||
WhileNode whileDirective(String condition, String body); | |||||
IfNode ifDirective(); | |||||
void extendDirective(SelectorList list); | |||||
void startNestedProperties(String name); | |||||
void endNestedProperties(String name); | |||||
void includeDirective(String name, Collection<LexicalUnit> args); | |||||
void importStyle(String uri, SACMediaList media, boolean isURL); | |||||
void property(String name, LexicalUnit value, boolean important, | |||||
String comment); | |||||
} |
package com.vaadin.sass.handler; | |||||
import java.util.Collection; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import java.util.Stack; | |||||
import org.w3c.css.sac.CSSException; | |||||
import org.w3c.css.sac.InputSource; | |||||
import org.w3c.css.sac.LexicalUnit; | |||||
import org.w3c.css.sac.SACMediaList; | |||||
import org.w3c.css.sac.SelectorList; | |||||
import com.vaadin.sass.ScssStylesheet; | |||||
import com.vaadin.sass.tree.BlockNode; | |||||
import com.vaadin.sass.tree.EachNode; | |||||
import com.vaadin.sass.tree.ExtendNode; | |||||
import com.vaadin.sass.tree.ForNode; | |||||
import com.vaadin.sass.tree.IfNode; | |||||
import com.vaadin.sass.tree.ImportNode; | |||||
import com.vaadin.sass.tree.MediaNode; | |||||
import com.vaadin.sass.tree.MixinDefNode; | |||||
import com.vaadin.sass.tree.MixinNode; | |||||
import com.vaadin.sass.tree.NestPropertiesNode; | |||||
import com.vaadin.sass.tree.Node; | |||||
import com.vaadin.sass.tree.RuleNode; | |||||
import com.vaadin.sass.tree.VariableNode; | |||||
import com.vaadin.sass.tree.WhileNode; | |||||
public class SCSSDocumentHandlerImpl implements SCSSDocumentHandler { | |||||
private final ScssStylesheet styleSheet; | |||||
Stack<Node> nodeStack = new Stack<Node>(); | |||||
private Map<String, Stack<LexicalUnit>> variableMap; | |||||
public SCSSDocumentHandlerImpl() { | |||||
this(new ScssStylesheet()); | |||||
variableMap = new HashMap<String, Stack<LexicalUnit>>(); | |||||
} | |||||
public SCSSDocumentHandlerImpl(ScssStylesheet styleSheet) { | |||||
this.styleSheet = styleSheet; | |||||
nodeStack.push(styleSheet); | |||||
} | |||||
public void addVariable(String varName, LexicalUnit value) { | |||||
if (variableMap.get(varName) == null) { | |||||
variableMap.put(varName, new Stack<LexicalUnit>()); | |||||
} | |||||
Stack<LexicalUnit> valueStack = variableMap.get(varName); | |||||
valueStack.push(value); | |||||
} | |||||
public void removeVaraible(String varName) { | |||||
Stack<LexicalUnit> valueStack = variableMap.get(varName); | |||||
if (valueStack != null && !valueStack.isEmpty()) { | |||||
valueStack.pop(); | |||||
} | |||||
} | |||||
public LexicalUnit getVariable(String varName) { | |||||
Stack<LexicalUnit> valueStack = variableMap.get(varName); | |||||
if (valueStack != null && !valueStack.isEmpty()) { | |||||
return valueStack.peek(); | |||||
} | |||||
return null; | |||||
} | |||||
@Override | |||||
public ScssStylesheet getStyleSheet() { | |||||
return styleSheet; | |||||
} | |||||
@Override | |||||
public void startDocument(InputSource source) throws CSSException { | |||||
nodeStack.push(styleSheet); | |||||
// System.out.println("startDocument(InputSource source): " | |||||
// + source.getURI()); | |||||
} | |||||
@Override | |||||
public void endDocument(InputSource source) throws CSSException { | |||||
// System.out.println("endDocument(InputSource source): " | |||||
// + source.getURI()); | |||||
} | |||||
@Override | |||||
public void variable(String name, LexicalUnit value, boolean guarded) { | |||||
VariableNode node = new VariableNode(name, value, guarded); | |||||
nodeStack.peek().appendChild(node); | |||||
} | |||||
@Override | |||||
public void debugDirective() { | |||||
} | |||||
@Override | |||||
public ForNode forDirective(String var, String from, String to, | |||||
boolean exclusive, String body) { | |||||
ForNode node = new ForNode(var, from, to, exclusive, body); | |||||
System.out.println(node); | |||||
return node; | |||||
} | |||||
@Override | |||||
public EachNode eachDirective(String var, String list, String body) { | |||||
EachNode node = new EachNode(var, list, body); | |||||
System.out.println(node); | |||||
return node; | |||||
} | |||||
@Override | |||||
public WhileNode whileDirective(String condition, String body) { | |||||
WhileNode node = new WhileNode(condition, body); | |||||
System.out.println(node); | |||||
return node; | |||||
} | |||||
@Override | |||||
public IfNode ifDirective() { | |||||
return new IfNode(); | |||||
} | |||||
@Override | |||||
public void comment(String text) throws CSSException { | |||||
System.out.println("comment(String text): " + text); | |||||
} | |||||
@Override | |||||
public void ignorableAtRule(String atRule) throws CSSException { | |||||
System.out.println("ignorableAtRule(String atRule): " + atRule); | |||||
} | |||||
@Override | |||||
public void namespaceDeclaration(String prefix, String uri) | |||||
throws CSSException { | |||||
System.out.println("namespaceDeclaration(String prefix, String uri): " | |||||
+ prefix + ", " + uri); | |||||
} | |||||
@Override | |||||
public void importStyle(String uri, SACMediaList media, | |||||
String defaultNamespaceURI) throws CSSException { | |||||
} | |||||
@Override | |||||
public void startMedia(SACMediaList media) throws CSSException { | |||||
MediaNode node = new MediaNode(media); | |||||
nodeStack.peek().appendChild(node); | |||||
nodeStack.push(node); | |||||
} | |||||
@Override | |||||
public void endMedia(SACMediaList media) throws CSSException { | |||||
nodeStack.pop(); | |||||
} | |||||
@Override | |||||
public void startPage(String name, String pseudo_page) throws CSSException { | |||||
System.out.println("startPage(String name, String pseudo_page): " | |||||
+ name + ", " + pseudo_page); | |||||
} | |||||
@Override | |||||
public void endPage(String name, String pseudo_page) throws CSSException { | |||||
System.out.println("endPage(String name, String pseudo_page): " + name | |||||
+ ", " + pseudo_page); | |||||
} | |||||
@Override | |||||
public void startFontFace() throws CSSException { | |||||
System.out.println("startFontFace()"); | |||||
} | |||||
@Override | |||||
public void endFontFace() throws CSSException { | |||||
System.out.println("endFontFace()"); | |||||
} | |||||
@Override | |||||
public void startSelector(SelectorList selectors) throws CSSException { | |||||
BlockNode node = new BlockNode(selectors); | |||||
nodeStack.peek().appendChild(node); | |||||
nodeStack.push(node); | |||||
} | |||||
@Override | |||||
public void endSelector(SelectorList selectors) throws CSSException { | |||||
nodeStack.pop(); | |||||
} | |||||
@Override | |||||
public void property(String name, LexicalUnit value, boolean important) | |||||
throws CSSException { | |||||
property(name, value, important, null); | |||||
} | |||||
public void property(String name, LexicalUnit value, boolean important, | |||||
String comment) { | |||||
RuleNode node = new RuleNode(name, value, important, comment); | |||||
nodeStack.peek().appendChild(node); | |||||
} | |||||
@Override | |||||
public void extendDirective(SelectorList list) { | |||||
ExtendNode node = new ExtendNode(list); | |||||
nodeStack.peek().appendChild(node); | |||||
} | |||||
@Override | |||||
public MixinDefNode mixinDirective(String name, String args, String body) { | |||||
MixinDefNode node = new MixinDefNode(name, args, body); | |||||
return node; | |||||
} | |||||
@Override | |||||
public void startNestedProperties(String name) { | |||||
NestPropertiesNode node = new NestPropertiesNode(name); | |||||
nodeStack.peek().appendChild(node); | |||||
nodeStack.push(node); | |||||
} | |||||
@Override | |||||
public void endNestedProperties(String name) { | |||||
nodeStack.pop(); | |||||
} | |||||
@Override | |||||
public void startMixinDirective(String name, Collection<VariableNode> args) { | |||||
MixinDefNode node = new MixinDefNode(name, args); | |||||
nodeStack.peek().appendChild(node); | |||||
nodeStack.push(node); | |||||
} | |||||
@Override | |||||
public void endMixinDirective(String name, Collection<VariableNode> args) { | |||||
nodeStack.pop(); | |||||
} | |||||
@Override | |||||
public void includeDirective(String name, Collection<LexicalUnit> args) { | |||||
MixinNode node = new MixinNode(name, args); | |||||
nodeStack.peek().appendChild(node); | |||||
} | |||||
@Override | |||||
public void importStyle(String uri, SACMediaList media, boolean isURL) { | |||||
ImportNode node = new ImportNode(uri, media, isURL); | |||||
nodeStack.peek().appendChild(node); | |||||
} | |||||
} |
/* Generated By:JavaCC: Do not edit this line. CharStream.java Version 5.0 */ | |||||
/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ | |||||
package com.vaadin.sass.parser; | |||||
/** | |||||
* This interface describes a character stream that maintains line and | |||||
* column number positions of the characters. It also has the capability | |||||
* to backup the stream to some extent. An implementation of this | |||||
* interface is used in the TokenManager implementation generated by | |||||
* JavaCCParser. | |||||
* | |||||
* All the methods except backup can be implemented in any fashion. backup | |||||
* needs to be implemented correctly for the correct operation of the lexer. | |||||
* Rest of the methods are all used to get information like line number, | |||||
* column number and the String that constitutes a token and are not used | |||||
* by the lexer. Hence their implementation won't affect the generated lexer's | |||||
* operation. | |||||
*/ | |||||
public | |||||
interface CharStream { | |||||
/** | |||||
* Returns the next character from the selected input. The method | |||||
* of selecting the input is the responsibility of the class | |||||
* implementing this interface. Can throw any java.io.IOException. | |||||
*/ | |||||
char readChar() throws java.io.IOException; | |||||
@Deprecated | |||||
/** | |||||
* Returns the column position of the character last read. | |||||
* @deprecated | |||||
* @see #getEndColumn | |||||
*/ | |||||
int getColumn(); | |||||
@Deprecated | |||||
/** | |||||
* Returns the line number of the character last read. | |||||
* @deprecated | |||||
* @see #getEndLine | |||||
*/ | |||||
int getLine(); | |||||
/** | |||||
* Returns the column number of the last character for current token (being | |||||
* matched after the last call to BeginTOken). | |||||
*/ | |||||
int getEndColumn(); | |||||
/** | |||||
* Returns the line number of the last character for current token (being | |||||
* matched after the last call to BeginTOken). | |||||
*/ | |||||
int getEndLine(); | |||||
/** | |||||
* Returns the column number of the first character for current token (being | |||||
* matched after the last call to BeginTOken). | |||||
*/ | |||||
int getBeginColumn(); | |||||
/** | |||||
* Returns the line number of the first character for current token (being | |||||
* matched after the last call to BeginTOken). | |||||
*/ | |||||
int getBeginLine(); | |||||
/** | |||||
* Backs up the input stream by amount steps. Lexer calls this method if it | |||||
* had already read some characters, but could not use them to match a | |||||
* (longer) token. So, they will be used again as the prefix of the next | |||||
* token and it is the implemetation's responsibility to do this right. | |||||
*/ | |||||
void backup(int amount); | |||||
/** | |||||
* Returns the next character that marks the beginning of the next token. | |||||
* All characters must remain in the buffer between two successive calls | |||||
* to this method to implement backup correctly. | |||||
*/ | |||||
char BeginToken() throws java.io.IOException; | |||||
/** | |||||
* Returns a string made up of characters from the marked token beginning | |||||
* to the current buffer position. Implementations have the choice of returning | |||||
* anything that they want to. For example, for efficiency, one might decide | |||||
* to just return null, which is a valid implementation. | |||||
*/ | |||||
String GetImage(); | |||||
/** | |||||
* Returns an array of characters that make up the suffix of length 'len' for | |||||
* the currently matched token. This is used to build up the matched string | |||||
* for use in actions in the case of MORE. A simple and inefficient | |||||
* implementation of this is as follows : | |||||
* | |||||
* { | |||||
* String t = GetImage(); | |||||
* return t.substring(t.length() - len, t.length()).toCharArray(); | |||||
* } | |||||
*/ | |||||
char[] GetSuffix(int len); | |||||
/** | |||||
* The lexer calls this function to indicate that it is done with the stream | |||||
* and hence implementations can free any resources held by this class. | |||||
* Again, the body of this function can be just empty and it will not | |||||
* affect the lexer's operation. | |||||
*/ | |||||
void Done(); | |||||
} | |||||
/* JavaCC - OriginalChecksum=28e31651bf0ffe57018eaaa3310c55ac (do not edit this line) */ |
/* Generated By:JavaCC: Do not edit this line. Generic_CharStream.java Version 0.7pre6 */ | |||||
package com.vaadin.sass.parser; | |||||
/** | |||||
* An implementation of interface CharStream, where the stream is assumed to | |||||
* contain only ASCII characters (without unicode processing). | |||||
*/ | |||||
public final class Generic_CharStream implements CharStream | |||||
{ | |||||
public static final boolean staticFlag = false; | |||||
int bufsize; | |||||
int available; | |||||
int tokenBegin; | |||||
public int bufpos = -1; | |||||
private int bufline[]; | |||||
private int bufcolumn[]; | |||||
private int column = 0; | |||||
private int line = 1; | |||||
private boolean prevCharIsCR = false; | |||||
private boolean prevCharIsLF = false; | |||||
private java.io.Reader reader; | |||||
private char[] buffer; | |||||
private int maxNextCharInd = 0; | |||||
private int inBuf = 0; | |||||
private final void ExpandBuff(boolean wrapAround) | |||||
{ | |||||
char[] newbuffer = new char[bufsize + 2048]; | |||||
int newbufline[] = new int[bufsize + 2048]; | |||||
int newbufcolumn[] = new int[bufsize + 2048]; | |||||
try | |||||
{ | |||||
if (wrapAround) | |||||
{ | |||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); | |||||
System.arraycopy(buffer, 0, newbuffer, | |||||
bufsize - tokenBegin, bufpos); | |||||
buffer = newbuffer; | |||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); | |||||
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); | |||||
bufline = newbufline; | |||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); | |||||
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); | |||||
bufcolumn = newbufcolumn; | |||||
maxNextCharInd = (bufpos += (bufsize - tokenBegin)); | |||||
} | |||||
else | |||||
{ | |||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); | |||||
buffer = newbuffer; | |||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); | |||||
bufline = newbufline; | |||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); | |||||
bufcolumn = newbufcolumn; | |||||
maxNextCharInd = (bufpos -= tokenBegin); | |||||
} | |||||
} | |||||
catch (Throwable t) | |||||
{ | |||||
throw new Error(t.getMessage()); | |||||
} | |||||
bufsize += 2048; | |||||
available = bufsize; | |||||
tokenBegin = 0; | |||||
} | |||||
private final void FillBuff() throws java.io.IOException | |||||
{ | |||||
if (maxNextCharInd == available) | |||||
{ | |||||
if (available == bufsize) | |||||
{ | |||||
if (tokenBegin > 2048) | |||||
{ | |||||
bufpos = maxNextCharInd = 0; | |||||
available = tokenBegin; | |||||
} | |||||
else if (tokenBegin < 0) | |||||
bufpos = maxNextCharInd = 0; | |||||
else | |||||
ExpandBuff(false); | |||||
} | |||||
else if (available > tokenBegin) | |||||
available = bufsize; | |||||
else if ((tokenBegin - available) < 2048) | |||||
ExpandBuff(true); | |||||
else | |||||
available = tokenBegin; | |||||
} | |||||
int i; | |||||
try { | |||||
if ((i = reader.read(buffer, maxNextCharInd, | |||||
available - maxNextCharInd)) == -1) | |||||
{ | |||||
reader.close(); | |||||
throw new java.io.IOException(); | |||||
} | |||||
else | |||||
maxNextCharInd += i; | |||||
return; | |||||
} | |||||
catch(java.io.IOException e) { | |||||
--bufpos; | |||||
backup(0); | |||||
if (tokenBegin == -1) | |||||
tokenBegin = bufpos; | |||||
throw e; | |||||
} | |||||
} | |||||
public final char BeginToken() throws java.io.IOException | |||||
{ | |||||
tokenBegin = -1; | |||||
char c = readChar(); | |||||
tokenBegin = bufpos; | |||||
return c; | |||||
} | |||||
private final void UpdateLineColumn(char c) | |||||
{ | |||||
column++; | |||||
if (prevCharIsLF) | |||||
{ | |||||
prevCharIsLF = false; | |||||
line += (column = 1); | |||||
} | |||||
else if (prevCharIsCR) | |||||
{ | |||||
prevCharIsCR = false; | |||||
if (c == '\n') | |||||
{ | |||||
prevCharIsLF = true; | |||||
} | |||||
else | |||||
line += (column = 1); | |||||
} | |||||
switch (c) | |||||
{ | |||||
case '\r' : | |||||
prevCharIsCR = true; | |||||
break; | |||||
case '\n' : | |||||
prevCharIsLF = true; | |||||
break; | |||||
case '\t' : | |||||
column--; | |||||
column += (8 - (column & 07)); | |||||
break; | |||||
default : | |||||
break; | |||||
} | |||||
bufline[bufpos] = line; | |||||
bufcolumn[bufpos] = column; | |||||
} | |||||
public final char readChar() throws java.io.IOException | |||||
{ | |||||
if (inBuf > 0) | |||||
{ | |||||
--inBuf; | |||||
return (char)((char)0xff & buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos]); | |||||
} | |||||
if (++bufpos >= maxNextCharInd) | |||||
FillBuff(); | |||||
char c = (char)((char)0xff & buffer[bufpos]); | |||||
UpdateLineColumn(c); | |||||
return (c); | |||||
} | |||||
/** | |||||
* @deprecated | |||||
* @see #getEndColumn | |||||
*/ | |||||
public final int getColumn() { | |||||
return bufcolumn[bufpos]; | |||||
} | |||||
/** | |||||
* @deprecated | |||||
* @see #getEndLine | |||||
*/ | |||||
public final int getLine() { | |||||
return bufline[bufpos]; | |||||
} | |||||
public final int getEndColumn() { | |||||
return bufcolumn[bufpos]; | |||||
} | |||||
public final int getEndLine() { | |||||
return bufline[bufpos]; | |||||
} | |||||
public final int getBeginColumn() { | |||||
return bufcolumn[tokenBegin]; | |||||
} | |||||
public final int getBeginLine() { | |||||
return bufline[tokenBegin]; | |||||
} | |||||
public final void backup(int amount) { | |||||
inBuf += amount; | |||||
if ((bufpos -= amount) < 0) | |||||
bufpos += bufsize; | |||||
} | |||||
public Generic_CharStream(java.io.Reader dstream, int startline, | |||||
int startcolumn, int buffersize) | |||||
{ | |||||
reader = dstream; | |||||
line = startline; | |||||
column = startcolumn - 1; | |||||
available = bufsize = buffersize; | |||||
buffer = new char[buffersize]; | |||||
bufline = new int[buffersize]; | |||||
bufcolumn = new int[buffersize]; | |||||
} | |||||
public Generic_CharStream(java.io.Reader dstream, int startline, | |||||
int startcolumn) | |||||
{ | |||||
this(dstream, startline, startcolumn, 4096); | |||||
} | |||||
public void ReInit(java.io.Reader dstream, int startline, | |||||
int startcolumn, int buffersize) | |||||
{ | |||||
reader = dstream; | |||||
line = startline; | |||||
column = startcolumn - 1; | |||||
if (buffer == null || buffersize != buffer.length) | |||||
{ | |||||
available = bufsize = buffersize; | |||||
buffer = new char[buffersize]; | |||||
bufline = new int[buffersize]; | |||||
bufcolumn = new int[buffersize]; | |||||
} | |||||
prevCharIsLF = prevCharIsCR = false; | |||||
tokenBegin = inBuf = maxNextCharInd = 0; | |||||
bufpos = -1; | |||||
} | |||||
public void ReInit(java.io.Reader dstream, int startline, | |||||
int startcolumn) | |||||
{ | |||||
ReInit(dstream, startline, startcolumn, 4096); | |||||
} | |||||
public final String GetImage() | |||||
{ | |||||
if (bufpos >= tokenBegin) | |||||
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); | |||||
else | |||||
return new String(buffer, tokenBegin, bufsize - tokenBegin) + | |||||
new String(buffer, 0, bufpos + 1); | |||||
} | |||||
public final char[] GetSuffix(int len) | |||||
{ | |||||
char[] ret = new char[len]; | |||||
if ((bufpos + 1) >= len) | |||||
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); | |||||
else | |||||
{ | |||||
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, | |||||
len - bufpos - 1); | |||||
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); | |||||
} | |||||
return ret; | |||||
} | |||||
public void Done() | |||||
{ | |||||
buffer = null; | |||||
bufline = null; | |||||
bufcolumn = null; | |||||
} | |||||
/** | |||||
* Method to adjust line and column numbers for the start of a token.<BR> | |||||
*/ | |||||
public void adjustBeginLineColumn(int newLine, int newCol) | |||||
{ | |||||
int start = tokenBegin; | |||||
int len; | |||||
if (bufpos >= tokenBegin) | |||||
{ | |||||
len = bufpos - tokenBegin + inBuf + 1; | |||||
} | |||||
else | |||||
{ | |||||
len = bufsize - tokenBegin + bufpos + 1 + inBuf; | |||||
} | |||||
int i = 0, j = 0, k = 0; | |||||
int nextColDiff = 0, columnDiff = 0; | |||||
while (i < len && | |||||
bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) | |||||
{ | |||||
bufline[j] = newLine; | |||||
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; | |||||
bufcolumn[j] = newCol + columnDiff; | |||||
columnDiff = nextColDiff; | |||||
i++; | |||||
} | |||||
if (i < len) | |||||
{ | |||||
bufline[j] = newLine++; | |||||
bufcolumn[j] = newCol + columnDiff; | |||||
while (i++ < len) | |||||
{ | |||||
if (bufline[j = start % bufsize] != bufline[++start % bufsize]) | |||||
bufline[j] = newLine++; | |||||
else | |||||
bufline[j] = newLine; | |||||
} | |||||
} | |||||
line = bufline[j]; | |||||
column = bufcolumn[j]; | |||||
} | |||||
} |
/* | |||||
* (c) COPYRIGHT 1999 World Wide Web Consortium | |||||
* (Massachusetts Institute of Technology, Institut National de Recherche | |||||
* en Informatique et en Automatique, Keio University). | |||||
* All Rights Reserved. http://www.w3.org/Consortium/Legal/ | |||||
* | |||||
* $Id: JumpException.java,v 1.1 1999/06/09 15:21:33 plehegar Exp $ | |||||
*/ | |||||
package com.vaadin.sass.parser; | |||||
/** | |||||
* @version $Revision: 1.1 $ | |||||
* @author Philippe Le Hegaret | |||||
*/ | |||||
public class JumpException extends RuntimeException { | |||||
private static final long serialVersionUID = -2010286909393046205L; | |||||
/** | |||||
* Creates a new JumpException | |||||
*/ | |||||
public JumpException() { | |||||
} | |||||
} |
/* | |||||
* Copyright (c) 1999 World Wide Web Consortium | |||||
* (Massachusetts Institute of Technology, Institut National de Recherche | |||||
* en Informatique et en Automatique, Keio University). | |||||
* All Rights Reserved. http://www.w3.org/Consortium/Legal/ | |||||
* | |||||
* $Id: LexicalUnitImpl.java,v 1.3 2000/02/15 02:08:19 plehegar Exp $ | |||||
*/ | |||||
package com.vaadin.sass.parser; | |||||
import java.io.Serializable; | |||||
import org.w3c.css.sac.LexicalUnit; | |||||
import com.vaadin.sass.util.ColorUtil; | |||||
/** | |||||
* @version $Revision: 1.3 $ | |||||
* @author Philippe Le Hegaret | |||||
*/ | |||||
public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit, | |||||
Serializable { | |||||
private static final long serialVersionUID = -6649833716809789399L; | |||||
LexicalUnit prev; | |||||
LexicalUnit next; | |||||
short type; | |||||
int line; | |||||
int column; | |||||
int i; | |||||
float f; | |||||
short dimension; | |||||
String sdimension; | |||||
String s; | |||||
String fname; | |||||
LexicalUnitImpl params; | |||||
LexicalUnitImpl(short type, int line, int column, LexicalUnitImpl p) { | |||||
if (p != null) { | |||||
prev = p; | |||||
p.next = this; | |||||
} | |||||
this.line = line; | |||||
this.column = column - 1; | |||||
this.type = type; | |||||
} | |||||
LexicalUnitImpl(int line, int column, LexicalUnitImpl previous, int i) { | |||||
this(SAC_INTEGER, line, column, previous); | |||||
this.i = i; | |||||
} | |||||
LexicalUnitImpl(int line, int column, LexicalUnitImpl previous, | |||||
short dimension, String sdimension, float f) { | |||||
this(dimension, line, column, previous); | |||||
this.f = f; | |||||
this.dimension = dimension; | |||||
this.sdimension = sdimension; | |||||
} | |||||
LexicalUnitImpl(int line, int column, LexicalUnitImpl previous, short type, | |||||
String s) { | |||||
this(type, line, column, previous); | |||||
this.s = s; | |||||
} | |||||
LexicalUnitImpl(short type, int line, int column, LexicalUnitImpl previous, | |||||
String fname, LexicalUnitImpl params) { | |||||
this(type, line, column, previous); | |||||
this.fname = fname; | |||||
this.params = params; | |||||
} | |||||
public int getLineNumber() { | |||||
return line; | |||||
} | |||||
public int getColumnNumber() { | |||||
return column; | |||||
} | |||||
@Override | |||||
public short getLexicalUnitType() { | |||||
return type; | |||||
} | |||||
@Override | |||||
public LexicalUnit getNextLexicalUnit() { | |||||
return next; | |||||
} | |||||
public void setNextLexicalUnit(LexicalUnit n) { | |||||
next = n; | |||||
} | |||||
@Override | |||||
public LexicalUnit getPreviousLexicalUnit() { | |||||
return prev; | |||||
} | |||||
@Override | |||||
public int getIntegerValue() { | |||||
return i; | |||||
} | |||||
void setIntegerValue(int i) { | |||||
this.i = i; | |||||
} | |||||
@Override | |||||
public float getFloatValue() { | |||||
return f; | |||||
} | |||||
public void setFloatValue(float f) { | |||||
this.f = f; | |||||
} | |||||
@Override | |||||
public String getDimensionUnitText() { | |||||
switch (type) { | |||||
case SAC_PERCENTAGE: | |||||
return "%"; | |||||
case SAC_EM: | |||||
return "em"; | |||||
case SAC_EX: | |||||
return "ex"; | |||||
case SAC_PIXEL: | |||||
return "px"; | |||||
case SAC_CENTIMETER: | |||||
return "cm"; | |||||
case SAC_MILLIMETER: | |||||
return "mm"; | |||||
case SAC_INCH: | |||||
return "in"; | |||||
case SAC_POINT: | |||||
return "pt"; | |||||
case SAC_PICA: | |||||
return "pc"; | |||||
case SAC_DEGREE: | |||||
return "deg"; | |||||
case SAC_RADIAN: | |||||
return "rad"; | |||||
case SAC_GRADIAN: | |||||
return "grad"; | |||||
case SAC_MILLISECOND: | |||||
return "ms"; | |||||
case SAC_SECOND: | |||||
return "s"; | |||||
case SAC_HERTZ: | |||||
return "Hz"; | |||||
case SAC_KILOHERTZ: | |||||
return "kHz"; | |||||
case SAC_DIMENSION: | |||||
return sdimension; | |||||
default: | |||||
throw new IllegalStateException("invalid dimension " + type); | |||||
} | |||||
} | |||||
@Override | |||||
public String getStringValue() { | |||||
return s; | |||||
} | |||||
public void setStringValue(String str) { | |||||
s = str; | |||||
} | |||||
@Override | |||||
public String getFunctionName() { | |||||
return fname; | |||||
} | |||||
@Override | |||||
public LexicalUnitImpl getParameters() { | |||||
return params; | |||||
} | |||||
@Override | |||||
public LexicalUnitImpl getSubValues() { | |||||
return params; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
short type = getLexicalUnitType(); | |||||
String text = null; | |||||
switch (type) { | |||||
case SCSS_VARIABLE: | |||||
text = "$" + s; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_COMMA: | |||||
text = ","; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_PLUS: | |||||
text = "+"; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_MINUS: | |||||
text = "-"; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_MULTIPLY: | |||||
text = "*"; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_SLASH: | |||||
text = "/"; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_MOD: | |||||
text = "%"; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_EXP: | |||||
text = "^"; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_LT: | |||||
text = "<"; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_GT: | |||||
text = ">"; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_LE: | |||||
text = "<="; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_GE: | |||||
text = "=>"; | |||||
break; | |||||
case LexicalUnit.SAC_OPERATOR_TILDE: | |||||
text = "~"; | |||||
break; | |||||
case LexicalUnit.SAC_INHERIT: | |||||
text = "inherit"; | |||||
break; | |||||
case LexicalUnit.SAC_INTEGER: | |||||
text = Integer.toString(getIntegerValue(), 10); | |||||
break; | |||||
case LexicalUnit.SAC_REAL: | |||||
text = getFloatValue() + ""; | |||||
break; | |||||
case LexicalUnit.SAC_EM: | |||||
case LexicalUnit.SAC_EX: | |||||
case LexicalUnit.SAC_PIXEL: | |||||
case LexicalUnit.SAC_INCH: | |||||
case LexicalUnit.SAC_CENTIMETER: | |||||
case LexicalUnit.SAC_MILLIMETER: | |||||
case LexicalUnit.SAC_POINT: | |||||
case LexicalUnit.SAC_PICA: | |||||
case LexicalUnit.SAC_PERCENTAGE: | |||||
case LexicalUnit.SAC_DEGREE: | |||||
case LexicalUnit.SAC_GRADIAN: | |||||
case LexicalUnit.SAC_RADIAN: | |||||
case LexicalUnit.SAC_MILLISECOND: | |||||
case LexicalUnit.SAC_SECOND: | |||||
case LexicalUnit.SAC_HERTZ: | |||||
case LexicalUnit.SAC_KILOHERTZ: | |||||
case LexicalUnit.SAC_DIMENSION: | |||||
float f = getFloatValue(); | |||||
int i = (int) f; | |||||
if ((i) == f) { | |||||
text = i + getDimensionUnitText(); | |||||
} else { | |||||
text = f + getDimensionUnitText(); | |||||
} | |||||
break; | |||||
case LexicalUnit.SAC_URI: | |||||
text = "url(" + getStringValue() + ")"; | |||||
break; | |||||
case LexicalUnit.SAC_RGBCOLOR: | |||||
case LexicalUnit.SAC_COUNTER_FUNCTION: | |||||
case LexicalUnit.SAC_COUNTERS_FUNCTION: | |||||
case LexicalUnit.SAC_RECT_FUNCTION: | |||||
case LexicalUnit.SAC_FUNCTION: | |||||
String funcName = getFunctionName(); | |||||
LexicalUnitImpl firstParam = getParameters(); | |||||
if ("round".equals(funcName)) { | |||||
firstParam | |||||
.setFloatValue(Math.round(firstParam.getFloatValue())); | |||||
text = firstParam.toString(); | |||||
} else if ("ceil".equals(funcName)) { | |||||
firstParam.setFloatValue((float) Math.ceil(firstParam | |||||
.getFloatValue())); | |||||
text = firstParam.toString(); | |||||
} else if ("floor".equals(funcName)) { | |||||
firstParam.setFloatValue((float) Math.floor(firstParam | |||||
.getFloatValue())); | |||||
text = firstParam.toString(); | |||||
} else if ("abs".equals(funcName)) { | |||||
firstParam.setFloatValue(Math.abs(firstParam.getFloatValue())); | |||||
text = firstParam.toString(); | |||||
} else if ("darken".equals(funcName)) { | |||||
LexicalUnitImpl dark = ColorUtil.darken(this); | |||||
text = dark.toString(); | |||||
} else if ("lighten".equals(funcName)) { | |||||
text = ColorUtil.lighten(this).toString(); | |||||
} else { | |||||
text = getFunctionName() + "(" + getParameters() + ")"; | |||||
} | |||||
break; | |||||
case LexicalUnit.SAC_IDENT: | |||||
text = getStringValue(); | |||||
break; | |||||
case LexicalUnit.SAC_STRING_VALUE: | |||||
// @@SEEME. not exact | |||||
text = "\"" + getStringValue() + "\""; | |||||
break; | |||||
case LexicalUnit.SAC_ATTR: | |||||
text = "attr(" + getStringValue() + ")"; | |||||
break; | |||||
case LexicalUnit.SAC_UNICODERANGE: | |||||
text = "@@TODO"; | |||||
break; | |||||
case LexicalUnit.SAC_SUB_EXPRESSION: | |||||
text = getSubValues().toString(); | |||||
break; | |||||
default: | |||||
text = "@unknown"; | |||||
break; | |||||
} | |||||
if (getNextLexicalUnit() != null) { | |||||
if (getNextLexicalUnit().getLexicalUnitType() == SAC_OPERATOR_COMMA) { | |||||
return text + getNextLexicalUnit(); | |||||
} | |||||
return text + ' ' + getNextLexicalUnit(); | |||||
} else { | |||||
return text; | |||||
} | |||||
} | |||||
@Override | |||||
public LexicalUnitImpl divide(LexicalUnitImpl denominator) { | |||||
setFloatValue(getFloatValue() / denominator.getIntegerValue()); | |||||
return this; | |||||
} | |||||
@Override | |||||
public LexicalUnitImpl add(LexicalUnitImpl another) { | |||||
setFloatValue(getFloatValue() + another.getFloatValue()); | |||||
return this; | |||||
} | |||||
@Override | |||||
public LexicalUnitImpl minus(LexicalUnitImpl another) { | |||||
setFloatValue(getFloatValue() - another.getFloatValue()); | |||||
return this; | |||||
} | |||||
@Override | |||||
public LexicalUnitImpl multiply(LexicalUnitImpl another) { | |||||
setFloatValue(getFloatValue() * another.getIntegerValue()); | |||||
return this; | |||||
} | |||||
public void replaceValue(LexicalUnitImpl another) { | |||||
type = another.getLexicalUnitType(); | |||||
i = another.getIntegerValue(); | |||||
f = another.getFloatValue(); | |||||
dimension = another.getDimension(); | |||||
sdimension = another.getSdimension(); | |||||
s = another.getStringValue(); | |||||
fname = getFunctionName(); | |||||
params = another.getParameters(); | |||||
prev = another.getPreviousLexicalUnit(); | |||||
LexicalUnit finalNextInAnother = another; | |||||
while (finalNextInAnother.getNextLexicalUnit() != null) { | |||||
finalNextInAnother = finalNextInAnother.getNextLexicalUnit(); | |||||
} | |||||
((LexicalUnitImpl) finalNextInAnother).setNextLexicalUnit(next); | |||||
next = another.next; | |||||
} | |||||
public short getDimension() { | |||||
return dimension; | |||||
} | |||||
public String getSdimension() { | |||||
return sdimension; | |||||
} | |||||
// here some useful function for creation | |||||
public static LexicalUnitImpl createVariable(int line, int column, | |||||
LexicalUnitImpl previous, String name) { | |||||
return new LexicalUnitImpl(line, column, previous, SCSS_VARIABLE, name); | |||||
} | |||||
public static LexicalUnitImpl createNumber(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
int i = (int) v; | |||||
if (v == i) { | |||||
return new LexicalUnitImpl(line, column, previous, i); | |||||
} else { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_REAL, "", v); | |||||
} | |||||
} | |||||
public static LexicalUnitImpl createInteger(int line, int column, | |||||
LexicalUnitImpl previous, int i) { | |||||
return new LexicalUnitImpl(line, column, previous, i); | |||||
} | |||||
public static LexicalUnitImpl createPercentage(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_PERCENTAGE, | |||||
null, v); | |||||
} | |||||
static LexicalUnitImpl createEMS(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_EM, null, v); | |||||
} | |||||
static LexicalUnitImpl createEXS(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_EX, null, v); | |||||
} | |||||
static LexicalUnitImpl createPX(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_PIXEL, null, v); | |||||
} | |||||
static LexicalUnitImpl createCM(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_CENTIMETER, | |||||
null, v); | |||||
} | |||||
static LexicalUnitImpl createMM(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_MILLIMETER, | |||||
null, v); | |||||
} | |||||
static LexicalUnitImpl createIN(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_INCH, null, v); | |||||
} | |||||
static LexicalUnitImpl createPT(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_POINT, null, v); | |||||
} | |||||
static LexicalUnitImpl createPC(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_PICA, null, v); | |||||
} | |||||
static LexicalUnitImpl createDEG(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_DEGREE, null, v); | |||||
} | |||||
static LexicalUnitImpl createRAD(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_RADIAN, null, v); | |||||
} | |||||
static LexicalUnitImpl createGRAD(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_GRADIAN, null, v); | |||||
} | |||||
static LexicalUnitImpl createMS(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
if (v < 0) { | |||||
throw new ParseException("Time values may not be negative"); | |||||
} | |||||
return new LexicalUnitImpl(line, column, previous, SAC_MILLISECOND, | |||||
null, v); | |||||
} | |||||
static LexicalUnitImpl createS(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
if (v < 0) { | |||||
throw new ParseException("Time values may not be negative"); | |||||
} | |||||
return new LexicalUnitImpl(line, column, previous, SAC_SECOND, null, v); | |||||
} | |||||
static LexicalUnitImpl createHZ(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
if (v < 0) { | |||||
throw new ParseException("Frequency values may not be negative"); | |||||
} | |||||
return new LexicalUnitImpl(line, column, previous, SAC_HERTZ, null, v); | |||||
} | |||||
static LexicalUnitImpl createKHZ(int line, int column, | |||||
LexicalUnitImpl previous, float v) { | |||||
if (v < 0) { | |||||
throw new ParseException("Frequency values may not be negative"); | |||||
} | |||||
return new LexicalUnitImpl(line, column, previous, SAC_KILOHERTZ, null, | |||||
v); | |||||
} | |||||
static LexicalUnitImpl createDimen(int line, int column, | |||||
LexicalUnitImpl previous, float v, String s) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_DIMENSION, s, v); | |||||
} | |||||
static LexicalUnitImpl createInherit(int line, int column, | |||||
LexicalUnitImpl previous) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_INHERIT, | |||||
"inherit"); | |||||
} | |||||
public static LexicalUnitImpl createIdent(int line, int column, | |||||
LexicalUnitImpl previous, String s) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_IDENT, s); | |||||
} | |||||
static LexicalUnitImpl createString(int line, int column, | |||||
LexicalUnitImpl previous, String s) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_STRING_VALUE, s); | |||||
} | |||||
static LexicalUnitImpl createURL(int line, int column, | |||||
LexicalUnitImpl previous, String s) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_URI, s); | |||||
} | |||||
static LexicalUnitImpl createAttr(int line, int column, | |||||
LexicalUnitImpl previous, String s) { | |||||
return new LexicalUnitImpl(line, column, previous, SAC_ATTR, s); | |||||
} | |||||
static LexicalUnitImpl createCounter(int line, int column, | |||||
LexicalUnitImpl previous, LexicalUnit params) { | |||||
return new LexicalUnitImpl(SAC_COUNTER_FUNCTION, line, column, | |||||
previous, "counter", (LexicalUnitImpl) params); | |||||
} | |||||
public static LexicalUnitImpl createCounters(int line, int column, | |||||
LexicalUnitImpl previous, LexicalUnit params) { | |||||
return new LexicalUnitImpl(SAC_COUNTERS_FUNCTION, line, column, | |||||
previous, "counters", (LexicalUnitImpl) params); | |||||
} | |||||
public static LexicalUnitImpl createRGBColor(int line, int column, | |||||
LexicalUnitImpl previous, LexicalUnit params) { | |||||
return new LexicalUnitImpl(SAC_RGBCOLOR, line, column, previous, "rgb", | |||||
(LexicalUnitImpl) params); | |||||
} | |||||
public static LexicalUnitImpl createRect(int line, int column, | |||||
LexicalUnitImpl previous, LexicalUnit params) { | |||||
return new LexicalUnitImpl(SAC_RECT_FUNCTION, line, column, previous, | |||||
"rect", (LexicalUnitImpl) params); | |||||
} | |||||
public static LexicalUnitImpl createFunction(int line, int column, | |||||
LexicalUnitImpl previous, String fname, LexicalUnit params) { | |||||
return new LexicalUnitImpl(SAC_FUNCTION, line, column, previous, fname, | |||||
(LexicalUnitImpl) params); | |||||
} | |||||
public static LexicalUnitImpl createUnicodeRange(int line, int column, | |||||
LexicalUnit previous, LexicalUnit params) { | |||||
// @@ return new LexicalUnitImpl(line, column, previous, null, | |||||
// SAC_UNICODERANGE, params); | |||||
return null; | |||||
} | |||||
public static LexicalUnitImpl createComma(int line, int column, | |||||
LexicalUnitImpl previous) { | |||||
return new LexicalUnitImpl(SAC_OPERATOR_COMMA, line, column, previous); | |||||
} | |||||
public static LexicalUnitImpl createSlash(int line, int column, | |||||
LexicalUnitImpl previous) { | |||||
return new LexicalUnitImpl(SAC_OPERATOR_SLASH, line, column, previous); | |||||
} | |||||
} |
/* | |||||
* Copyright (c) 1999 World Wide Web Consortium | |||||
* (Massachusetts Institute of Technology, Institut National de Recherche | |||||
* en Informatique et en Automatique, Keio University). | |||||
* All Rights Reserved. http://www.w3.org/Consortium/Legal/ | |||||
* | |||||
* $Id: LocatorImpl.java,v 1.2 2000/02/14 16:59:06 plehegar Exp $ | |||||
*/ | |||||
package com.vaadin.sass.parser; | |||||
import org.w3c.css.sac.Locator; | |||||
/** | |||||
* @version $Revision: 1.2 $ | |||||
* @author Philippe Le Hegaret | |||||
*/ | |||||
public class LocatorImpl implements Locator { | |||||
// W3C DEBUG mode | |||||
private static boolean W3CDebug; | |||||
static { | |||||
try { | |||||
W3CDebug = (Boolean.getBoolean("debug") | |||||
|| Boolean.getBoolean("org.w3c.flute.parser.LocatorImpl.debug") | |||||
|| Boolean.getBoolean("org.w3c.flute.parser.debug") | |||||
|| Boolean.getBoolean("org.w3c.flute.debug") | |||||
|| Boolean.getBoolean("org.w3c.debug") | |||||
|| Boolean.getBoolean("org.debug")); | |||||
} catch (Exception e) { | |||||
// nothing | |||||
} | |||||
} | |||||
String uri; | |||||
int line; | |||||
int column; | |||||
public String getURI() { | |||||
return uri; | |||||
} | |||||
public int getLineNumber() { | |||||
return line; | |||||
} | |||||
public int getColumnNumber() { | |||||
return column; | |||||
} | |||||
/** | |||||
* Creates a new LocatorImpl | |||||
*/ | |||||
public LocatorImpl(Parser p) { | |||||
if (W3CDebug) { | |||||
System.err.println( "LocatorImpl::newLocator(" + p + ");"); | |||||
} | |||||
uri = p.source.getURI(); | |||||
line = p.token.beginLine; | |||||
column = p.token.beginColumn; | |||||
} | |||||
/** | |||||
* Reinitializes a LocatorImpl | |||||
*/ | |||||
public LocatorImpl(Parser p, Token tok) { | |||||
if (W3CDebug) { | |||||
System.err.println( "LocatorImpl::newLocator(" + p | |||||
+ ", " + tok + ");"); | |||||
} | |||||
uri = p.source.getURI(); | |||||
line = tok.beginLine; | |||||
column = tok.beginColumn; | |||||
} | |||||
/** | |||||
* Reinitializes a LocatorImpl | |||||
*/ | |||||
public LocatorImpl(Parser p, int line, int column) { | |||||
if (W3CDebug) { | |||||
System.err.println( "LocatorImpl::newLocator(" + p | |||||
+ ", " + line | |||||
+ ", " + column + ");"); | |||||
} | |||||
uri = p.source.getURI(); | |||||
this.line = line; | |||||
this.column = column; | |||||
} | |||||
/** | |||||
* Reinitializes a LocatorImpl | |||||
*/ | |||||
public LocatorImpl reInit(Parser p) { | |||||
if (W3CDebug) { | |||||
System.err.println( "LocatorImpl::reInit(" + p + ");" ); | |||||
} | |||||
uri = p.source.getURI(); | |||||
line = p.token.beginLine; | |||||
column = p.token.beginColumn; | |||||
return this; | |||||
} | |||||
/** | |||||
* Reinitializes a LocatorImpl | |||||
*/ | |||||
public LocatorImpl reInit(Parser p, Token tok) { | |||||
if (W3CDebug) { | |||||
System.err.println( "LocatorImpl::reInit(" + p | |||||
+ ", " + tok + ");"); | |||||
} | |||||
uri = p.source.getURI(); | |||||
line = tok.beginLine; | |||||
column = tok.beginColumn; | |||||
return this; | |||||
} | |||||
/** | |||||
* Reinitializes a LocatorImpl | |||||
*/ | |||||
public LocatorImpl reInit(Parser p, int line, int column) { | |||||
if (W3CDebug) { | |||||
System.err.println("LocatorImpl::reInit(" + p | |||||
+ ", " + line | |||||
+ ", " + column + ");"); | |||||
} | |||||
uri = p.source.getURI(); | |||||
this.line = line; | |||||
this.column = column; | |||||
return this; | |||||
} | |||||
} |
/* | |||||
* (c) COPYRIGHT 1999 World Wide Web Consortium | |||||
* (Massachusetts Institute of Technology, Institut National de Recherche | |||||
* en Informatique et en Automatique, Keio University). | |||||
* All Rights Reserved. http://www.w3.org/Consortium/Legal/ | |||||
* | |||||
* $Id: MediaListImpl.java,v 1.4 2000/04/26 13:40:19 plehegar Exp $ | |||||
*/ | |||||
package com.vaadin.sass.parser; | |||||
import org.w3c.css.sac.SACMediaList; | |||||
/** | |||||
* @version $Revision: 1.4 $ | |||||
* @author Philippe Le Hegaret | |||||
*/ | |||||
public class MediaListImpl implements SACMediaList { | |||||
String[] array = new String[10]; | |||||
int current; | |||||
@Override | |||||
public int getLength() { | |||||
return current; | |||||
} | |||||
@Override | |||||
public String item(int index) { | |||||
if ((index < 0) || (index >= current)) { | |||||
return null; | |||||
} | |||||
return array[index]; | |||||
} | |||||
void addItem(String medium) { | |||||
if (medium.equals("all")) { | |||||
array[0] = "all"; | |||||
current = 1; | |||||
return; | |||||
} | |||||
for (int i = 0; i < current; i++) { | |||||
if (medium.equals(array[i])) { | |||||
return; | |||||
} | |||||
} | |||||
if (current == array.length) { | |||||
String[] old = array; | |||||
array = new String[current + current]; | |||||
System.arraycopy(old, 0, array, 0, current); | |||||
} | |||||
array[current++] = medium; | |||||
} | |||||
/** | |||||
* Returns a string representation of this object. | |||||
*/ | |||||
@Override | |||||
public String toString() { | |||||
switch (current) { | |||||
case 0: | |||||
return ""; | |||||
case 1: | |||||
return array[0]; | |||||
default: | |||||
boolean not_done = true; | |||||
int i = 0; | |||||
StringBuffer buf = new StringBuffer(50); | |||||
do { | |||||
buf.append(array[i++]); | |||||
if (i == current) { | |||||
not_done = false; | |||||
} else { | |||||
buf.append(", "); | |||||
} | |||||
} while (not_done); | |||||
return buf.toString(); | |||||
} | |||||
} | |||||
} |
/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 0.7pre6 */ | |||||
package com.vaadin.sass.parser; | |||||
import org.w3c.css.sac.CSSException; | |||||
/** | |||||
* This exception is thrown when parse errors are encountered. You can | |||||
* explicitly create objects of this exception type by calling the method | |||||
* generateParseException in the generated parser. | |||||
* | |||||
* You can modify this class to customize your error reporting mechanisms so | |||||
* long as you retain the public fields. | |||||
*/ | |||||
public class ParseException extends CSSException { | |||||
private static final long serialVersionUID = -8556588037264585977L; | |||||
/** | |||||
* This constructor is used by the method "generateParseException" in the | |||||
* generated parser. Calling this constructor generates a new object of this | |||||
* type with the fields "currentToken", "expectedTokenSequences", and | |||||
* "tokenImage" set. The boolean flag "specialConstructor" is also set to | |||||
* true to indicate that this constructor was used to create this object. | |||||
* This constructor calls its super class with the empty string to force the | |||||
* "toString" method of parent class "Throwable" to print the error message | |||||
* in the form: ParseException: <result of getMessage> | |||||
*/ | |||||
public ParseException(Token currentTokenVal, | |||||
int[][] expectedTokenSequencesVal, String[] tokenImageVal) { | |||||
super(""); | |||||
specialConstructor = true; | |||||
currentToken = currentTokenVal; | |||||
expectedTokenSequences = expectedTokenSequencesVal; | |||||
tokenImage = tokenImageVal; | |||||
} | |||||
/** | |||||
* The following constructors are for use by you for whatever purpose you | |||||
* can think of. Constructing the exception in this manner makes the | |||||
* exception behave in the normal way - i.e., as documented in the class | |||||
* "Throwable". The fields "errorToken", "expectedTokenSequences", and | |||||
* "tokenImage" do not contain relevant information. The JavaCC generated | |||||
* code does not use these constructors. | |||||
*/ | |||||
public ParseException() { | |||||
super(); | |||||
specialConstructor = false; | |||||
} | |||||
public ParseException(String message) { | |||||
super(message); | |||||
specialConstructor = false; | |||||
} | |||||
/** | |||||
* This variable determines which constructor was used to create this object | |||||
* and thereby affects the semantics of the "getMessage" method (see below). | |||||
*/ | |||||
protected boolean specialConstructor; | |||||
/** | |||||
* This is the last token that has been consumed successfully. If this | |||||
* object has been created due to a parse error, the token followng this | |||||
* token will (therefore) be the first error token. | |||||
*/ | |||||
public Token currentToken; | |||||
/** | |||||
* Each entry in this array is an array of integers. Each array of integers | |||||
* represents a sequence of tokens (by their ordinal values) that is | |||||
* expected at this point of the parse. | |||||
*/ | |||||
public int[][] expectedTokenSequences; | |||||
/** | |||||
* This is a reference to the "tokenImage" array of the generated parser | |||||
* within which the parse error occurred. This array is defined in the | |||||
* generated ...Constants interface. | |||||
*/ | |||||
public String[] tokenImage; | |||||
/** | |||||
* This method has the standard behavior when this object has been created | |||||
* using the standard constructors. Otherwise, it uses "currentToken" and | |||||
* "expectedTokenSequences" to generate a parse error message and returns | |||||
* it. If this object has been created due to a parse error, and you do not | |||||
* catch it (it gets thrown from the parser), then this method is called | |||||
* during the printing of the final stack trace, and hence the correct error | |||||
* message gets displayed. | |||||
*/ | |||||
@Override | |||||
public String getMessage() { | |||||
if (!specialConstructor) { | |||||
return super.getMessage(); | |||||
} | |||||
String expected = ""; | |||||
int maxSize = 0; | |||||
for (int i = 0; i < expectedTokenSequences.length; i++) { | |||||
if (maxSize < expectedTokenSequences[i].length) { | |||||
maxSize = expectedTokenSequences[i].length; | |||||
} | |||||
for (int j = 0; j < expectedTokenSequences[i].length; j++) { | |||||
expected += tokenImage[expectedTokenSequences[i][j]] + " "; | |||||
} | |||||
if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) { | |||||
expected += "..."; | |||||
} | |||||
expected += eol + " "; | |||||
} | |||||
String retval = "Encountered \""; | |||||
Token tok = currentToken.next; | |||||
for (int i = 0; i < maxSize; i++) { | |||||
if (i != 0) { | |||||
retval += " "; | |||||
} | |||||
if (tok.kind == 0) { | |||||
retval += tokenImage[0]; | |||||
break; | |||||
} | |||||
retval += add_escapes(tok.image); | |||||
tok = tok.next; | |||||
} | |||||
retval += "\" at line " + currentToken.next.beginLine + ", column " | |||||
+ currentToken.next.beginColumn + "." + eol; | |||||
if (expectedTokenSequences.length == 1) { | |||||
retval += "Was expecting:" + eol + " "; | |||||
} else { | |||||
retval += "Was expecting one of:" + eol + " "; | |||||
} | |||||
retval += expected; | |||||
return retval; | |||||
} | |||||
/** | |||||
* The end of line string for this machine. | |||||
*/ | |||||
protected String eol = System.getProperty("line.separator", "\n"); | |||||
/** | |||||
* Used to convert raw characters to their escaped version when these raw | |||||
* version cannot be used as part of an ASCII string literal. | |||||
*/ | |||||
protected String add_escapes(String str) { | |||||
StringBuffer retval = new StringBuffer(); | |||||
char ch; | |||||
for (int i = 0; i < str.length(); i++) { | |||||
switch (str.charAt(i)) { | |||||
case 0: | |||||
continue; | |||||
case '\b': | |||||
retval.append("\\b"); | |||||
continue; | |||||
case '\t': | |||||
retval.append("\\t"); | |||||
continue; | |||||
case '\n': | |||||
retval.append("\\n"); | |||||
continue; | |||||
case '\f': | |||||
retval.append("\\f"); | |||||
continue; | |||||
case '\r': | |||||
retval.append("\\r"); | |||||
continue; | |||||
case '\"': | |||||
retval.append("\\\""); | |||||
continue; | |||||
case '\'': | |||||
retval.append("\\\'"); | |||||
continue; | |||||
case '\\': | |||||
retval.append("\\\\"); | |||||
continue; | |||||
default: | |||||
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { | |||||
String s = "0000" + Integer.toString(ch, 16); | |||||
retval.append("\\u" | |||||
+ s.substring(s.length() - 4, s.length())); | |||||
} else { | |||||
retval.append(ch); | |||||
} | |||||
continue; | |||||
} | |||||
} | |||||
return retval.toString(); | |||||
} | |||||
} |
/* Generated By:JavaCC: Do not edit this line. ParserConstants.java */ | |||||
package com.vaadin.sass.parser; | |||||
/** | |||||
* Token literal values and constants. | |||||
* Generated by org.javacc.parser.OtherFilesGen#start() | |||||
*/ | |||||
public interface ParserConstants { | |||||
/** End of File. */ | |||||
int EOF = 0; | |||||
/** RegularExpression Id. */ | |||||
int S = 1; | |||||
/** RegularExpression Id. */ | |||||
int INTERPOLATION = 4; | |||||
/** RegularExpression Id. */ | |||||
int FORMAL_COMMENT = 10; | |||||
/** RegularExpression Id. */ | |||||
int MULTI_LINE_COMMENT = 11; | |||||
/** RegularExpression Id. */ | |||||
int CDO = 13; | |||||
/** RegularExpression Id. */ | |||||
int CDC = 14; | |||||
/** RegularExpression Id. */ | |||||
int LBRACE = 15; | |||||
/** RegularExpression Id. */ | |||||
int RBRACE = 16; | |||||
/** RegularExpression Id. */ | |||||
int DASHMATCH = 17; | |||||
/** RegularExpression Id. */ | |||||
int INCLUDES = 18; | |||||
/** RegularExpression Id. */ | |||||
int EQ = 19; | |||||
/** RegularExpression Id. */ | |||||
int PLUS = 20; | |||||
/** RegularExpression Id. */ | |||||
int MINUS = 21; | |||||
/** RegularExpression Id. */ | |||||
int COMMA = 22; | |||||
/** RegularExpression Id. */ | |||||
int SEMICOLON = 23; | |||||
/** RegularExpression Id. */ | |||||
int PRECEDES = 24; | |||||
/** RegularExpression Id. */ | |||||
int DIV = 25; | |||||
/** RegularExpression Id. */ | |||||
int LBRACKET = 26; | |||||
/** RegularExpression Id. */ | |||||
int RBRACKET = 27; | |||||
/** RegularExpression Id. */ | |||||
int ANY = 28; | |||||
/** RegularExpression Id. */ | |||||
int PARENT = 29; | |||||
/** RegularExpression Id. */ | |||||
int DOT = 30; | |||||
/** RegularExpression Id. */ | |||||
int LPARAN = 31; | |||||
/** RegularExpression Id. */ | |||||
int RPARAN = 32; | |||||
/** RegularExpression Id. */ | |||||
int COLON = 33; | |||||
/** RegularExpression Id. */ | |||||
int NONASCII = 34; | |||||
/** RegularExpression Id. */ | |||||
int H = 35; | |||||
/** RegularExpression Id. */ | |||||
int UNICODE = 36; | |||||
/** RegularExpression Id. */ | |||||
int ESCAPE = 37; | |||||
/** RegularExpression Id. */ | |||||
int NMSTART = 38; | |||||
/** RegularExpression Id. */ | |||||
int NMCHAR = 39; | |||||
/** RegularExpression Id. */ | |||||
int STRINGCHAR = 40; | |||||
/** RegularExpression Id. */ | |||||
int D = 41; | |||||
/** RegularExpression Id. */ | |||||
int NAME = 42; | |||||
/** RegularExpression Id. */ | |||||
int TO = 43; | |||||
/** RegularExpression Id. */ | |||||
int THROUGH = 44; | |||||
/** RegularExpression Id. */ | |||||
int EACH_IN = 45; | |||||
/** RegularExpression Id. */ | |||||
int MIXIN_SYM = 46; | |||||
/** RegularExpression Id. */ | |||||
int INCLUDE_SYM = 47; | |||||
/** RegularExpression Id. */ | |||||
int FUNCTION_SYM = 48; | |||||
/** RegularExpression Id. */ | |||||
int RETURN_SYM = 49; | |||||
/** RegularExpression Id. */ | |||||
int DEBUG_SYM = 50; | |||||
/** RegularExpression Id. */ | |||||
int WARN_SYM = 51; | |||||
/** RegularExpression Id. */ | |||||
int FOR_SYM = 52; | |||||
/** RegularExpression Id. */ | |||||
int EACH_SYM = 53; | |||||
/** RegularExpression Id. */ | |||||
int WHILE_SYM = 54; | |||||
/** RegularExpression Id. */ | |||||
int IF_SYM = 55; | |||||
/** RegularExpression Id. */ | |||||
int ELSE_SYM = 56; | |||||
/** RegularExpression Id. */ | |||||
int EXTEND_SYM = 57; | |||||
/** RegularExpression Id. */ | |||||
int MOZ_DOCUMENT_SYM = 58; | |||||
/** RegularExpression Id. */ | |||||
int SUPPORTS_SYM = 59; | |||||
/** RegularExpression Id. */ | |||||
int GUARDED_SYM = 60; | |||||
/** RegularExpression Id. */ | |||||
int STRING = 61; | |||||
/** RegularExpression Id. */ | |||||
int IDENT = 62; | |||||
/** RegularExpression Id. */ | |||||
int NUMBER = 63; | |||||
/** RegularExpression Id. */ | |||||
int _URL = 64; | |||||
/** RegularExpression Id. */ | |||||
int URL = 65; | |||||
/** RegularExpression Id. */ | |||||
int VARIABLE = 66; | |||||
/** RegularExpression Id. */ | |||||
int PERCENTAGE = 67; | |||||
/** RegularExpression Id. */ | |||||
int PT = 68; | |||||
/** RegularExpression Id. */ | |||||
int MM = 69; | |||||
/** RegularExpression Id. */ | |||||
int CM = 70; | |||||
/** RegularExpression Id. */ | |||||
int PC = 71; | |||||
/** RegularExpression Id. */ | |||||
int IN = 72; | |||||
/** RegularExpression Id. */ | |||||
int PX = 73; | |||||
/** RegularExpression Id. */ | |||||
int EMS = 74; | |||||
/** RegularExpression Id. */ | |||||
int EXS = 75; | |||||
/** RegularExpression Id. */ | |||||
int DEG = 76; | |||||
/** RegularExpression Id. */ | |||||
int RAD = 77; | |||||
/** RegularExpression Id. */ | |||||
int GRAD = 78; | |||||
/** RegularExpression Id. */ | |||||
int MS = 79; | |||||
/** RegularExpression Id. */ | |||||
int SECOND = 80; | |||||
/** RegularExpression Id. */ | |||||
int HZ = 81; | |||||
/** RegularExpression Id. */ | |||||
int KHZ = 82; | |||||
/** RegularExpression Id. */ | |||||
int DIMEN = 83; | |||||
/** RegularExpression Id. */ | |||||
int HASH = 84; | |||||
/** RegularExpression Id. */ | |||||
int IMPORT_SYM = 85; | |||||
/** RegularExpression Id. */ | |||||
int MEDIA_SYM = 86; | |||||
/** RegularExpression Id. */ | |||||
int CHARSET_SYM = 87; | |||||
/** RegularExpression Id. */ | |||||
int PAGE_SYM = 88; | |||||
/** RegularExpression Id. */ | |||||
int FONT_FACE_SYM = 89; | |||||
/** RegularExpression Id. */ | |||||
int ATKEYWORD = 90; | |||||
/** RegularExpression Id. */ | |||||
int IMPORTANT_SYM = 91; | |||||
/** RegularExpression Id. */ | |||||
int RANGE0 = 92; | |||||
/** RegularExpression Id. */ | |||||
int RANGE1 = 93; | |||||
/** RegularExpression Id. */ | |||||
int RANGE2 = 94; | |||||
/** RegularExpression Id. */ | |||||
int RANGE3 = 95; | |||||
/** RegularExpression Id. */ | |||||
int RANGE4 = 96; | |||||
/** RegularExpression Id. */ | |||||
int RANGE5 = 97; | |||||
/** RegularExpression Id. */ | |||||
int RANGE6 = 98; | |||||
/** RegularExpression Id. */ | |||||
int RANGE = 99; | |||||
/** RegularExpression Id. */ | |||||
int UNI = 100; | |||||
/** RegularExpression Id. */ | |||||
int UNICODERANGE = 101; | |||||
/** RegularExpression Id. */ | |||||
int FUNCTION = 102; | |||||
/** RegularExpression Id. */ | |||||
int UNKNOWN = 103; | |||||
/** Lexical state. */ | |||||
int DEFAULT = 0; | |||||
/** Lexical state. */ | |||||
int IN_INTERPOLATION = 1; | |||||
/** Lexical state. */ | |||||
int IN_SINGLE_LINE_COMMENT = 2; | |||||
/** Lexical state. */ | |||||
int IN_FORMAL_COMMENT = 3; | |||||
/** Lexical state. */ | |||||
int IN_MULTI_LINE_COMMENT = 4; | |||||
/** Literal token values. */ | |||||
String[] tokenImage = { | |||||
"<EOF>", | |||||
"<S>", | |||||
"\"#{\"", | |||||
"<token of kind 3>", | |||||
"\"}\"", | |||||
"\"//\"", | |||||
"<token of kind 6>", | |||||
"<token of kind 7>", | |||||
"<token of kind 8>", | |||||
"\"/*\"", | |||||
"\"*/\"", | |||||
"\"*/\"", | |||||
"<token of kind 12>", | |||||
"\"<!--\"", | |||||
"\"-->\"", | |||||
"\"{\"", | |||||
"\"}\"", | |||||
"\"|=\"", | |||||
"\"~=\"", | |||||
"\"=\"", | |||||
"\"+\"", | |||||
"\"-\"", | |||||
"\",\"", | |||||
"\";\"", | |||||
"\">\"", | |||||
"\"/\"", | |||||
"\"[\"", | |||||
"\"]\"", | |||||
"\"*\"", | |||||
"\"&\"", | |||||
"\".\"", | |||||
"\"(\"", | |||||
"\")\"", | |||||
"\":\"", | |||||
"<NONASCII>", | |||||
"<H>", | |||||
"<UNICODE>", | |||||
"<ESCAPE>", | |||||
"<NMSTART>", | |||||
"<NMCHAR>", | |||||
"<STRINGCHAR>", | |||||
"<D>", | |||||
"<NAME>", | |||||
"\"to\"", | |||||
"\"through\"", | |||||
"\"in\"", | |||||
"\"@mixin\"", | |||||
"\"@include\"", | |||||
"\"@function\"", | |||||
"\"@return\"", | |||||
"\"@debug\"", | |||||
"\"@warn\"", | |||||
"\"@for\"", | |||||
"\"@each\"", | |||||
"\"@while\"", | |||||
"\"@if\"", | |||||
"\"@else\"", | |||||
"\"@extend\"", | |||||
"\"@-moz-document\"", | |||||
"\"@supports\"", | |||||
"<GUARDED_SYM>", | |||||
"<STRING>", | |||||
"<IDENT>", | |||||
"<NUMBER>", | |||||
"<_URL>", | |||||
"<URL>", | |||||
"<VARIABLE>", | |||||
"<PERCENTAGE>", | |||||
"<PT>", | |||||
"<MM>", | |||||
"<CM>", | |||||
"<PC>", | |||||
"<IN>", | |||||
"<PX>", | |||||
"<EMS>", | |||||
"<EXS>", | |||||
"<DEG>", | |||||
"<RAD>", | |||||
"<GRAD>", | |||||
"<MS>", | |||||
"<SECOND>", | |||||
"<HZ>", | |||||
"<KHZ>", | |||||
"<DIMEN>", | |||||
"<HASH>", | |||||
"\"@import\"", | |||||
"\"@media\"", | |||||
"\"@charset\"", | |||||
"\"@page\"", | |||||
"\"@font-face\"", | |||||
"<ATKEYWORD>", | |||||
"<IMPORTANT_SYM>", | |||||
"<RANGE0>", | |||||
"<RANGE1>", | |||||
"<RANGE2>", | |||||
"<RANGE3>", | |||||
"<RANGE4>", | |||||
"<RANGE5>", | |||||
"<RANGE6>", | |||||
"<RANGE>", | |||||
"<UNI>", | |||||
"<UNICODERANGE>", | |||||
"<FUNCTION>", | |||||
"<UNKNOWN>", | |||||
}; | |||||
} |
package com.vaadin.sass.parser; | |||||
import org.w3c.css.sac.LexicalUnit; | |||||
public interface SCSSLexicalUnit extends LexicalUnit { | |||||
static final short SCSS_VARIABLE = 100; | |||||
LexicalUnitImpl divide(LexicalUnitImpl denominator); | |||||
LexicalUnitImpl add(LexicalUnitImpl another); | |||||
LexicalUnitImpl minus(LexicalUnitImpl another); | |||||
LexicalUnitImpl multiply(LexicalUnitImpl another); | |||||
} |
/* | |||||
* Copyright (c) 1999 World Wide Web Consortium, | |||||
* (Massachusetts Institute of Technology, Institut National de | |||||
* Recherche en Informatique et en Automatique, Keio University). All | |||||
* Rights Reserved. This program is distributed under the W3C's Software | |||||
* Intellectual Property License. This program is distributed in the | |||||
* hope that it will be useful, but WITHOUT ANY WARRANTY; without even | |||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||||
* PURPOSE. | |||||
* See W3C License http://www.w3.org/Consortium/Legal/ for more details. | |||||
* | |||||
* $Id: SelectorListImpl.java,v 1.1 2000/08/07 01:16:21 plehegar Exp $ | |||||
*/ | |||||
package com.vaadin.sass.parser; | |||||
import org.w3c.css.sac.Selector; | |||||
import org.w3c.css.sac.SelectorList; | |||||
/** | |||||
* @version $Revision: 1.1 $ | |||||
* @author Philippe Le Hegaret | |||||
*/ | |||||
public class SelectorListImpl implements SelectorList { | |||||
Selector[] selectors = new Selector[5]; | |||||
int current; | |||||
@Override | |||||
public Selector item(int index) { | |||||
if ((index < 0) || (index >= current)) { | |||||
return null; | |||||
} | |||||
return selectors[index]; | |||||
} | |||||
public Selector itemSelector(int index) { | |||||
if ((index < 0) || (index >= current)) { | |||||
return null; | |||||
} | |||||
return selectors[index]; | |||||
} | |||||
@Override | |||||
public int getLength() { | |||||
return current; | |||||
} | |||||
public void addSelector(Selector selector) { | |||||
if (current == selectors.length) { | |||||
Selector[] old = selectors; | |||||
selectors = new Selector[old.length + old.length]; | |||||
System.arraycopy(old, 0, selectors, 0, old.length); | |||||
} | |||||
selectors[current++] = selector; | |||||
} | |||||
public void replaceSelector(int index, Selector selector) { | |||||
if ((index >= 0) && (index < current)) { | |||||
selectors[index] = selector; | |||||
} | |||||
} | |||||
} |
/* | |||||
* Copyright (c) 1999 World Wide Web Consortium, | |||||
* (Massachusetts Institute of Technology, Institut National de | |||||
* Recherche en Informatique et en Automatique, Keio University). All | |||||
* Rights Reserved. This program is distributed under the W3C's Software | |||||
* Intellectual Property License. This program is distributed in the | |||||
* hope that it will be useful, but WITHOUT ANY WARRANTY; without even | |||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |||||
* PURPOSE. | |||||
* See W3C License http://www.w3.org/Consortium/Legal/ for more details. | |||||
* | |||||
* $Id: Selectors.java,v 1.1 2000/02/14 16:58:31 plehegar Exp $ | |||||
*/ | |||||
package com.vaadin.sass.parser; | |||||
import org.w3c.css.sac.SelectorList; | |||||
import org.w3c.css.sac.Selector; | |||||
/** | |||||
* @version $Revision: 1.1 $ | |||||
* @author Philippe Le Hegaret | |||||
*/ | |||||
class Selectors implements SelectorList { | |||||
Selector[] selectors = new Selector[5]; | |||||
int current; | |||||
public Selector item(int index) { | |||||
if ((index < 0) || (index >= current)) { | |||||
return null; | |||||
} | |||||
return selectors[index]; | |||||
} | |||||
public Selector itemSelector(int index) { | |||||
if ((index < 0) || (index >= current)) { | |||||
return null; | |||||
} | |||||
return selectors[index]; | |||||
} | |||||
public int getLength() { | |||||
return current; | |||||
} | |||||
void addSelector(Selector selector) { | |||||
if (current == selectors.length) { | |||||
Selector[] old = selectors; | |||||
selectors = new Selector[old.length + old.length]; | |||||
System.arraycopy(old, 0, selectors, 0, old.length); | |||||
} | |||||
selectors[current++] = selector; | |||||
} | |||||
} |
/* | |||||
* (c) COPYRIGHT 1999 World Wide Web Consortium | |||||
* (Massachusetts Institute of Technology, Institut National de Recherche | |||||
* en Informatique et en Automatique, Keio University). | |||||
* All Rights Reserved. http://www.w3.org/Consortium/Legal/ | |||||
* | |||||
* $Id: ThrowedParseException.java,v 1.1 1999/06/09 15:21:33 plehegar Exp $ | |||||
*/ | |||||
package com.vaadin.sass.parser; | |||||
/** | |||||
* @version $Revision: 1.1 $ | |||||
* @author Philippe Le Hegaret | |||||
*/ | |||||
class ThrowedParseException extends RuntimeException { | |||||
private static final long serialVersionUID = -7926371344505913546L; | |||||
ParseException e; | |||||
/** | |||||
* Creates a new ThrowedParseException | |||||
*/ | |||||
ThrowedParseException(ParseException e) { | |||||
this.e = e; | |||||
} | |||||
} |
/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */ | |||||
/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ | |||||
package com.vaadin.sass.parser; | |||||
/** | |||||
* Describes the input token stream. | |||||
*/ | |||||
public class Token implements java.io.Serializable { | |||||
/** | |||||
* The version identifier for this Serializable class. | |||||
* Increment only if the <i>serialized</i> form of the | |||||
* class changes. | |||||
*/ | |||||
private static final long serialVersionUID = 1L; | |||||
/** | |||||
* An integer that describes the kind of this token. This numbering | |||||
* system is determined by JavaCCParser, and a table of these numbers is | |||||
* stored in the file ...Constants.java. | |||||
*/ | |||||
public int kind; | |||||
/** The line number of the first character of this Token. */ | |||||
public int beginLine; | |||||
/** The column number of the first character of this Token. */ | |||||
public int beginColumn; | |||||
/** The line number of the last character of this Token. */ | |||||
public int endLine; | |||||
/** The column number of the last character of this Token. */ | |||||
public int endColumn; | |||||
/** | |||||
* The string image of the token. | |||||
*/ | |||||
public String image; | |||||
/** | |||||
* A reference to the next regular (non-special) token from the input | |||||
* stream. If this is the last token from the input stream, or if the | |||||
* token manager has not read tokens beyond this one, this field is | |||||
* set to null. This is true only if this token is also a regular | |||||
* token. Otherwise, see below for a description of the contents of | |||||
* this field. | |||||
*/ | |||||
public Token next; | |||||
/** | |||||
* This field is used to access special tokens that occur prior to this | |||||
* token, but after the immediately preceding regular (non-special) token. | |||||
* If there are no such special tokens, this field is set to null. | |||||
* When there are more than one such special token, this field refers | |||||
* to the last of these special tokens, which in turn refers to the next | |||||
* previous special token through its specialToken field, and so on | |||||
* until the first special token (whose specialToken field is null). | |||||
* The next fields of special tokens refer to other special tokens that | |||||
* immediately follow it (without an intervening regular token). If there | |||||
* is no such token, this field is null. | |||||
*/ | |||||
public Token specialToken; | |||||
/** | |||||
* An optional attribute value of the Token. | |||||
* Tokens which are not used as syntactic sugar will often contain | |||||
* meaningful values that will be used later on by the compiler or | |||||
* interpreter. This attribute value is often different from the image. | |||||
* Any subclass of Token that actually wants to return a non-null value can | |||||
* override this method as appropriate. | |||||
*/ | |||||
public Object getValue() { | |||||
return null; | |||||
} | |||||
/** | |||||
* No-argument constructor | |||||
*/ | |||||
public Token() {} | |||||
/** | |||||
* Constructs a new token for the specified Image. | |||||
*/ | |||||
public Token(int kind) | |||||
{ | |||||
this(kind, null); | |||||
} | |||||
/** | |||||
* Constructs a new token for the specified Image and Kind. | |||||
*/ | |||||
public Token(int kind, String image) | |||||
{ | |||||
this.kind = kind; | |||||
this.image = image; | |||||
} | |||||
/** | |||||
* Returns the image. | |||||
*/ | |||||
public String toString() | |||||
{ | |||||
return image; | |||||
} | |||||
/** | |||||
* Returns a new Token object, by default. However, if you want, you | |||||
* can create and return subclass objects based on the value of ofKind. | |||||
* Simply add the cases to the switch for all those special cases. | |||||
* For example, if you have a subclass of Token called IDToken that | |||||
* you want to create if ofKind is ID, simply add something like : | |||||
* | |||||
* case MyParserConstants.ID : return new IDToken(ofKind, image); | |||||
* | |||||
* to the following switch statement. Then you can cast matchedToken | |||||
* variable to the appropriate type and use sit in your lexical actions. | |||||
*/ | |||||
public static Token newToken(int ofKind, String image) | |||||
{ | |||||
switch(ofKind) | |||||
{ | |||||
default : return new Token(ofKind, image); | |||||
} | |||||
} | |||||
public static Token newToken(int ofKind) | |||||
{ | |||||
return newToken(ofKind, null); | |||||
} | |||||
} | |||||
/* JavaCC - OriginalChecksum=fd921a11cd37e391729b9460c71d3ad6 (do not edit this line) */ |
/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */ | |||||
/* JavaCCOptions: */ | |||||
package com.vaadin.sass.parser; | |||||
/** Token Manager Error. */ | |||||
public class TokenMgrError extends Error | |||||
{ | |||||
/** | |||||
* The version identifier for this Serializable class. | |||||
* Increment only if the <i>serialized</i> form of the | |||||
* class changes. | |||||
*/ | |||||
private static final long serialVersionUID = 1L; | |||||
/* | |||||
* Ordinals for various reasons why an Error of this type can be thrown. | |||||
*/ | |||||
/** | |||||
* Lexical error occurred. | |||||
*/ | |||||
static final int LEXICAL_ERROR = 0; | |||||
/** | |||||
* An attempt was made to create a second instance of a static token manager. | |||||
*/ | |||||
static final int STATIC_LEXER_ERROR = 1; | |||||
/** | |||||
* Tried to change to an invalid lexical state. | |||||
*/ | |||||
static final int INVALID_LEXICAL_STATE = 2; | |||||
/** | |||||
* Detected (and bailed out of) an infinite loop in the token manager. | |||||
*/ | |||||
static final int LOOP_DETECTED = 3; | |||||
/** | |||||
* Indicates the reason why the exception is thrown. It will have | |||||
* one of the above 4 values. | |||||
*/ | |||||
int errorCode; | |||||
/** | |||||
* Replaces unprintable characters by their escaped (or unicode escaped) | |||||
* equivalents in the given string | |||||
*/ | |||||
protected static final String addEscapes(String str) { | |||||
StringBuffer retval = new StringBuffer(); | |||||
char ch; | |||||
for (int i = 0; i < str.length(); i++) { | |||||
switch (str.charAt(i)) | |||||
{ | |||||
case 0 : | |||||
continue; | |||||
case '\b': | |||||
retval.append("\\b"); | |||||
continue; | |||||
case '\t': | |||||
retval.append("\\t"); | |||||
continue; | |||||
case '\n': | |||||
retval.append("\\n"); | |||||
continue; | |||||
case '\f': | |||||
retval.append("\\f"); | |||||
continue; | |||||
case '\r': | |||||
retval.append("\\r"); | |||||
continue; | |||||
case '\"': | |||||
retval.append("\\\""); | |||||
continue; | |||||
case '\'': | |||||
retval.append("\\\'"); | |||||
continue; | |||||
case '\\': | |||||
retval.append("\\\\"); | |||||
continue; | |||||
default: | |||||
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { | |||||
String s = "0000" + Integer.toString(ch, 16); | |||||
retval.append("\\u" + s.substring(s.length() - 4, s.length())); | |||||
} else { | |||||
retval.append(ch); | |||||
} | |||||
continue; | |||||
} | |||||
} | |||||
return retval.toString(); | |||||
} | |||||
/** | |||||
* Returns a detailed message for the Error when it is thrown by the | |||||
* token manager to indicate a lexical error. | |||||
* Parameters : | |||||
* EOFSeen : indicates if EOF caused the lexical error | |||||
* curLexState : lexical state in which this error occurred | |||||
* errorLine : line number when the error occurred | |||||
* errorColumn : column number when the error occurred | |||||
* errorAfter : prefix that was seen before this error occurred | |||||
* curchar : the offending character | |||||
* Note: You can customize the lexical error message by modifying this method. | |||||
*/ | |||||
protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { | |||||
return("Lexical error at line " + | |||||
errorLine + ", column " + | |||||
errorColumn + ". Encountered: " + | |||||
(EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") + | |||||
"after : \"" + addEscapes(errorAfter) + "\""); | |||||
} | |||||
/** | |||||
* You can also modify the body of this method to customize your error messages. | |||||
* For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not | |||||
* of end-users concern, so you can return something like : | |||||
* | |||||
* "Internal Error : Please file a bug report .... " | |||||
* | |||||
* from this method for such cases in the release version of your parser. | |||||
*/ | |||||
public String getMessage() { | |||||
return super.getMessage(); | |||||
} | |||||
/* | |||||
* Constructors of various flavors follow. | |||||
*/ | |||||
/** No arg constructor. */ | |||||
public TokenMgrError() { | |||||
} | |||||
/** Constructor with message and reason. */ | |||||
public TokenMgrError(String message, int reason) { | |||||
super(message); | |||||
errorCode = reason; | |||||
} | |||||
/** Full Constructor. */ | |||||
public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { | |||||
this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); | |||||
} | |||||
} | |||||
/* JavaCC - OriginalChecksum=7d5524d89510a94f7c2ac022e99c24c3 (do not edit this line) */ |
package com.vaadin.sass.selector; | |||||
import org.w3c.css.sac.Selector; | |||||
public class CompositeSelector implements Selector { | |||||
public static final short SCSS_COMPOSITE_SELECTOR = 100; | |||||
private Selector first; | |||||
private Selector second; | |||||
public CompositeSelector(Selector first, Selector second) { | |||||
this.first = first; | |||||
this.second = second; | |||||
} | |||||
public Selector getFirst() { | |||||
return first; | |||||
} | |||||
public Selector getSecond() { | |||||
return second; | |||||
} | |||||
@Override | |||||
public short getSelectorType() { | |||||
return SCSS_COMPOSITE_SELECTOR; | |||||
} | |||||
} |
package com.vaadin.sass.selector; | |||||
import org.w3c.css.sac.CombinatorCondition; | |||||
import org.w3c.css.sac.Condition; | |||||
import org.w3c.css.sac.ConditionFactory; | |||||
import org.w3c.css.sac.ConditionalSelector; | |||||
import org.w3c.css.sac.DescendantSelector; | |||||
import org.w3c.css.sac.ElementSelector; | |||||
import org.w3c.css.sac.Selector; | |||||
import org.w3c.css.sac.SelectorFactory; | |||||
import org.w3c.css.sac.SelectorList; | |||||
import org.w3c.css.sac.SiblingSelector; | |||||
import org.w3c.css.sac.SimpleSelector; | |||||
import org.w3c.flute.parser.selectors.AndConditionImpl; | |||||
import org.w3c.flute.parser.selectors.AttributeConditionImpl; | |||||
import org.w3c.flute.parser.selectors.ClassConditionImpl; | |||||
import org.w3c.flute.parser.selectors.ConditionFactoryImpl; | |||||
import org.w3c.flute.parser.selectors.DirectAdjacentSelectorImpl; | |||||
import org.w3c.flute.parser.selectors.ElementSelectorImpl; | |||||
import org.w3c.flute.parser.selectors.IdConditionImpl; | |||||
import org.w3c.flute.parser.selectors.PseudoClassConditionImpl; | |||||
import org.w3c.flute.parser.selectors.PseudoElementSelectorImpl; | |||||
import org.w3c.flute.parser.selectors.SelectorFactoryImpl; | |||||
import com.vaadin.sass.parser.SelectorListImpl; | |||||
public class SelectorUtil { | |||||
public static String toString(CompositeSelector compositeSelector) { | |||||
StringBuilder builder = new StringBuilder(); | |||||
if (compositeSelector != null) { | |||||
if (compositeSelector.getFirst() != null) { | |||||
builder.append(toString(compositeSelector.getFirst())).append( | |||||
" "); | |||||
} | |||||
if (compositeSelector.getSecond() != null) { | |||||
builder.append(toString(compositeSelector.getSecond())); | |||||
} | |||||
} | |||||
return builder.toString(); | |||||
} | |||||
public static String toString(SelectorList selectorList) { | |||||
StringBuilder stringBuilder = new StringBuilder(); | |||||
for (int i = 0; i < selectorList.getLength(); i++) { | |||||
String selectorString = toString(selectorList.item(i)); | |||||
stringBuilder.append(selectorString); | |||||
if (selectorList.getLength() > i + 1) { | |||||
stringBuilder.append(", "); | |||||
} | |||||
} | |||||
return stringBuilder.toString(); | |||||
} | |||||
public static String toString(Selector selector) { | |||||
if (selector == null) { | |||||
return ""; | |||||
} | |||||
if (selector.getSelectorType() == Selector.SAC_CONDITIONAL_SELECTOR) { | |||||
StringBuilder stringBuilder = new StringBuilder(); | |||||
ConditionalSelector conditionalSelector = (ConditionalSelector) selector; | |||||
String simpleSelectorString = toString(conditionalSelector | |||||
.getSimpleSelector()); | |||||
if (simpleSelectorString != null) { | |||||
stringBuilder.append(simpleSelectorString); | |||||
} | |||||
String conditionString = getConditionString(conditionalSelector | |||||
.getCondition()); | |||||
stringBuilder.append(conditionString); | |||||
return stringBuilder.toString(); | |||||
} else if (selector.getSelectorType() == Selector.SAC_DESCENDANT_SELECTOR) { | |||||
return getDecendantSelectorString((DescendantSelector) selector, | |||||
" "); | |||||
} else if (selector.getSelectorType() == Selector.SAC_CHILD_SELECTOR) { | |||||
DescendantSelector childSelector = (DescendantSelector) selector; | |||||
String seperator = " > "; | |||||
if (childSelector.getSimpleSelector() instanceof PseudoElementSelectorImpl) { | |||||
seperator = "::"; | |||||
} | |||||
return getDecendantSelectorString((DescendantSelector) selector, | |||||
seperator); | |||||
} else if (selector.getSelectorType() == Selector.SAC_ELEMENT_NODE_SELECTOR) { | |||||
ElementSelectorImpl elementSelector = (ElementSelectorImpl) selector; | |||||
return elementSelector.getLocalName() == null ? "" | |||||
: elementSelector.getLocalName(); | |||||
} else if (selector.getSelectorType() == Selector.SAC_DIRECT_ADJACENT_SELECTOR) { | |||||
DirectAdjacentSelectorImpl directAdjacentSelector = (DirectAdjacentSelectorImpl) selector; | |||||
StringBuilder stringBuilder = new StringBuilder(); | |||||
stringBuilder | |||||
.append(toString(directAdjacentSelector.getSelector())); | |||||
stringBuilder.append(" + "); | |||||
stringBuilder.append(toString(directAdjacentSelector | |||||
.getSiblingSelector())); | |||||
return stringBuilder.toString(); | |||||
} else if (selector.getSelectorType() == Selector.SAC_PSEUDO_ELEMENT_SELECTOR) { | |||||
PseudoElementSelectorImpl pseudoElementSelectorImpl = (PseudoElementSelectorImpl) selector; | |||||
return pseudoElementSelectorImpl.getLocalName(); | |||||
} else if (selector.getSelectorType() == CompositeSelector.SCSS_COMPOSITE_SELECTOR) { | |||||
return toString((CompositeSelector) selector); | |||||
} else { | |||||
System.out.println("SU !Unknown selector type, type: " | |||||
+ selector.getSelectorType() + ", " + selector.toString()); | |||||
} | |||||
return ""; | |||||
} | |||||
private static String getDecendantSelectorString( | |||||
DescendantSelector selector, String separator) { | |||||
StringBuilder stringBuilder = new StringBuilder(); | |||||
String ancestor = toString(selector.getAncestorSelector()); | |||||
String simpleSelector = toString(selector.getSimpleSelector()); | |||||
stringBuilder.append(ancestor); | |||||
stringBuilder.append(separator); | |||||
stringBuilder.append(simpleSelector); | |||||
return stringBuilder.toString(); | |||||
} | |||||
private static String getConditionString(Condition condition) { | |||||
short conditionType = condition.getConditionType(); | |||||
if (conditionType == Condition.SAC_CLASS_CONDITION) { | |||||
ClassConditionImpl classCondition = (ClassConditionImpl) condition; | |||||
return "." + classCondition.getValue(); | |||||
} else if (conditionType == Condition.SAC_ID_CONDITION) { | |||||
IdConditionImpl idCondition = (IdConditionImpl) condition; | |||||
return "#" + idCondition.getValue(); | |||||
} else if (conditionType == Condition.SAC_AND_CONDITION) { | |||||
AndConditionImpl andCondition = (AndConditionImpl) condition; | |||||
return getConditionString(andCondition.getFirstCondition()) | |||||
+ getConditionString(andCondition.getSecondCondition()); | |||||
} else if (conditionType == Condition.SAC_ATTRIBUTE_CONDITION) { | |||||
AttributeConditionImpl attributeCondition = (AttributeConditionImpl) condition; | |||||
StringBuilder string = new StringBuilder(); | |||||
string.append('['); | |||||
string.append(attributeCondition.getLocalName()); | |||||
String value = attributeCondition.getValue(); | |||||
if ("true".equals(value) || "false".equals(value)) { | |||||
string.append("=").append(value).append(']'); | |||||
} else { | |||||
string.append("=\""); | |||||
string.append(attributeCondition.getValue()); | |||||
string.append("\"]"); | |||||
} | |||||
return string.toString(); | |||||
} else if (conditionType == Condition.SAC_PSEUDO_CLASS_CONDITION) { | |||||
PseudoClassConditionImpl pseudoClassCondition = (PseudoClassConditionImpl) condition; | |||||
return ":" + pseudoClassCondition.getValue(); | |||||
} else { | |||||
System.out.println("CU !condition type not identified, type: " | |||||
+ conditionType + ", " + condition.toString()); | |||||
return ""; | |||||
} | |||||
} | |||||
public static boolean hasParentSelector(SelectorList selectorList) { | |||||
String selectorString = toString(selectorList); | |||||
return selectorString.contains("&"); | |||||
} | |||||
public static SelectorList createNewSelectorListFromAnOldOneWithSomPartReplaced( | |||||
SelectorList oldList, String toBeReplacedSelectorName, | |||||
SelectorList candidateSelectorList) throws Exception { | |||||
if (candidateSelectorList.getLength() != 1) { | |||||
throw new Exception("Candidate selector should not be a list"); | |||||
} | |||||
if (!(candidateSelectorList.item(0) instanceof SimpleSelector)) { | |||||
throw new Exception( | |||||
"Candidate selector should only be a SimpleSelector"); | |||||
} | |||||
SelectorListImpl newSelectorList = new SelectorListImpl(); | |||||
SimpleSelector candidateSelector = (SimpleSelector) candidateSelectorList | |||||
.item(0); | |||||
for (int i = 0; i < oldList.getLength(); i++) { | |||||
Selector selector = oldList.item(i); | |||||
newSelectorList.addSelector(createSelectorWithSomePartReplaced( | |||||
selector, toBeReplacedSelectorName, candidateSelector)); | |||||
} | |||||
return newSelectorList; | |||||
} | |||||
private static Selector createSelectorWithSomePartReplaced( | |||||
Selector selector, String toBeReplacedSelectorName, | |||||
SimpleSelector candidateSelector) { | |||||
if (!toString(selector).contains(toBeReplacedSelectorName)) { | |||||
return selector; | |||||
} | |||||
SelectorFactory factory = new SelectorFactoryImpl(); | |||||
if (selector instanceof SimpleSelector) { | |||||
return createSimpleSelectorWithSomePartReplaced( | |||||
(SimpleSelector) selector, toBeReplacedSelectorName, | |||||
candidateSelector); | |||||
} else if (selector instanceof DescendantSelector) { | |||||
DescendantSelector descendantSelector = (DescendantSelector) selector; | |||||
Selector ancestor = descendantSelector.getAncestorSelector(); | |||||
SimpleSelector simpleSelector = descendantSelector | |||||
.getSimpleSelector(); | |||||
return factory.createDescendantSelector( | |||||
createSelectorWithSomePartReplaced(ancestor, | |||||
toBeReplacedSelectorName, candidateSelector), | |||||
createSimpleSelectorWithSomePartReplaced(simpleSelector, | |||||
toBeReplacedSelectorName, candidateSelector)); | |||||
} else if (selector instanceof DirectAdjacentSelectorImpl) { | |||||
SiblingSelector siblingSelector = (SiblingSelector) selector; | |||||
Selector ancestor = siblingSelector.getSelector(); | |||||
SimpleSelector simpleSelector = siblingSelector | |||||
.getSiblingSelector(); | |||||
return factory.createDirectAdjacentSelector( | |||||
Selector.SAC_DIRECT_ADJACENT_SELECTOR, ancestor, | |||||
simpleSelector); | |||||
} else if (selector instanceof CompositeSelector) { | |||||
CompositeSelector compositeSelector = (CompositeSelector) selector; | |||||
Selector first = compositeSelector.getFirst(); | |||||
Selector second = compositeSelector.getSecond(); | |||||
return new CompositeSelector(createSelectorWithSomePartReplaced( | |||||
first, toBeReplacedSelectorName, candidateSelector), | |||||
createSelectorWithSomePartReplaced(second, | |||||
toBeReplacedSelectorName, candidateSelector)); | |||||
} | |||||
return null; | |||||
} | |||||
private static SimpleSelector createSimpleSelectorWithSomePartReplaced( | |||||
SimpleSelector simpleSelector, String toBeReplacedSelectorName, | |||||
SimpleSelector candidateSelector) { | |||||
if (simpleSelector == null | |||||
|| !toString(simpleSelector).contains(toBeReplacedSelectorName)) { | |||||
return simpleSelector; | |||||
} | |||||
if (simpleSelector instanceof ElementSelector | |||||
&& candidateSelector instanceof ElementSelector) { | |||||
return candidateSelector; | |||||
} | |||||
if (simpleSelector instanceof ConditionalSelector) { | |||||
return createConditionSelectorWithSomePartReplaced( | |||||
(ConditionalSelector) simpleSelector, | |||||
toBeReplacedSelectorName, candidateSelector); | |||||
} | |||||
return simpleSelector; | |||||
} | |||||
private static ConditionalSelector createConditionSelectorWithSomePartReplaced( | |||||
ConditionalSelector oldConditionSelector, | |||||
String toBeReplacedSelectorName, SimpleSelector candidateSelector) { | |||||
if (oldConditionSelector == null | |||||
|| !toString(oldConditionSelector).contains( | |||||
toBeReplacedSelectorName)) { | |||||
return oldConditionSelector; | |||||
} | |||||
SelectorFactory selectorFactory = new SelectorFactoryImpl(); | |||||
if (candidateSelector instanceof ElementSelector) { | |||||
return selectorFactory.createConditionalSelector(candidateSelector, | |||||
oldConditionSelector.getCondition()); | |||||
} | |||||
if (candidateSelector instanceof ConditionalSelector) { | |||||
// TODO some cases not covered. | |||||
ConditionalSelector candidateConditionSelector = (ConditionalSelector) candidateSelector; | |||||
Condition newCondition = createConditionWithSomePartReplaced( | |||||
oldConditionSelector.getCondition(), | |||||
toBeReplacedSelectorName, | |||||
candidateConditionSelector.getCondition()); | |||||
return selectorFactory.createConditionalSelector( | |||||
oldConditionSelector.getSimpleSelector(), newCondition); | |||||
} | |||||
return oldConditionSelector; | |||||
} | |||||
private static Condition createConditionWithSomePartReplaced( | |||||
Condition oldCondition, String toBeReplaced, Condition candidate) { | |||||
if (oldCondition == null | |||||
|| !getConditionString(oldCondition).contains(toBeReplaced)) { | |||||
return oldCondition; | |||||
} | |||||
if (oldCondition.getConditionType() == Condition.SAC_AND_CONDITION) { | |||||
ConditionFactory conditionFactory = new ConditionFactoryImpl(); | |||||
CombinatorCondition oldCombinatorCondition = (CombinatorCondition) oldCondition; | |||||
Condition newFirstCondition = createConditionWithSomePartReplaced( | |||||
oldCombinatorCondition.getFirstCondition(), toBeReplaced, | |||||
candidate); | |||||
Condition newSecondCondition = createConditionWithSomePartReplaced( | |||||
oldCombinatorCondition.getSecondCondition(), toBeReplaced, | |||||
candidate); | |||||
return conditionFactory.createAndCondition(newFirstCondition, | |||||
newSecondCondition); | |||||
} else { | |||||
return candidate; | |||||
} | |||||
} | |||||
public static boolean equals(Selector one, Selector another) { | |||||
return one == null ? another == null : toString(one).equals( | |||||
toString(another)); | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
import org.w3c.css.sac.SelectorList; | |||||
import com.vaadin.sass.parser.SelectorListImpl; | |||||
import com.vaadin.sass.selector.SelectorUtil; | |||||
public class BlockNode extends Node { | |||||
private static final long serialVersionUID = 5742962631468325048L; | |||||
SelectorList selectorList; | |||||
public BlockNode(SelectorList selectorList) { | |||||
this.selectorList = selectorList; | |||||
} | |||||
public SelectorList getSelectorList() { | |||||
return selectorList; | |||||
} | |||||
public void setSelectorList(SelectorList selectorList) { | |||||
this.selectorList = selectorList; | |||||
} | |||||
public String toString(boolean indent) { | |||||
StringBuilder string = new StringBuilder(); | |||||
string.append(SelectorUtil.toString(selectorList)); | |||||
string.append(" {\n"); | |||||
for (Node child : children) { | |||||
if (indent) { | |||||
string.append("\t"); | |||||
} | |||||
string.append("\t" + child.toString() + "\n"); | |||||
} | |||||
if (indent) { | |||||
string.append("\t"); | |||||
} | |||||
string.append("}"); | |||||
return string.toString(); | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return toString(false); | |||||
} | |||||
@Override | |||||
protected Object clone() throws CloneNotSupportedException { | |||||
SelectorListImpl clonedSelectorList = new SelectorListImpl(); | |||||
for (int i = 0; i < selectorList.getLength(); i++) { | |||||
clonedSelectorList.addSelector(selectorList.item(i)); | |||||
} | |||||
return null; | |||||
// BlockNode clone = new BlockNode() | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
public class EachNode extends Node { | |||||
private static final long serialVersionUID = 7943948981204906221L; | |||||
private String var; | |||||
private String list; | |||||
private String body; | |||||
public EachNode(String var, String list, String body) { | |||||
super(); | |||||
this.var = var; | |||||
this.list = list; | |||||
this.body = body; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "Each Node: {variable: " + var + ", list: " + list + ", body: " | |||||
+ body + "}"; | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
import org.w3c.css.sac.SelectorList; | |||||
public class ExtendNode extends Node { | |||||
private static final long serialVersionUID = 3301805078983796878L; | |||||
SelectorList list; | |||||
public ExtendNode(SelectorList list) { | |||||
super(); | |||||
this.list = list; | |||||
} | |||||
public SelectorList getList() { | |||||
return list; | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
public class ForNode extends Node { | |||||
private static final long serialVersionUID = -1159180539216623335L; | |||||
String var; | |||||
String from; | |||||
String to; | |||||
boolean exclusive; | |||||
String body; | |||||
public ForNode(String var, String from, String to, boolean exclusive, | |||||
String body) { | |||||
super(); | |||||
this.var = var; | |||||
this.from = from; | |||||
this.to = to; | |||||
this.exclusive = exclusive; | |||||
this.body = body; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "For Node: " + "{variable: " + var + ", from:" + from + ", to: " | |||||
+ to + ", exclusive: " + exclusive + ", body" + body; | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
public class FunctionNode extends Node { | |||||
private static final long serialVersionUID = -5383104165955523923L; | |||||
private String name; | |||||
private String args; | |||||
private String body; | |||||
public FunctionNode(String name) { | |||||
super(); | |||||
this.name = name; | |||||
} | |||||
public FunctionNode(String name, String args, String body) { | |||||
this.name = name; | |||||
this.args = args; | |||||
this.body = body; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "Function Node: {name: " + name + ", args: " + args + ", body: " | |||||
+ body + "}"; | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
public class IfNode extends Node { | |||||
private static final long serialVersionUID = 1561250630856748066L; | |||||
} |
package com.vaadin.sass.tree; | |||||
import org.w3c.css.sac.SACMediaList; | |||||
public class ImportNode extends Node { | |||||
private static final long serialVersionUID = 5671255892282668438L; | |||||
private String uri; | |||||
private SACMediaList ml; | |||||
private boolean isURL; | |||||
public ImportNode(String uri, SACMediaList ml, boolean isURL) { | |||||
super(); | |||||
this.uri = uri; | |||||
this.ml = ml; | |||||
this.isURL = isURL; | |||||
} | |||||
public boolean isPureCssImport() { | |||||
return (isURL || uri.endsWith(".css") || uri.startsWith("http://") || hasMediaQueries()); | |||||
} | |||||
private boolean hasMediaQueries() { | |||||
return (ml != null && ml.getLength() >= 1 && !"all".equals(ml.item(0))); | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
StringBuilder builder = new StringBuilder("@import "); | |||||
if (isURL) { | |||||
builder.append("url(").append(uri).append(")"); | |||||
} else { | |||||
builder.append("\"").append(uri).append("\""); | |||||
} | |||||
if (hasMediaQueries()) { | |||||
for (int i = 0; i < ml.getLength(); i++) { | |||||
builder.append(" ").append(ml.item(i)); | |||||
} | |||||
} | |||||
builder.append(";"); | |||||
return builder.toString(); | |||||
} | |||||
public String getUri() { | |||||
return uri; | |||||
} | |||||
public void setUri(String uri) { | |||||
this.uri = uri; | |||||
} | |||||
public SACMediaList getMl() { | |||||
return ml; | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
import org.w3c.css.sac.SACMediaList; | |||||
public class MediaNode extends Node { | |||||
private static final long serialVersionUID = 2502097081457509523L; | |||||
SACMediaList media; | |||||
public MediaNode(SACMediaList media) { | |||||
super(); | |||||
this.media = media; | |||||
} | |||||
public SACMediaList getMedia() { | |||||
return media; | |||||
} | |||||
public void setMedia(SACMediaList media) { | |||||
this.media = media; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
StringBuilder builder = new StringBuilder("@media "); | |||||
if (media != null) { | |||||
for (int i = 0; i < media.getLength(); i++) { | |||||
builder.append(media.item(i)); | |||||
} | |||||
} | |||||
builder.append(" {\n"); | |||||
for (Node child : children) { | |||||
if (child instanceof BlockNode) { | |||||
builder.append("\t" + ((BlockNode) child).toString(true) + "\n"); | |||||
} else { | |||||
builder.append("\t" + child.toString() + "\n"); | |||||
} | |||||
} | |||||
builder.append("}"); | |||||
return builder.toString(); | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
import java.util.ArrayList; | |||||
import java.util.Collection; | |||||
public class MixinDefNode extends Node { | |||||
private static final long serialVersionUID = 5469294053247343948L; | |||||
private String name; | |||||
private ArrayList<VariableNode> arglist; | |||||
private String args; | |||||
private String body; | |||||
public MixinDefNode(String name, Collection<VariableNode> args) { | |||||
super(); | |||||
this.name = name; | |||||
arglist = new ArrayList<VariableNode>(); | |||||
if (args != null && !args.isEmpty()) { | |||||
arglist.addAll(args); | |||||
} | |||||
} | |||||
public MixinDefNode(String name, String args, String body) { | |||||
this.name = name; | |||||
this.args = args; | |||||
this.body = body; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "Mixin Definition Node: {name: " + name + ", args: " + args | |||||
+ ", body: " + body + "}"; | |||||
} | |||||
public String getName() { | |||||
return name; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public ArrayList<VariableNode> getArglist() { | |||||
return arglist; | |||||
} | |||||
public void setArglist(ArrayList<VariableNode> arglist) { | |||||
this.arglist = arglist; | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
import java.util.ArrayList; | |||||
import java.util.Collection; | |||||
import org.w3c.css.sac.LexicalUnit; | |||||
public class MixinNode extends Node { | |||||
private static final long serialVersionUID = 4725008226813110658L; | |||||
private String name; | |||||
private ArrayList<LexicalUnit> arglist; | |||||
public MixinNode(String name, Collection<LexicalUnit> args) { | |||||
super(); | |||||
this.name = name; | |||||
arglist = new ArrayList<LexicalUnit>(); | |||||
if (args != null && !args.isEmpty()) { | |||||
arglist.addAll(args); | |||||
} | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "name: " + name + " args: " + arglist; | |||||
} | |||||
public String getName() { | |||||
return name; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public ArrayList<LexicalUnit> getArglist() { | |||||
return arglist; | |||||
} | |||||
public void setArglist(ArrayList<LexicalUnit> arglist) { | |||||
this.arglist = arglist; | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
import java.util.ArrayList; | |||||
import java.util.Collection; | |||||
import java.util.List; | |||||
public class NestPropertiesNode extends Node { | |||||
private static final long serialVersionUID = 3671253315690598308L; | |||||
public NestPropertiesNode(String name) { | |||||
super(); | |||||
this.name = name; | |||||
} | |||||
private String name; | |||||
public String getName() { | |||||
return name; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public Collection<RuleNode> unNesting() { | |||||
List<RuleNode> result = new ArrayList<RuleNode>(); | |||||
for (Node child : children) { | |||||
result.add(createNewRuleNodeFromChild((RuleNode) child)); | |||||
} | |||||
return result; | |||||
} | |||||
public RuleNode createNewRuleNodeFromChild(RuleNode child) { | |||||
StringBuilder builder = new StringBuilder(name); | |||||
builder.append("-").append(child.getVariable()); | |||||
RuleNode newRuleNode = new RuleNode(builder.toString(), | |||||
child.getValue(), child.isImportant(), null); | |||||
return newRuleNode; | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
import java.io.Serializable; | |||||
import java.util.ArrayList; | |||||
import java.util.Collection; | |||||
import java.util.List; | |||||
public abstract class Node implements Serializable { | |||||
private static final long serialVersionUID = 5914711715839294816L; | |||||
protected ArrayList<Node> children; | |||||
private String fileName; | |||||
protected String rawString; | |||||
protected List<String> variables; | |||||
public Node() { | |||||
children = new ArrayList<Node>(); | |||||
variables = new ArrayList<String>(); | |||||
} | |||||
public Node(String raw) { | |||||
this(); | |||||
rawString = raw; | |||||
} | |||||
public void appendAll(Collection<Node> nodes) { | |||||
if (nodes != null && !nodes.isEmpty()) { | |||||
children.addAll(nodes); | |||||
} | |||||
} | |||||
public void appendChild(Node node) { | |||||
if (node != null) { | |||||
children.add(node); | |||||
} | |||||
} | |||||
public void appendChild(Node node, Node after) { | |||||
if (node != null) { | |||||
int index = children.indexOf(after); | |||||
if (index != -1) { | |||||
children.add(index + 1, node); | |||||
} else { | |||||
throw new NullPointerException("after-node was not found"); | |||||
} | |||||
} | |||||
} | |||||
public void removeChild(Node node) { | |||||
if (node != null) { | |||||
children.remove(node); | |||||
} | |||||
} | |||||
public ArrayList<Node> getChildren() { | |||||
return children; | |||||
} | |||||
public void setChildren(ArrayList<Node> children) { | |||||
this.children = children; | |||||
} | |||||
public boolean hasChildren() { | |||||
return !children.isEmpty(); | |||||
} | |||||
public void setFileName(String fileName) { | |||||
this.fileName = fileName; | |||||
} | |||||
public String getFileName() { | |||||
return fileName; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return ""; | |||||
} | |||||
public String getRawString() { | |||||
return rawString; | |||||
} | |||||
public void addVariable(String var) { | |||||
variables.add(var); | |||||
} | |||||
public void removeVariable(String var) { | |||||
variables.remove(var); | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
import org.w3c.css.sac.LexicalUnit; | |||||
public class RuleNode extends Node { | |||||
private static final long serialVersionUID = 6653493127869037022L; | |||||
String variable; | |||||
LexicalUnit value; | |||||
String comment; | |||||
private boolean important; | |||||
public RuleNode(String variable, LexicalUnit value, boolean important, | |||||
String comment) { | |||||
this.variable = variable; | |||||
this.value = value; | |||||
this.important = important; | |||||
this.comment = comment; | |||||
} | |||||
public String getVariable() { | |||||
return variable; | |||||
} | |||||
public void setVariable(String variable) { | |||||
this.variable = variable; | |||||
} | |||||
public LexicalUnit getValue() { | |||||
return value; | |||||
} | |||||
public void setValue(LexicalUnit value) { | |||||
this.value = value; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
StringBuilder builder = new StringBuilder(); | |||||
builder.append(variable).append(": ").append(value.toString()); | |||||
builder.append(important ? " !important;" : ";"); | |||||
if (comment != null) { | |||||
builder.append(comment); | |||||
} | |||||
return builder.toString(); | |||||
} | |||||
public boolean isImportant() { | |||||
return important; | |||||
} | |||||
public void setImportant(boolean important) { | |||||
this.important = important; | |||||
} | |||||
public String getComment() { | |||||
return comment; | |||||
} | |||||
public void setComment(String comment) { | |||||
this.comment = comment; | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
import org.w3c.css.sac.LexicalUnit; | |||||
public class VariableNode extends Node { | |||||
private static final long serialVersionUID = 7003372557547748734L; | |||||
private String name; | |||||
private LexicalUnit expr; | |||||
private boolean guarded; | |||||
public VariableNode(String name, LexicalUnit expr, boolean guarded) { | |||||
super(); | |||||
this.name = name; | |||||
this.expr = expr; | |||||
this.guarded = guarded; | |||||
} | |||||
public VariableNode(String name, String raw) { | |||||
super(raw); | |||||
this.name = name; | |||||
} | |||||
public LexicalUnit getExpr() { | |||||
return expr; | |||||
} | |||||
public void setExpr(LexicalUnit expr) { | |||||
this.expr = expr; | |||||
} | |||||
public String getName() { | |||||
return name; | |||||
} | |||||
public boolean isGuarded() { | |||||
return guarded; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
StringBuilder builder = new StringBuilder("$"); | |||||
builder.append(name).append(": ").append(expr); | |||||
return builder.toString(); | |||||
} | |||||
public void setGuarded(boolean guarded) { | |||||
this.guarded = guarded; | |||||
} | |||||
} |
package com.vaadin.sass.tree; | |||||
public class WhileNode extends Node { | |||||
private static final long serialVersionUID = 7593896018196027279L; | |||||
private String condition; | |||||
private String body; | |||||
public WhileNode(String condition, String body) { | |||||
this.condition = condition; | |||||
this.body = body; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "While Node: { condition: " + condition + ", body:" + body + "}"; | |||||
} | |||||
} |
package com.vaadin.sass.util; | |||||
import org.w3c.css.sac.LexicalUnit; | |||||
import com.vaadin.sass.parser.LexicalUnitImpl; | |||||
public class ColorUtil { | |||||
public static LexicalUnitImpl hexColorToHsl(LexicalUnitImpl hexColor) { | |||||
String s = hexColor.getStringValue().substring(1); | |||||
int r = 0, g = 0, b = 0; | |||||
if (s.length() == 3) { | |||||
String sh = s.substring(0, 1); | |||||
r = Integer.parseInt(sh + sh, 16); | |||||
sh = s.substring(1, 2); | |||||
g = Integer.parseInt(sh + sh, 16); | |||||
sh = s.substring(2, 3); | |||||
b = Integer.parseInt(sh + sh, 16); | |||||
} else if (s.length() == 6) { | |||||
r = Integer.parseInt(s.substring(0, 2), 16); | |||||
g = Integer.parseInt(s.substring(2, 4), 16); | |||||
b = Integer.parseInt(s.substring(4, 6), 16); | |||||
} | |||||
int hsl[] = calculateHsl(r, g, b); | |||||
LexicalUnitImpl hslParams = createHslParameters(hsl[0], hsl[1], hsl[2], | |||||
hexColor.getLineNumber(), hexColor.getColumnNumber(), | |||||
(LexicalUnitImpl) hexColor.getPreviousLexicalUnit()); | |||||
return LexicalUnitImpl.createFunction(hexColor.getLineNumber(), | |||||
hexColor.getColumnNumber(), | |||||
(LexicalUnitImpl) hexColor.getPreviousLexicalUnit(), "hsl", | |||||
hslParams); | |||||
} | |||||
public static LexicalUnitImpl hslToHexColor(LexicalUnitImpl hsl, int lengh) { | |||||
int[] rgb = calculateRgb(hsl); | |||||
StringBuilder builder = new StringBuilder("#"); | |||||
for (int i = 0; i < 3; i++) { | |||||
String color = Integer.toHexString(rgb[i]); | |||||
if (lengh == 3) { | |||||
if (color.length() == 1) { | |||||
color = "0" + color; | |||||
} | |||||
} | |||||
if (lengh == 6) { | |||||
color = color.substring(0, 1); | |||||
} | |||||
builder.append(color); | |||||
} | |||||
return LexicalUnitImpl.createIdent(hsl.getLineNumber(), | |||||
hsl.getColumnNumber(), | |||||
(LexicalUnitImpl) hsl.getPreviousLexicalUnit(), | |||||
builder.toString()); | |||||
} | |||||
private static int[] calculateRgb(LexicalUnitImpl hsl) { | |||||
LexicalUnitImpl hslParam = hsl.getParameters(); | |||||
LexicalUnitImpl hue = null; | |||||
LexicalUnitImpl saturation = null; | |||||
LexicalUnitImpl lightness = null; | |||||
int i = 0; | |||||
while (i < 5) { | |||||
switch (i) { | |||||
case 0: | |||||
hue = hslParam; | |||||
break; | |||||
case 2: | |||||
saturation = hslParam; | |||||
break; | |||||
case 4: | |||||
lightness = hslParam; | |||||
break; | |||||
case 1: | |||||
case 3: | |||||
break; | |||||
} | |||||
hslParam = (LexicalUnitImpl) hslParam.getNextLexicalUnit(); | |||||
i++; | |||||
} | |||||
float h = ((hue.getFloatValue() % 360) + 360) % 360 / 360; | |||||
float s = saturation.getFloatValue() / 100; | |||||
float l = lightness.getFloatValue() / 100; | |||||
float m2, m1; | |||||
int[] rgb = new int[3]; | |||||
m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; | |||||
m1 = l * 2 - m2; | |||||
rgb[0] = Math.round(hueToRgb(m1, m2, h + 1f / 3) * 255); | |||||
rgb[1] = Math.round(hueToRgb(m1, m2, h) * 255); | |||||
rgb[2] = Math.round(hueToRgb(m1, m2, h - 1f / 3) * 255); | |||||
return rgb; | |||||
} | |||||
public static LexicalUnitImpl rgbToHsl(LexicalUnitImpl rgb) { | |||||
LexicalUnitImpl rgbParam = rgb.getParameters(); | |||||
LexicalUnitImpl red = null; | |||||
LexicalUnitImpl green = null; | |||||
LexicalUnitImpl blue = null; | |||||
int i = 0; | |||||
while (i < 5) { | |||||
switch (i) { | |||||
case 0: | |||||
red = rgbParam; | |||||
break; | |||||
case 2: | |||||
green = rgbParam; | |||||
break; | |||||
case 4: | |||||
blue = rgbParam; | |||||
break; | |||||
case 1: | |||||
case 3: | |||||
break; | |||||
} | |||||
rgbParam = (LexicalUnitImpl) rgbParam.getNextLexicalUnit(); | |||||
i++; | |||||
} | |||||
int hsl[] = calculateHsl(red.getIntegerValue(), | |||||
green.getIntegerValue(), blue.getIntegerValue()); | |||||
rgbParam = rgb.getParameters(); | |||||
LexicalUnitImpl hslParams = createHslParameters(hsl[0], hsl[1], hsl[2], | |||||
rgbParam.getLineNumber(), rgbParam.getColumnNumber(), | |||||
(LexicalUnitImpl) rgbParam.getPreviousLexicalUnit()); | |||||
return LexicalUnitImpl.createFunction(rgb.getLineNumber(), | |||||
rgb.getColumnNumber(), | |||||
(LexicalUnitImpl) rgb.getPreviousLexicalUnit(), "hsl", | |||||
hslParams); | |||||
} | |||||
private static int[] calculateHsl(int red, int green, int blue) { | |||||
int[] hsl = new int[3]; | |||||
float r = red / 255f; | |||||
float g = green / 255f; | |||||
float b = blue / 255f; | |||||
float max = Math.max(Math.max(r, g), b); | |||||
float min = Math.min(Math.min(r, g), b); | |||||
float d = max - min; | |||||
float h = 0f, s = 0f, l = 0f; | |||||
if (max == min) { | |||||
h = 0; | |||||
} | |||||
if (max == r) { | |||||
h = 60 * (g - b) / d; | |||||
} else if (max == g) { | |||||
h = 60 * (b - r) / d + 120; | |||||
} else if (max == b) { | |||||
h = 60 * (r - g) / d + 240; | |||||
} | |||||
l = (max + min) / 2f; | |||||
if (max == min) { | |||||
s = 0; | |||||
} else if (l < 0.5) { | |||||
s = d / (2 * l); | |||||
} else { | |||||
s = d / (2 - 2 * l); | |||||
} | |||||
hsl[0] = Math.round(h % 360); | |||||
hsl[1] = Math.round(s * 100); | |||||
hsl[2] = Math.round(l * 100); | |||||
return hsl; | |||||
} | |||||
public static LexicalUnitImpl hslToRgb(LexicalUnitImpl hsl) { | |||||
int[] rgb = calculateRgb(hsl); | |||||
LexicalUnitImpl hslParam = hsl.getParameters(); | |||||
LexicalUnitImpl rgbParams = createRgbParameters(rgb[0], rgb[1], rgb[2], | |||||
hslParam.getLineNumber(), hslParam.getColumnNumber(), | |||||
(LexicalUnitImpl) hslParam.getPreviousLexicalUnit()); | |||||
return LexicalUnitImpl.createFunction(hsl.getLineNumber(), | |||||
hsl.getColumnNumber(), | |||||
(LexicalUnitImpl) hsl.getPreviousLexicalUnit(), "rgb", | |||||
rgbParams); | |||||
} | |||||
private static float hueToRgb(float m1, float m2, float h) { | |||||
if (h < 0) { | |||||
h = h + 1; | |||||
} | |||||
if (h > 1) { | |||||
h = h - 1; | |||||
} | |||||
if (h * 6 < 1) { | |||||
return m1 + (m2 - m1) * h * 6; | |||||
} | |||||
if (h * 2 < 1) { | |||||
return m2; | |||||
} | |||||
if (h * 3 < 2) { | |||||
return m1 + (m2 - m1) * (2f / 3 - h) * 6; | |||||
} | |||||
return m1; | |||||
} | |||||
private static LexicalUnitImpl createRgbParameters(int r, int g, int b, | |||||
int ln, int cn, LexicalUnitImpl prev) { | |||||
LexicalUnitImpl red = LexicalUnitImpl.createInteger(ln, cn, prev, r); | |||||
LexicalUnitImpl firstComma = LexicalUnitImpl.createComma(ln, cn, red); | |||||
LexicalUnitImpl green = LexicalUnitImpl.createInteger(ln, cn, | |||||
firstComma, g); | |||||
LexicalUnitImpl secondComma = LexicalUnitImpl | |||||
.createComma(ln, cn, green); | |||||
LexicalUnitImpl.createInteger(ln, cn, secondComma, b); | |||||
return red; | |||||
} | |||||
private static LexicalUnitImpl createHslParameters(int h, int s, int l, | |||||
int ln, int cn, LexicalUnitImpl prev) { | |||||
LexicalUnitImpl hue = LexicalUnitImpl.createInteger(ln, cn, prev, h); | |||||
LexicalUnitImpl firstComma = LexicalUnitImpl.createComma(ln, cn, hue); | |||||
LexicalUnitImpl saturation = LexicalUnitImpl.createPercentage(ln, cn, | |||||
firstComma, s); | |||||
LexicalUnitImpl secondComma = LexicalUnitImpl.createComma(ln, cn, | |||||
saturation); | |||||
LexicalUnitImpl.createPercentage(ln, cn, secondComma, l); | |||||
return hue; | |||||
} | |||||
public static LexicalUnitImpl darken(LexicalUnitImpl darkenFunc) { | |||||
LexicalUnitImpl color = darkenFunc.getParameters(); | |||||
LexicalUnit amount = color.getNextLexicalUnit().getNextLexicalUnit(); | |||||
LexicalUnitImpl pre = (LexicalUnitImpl) darkenFunc | |||||
.getPreviousLexicalUnit(); | |||||
return adjust(color, amount, ColorOperation.Darken, pre); | |||||
} | |||||
private static LexicalUnitImpl adjust(LexicalUnitImpl color, | |||||
LexicalUnit amount, ColorOperation op, LexicalUnitImpl pre) { | |||||
if (color.getLexicalUnitType() == LexicalUnit.SAC_FUNCTION) { | |||||
LexicalUnit funcParam = color.getParameters(); | |||||
if ("hsl".equals(color.getFunctionName())) { | |||||
LexicalUnit lightness = funcParam; | |||||
for (int index = 0; index < 4; index++) { | |||||
lightness = lightness.getNextLexicalUnit(); | |||||
} | |||||
float newValue = 0f; | |||||
if (op == ColorOperation.Darken) { | |||||
newValue = lightness.getFloatValue() | |||||
- amount.getFloatValue(); | |||||
newValue = newValue < 0 ? 0 : newValue; | |||||
} else if (op == ColorOperation.Lighten) { | |||||
newValue = lightness.getFloatValue() | |||||
+ amount.getFloatValue(); | |||||
newValue = newValue > 100 ? 100 : newValue; | |||||
} | |||||
((LexicalUnitImpl) lightness).setFloatValue(newValue); | |||||
return LexicalUnitImpl.createFunction(color.getLineNumber(), | |||||
color.getColumnNumber(), pre, color.getFunctionName(), | |||||
funcParam); | |||||
} | |||||
} else if (color.getLexicalUnitType() == LexicalUnit.SAC_IDENT) { | |||||
if (color.getStringValue().startsWith("#")) { | |||||
return hslToHexColor( | |||||
adjust(hexColorToHsl(color), amount, op, pre), color | |||||
.getStringValue().substring(1).length()); | |||||
} | |||||
} else if (color.getLexicalUnitType() == LexicalUnit.SAC_RGBCOLOR) { | |||||
LexicalUnitImpl hsl = rgbToHsl(color); | |||||
LexicalUnitImpl hslAfterDarken = adjust(hsl, amount, op, pre); | |||||
return hslToRgb(hslAfterDarken); | |||||
} | |||||
return color; | |||||
} | |||||
public static LexicalUnitImpl lighten(LexicalUnitImpl lightenFunc) { | |||||
LexicalUnitImpl color = lightenFunc.getParameters(); | |||||
LexicalUnit amount = color.getNextLexicalUnit().getNextLexicalUnit(); | |||||
LexicalUnitImpl pre = (LexicalUnitImpl) lightenFunc | |||||
.getPreviousLexicalUnit(); | |||||
return adjust(color, amount, ColorOperation.Lighten, pre); | |||||
} | |||||
enum ColorOperation { | |||||
Darken, Lighten | |||||
} | |||||
} |
package com.vaadin.sass.util; | |||||
import java.io.IOException; | |||||
import java.io.ObjectInputStream; | |||||
import java.io.ObjectOutputStream; | |||||
/** | |||||
* Utility for making deep copies (vs. clone()'s shallow copies) of objects. | |||||
* Objects are first serialized and then deserialized. Error checking is fairly | |||||
* minimal in this implementation. If an object is encountered that cannot be | |||||
* serialized (or that references an object that cannot be serialized) an error | |||||
* is printed to System.err and null is returned. Depending on your specific | |||||
* application, it might make more sense to have copy(...) re-throw the | |||||
* exception. | |||||
*/ | |||||
public class DeepCopy { | |||||
/** | |||||
* Returns a copy of the object, or null if the object cannot be serialized. | |||||
*/ | |||||
public static Object copy(Object orig) { | |||||
Object obj = null; | |||||
try { | |||||
// Write the object out to a byte array | |||||
FastByteArrayOutputStream fbos = new FastByteArrayOutputStream(); | |||||
ObjectOutputStream out = new ObjectOutputStream(fbos); | |||||
out.writeObject(orig); | |||||
out.flush(); | |||||
out.close(); | |||||
// Retrieve an input stream from the byte array and read | |||||
// a copy of the object back in. | |||||
ObjectInputStream in = new ObjectInputStream(fbos.getInputStream()); | |||||
obj = in.readObject(); | |||||
in.close(); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} catch (ClassNotFoundException cnfe) { | |||||
cnfe.printStackTrace(); | |||||
} | |||||
return obj; | |||||
} | |||||
} |
package com.vaadin.sass.util; | |||||
import java.io.InputStream; | |||||
/** | |||||
* ByteArrayInputStream implementation that does not synchronize methods. | |||||
*/ | |||||
public class FastByteArrayInputStream extends InputStream { | |||||
/** | |||||
* Our byte buffer | |||||
*/ | |||||
protected byte[] buf = null; | |||||
/** | |||||
* Number of bytes that we can read from the buffer | |||||
*/ | |||||
protected int count = 0; | |||||
/** | |||||
* Number of bytes that have been read from the buffer | |||||
*/ | |||||
protected int pos = 0; | |||||
public FastByteArrayInputStream(byte[] buf, int count) { | |||||
this.buf = buf; | |||||
this.count = count; | |||||
} | |||||
@Override | |||||
public final int available() { | |||||
return count - pos; | |||||
} | |||||
@Override | |||||
public final int read() { | |||||
return (pos < count) ? (buf[pos++] & 0xff) : -1; | |||||
} | |||||
@Override | |||||
public final int read(byte[] b, int off, int len) { | |||||
if (pos >= count) { | |||||
return -1; | |||||
} | |||||
if ((pos + len) > count) { | |||||
len = (count - pos); | |||||
} | |||||
System.arraycopy(buf, pos, b, off, len); | |||||
pos += len; | |||||
return len; | |||||
} | |||||
@Override | |||||
public final long skip(long n) { | |||||
if ((pos + n) > count) { | |||||
n = count - pos; | |||||
} | |||||
if (n < 0) { | |||||
return 0; | |||||
} | |||||
pos += n; | |||||
return n; | |||||
} | |||||
} |
package com.vaadin.sass.util; | |||||
import java.io.InputStream; | |||||
import java.io.OutputStream; | |||||
/** | |||||
* ByteArrayOutputStream implementation that doesn't synchronize methods and | |||||
* doesn't copy the data on toByteArray(). | |||||
*/ | |||||
public class FastByteArrayOutputStream extends OutputStream { | |||||
/** | |||||
* Buffer and size | |||||
*/ | |||||
protected byte[] buf = null; | |||||
protected int size = 0; | |||||
/** | |||||
* Constructs a stream with buffer capacity size 5K | |||||
*/ | |||||
public FastByteArrayOutputStream() { | |||||
this(5 * 1024); | |||||
} | |||||
/** | |||||
* Constructs a stream with the given initial size | |||||
*/ | |||||
public FastByteArrayOutputStream(int initSize) { | |||||
size = 0; | |||||
buf = new byte[initSize]; | |||||
} | |||||
/** | |||||
* Ensures that we have a large enough buffer for the given size. | |||||
*/ | |||||
private void verifyBufferSize(int sz) { | |||||
if (sz > buf.length) { | |||||
byte[] old = buf; | |||||
buf = new byte[Math.max(sz, 2 * buf.length)]; | |||||
System.arraycopy(old, 0, buf, 0, old.length); | |||||
old = null; | |||||
} | |||||
} | |||||
public int getSize() { | |||||
return size; | |||||
} | |||||
/** | |||||
* Returns the byte array containing the written data. Note that this array | |||||
* will almost always be larger than the amount of data actually written. | |||||
*/ | |||||
public byte[] getByteArray() { | |||||
return buf; | |||||
} | |||||
@Override | |||||
public final void write(byte b[]) { | |||||
verifyBufferSize(size + b.length); | |||||
System.arraycopy(b, 0, buf, size, b.length); | |||||
size += b.length; | |||||
} | |||||
@Override | |||||
public final void write(byte b[], int off, int len) { | |||||
verifyBufferSize(size + len); | |||||
System.arraycopy(b, off, buf, size, len); | |||||
size += len; | |||||
} | |||||
@Override | |||||
public final void write(int b) { | |||||
verifyBufferSize(size + 1); | |||||
buf[size++] = (byte) b; | |||||
} | |||||
public void reset() { | |||||
size = 0; | |||||
} | |||||
/** | |||||
* Returns a ByteArrayInputStream for reading back the written data | |||||
*/ | |||||
public InputStream getInputStream() { | |||||
return new FastByteArrayInputStream(buf, size); | |||||
} | |||||
} |
package com.vaadin.sass.util; | |||||
import java.util.ArrayList; | |||||
import java.util.Collection; | |||||
import java.util.Iterator; | |||||
import java.util.LinkedList; | |||||
import java.util.List; | |||||
public class StringUtil { | |||||
private static final String FOLDER_SEPARATOR = "/"; // folder separator | |||||
private static final String WINDOWS_FOLDER_SEPARATOR = "\\"; // Windows | |||||
// folder | |||||
// separator | |||||
private static final String TOP_PATH = ".."; // top folder | |||||
private static final String CURRENT_PATH = "."; // current folder | |||||
public static String cleanPath(String path) { | |||||
String pathToUse = replace(path, WINDOWS_FOLDER_SEPARATOR, | |||||
FOLDER_SEPARATOR); | |||||
String[] pathArray = delimitedListToStringArray(pathToUse, | |||||
FOLDER_SEPARATOR); | |||||
List pathElements = new LinkedList(); | |||||
int tops = 0; | |||||
for (int i = pathArray.length - 1; i >= 0; i--) { | |||||
if (CURRENT_PATH.equals(pathArray[i])) { | |||||
// do nothing | |||||
} else if (TOP_PATH.equals(pathArray[i])) { | |||||
tops++; | |||||
} else { | |||||
if (tops > 0) { | |||||
tops--; | |||||
} else { | |||||
pathElements.add(0, pathArray[i]); | |||||
} | |||||
} | |||||
} | |||||
for (int i = 0; i < tops; i++) { | |||||
pathElements.add(0, TOP_PATH); | |||||
} | |||||
return collectionToDelimitedString(pathElements, FOLDER_SEPARATOR); | |||||
} | |||||
public static String replace(String inString, String oldPattern, | |||||
String newPattern) { | |||||
if (inString == null) { | |||||
return null; | |||||
} | |||||
if (oldPattern == null || newPattern == null) { | |||||
return inString; | |||||
} | |||||
StringBuffer sbuf = new StringBuffer(); | |||||
// output StringBuffer we'll build up | |||||
int pos = 0; // our position in the old string | |||||
int index = inString.indexOf(oldPattern); | |||||
// the index of an occurrence we've found, or -1 | |||||
int patLen = oldPattern.length(); | |||||
while (index >= 0) { | |||||
sbuf.append(inString.substring(pos, index)); | |||||
sbuf.append(newPattern); | |||||
pos = index + patLen; | |||||
index = inString.indexOf(oldPattern, pos); | |||||
} | |||||
sbuf.append(inString.substring(pos)); | |||||
// remember to append any characters to the right of a match | |||||
return sbuf.toString(); | |||||
} | |||||
public static String[] delimitedListToStringArray(String str, | |||||
String delimiter) { | |||||
if (str == null) { | |||||
return new String[0]; | |||||
} | |||||
if (delimiter == null) { | |||||
return new String[] { str }; | |||||
} | |||||
List result = new ArrayList(); | |||||
int pos = 0; | |||||
int delPos = 0; | |||||
while ((delPos = str.indexOf(delimiter, pos)) != -1) { | |||||
result.add(str.substring(pos, delPos)); | |||||
pos = delPos + delimiter.length(); | |||||
} | |||||
if (str.length() > 0 && pos <= str.length()) { | |||||
// Add rest of String, but not in case of empty input. | |||||
result.add(str.substring(pos)); | |||||
} | |||||
return (String[]) result.toArray(new String[result.size()]); | |||||
} | |||||
public static String collectionToDelimitedString(Collection coll, | |||||
String delim, String prefix, String suffix) { | |||||
if (coll == null) { | |||||
return ""; | |||||
} | |||||
StringBuffer sb = new StringBuffer(); | |||||
Iterator it = coll.iterator(); | |||||
int i = 0; | |||||
while (it.hasNext()) { | |||||
if (i > 0) { | |||||
sb.append(delim); | |||||
} | |||||
sb.append(prefix).append(it.next()).append(suffix); | |||||
i++; | |||||
} | |||||
return sb.toString(); | |||||
} | |||||
public static String collectionToDelimitedString(Collection coll, | |||||
String delim) { | |||||
return collectionToDelimitedString(coll, delim, "", ""); | |||||
} | |||||
} |
package com.vaadin.sass.visitor; | |||||
import java.util.HashSet; | |||||
import java.util.Set; | |||||
import org.w3c.css.sac.Selector; | |||||
import org.w3c.css.sac.SelectorList; | |||||
import com.vaadin.sass.parser.SelectorListImpl; | |||||
import com.vaadin.sass.selector.CompositeSelector; | |||||
import com.vaadin.sass.tree.BlockNode; | |||||
import com.vaadin.sass.tree.Node; | |||||
public class BlockVisitor implements Visitor { | |||||
@Override | |||||
public void traverse(Node node) { | |||||
traverse(null, node); | |||||
} | |||||
private void traverse(Node parent, Node node) { | |||||
Node after = node; | |||||
Set<Node> toBeDeleted = new HashSet<Node>(); | |||||
for (int pos = 0; pos < node.getChildren().size(); pos++) { | |||||
Node child = node.getChildren().get(pos); | |||||
traverse(node, child); | |||||
if (child instanceof BlockNode && node instanceof BlockNode | |||||
&& parent != null) { | |||||
combineParentSelectorListToChild(node, child); | |||||
toBeDeleted.add(child); | |||||
parent.appendChild(child, after); | |||||
after = child; | |||||
} | |||||
} | |||||
for (Node child : toBeDeleted) { | |||||
node.removeChild(child); | |||||
} | |||||
} | |||||
private void combineParentSelectorListToChild(Node parent, Node child) { | |||||
if (parent instanceof BlockNode && child instanceof BlockNode) { | |||||
SelectorListImpl newList = new SelectorListImpl(); | |||||
SelectorList parentSelectors = ((BlockNode) parent) | |||||
.getSelectorList(); | |||||
SelectorList childSelectors = ((BlockNode) child).getSelectorList(); | |||||
for (int i = 0; i < parentSelectors.getLength(); i++) { | |||||
Selector parentSelector = parentSelectors.item(i); | |||||
for (int j = 0; j < childSelectors.getLength(); j++) { | |||||
Selector childSelector = childSelectors.item(j); | |||||
newList.addSelector(new CompositeSelector(parentSelector, | |||||
childSelector)); | |||||
} | |||||
} | |||||
((BlockNode) child).setSelectorList(newList); | |||||
} | |||||
} | |||||
} |
package com.vaadin.sass.visitor; | |||||
import java.util.ArrayList; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.Map.Entry; | |||||
import org.w3c.css.sac.SelectorList; | |||||
import com.vaadin.sass.parser.SelectorListImpl; | |||||
import com.vaadin.sass.selector.SelectorUtil; | |||||
import com.vaadin.sass.tree.BlockNode; | |||||
import com.vaadin.sass.tree.ExtendNode; | |||||
import com.vaadin.sass.tree.Node; | |||||
public class ExtendVisitor implements Visitor { | |||||
private Map<String, List<SelectorList>> extendsMap = new HashMap<String, List<SelectorList>>(); | |||||
@Override | |||||
public void traverse(Node node) throws Exception { | |||||
buildExtendsMap(node); | |||||
modifyTree(node); | |||||
} | |||||
private void modifyTree(Node node) throws Exception { | |||||
for (Node child : node.getChildren()) { | |||||
if (child instanceof BlockNode) { | |||||
BlockNode blockNode = (BlockNode) child; | |||||
String selectorString = SelectorUtil.toString(blockNode | |||||
.getSelectorList()); | |||||
if (extendsMap.get(selectorString) != null) { | |||||
for (SelectorList sList : extendsMap.get(selectorString)) { | |||||
SelectorList newList = SelectorUtil | |||||
.createNewSelectorListFromAnOldOneWithSomPartReplaced( | |||||
blockNode.getSelectorList(), | |||||
selectorString, sList); | |||||
addAdditionalSelectorListToBlockNode(blockNode, newList); | |||||
} | |||||
} else { | |||||
for (Entry<String, List<SelectorList>> entry : extendsMap | |||||
.entrySet()) { | |||||
if (selectorString.contains(entry.getKey())) { | |||||
for (SelectorList sList : entry.getValue()) { | |||||
SelectorList newList = SelectorUtil | |||||
.createNewSelectorListFromAnOldOneWithSomPartReplaced( | |||||
blockNode.getSelectorList(), | |||||
entry.getKey(), sList); | |||||
addAdditionalSelectorListToBlockNode(blockNode, | |||||
newList); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} else { | |||||
buildExtendsMap(child); | |||||
} | |||||
} | |||||
} | |||||
private void buildExtendsMap(Node node) { | |||||
if (node instanceof BlockNode) { | |||||
BlockNode blockNode = (BlockNode) node; | |||||
for (Node child : new ArrayList<Node>(node.getChildren())) { | |||||
if (child instanceof ExtendNode) { | |||||
ExtendNode extendNode = (ExtendNode) child; | |||||
String extendedString = SelectorUtil.toString(extendNode | |||||
.getList()); | |||||
if (extendsMap.get(extendedString) == null) { | |||||
extendsMap.put(extendedString, | |||||
new ArrayList<SelectorList>()); | |||||
} | |||||
extendsMap.get(extendedString).add( | |||||
blockNode.getSelectorList()); | |||||
node.removeChild(child); | |||||
} else { | |||||
buildExtendsMap(child); | |||||
} | |||||
} | |||||
} else { | |||||
for (Node child : node.getChildren()) { | |||||
buildExtendsMap(child); | |||||
} | |||||
} | |||||
} | |||||
private void addAdditionalSelectorListToBlockNode(BlockNode blockNode, | |||||
SelectorList list) { | |||||
if (list != null) { | |||||
for (int i = 0; i < list.getLength(); i++) { | |||||
((SelectorListImpl) blockNode.getSelectorList()) | |||||
.addSelector(list.item(i)); | |||||
} | |||||
} | |||||
} | |||||
} |
package com.vaadin.sass.visitor; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.util.ArrayList; | |||||
import org.w3c.css.sac.CSSException; | |||||
import org.w3c.css.sac.LexicalUnit; | |||||
import com.vaadin.sass.ScssStylesheet; | |||||
import com.vaadin.sass.parser.LexicalUnitImpl; | |||||
import com.vaadin.sass.tree.ImportNode; | |||||
import com.vaadin.sass.tree.Node; | |||||
import com.vaadin.sass.tree.RuleNode; | |||||
import com.vaadin.sass.util.StringUtil; | |||||
public class ImportVisitor implements Visitor { | |||||
@Override | |||||
public void traverse(Node node) { | |||||
for (Node child : new ArrayList<Node>(node.getChildren())) { | |||||
if (child instanceof ImportNode) { | |||||
ImportNode importNode = (ImportNode) child; | |||||
if (!importNode.isPureCssImport()) { | |||||
StringBuilder filePathBuilder = new StringBuilder( | |||||
node.getFileName()); | |||||
filePathBuilder.append(File.separatorChar).append( | |||||
importNode.getUri()); | |||||
if (!filePathBuilder.toString().endsWith(".scss")) { | |||||
filePathBuilder.append(".scss"); | |||||
} | |||||
try { | |||||
ScssStylesheet imported = ScssStylesheet.get(new File( | |||||
filePathBuilder.toString())); | |||||
traverse(imported); | |||||
String prefix = getUrlPrefix(importNode.getUri()); | |||||
if (prefix != null) { | |||||
updateUrlInImportedSheet(imported, prefix); | |||||
} | |||||
Node pre = importNode; | |||||
for (Node importedChild : imported.getChildren()) { | |||||
node.appendChild(importedChild, pre); | |||||
pre = importedChild; | |||||
} | |||||
node.removeChild(importNode); | |||||
} catch (CSSException e) { | |||||
e.printStackTrace(); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
private String getUrlPrefix(String url) { | |||||
if (url == null) { | |||||
return null; | |||||
} | |||||
int pos = url.lastIndexOf(File.separatorChar); | |||||
if (pos == -1) { | |||||
return null; | |||||
} | |||||
return url.substring(0, pos + 1); | |||||
} | |||||
private void updateUrlInImportedSheet(Node node, String prefix) { | |||||
for (Node child : node.getChildren()) { | |||||
if (child instanceof RuleNode) { | |||||
LexicalUnit value = ((RuleNode) child).getValue(); | |||||
while (value != null) { | |||||
if (value.getLexicalUnitType() == LexicalUnit.SAC_URI) { | |||||
String path = value.getStringValue(); | |||||
if (!path.startsWith("/") && !path.contains(":")) { | |||||
path = prefix + path; | |||||
path = StringUtil.cleanPath(path); | |||||
((LexicalUnitImpl) value).setStringValue(path); | |||||
} | |||||
} | |||||
value = value.getNextLexicalUnit(); | |||||
} | |||||
} | |||||
updateUrlInImportedSheet(child, prefix); | |||||
} | |||||
} | |||||
} |
package com.vaadin.sass.visitor; | |||||
import java.util.ArrayList; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import com.vaadin.sass.tree.MixinDefNode; | |||||
import com.vaadin.sass.tree.MixinNode; | |||||
import com.vaadin.sass.tree.Node; | |||||
import com.vaadin.sass.tree.VariableNode; | |||||
import com.vaadin.sass.util.DeepCopy; | |||||
public class MixinVisitor implements Visitor { | |||||
Map<String, MixinDefNode> mixinDefs = new HashMap<String, MixinDefNode>(); | |||||
@Override | |||||
public void traverse(Node node) throws Exception { | |||||
// create mixin map. | |||||
for (Node child : node.getChildren()) { | |||||
if (child instanceof MixinDefNode) { | |||||
mixinDefs.put(((MixinDefNode) child).getName(), | |||||
(MixinDefNode) child); | |||||
} | |||||
} | |||||
replaceMixins(node); | |||||
// delete MixinDefNode | |||||
for (Node child : new ArrayList<Node>(node.getChildren())) { | |||||
if (child instanceof MixinDefNode) { | |||||
node.removeChild(child); | |||||
} | |||||
} | |||||
} | |||||
private void replaceMixins(Node node) throws Exception { | |||||
for (Node child : new ArrayList<Node>(node.getChildren())) { | |||||
replaceMixins(child); | |||||
if (child instanceof MixinNode) { | |||||
MixinNode mixinNode = (MixinNode) child; | |||||
MixinDefNode mixinDef = mixinDefs.get(mixinNode.getName()); | |||||
if (mixinDef == null) { | |||||
throw new Exception("Mixin Definition: " | |||||
+ mixinNode.getName() + " not found"); | |||||
} | |||||
replaceMixinNode(node, mixinNode, mixinDef); | |||||
} | |||||
} | |||||
} | |||||
private void replaceMixinNode(Node current, MixinNode mixinNode, | |||||
MixinDefNode mixinDef) { | |||||
Node pre = mixinNode; | |||||
if (mixinDef.getArglist().isEmpty()) { | |||||
for (Node child : mixinDef.getChildren()) { | |||||
current.appendChild(child, pre); | |||||
pre = child; | |||||
} | |||||
} else { | |||||
for (int i = 0; i < mixinDef.getArglist().size(); i++) { | |||||
VariableNode arg = (VariableNode) DeepCopy.copy(mixinDef | |||||
.getArglist().get(i)); | |||||
if (i < mixinNode.getArglist().size()) { | |||||
arg.setExpr(mixinNode.getArglist().get(i)); | |||||
} | |||||
current.appendChild(arg, pre); | |||||
pre = arg; | |||||
} | |||||
for (Node child : mixinDef.getChildren()) { | |||||
Node clonedChild = (Node) DeepCopy.copy(child); | |||||
current.appendChild(clonedChild, pre); | |||||
pre = clonedChild; | |||||
} | |||||
} | |||||
current.removeChild(mixinNode); | |||||
} | |||||
} |
package com.vaadin.sass.visitor; | |||||
import java.util.ArrayList; | |||||
import com.vaadin.sass.tree.NestPropertiesNode; | |||||
import com.vaadin.sass.tree.Node; | |||||
import com.vaadin.sass.tree.RuleNode; | |||||
public class NestPropertiesVisitor implements Visitor { | |||||
@Override | |||||
public void traverse(Node node) { | |||||
for (Node child : new ArrayList<Node>(node.getChildren())) { | |||||
if (child instanceof NestPropertiesNode) { | |||||
Node previous = child; | |||||
for (RuleNode unNested : ((NestPropertiesNode) child) | |||||
.unNesting()) { | |||||
node.appendChild(unNested, previous); | |||||
previous = unNested; | |||||
node.removeChild(child); | |||||
} | |||||
} else { | |||||
traverse(child); | |||||
} | |||||
} | |||||
} | |||||
} |
package com.vaadin.sass.visitor; | |||||
import java.util.ArrayList; | |||||
import org.w3c.css.sac.SelectorList; | |||||
import com.vaadin.sass.selector.SelectorUtil; | |||||
import com.vaadin.sass.tree.BlockNode; | |||||
import com.vaadin.sass.tree.Node; | |||||
public class ParentSelectorVisitor implements Visitor { | |||||
@Override | |||||
public void traverse(Node node) throws Exception { | |||||
for (Node child : new ArrayList<Node>(node.getChildren())) { | |||||
if (child instanceof BlockNode) { | |||||
traverse(node, (BlockNode) child); | |||||
} | |||||
} | |||||
} | |||||
private void traverse(Node parent, BlockNode block) throws Exception { | |||||
Node pre = block; | |||||
for (Node child : new ArrayList<Node>(block.getChildren())) { | |||||
if (child instanceof BlockNode) { | |||||
BlockNode blockChild = (BlockNode) child; | |||||
traverse(block, blockChild); | |||||
if (SelectorUtil | |||||
.hasParentSelector(blockChild.getSelectorList())) { | |||||
parent.appendChild(child, pre); | |||||
pre = child; | |||||
block.removeChild(child); | |||||
SelectorList newSelectorList = SelectorUtil | |||||
.createNewSelectorListFromAnOldOneWithSomPartReplaced( | |||||
blockChild.getSelectorList(), "&", | |||||
block.getSelectorList()); | |||||
blockChild.setSelectorList(newSelectorList); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
package com.vaadin.sass.visitor; | |||||
import java.util.HashMap; | |||||
import java.util.HashSet; | |||||
import java.util.Map; | |||||
import java.util.Set; | |||||
import org.w3c.css.sac.LexicalUnit; | |||||
import com.vaadin.sass.parser.LexicalUnitImpl; | |||||
import com.vaadin.sass.parser.SCSSLexicalUnit; | |||||
import com.vaadin.sass.tree.Node; | |||||
import com.vaadin.sass.tree.RuleNode; | |||||
import com.vaadin.sass.tree.VariableNode; | |||||
public class VariableVisitor implements Visitor { | |||||
@Override | |||||
public void traverse(Node node) { | |||||
Map<String, LexicalUnitImpl> variables = new HashMap<String, LexicalUnitImpl>(); | |||||
traverse(node, variables); | |||||
} | |||||
private void traverse(Node node, Map<String, LexicalUnitImpl> variables) { | |||||
if (node instanceof RuleNode) { | |||||
LexicalUnit value = ((RuleNode) node).getValue(); | |||||
for (String variable : variables.keySet()) { | |||||
if (value.getLexicalUnitType() == SCSSLexicalUnit.SCSS_VARIABLE) { | |||||
if (value.getStringValue().contains(variable)) { | |||||
LexicalUnitImpl lexVal = (LexicalUnitImpl) value; | |||||
lexVal.replaceValue(variables.get(variable)); | |||||
} | |||||
} | |||||
} | |||||
} else { | |||||
Set<Node> toBeDeleted = new HashSet<Node>(); | |||||
for (Node child : node.getChildren()) { | |||||
if (child instanceof VariableNode) { | |||||
variables.put(((VariableNode) child).getName(), | |||||
(LexicalUnitImpl) ((VariableNode) child).getExpr()); | |||||
toBeDeleted.add(child); | |||||
} else { | |||||
traverse(child, new HashMap<String, LexicalUnitImpl>( | |||||
variables)); | |||||
} | |||||
} | |||||
for (Node child : toBeDeleted) { | |||||
node.removeChild(child); | |||||
} | |||||
} | |||||
} | |||||
} |
package com.vaadin.sass.visitor; | |||||
import com.vaadin.sass.tree.Node; | |||||
public interface Visitor { | |||||
public void traverse(Node node) throws Exception; | |||||
} |
.v-button:focus { | |||||
background-image: url(img/left-focus.png);/** sprite-ref: buttons */ | |||||
outline: none; | |||||
} | |||||
.v-button:focus .v-button-wrap { | |||||
background-image: url(img/right-focus.png);/** sprite-ref: buttons; sprite-alignment: right */ | |||||
outline: none; | |||||
} |
.v-panel-deco { | |||||
} |
.v-view { | |||||
height: 100%; | |||||
width: 100%; | |||||
overflow: auto; | |||||
outline: none; | |||||
margin-top: -1px; | |||||
border-top: 1px solid transparent; | |||||
position: relative; | |||||
} | |||||
@media print { | |||||
.v-generated-body { | |||||
height: auto; | |||||
min-height: 20cm; | |||||
overflow: visible; | |||||
} | |||||
.v-app { | |||||
height: auto; | |||||
min-height: 20cm; | |||||
} | |||||
.v-view { | |||||
overflow: visible; | |||||
} | |||||
.v-gridlayout { | |||||
overflow: visible !important; | |||||
} | |||||
} |
.all-the-properties { | |||||
font-family: Arial, Helvetica, "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif; ; | |||||
position: absolute;; | |||||
overflow: hidden; | |||||
outline: none; | |||||
text-align: left; | |||||
zoom: 1; | |||||
white-space: nowrap; | |||||
background: #123456; | |||||
border-bottom: 1px solid #ffffff; | |||||
filter: alpha(opacity = 30); | |||||
cursor: pointer; | |||||
overflow: auto; | |||||
width: 100%; | |||||
display: inline-block; | |||||
} | |||||
.missing-semicolon-on-last-row { | |||||
color: red; | |||||
background-color: blue | |||||
} | |||||
.lexical-value-test { | |||||
margin: none; | |||||
margin: 0px; | |||||
margin: 0; | |||||
margin: 0.5px; | |||||
margin: 2px; | |||||
margin: -0.5px; | |||||
margin: -2px; | |||||
margin: 10px 20px; | |||||
margin: -10px 20px; | |||||
margin: 20px -10px -20px 40px; | |||||
margin-right: -0.5px; | |||||
} | |||||
.background-positioning { | |||||
background-position: 0 0; | |||||
background-position: left top; | |||||
background-position: left 40px; | |||||
background-position: 50px left; | |||||
background-position: right -286px; | |||||
} | |||||
.user-select-rules { | |||||
user-select: none; | |||||
-ie-user-select: none; | |||||
} | |||||
.box-sizing-rules { | |||||
box-sizing: border-box; | |||||
-moz-box-sizing: border-box; | |||||
} | |||||
.user-select-and-box-sizing-combined { | |||||
-khtml-user-select: none; | |||||
-moz-user-select: none; | |||||
-ie-user-select: none; | |||||
user-select: none; | |||||
-webkit-box-sizing: border-box; | |||||
-moz-box-sizing: border-box; | |||||
-ms-box-sizing: border-box; | |||||
box-sizing: border-box; | |||||
} | |||||
@media print { | |||||
.v-generated-body { | |||||
height: auto; | |||||
min-height: 20cm; | |||||
overflow: visible; | |||||
} | |||||
} |
.foo { | |||||
color: red; | |||||
} | |||||
.foo-bar { | |||||
color: red; | |||||
} | |||||
.foo_bar { | |||||
color: red; | |||||
} | |||||
.foo .bar { | |||||
color: red; | |||||
} | |||||
.foo .bar .baz .fee .roo { | |||||
color: red; | |||||
} | |||||
.foo.bar.baz.fee.roo { | |||||
color: red; | |||||
} | |||||
.foo.bar .baz.fee.roo .dar { | |||||
color: red; | |||||
} | |||||
.foo > .bar { | |||||
color: red; | |||||
} | |||||
#foo { | |||||
color: red; | |||||
} | |||||
#foo .bar { | |||||
color: red; | |||||
} | |||||
.foo #bar { | |||||
color: red; | |||||
} | |||||
#foo.bar { | |||||
color: red; | |||||
} | |||||
#foo, #bar, .baz, .roo .dar { | |||||
color: red; | |||||
} | |||||
#foo a, .foo pre img { | |||||
color: red; | |||||
} | |||||
#foo a.bar { | |||||
color: red; | |||||
} | |||||
a:link { | |||||
color: red; | |||||
} | |||||
a.foo:visited, .bar { | |||||
color: red; | |||||
} | |||||
.v-app input[type="text"] { | |||||
color: red; | |||||
} | |||||
.foo + .bar { | |||||
color: red; | |||||
} | |||||
h1 + .foo { | |||||
color: red; | |||||
} | |||||
.foo * { | |||||
color: red; | |||||
} | |||||
.foo * h1 { | |||||
color: red; | |||||
} | |||||
h1 * .foo { | |||||
color: red; | |||||
} | |||||
* .foo { | |||||
color: red; | |||||
} | |||||
p::abc { | |||||
color: red; | |||||
} | |||||
p:first { | |||||
color: red; | |||||
} |
Implement a sane test case. |
.error, .badError { | |||||
border: 1px #f00; | |||||
background: #fdd; | |||||
} | |||||
.error.intrusion, .badError.intrusion { | |||||
font-size: 1.3em; | |||||
font-weight: bold; | |||||
} | |||||
.badError { | |||||
border-width: 3px; | |||||
} |
.main { | |||||
margin: 2px; | |||||
border: 11px; | |||||
border: 10px; | |||||
border: 10px; | |||||
color: hsl(0, 0%, 30%); | |||||
color: hsl(25, 100%, 50%); | |||||
color: rgb(36, 0, 0); | |||||
color: rgb(240, 0, 0); | |||||
color: #200; | |||||
color: #240000; | |||||
color: #f00; | |||||
color: #f00000; | |||||
} |
.caption { | |||||
border: 1px solid black; | |||||
background: #ff0000; | |||||
padding: 10px; | |||||
margin: 10px; | |||||
} | |||||
.text { | |||||
font-weight: bold; | |||||
color: red; | |||||
} |
.main { | |||||
border: 1px solid black; | |||||
-webkit-border-radius: 3px; | |||||
-moz-border-radius: 3px; | |||||
border-radius: 3px; | |||||
font-family: arial; | |||||
font-size: 16px; | |||||
font-weight: bold; | |||||
} | |||||
.footer { | |||||
border: 2px solid black; | |||||
-webkit-border-radius: 10px; | |||||
-moz-border-radius: 10px; | |||||
border-radius: 10px; | |||||
} | |||||
.header { | |||||
width: 100%; | |||||
} | |||||
.main { | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
.footer { | |||||
width: 100%; | |||||
} | |||||
@media print { | |||||
.v-view { | |||||
overflow: visible; | |||||
} | |||||
} | |||||
font-family: arial; | |||||
font-size: 16px; | |||||
font-weight: bold; |
li { | |||||
font-family: serif; | |||||
font-weight: bold; | |||||
font-size: 1.2em; | |||||
} |
.top-bar { | |||||
color: red; | |||||
} | |||||
.top-bar .alt { | |||||
color: blue; | |||||
} | |||||
.menu { | |||||
background-color: red; | |||||
} | |||||
.menu a { | |||||
color: blue; | |||||
} | |||||
.caption { | |||||
padding: 10px; | |||||
} | |||||
.caption .text, .caption .header { | |||||
color: green; | |||||
} | |||||
.footer { | |||||
padding: 10px; | |||||
} | |||||
.footer .left, .footer .right { | |||||
color: purple; | |||||
} | |||||
.footer .left a, .footer .right a { | |||||
color: orange; | |||||
} | |||||
.main { | |||||
color: red; | |||||
} | |||||
.main .second.third { | |||||
color: blue; | |||||
} | |||||
.main .second.third .fourth { | |||||
color: black; | |||||
} |
.content-navigation { | |||||
border-color: #3bbfce; | |||||
color: #0000ff; | |||||
} | |||||
.border { | |||||
padding: 8px; | |||||
margin: 8px; | |||||
border-color: #3bbfce; | |||||
} | |||||
.body { | |||||
background-image: url(../folder-test2/bg.png); | |||||
background: transparent url(../folder-test2/img/loading-indicator.gif); | |||||
background-image: url(http://abc/bg.png); | |||||
background-image: url(/abc/bg.png); | |||||
} | |||||
.base { | |||||
color: red; | |||||
} | |||||
.text { | |||||
font-weight: bold; | |||||
} |
a { | |||||
font-weight: bold; | |||||
text-decoration: none; | |||||
} | |||||
a:hover { | |||||
text-decoration: underline; | |||||
} | |||||
body.firefox a { | |||||
font-weight: normal; | |||||
} | |||||
#main { | |||||
color: black; | |||||
} | |||||
#main a { | |||||
font-weight: bold; | |||||
} | |||||
#main a:hover { | |||||
color: red; | |||||
} |
.content-navigation { | |||||
border-color: #3bbfce; | |||||
color: #0000ff; | |||||
font-family: Arial, Helvetica, "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif; | |||||
} | |||||
.border { | |||||
padding: 8px; | |||||
margin: 8px; | |||||
border-color: #3bbfce; | |||||
} |
$foo : red; | |||||
.caption { | |||||
$side: right; | |||||
border: 1px solid black; | |||||
background: #ff0000; | |||||
padding: 10px; | |||||
margin: 10px; | |||||
} |
@for $i from 1 through 3 { | |||||
.item-#{$i} { width: 2em * $i; } | |||||
} | |||||
@while $i > 0 { | |||||
.item-#{$i} { width: 2em * $i; } | |||||
$i: $i - 2; | |||||
} | |||||
@each $animal in puma, sea-slug, egret, salamander { | |||||
.#{$animal}-icon { | |||||
background-image: url('/images/#{$animal}.png'); | |||||
} | |||||
} |
.error { | |||||
border: 1px #f00; | |||||
background: #fdd; | |||||
} | |||||
.error.intrusion { | |||||
font-size: 1.3em; | |||||
font-weight: bold; | |||||
} | |||||
.badError { | |||||
@extend .error; | |||||
border-width: 3px; | |||||
} |
@import "../folder-test2/variables.scss"; | |||||
@import "../folder-test2/url"; | |||||
@import "../folder-test2/base-imported.scss"; | |||||
.text { | |||||
font-weight: bold; | |||||
} |
@import "base.scss"; |
.base{ | |||||
color: red; | |||||
} |
.body{ | |||||
background-image: url(bg.png); | |||||
background: transparent url(img/loading-indicator.gif); | |||||
background-image: url(http://abc/bg.png); | |||||
background-image: url(/abc/bg.png); | |||||
} |
$blue: #3bbfce; | |||||
$margin: 8px; | |||||
.content-navigation { | |||||
border-color: $blue; | |||||
$blue: #0000ff; | |||||
color: $blue; | |||||
} | |||||
.border { | |||||
padding: $margin; | |||||
margin: $margin; | |||||
border-color: $blue; | |||||
} |
.main { | |||||
margin: abs(-2px); | |||||
border: ceil(10.4px); | |||||
border: floor(10.4px); | |||||
border: round(10.4px); | |||||
color: lighten(hsl(0, 0%, 0%), 30%); | |||||
color: darken(hsl(25, 100%, 80%), 30%); | |||||
color: darken(rgb(136, 0, 0), 20%); | |||||
color: lighten(rgb(136, 0, 0), 20%); | |||||
color: darken(#880000, 20%); | |||||
color: darken(#800, 20%); | |||||
color: lighten(#880000, 20%); | |||||
color: lighten(#800, 20%); | |||||
} | |||||
@import "_partial-for-import"; | |||||
.text { | |||||
font-weight: bold; | |||||
color: $foo; | |||||
} |
$name: foo; | |||||
$attr: border; | |||||
p.#{$name}abc { abc#{$attr}-color: blue } |
//asfdasdf | |||||
@mixin font-settings { | |||||
font-family: arial; | |||||
font-size: 16px; | |||||
font-weight: bold; | |||||
} | |||||
@mixin rounded-borders($thickness, $radius : 3px) { | |||||
border: $thickness solid black; | |||||
-webkit-border-radius: $radius; | |||||
-moz-border-radius: $radius; | |||||
border-radius: $radius; | |||||
} | |||||
.main { | |||||
@include rounded-borders(1px); | |||||
@include font-settings; | |||||
} | |||||
.footer { | |||||
@include rounded-borders(2px, 10px); | |||||
} | |||||
@mixin layout { | |||||
.header { | |||||
width: 100%; | |||||
} | |||||
.main { | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
.footer { | |||||
width: 100%; | |||||
} | |||||
@media print { | |||||
.v-view { | |||||
overflow: visible; | |||||
} | |||||
} | |||||
@include font-settings; | |||||
} | |||||
@include layout; |
li { | |||||
font: { | |||||
family: serif;; | |||||
weight: bold; | |||||
size: 1.2em | |||||
} | |||||
} |
.top-bar { | |||||
color: red; | |||||
.alt { | |||||
color: blue; | |||||
} | |||||
} | |||||
.menu { | |||||
background-color: red; | |||||
a { | |||||
color: blue; | |||||
} | |||||
} | |||||
.caption { | |||||
padding: 10px; | |||||
.text, .header { | |||||
color: green; | |||||
} | |||||
} | |||||
.footer { | |||||
padding: 10px; | |||||
.left, .right { | |||||
color: purple; | |||||
a { | |||||
color: orange; | |||||
} | |||||
} | |||||
} | |||||
.main { | |||||
color: red; | |||||
.second.third { | |||||
color: blue; | |||||
.fourth { | |||||
color: black; | |||||
} | |||||
} | |||||
} |
a { | |||||
font-weight: bold; | |||||
text-decoration: none; | |||||
&:hover { text-decoration: underline; } | |||||
body.firefox & { font-weight: normal; } | |||||
} | |||||
#main { | |||||
color: black; | |||||
a { | |||||
font-weight: bold; | |||||
&:hover { color: red; } | |||||
} | |||||
} |
a { | |||||
color: #660000; | |||||
&:hover {color: #000000;} | |||||
&:visited {color:#660066;} | |||||
&:active {color: #ffffff;} | |||||
} |
$blue: #3bbfce; | |||||
$margin: 8px; | |||||
$chameleon-font-family: Arial, Helvetica, "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif; | |||||
.content-navigation { | |||||
border-color: $blue; | |||||
$blue: #0000ff; | |||||
color: $blue; | |||||
font-family: $chameleon-font-family; | |||||
} | |||||
.border { | |||||
padding: $margin; | |||||
margin: $margin; | |||||
border-color: $blue; | |||||
} |
package com.vaadin.sass; | |||||
import org.junit.runner.RunWith; | |||||
import org.junit.runners.Suite; | |||||
import org.junit.runners.Suite.SuiteClasses; | |||||
@RunWith(Suite.class) | |||||
@SuiteClasses({ CssTestSuite.class, ScssTestSuite.class, VisitorTestSuite.class }) | |||||
public class AllTests { | |||||
} |
package com.vaadin.sass; | |||||
import org.junit.runner.RunWith; | |||||
import org.junit.runners.Suite; | |||||
import org.junit.runners.Suite.SuiteClasses; | |||||
import com.vaadin.sass.testcases.css.Comments; | |||||
import com.vaadin.sass.testcases.css.Media; | |||||
import com.vaadin.sass.testcases.css.Properties; | |||||
import com.vaadin.sass.testcases.css.Reindeer; | |||||
import com.vaadin.sass.testcases.css.Selectors; | |||||
@RunWith(Suite.class) | |||||
@SuiteClasses({ Selectors.class, Properties.class, Reindeer.class, Media.class, | |||||
Comments.class }) | |||||
public class CssTestSuite { | |||||
} |
package com.vaadin.sass; | |||||
import org.junit.runner.RunWith; | |||||
import org.junit.runners.Suite; | |||||
import org.junit.runners.Suite.SuiteClasses; | |||||
import com.vaadin.sass.testcases.scss.ControlDirectives; | |||||
import com.vaadin.sass.testcases.scss.Extends; | |||||
import com.vaadin.sass.testcases.scss.Functions; | |||||
import com.vaadin.sass.testcases.scss.Imports; | |||||
import com.vaadin.sass.testcases.scss.Mixins; | |||||
import com.vaadin.sass.testcases.scss.NestedProperties; | |||||
import com.vaadin.sass.testcases.scss.Nesting; | |||||
import com.vaadin.sass.testcases.scss.ParentImports; | |||||
import com.vaadin.sass.testcases.scss.ParentSelector; | |||||
import com.vaadin.sass.testcases.scss.Variables; | |||||
import com.vaadin.sass.tree.ImportNodeTest; | |||||
@RunWith(Suite.class) | |||||
@SuiteClasses({ ControlDirectives.class, Extends.class, Functions.class, | |||||
ImportNodeTest.class, Imports.class, Mixins.class, | |||||
NestedProperties.class, Nesting.class, ParentImports.class, | |||||
Variables.class, ParentSelector.class }) | |||||
public class ScssTestSuite { | |||||
} |
package com.vaadin.sass; | |||||
import java.io.BufferedReader; | |||||
import java.io.File; | |||||
import java.io.FileReader; | |||||
import java.io.IOException; | |||||
import java.net.URISyntaxException; | |||||
import org.w3c.css.sac.CSSException; | |||||
public class TestBase { | |||||
protected ScssStylesheet stylesheet; | |||||
protected String originalScss; | |||||
protected String parsedScss; | |||||
protected String comparisonCss; | |||||
public ScssStylesheet getStyleSheet(String filename) | |||||
throws URISyntaxException, CSSException, IOException { | |||||
File file = getFile(filename); | |||||
stylesheet = ScssStylesheet.get(file); | |||||
return stylesheet; | |||||
} | |||||
public File getFile(String filename) throws URISyntaxException, | |||||
CSSException, IOException { | |||||
return new File(getClass().getResource(filename).toURI()); | |||||
} | |||||
public String getFileContent(String filename) throws IOException, | |||||
CSSException, URISyntaxException { | |||||
File file = getFile(filename); | |||||
return getFileContent(file); | |||||
} | |||||
/** | |||||
* Read in the full content of a file into a string. | |||||
* | |||||
* @param file | |||||
* the file to be read | |||||
* @return a String with the content of the | |||||
* @throws IOException | |||||
* when file reading fails | |||||
*/ | |||||
public String getFileContent(File file) throws IOException { | |||||
StringBuilder content = new StringBuilder(); | |||||
FileReader fileReader = new FileReader(file); | |||||
BufferedReader bufferedReader = new BufferedReader(fileReader); | |||||
String line = null; | |||||
// Handle the first line separately to get the right amount of line | |||||
// separators in the loop | |||||
if ((line = bufferedReader.readLine()) != null) { | |||||
content.append(line); | |||||
} | |||||
// Handle the rest of the lines | |||||
while ((line = bufferedReader.readLine()) != null) { | |||||
content.append(System.getProperty("line.separator")); | |||||
content.append(line); | |||||
} | |||||
bufferedReader.close(); | |||||
return content.toString(); | |||||
} | |||||
public boolean testParser(String file) throws CSSException, IOException, | |||||
URISyntaxException { | |||||
originalScss = getFileContent(file); | |||||
ScssStylesheet sheet = getStyleSheet(file); | |||||
parsedScss = sheet.toString(); | |||||
return parsedScss.equals(originalScss); | |||||
} | |||||
public boolean testCompiler(String scss, String css) { | |||||
try { | |||||
comparisonCss = getFileContent(css); | |||||
ScssStylesheet sheet = getStyleSheet(scss); | |||||
sheet.compile(); | |||||
parsedScss = sheet.toString(); | |||||
} catch (Exception e) { | |||||
return false; | |||||
} | |||||
return parsedScss.equals(comparisonCss); | |||||
} | |||||
} |
package com.vaadin.sass; | |||||
import org.junit.runner.RunWith; | |||||
import org.junit.runners.Suite; | |||||
import org.junit.runners.Suite.SuiteClasses; | |||||
import com.vaadin.sass.testcases.visitor.MixinVisitorTest; | |||||
import com.vaadin.sass.testcases.visitor.NestedPropertiesVisitorTest; | |||||
@RunWith(Suite.class) | |||||
@SuiteClasses({ NestedPropertiesVisitorTest.class, MixinVisitorTest.class }) | |||||
public class VisitorTestSuite { | |||||
} |
package com.vaadin.sass.parser; | |||||
import java.io.IOException; | |||||
import java.io.StringReader; | |||||
import org.junit.Assert; | |||||
import org.junit.Test; | |||||
import org.w3c.css.sac.CSSException; | |||||
import org.w3c.css.sac.InputSource; | |||||
import org.w3c.css.sac.LexicalUnit; | |||||
import com.vaadin.sass.handler.SCSSDocumentHandler; | |||||
import com.vaadin.sass.handler.SCSSDocumentHandlerImpl; | |||||
public class ParserTest { | |||||
@Test | |||||
public void testParsePropertyValue() throws CSSException, IOException { | |||||
Parser parser = new Parser(); | |||||
LexicalUnit value = parser.parsePropertyValue(new InputSource( | |||||
new StringReader("$margin/2;"))); | |||||
Assert.assertEquals("margin", value.getStringValue()); | |||||
Assert.assertEquals(SCSSLexicalUnit.SCSS_VARIABLE, | |||||
value.getLexicalUnitType()); | |||||
value = value.getNextLexicalUnit(); | |||||
Assert.assertEquals(LexicalUnit.SAC_OPERATOR_SLASH, | |||||
value.getLexicalUnitType()); | |||||
value = value.getNextLexicalUnit(); | |||||
Assert.assertEquals(LexicalUnit.SAC_INTEGER, value.getLexicalUnitType()); | |||||
Assert.assertEquals(2, value.getIntegerValue()); | |||||
} | |||||
@Test | |||||
public void testCanIngoreSingleLineComment() { | |||||
Parser parser = new Parser(); | |||||
SCSSDocumentHandler handler = new SCSSDocumentHandlerImpl(); | |||||
parser.setDocumentHandler(handler); | |||||
try { | |||||
parser.parseStyleSheet(new InputSource(new StringReader( | |||||
"//kjaljsföajsfalkj\n@12abcg;"))); | |||||
Assert.assertTrue(true); | |||||
} catch (Exception e) { | |||||
Assert.fail(e.getMessage()); | |||||
} | |||||
} | |||||
} |
package com.vaadin.sass.testcases.css; | |||||
import java.io.IOException; | |||||
import java.net.URISyntaxException; | |||||
import junit.framework.Assert; | |||||
import org.junit.Test; | |||||
import org.w3c.css.sac.CSSException; | |||||
import com.vaadin.sass.TestBase; | |||||
public class Comments extends TestBase { | |||||
String css = "/basic/comments.css"; | |||||
@Test | |||||
public void testParser() throws CSSException, URISyntaxException, | |||||
IOException { | |||||
testParser(css); | |||||
Assert.assertEquals("Original CSS and parsed CSS doesn't match", | |||||
originalScss, parsedScss); | |||||
} | |||||
} |
package com.vaadin.sass.testcases.css; | |||||
import java.io.IOException; | |||||
import java.net.URISyntaxException; | |||||
import junit.framework.Assert; | |||||
import org.junit.Test; | |||||
import org.w3c.css.sac.CSSException; | |||||
import com.vaadin.sass.TestBase; | |||||
public class EmptyBlock extends TestBase { | |||||
String css = "/basic/empty_block.css"; | |||||
@Test | |||||
public void testParser() throws CSSException, URISyntaxException, | |||||
IOException { | |||||
testParser(css); | |||||
Assert.assertEquals("Original CSS and parsed CSS doesn't match", | |||||
originalScss, parsedScss); | |||||
} | |||||
} |
package com.vaadin.sass.testcases.css; | |||||
import java.io.IOException; | |||||
import java.net.URISyntaxException; | |||||
import org.junit.Assert; | |||||
import org.junit.Test; | |||||
import org.w3c.css.sac.CSSException; | |||||
import com.vaadin.sass.ScssStylesheet; | |||||
import com.vaadin.sass.TestBase; | |||||
import com.vaadin.sass.handler.SCSSDocumentHandler; | |||||
import com.vaadin.sass.handler.SCSSDocumentHandlerImpl; | |||||
import com.vaadin.sass.parser.Parser; | |||||
import com.vaadin.sass.tree.BlockNode; | |||||
public class Interpolation extends TestBase { | |||||
String scss = "/scss/interpolation.scss"; | |||||
@Test | |||||
public void testParser() throws CSSException, URISyntaxException, | |||||
IOException { | |||||
Parser parser = new Parser(); | |||||
SCSSDocumentHandler handler = new SCSSDocumentHandlerImpl(); | |||||
parser.setDocumentHandler(handler); | |||||
parser.parseStyleSheet(getClass().getResource(scss).getPath()); | |||||
ScssStylesheet root = handler.getStyleSheet(); | |||||
Assert.assertEquals(3, root.getChildren().size()); | |||||
BlockNode blockNodeWithInterpolation = (BlockNode) root.getChildren() | |||||
.get(2); | |||||
} | |||||
} |
package com.vaadin.sass.testcases.css; | |||||
import java.io.IOException; | |||||
import java.net.URISyntaxException; | |||||
import junit.framework.Assert; | |||||
import org.junit.Test; | |||||
import org.w3c.css.sac.CSSException; | |||||
import com.vaadin.sass.TestBase; | |||||
public class Media extends TestBase { | |||||
String css = "/basic/media.css"; | |||||
@Test | |||||
public void testParser() throws CSSException, URISyntaxException, | |||||
IOException { | |||||
testParser(css); | |||||
Assert.assertEquals("Original CSS and parsed CSS doesn't match", | |||||
originalScss, parsedScss); | |||||
} | |||||
} |
package com.vaadin.sass.testcases.css; | |||||
import java.io.IOException; | |||||
import java.net.URISyntaxException; | |||||
import junit.framework.Assert; | |||||
import org.junit.Test; | |||||
import org.w3c.css.sac.CSSException; | |||||
import com.vaadin.sass.TestBase; | |||||
public class Properties extends TestBase { | |||||
String css = "/basic/properties.css"; | |||||
@Test | |||||
public void testParser() throws CSSException, URISyntaxException, | |||||
IOException { | |||||
testParser(css); | |||||
Assert.assertEquals("Original CSS and parsed CSS doesn't match", | |||||
originalScss, parsedScss); | |||||
} | |||||
} |
package com.vaadin.sass.testcases.css; | |||||
import java.io.IOException; | |||||
import java.net.URISyntaxException; | |||||
import junit.framework.Assert; | |||||
import org.junit.Test; | |||||
import org.w3c.css.sac.CSSException; | |||||
import com.vaadin.sass.TestBase; | |||||
public class Reindeer extends TestBase { | |||||
String css = "/basic/reindeer.css"; | |||||
@Test | |||||
public void testParser() throws CSSException, URISyntaxException, | |||||
IOException { | |||||
testParser(css); | |||||
Assert.assertEquals("Original CSS and parsed CSS doesn't match", | |||||
originalScss, parsedScss); | |||||
} | |||||
} |
package com.vaadin.sass.testcases.css; | |||||
import java.io.IOException; | |||||
import java.net.URISyntaxException; | |||||
import junit.framework.Assert; | |||||
import org.junit.Test; | |||||
import org.w3c.css.sac.CSSException; | |||||
import com.vaadin.sass.TestBase; | |||||
public class Selectors extends TestBase { | |||||
String css = "/basic/selectors.css"; | |||||
@Test | |||||
public void testParser() throws CSSException, URISyntaxException, | |||||
IOException { | |||||
testParser(css); | |||||
Assert.assertEquals("Original CSS and parsed CSS doesn't match", | |||||
originalScss, parsedScss); | |||||
} | |||||
} |
package com.vaadin.sass.testcases.scss; | |||||
import java.io.IOException; | |||||
import java.net.URISyntaxException; | |||||
import junit.framework.Assert; | |||||
import org.junit.Test; | |||||
import org.w3c.css.sac.CSSException; | |||||
import com.vaadin.sass.ScssStylesheet; | |||||
import com.vaadin.sass.TestBase; | |||||
import com.vaadin.sass.handler.SCSSDocumentHandler; | |||||
import com.vaadin.sass.handler.SCSSDocumentHandlerImpl; | |||||
import com.vaadin.sass.parser.Parser; | |||||
public class ControlDirectives extends TestBase { | |||||
String scss = "/scss/control-directives.scss"; | |||||
String css = "/css/control-directives.css"; | |||||
@Test | |||||
public void testParser() throws CSSException, IOException { | |||||
Parser parser = new Parser(); | |||||
SCSSDocumentHandler handler = new SCSSDocumentHandlerImpl(); | |||||
parser.setDocumentHandler(handler); | |||||
parser.parseStyleSheet(getClass().getResource(scss).getPath()); | |||||
ScssStylesheet root = handler.getStyleSheet(); | |||||
Assert.assertNotNull(root); | |||||
Assert.fail("Implement assert nodes"); | |||||
} | |||||
@Test | |||||
public void testCompiler() throws CSSException, URISyntaxException, | |||||
IOException { | |||||
testCompiler(scss, css); | |||||
Assert.assertEquals("Original CSS and parsed CSS doesn't match", | |||||
comparisonCss, parsedScss); | |||||
} | |||||
} |