--- a/org.symbian.tools.wrttools/bin/org/w3c/css/parser/analyzer/CssParser.jj Tue Jan 12 11:28:52 2010 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2425 +0,0 @@
-/* -*-java-extended-*-
- *
- * (c) COPYRIGHT MIT and INRIA, 1997.
- * Please first read the full copyright statement in file COPYRIGHT.html
- *
- * $Id: CssParser.jj,v 1.69 2009-10-11 09:19:37 ylafon Exp $
- *
- */
-
-options {
- IGNORE_CASE = true;
- STATIC = false;
- UNICODE_INPUT = true;
- /*
- DEBUG_TOKEN_MANAGER = true;
- DEBUG_PARSER = true;
- */
-}
-
-PARSER_BEGIN(CssParser)
-
-package org.w3c.css.parser.analyzer;
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
-import java.util.Vector;
-import java.util.Enumeration;
-import java.net.URL;
-
-import org.w3c.css.values.CssValue;
-import org.w3c.css.values.CssExpression;
-import org.w3c.css.values.CssString;
-import org.w3c.css.values.CssURL;
-import org.w3c.css.values.CssLength;
-import org.w3c.css.values.CssNumber;
-import org.w3c.css.values.CssColor;
-import org.w3c.css.values.CssIdent;
-import org.w3c.css.values.CssPercentage;
-import org.w3c.css.values.CssFrequency;
-import org.w3c.css.values.CssTime;
-import org.w3c.css.values.CssDate;
-import org.w3c.css.values.CssAngle;
-import org.w3c.css.values.CssFunction;
-import org.w3c.css.values.CssUnicodeRange;
-import org.w3c.css.values.CssResolution;
-import org.w3c.css.properties.css1.CssProperty;
-import org.w3c.css.parser.Frame;
-import org.w3c.css.util.ApplContext;
-import org.w3c.css.parser.CssError;
-import org.w3c.css.parser.CssSelectors;
-import org.w3c.css.parser.CssParseException;
-import org.w3c.css.parser.AtRule;
-import org.w3c.css.parser.AtRuleMedia;
-import org.w3c.css.parser.AtRuleFontFace;
-import org.w3c.css.parser.AtRulePage;
-import org.w3c.css.parser.AtRulePreference;
-import org.w3c.css.parser.AtRulePhoneticAlphabet;
-import org.w3c.css.properties.svg.AtRuleColorProfile;
-import org.w3c.css.util.InvalidParamException;
-import org.w3c.css.util.Util;
-import org.w3c.css.util.Messages;
-import org.w3c.css.css.StyleSheetCom;
-
-import org.w3c.css.selectors.AdjacentSiblingSelector;
-import org.w3c.css.selectors.AttributeSelector;
-import org.w3c.css.selectors.ChildSelector;
-import org.w3c.css.selectors.ClassSelector;
-import org.w3c.css.selectors.DescendantSelector;
-import org.w3c.css.selectors.GeneralSiblingSelector;
-import org.w3c.css.selectors.IdSelector;
-import org.w3c.css.selectors.TypeSelector;
-import org.w3c.css.selectors.UniversalSelector;
-import org.w3c.css.selectors.attributes.AttributeAny;
-import org.w3c.css.selectors.attributes.AttributeBegin;
-import org.w3c.css.selectors.attributes.AttributeExact;
-import org.w3c.css.selectors.attributes.AttributeOneOf;
-import org.w3c.css.selectors.attributes.AttributeStart;
-import org.w3c.css.selectors.attributes.AttributeSubstr;
-import org.w3c.css.selectors.attributes.AttributeSuffix;
-
-/**
- * A CSS3 parser
- *
- * @author Philippe Le Hegaret and Sijtsche Smeman
- * @version $Revision: 1.69 $
- */
-public abstract class CssParser {
-
- private static char hexdigits[] = { '0', '1', '2', '3',
- '4', '5', '6', '7',
- '8', '9', 'a', 'b',
- 'c', 'd', 'e', 'f' };
- // the current atRule
- protected AtRule atRule;
- protected String mediaDeclaration = "off";
-
- /**
- * The URL of the document
- */
- protected URL url;
-
- protected ApplContext ac;
-
- protected boolean incompatible_error;
-
- /**
- * The current context recognized by the parser (for errors).
- */
- protected Vector currentContext;
-
- /**
- * The current property recognized by the parser (for errors).
- */
- protected String currentProperty;
-
- /**
- * <code>true</code> if the parser should recognized Aural properties,
- * <code>false</code> otherwise.
- */
- protected boolean mode;
-
- /**
- * <code>true</code> if the parser had recognize a rule,
- * <code>false</code> otherwise.
- */
- protected boolean markRule;
-
- private boolean reinited = false;
- private boolean charsetdeclared = false;
-
- static StringBuilder SPACE = new StringBuilder(" ");
-
- // to be able to remove a ruleset if the selector is not valid
- protected boolean validSelector = true;
-
- /**
- * The ac for handling errors and warnings.
- *
- * @param ac the new ac for the parser.
- */
- public final void setApplContext(ApplContext ac) {
- this.ac = ac;
- }
-
- /**
- * Set the attribute atRule
- *
- * @param atRule the new value for the attribute
- */
- public void setAtRule(AtRule atRule) {
- this.atRule = atRule;
- }
-
- /**
- * Set the attribute mediaDeclaration
- *
- * @param mediaDeclaration indicator if in a media expression list or not
- */
- public void setMediaDeclaration(String mediadeclaration) {
- this.mediaDeclaration = mediadeclaration;
- }
-
- /**
- * Returns the attribute mediaDeclaration
- *
- * @return the value of the attribute
- */
- public String getMediaDeclaration() {
- return mediaDeclaration;
- }
-
- /**
- * Returns the attribute atRule
- *
- * @return the value of the attribute
- */
- public AtRule getAtRule() {
- return atRule;
- }
-
- /**
- * Reinitialized the parser.
- *
- * @param stream the stream data to parse.
- * @param ac the new ac to use for parsing.
- */
- public void ReInitWithAc(InputStream stream, ApplContext ac,
- String charset)
- {
- InputStream is = /*new CommentSkipperInputStream(stream);*/stream;
- if (charset == null) {
- charset = "iso-8859-1";
- }
- InputStreamReader isr = null;
- try {
- isr = new InputStreamReader(is, charset);
- } catch (UnsupportedEncodingException uex) {
- isr = new InputStreamReader(is);
- }
- // reinit, it can not happen...
- // ...in theory ;)
- ReInit(isr);
- markRule = false;
- reinited = true;
- setApplContext(ac);
- }
-
- /* utilities for a parser */
-
- /**
- * Call by the import statement.
- *
- * @param url The style sheet where this import statement appears.
- * @param file the file name in the import
- */
- public abstract void handleImport(URL url, String file,
- boolean is_url, AtRuleMedia media);
-
- /**
- * Call by the namespace declaration statement.
- *
- * @param url The style sheet where this namespace statement appears.
- * @param file the file/url name in the namespace declaration
- */
- public abstract void handleNamespaceDeclaration(URL url, String prefix,
- String file,
- boolean is_url);
-
- /**
- * Call by the at-rule statement.
- *
- * @param ident The ident for this at-rule (for example: 'font-face')
- * @param string The string associate to this at-rule
- * @see org.w3c.css.parser.Analyzer.Couple
- */
- public abstract void handleAtRule(String ident, String string);
-
- /* added by Sijtsche Smeman */
- public abstract void addCharSet(String charset);
- public abstract void newAtRule(AtRule atRule);
- public abstract void endOfAtRule();
- public abstract void setImportant(boolean important);
- public abstract void setSelectorList(Vector selectors);
- public abstract void addProperty(Vector properties);
- public abstract void endOfRule();
- public abstract void removeThisRule();
- public abstract void removeThisAtRule();
-
- /**
- * Assign an expression to a property. This function create a new property
- * with <code>property</code> and assign to it the expression with the
- * importance. Don't forget to set informations too.
- * <p>
- * A subclass must provide an implementation of this method.
- *
- * @param property the name of the property
- * @param values the expression representation of values
- * @param important <code>true</code> if values are important
- *
- * @return <code>null</code>or a property
- *
- * @see org.w3c.css.css.CssProperty
- */
- public abstract CssProperty handleDeclaration(String property,
- CssExpression values,
- boolean important)
- throws InvalidParamException;
-
- /**
- * Adds a vector of properties to a selector.
- * <p>
- * A subclass must provide an implementation of this method.
- *
- * @param selector the selector
- * @param declarations Properties to associate with contexts
- */
- public abstract void handleRule(CssSelectors selector,
- Vector declarations);
-
- /*Added by Sijtsche Smeman */
-
- /**
- * Returns the source file of the style sheet
- */
- public final String getSourceFile() {
- return getURL().toString();
- }
-
- /**
- * Returns the current line in the style sheet
- */
- public final int getLine() {
- //return token.beginLine;
- return 0;
- }
-
- /**
- * Set the URL of the style sheet.
- *
- * @param URL The URL for the style sheet
- */
- public final void setURL(URL url) {
- this.url = url;
- }
-
- public final URL getURL() {
- return url;
- }
-
- /**
- * Return the next selector from the inputstream
- */
- public CssSelectors parseSelector() throws ParseException {
- return externalSelector();
- }
-
- /*
- * Add a value to an expression
- */
- private void setValue(CssValue v, CssExpression expr,
- char operator, Token n, int token)
- throws ParseException {
- if (n != null) {
- if (ac.getCssVersion().equals("css1") &&
- (n.image).equals("inherit")) {
- incompatible_error = true;
- }
- String val = (operator == ' ') ? n.image : operator+n.image;
-
- if (n.kind == CssParserConstants.IDENT) {
- v.set(convertIdent(val), ac);
- } else if (n.kind == CssParserConstants.STRING) {
- v.set(val, ac);
- } else {
- v.set(val, ac);
- }
- }
- expr.addValue(v);
- }
-
- /*
- * Error control
- */
- private void addError(Exception e, String skippedText) {
- if (Util.onDebug) {
- System.err.println(e.getMessage());
- e.printStackTrace();
- }
- CssParseException ex = new CssParseException(e);
- ex.setSkippedString(skippedText);
- ex.setProperty(currentProperty);
- ex.setContexts(currentContext);
- CssError error = new CssError(getSourceFile(), getLine(), ex);
- ac.getFrame().addError(error);
- }
-
- /*
- * Error control 2
- */
- private void addError(Exception e, CssExpression exp) {
- if (Util.onDebug) {
- System.err.println(e.getMessage());
- e.printStackTrace();
- }
-
- // if ((exp != null) && (exp.getCount() != 0)) {
- CssParseException ex = new CssParseException(e);
- ex.setExp(exp);
- ex.setProperty(currentProperty);
- ex.setContexts(currentContext);
- CssError error = new CssError(getSourceFile(), getLine(), ex);
- ac.getFrame().addError(error);
- // }
- }
-}
-
-PARSER_END(CssParser)
-
-/*
- * The tokenizer
- */
-
-<DEFAULT>
-SPECIAL_TOKEN :
-{
- < COMMENT : "/*" ( ~["*"] )* ( "*" )+ ( ~["/", "*"] ( ~["*"] )* ( "*" )+ )* "/" >
-}
-
-<DEFAULT>
- TOKEN [IGNORE_CASE] : /* basic tokens */
-{
- < #H : ["0"-"9", "a"-"f"] >
- | < #NONASCII : ["\200"-"\377"] >
- | < #UNICODE : "\\" <H> ( <H> )? ( <H> )? ( <H> )? ( <H> )? ( <H> )?
- ( "\r\n" | [ " ", "\t" , "\n" , "\r", "\f" ] )? >
- | < #ESCAPE : <UNICODE> | ( "\\" ~[ "\r", "\n", "\f", "0"-"9", "a"-"f" ] ) >
- | < #NMSTART : [ "a"-"z", "_" ] | <NONASCII> | <ESCAPE> >
- | < #NMCHAR : ["a"-"z", "0"-"9", "-", "_"] | <NONASCII> | <ESCAPE> >
- | < #STRING1 : "\"" ( ~[ "\n", "\r", "\f", "\\", "\"" ] | "\\" <NL> | <ESCAPE> )* "\"" >
- | < #STRING2 : "\'" ( ~[ "\n", "\r", "\f", "\\", "\'" ] | "\\" <NL> | <ESCAPE> )* "\'" >
- | < #INVALID1 : "\"" ( ~[ "\n", "\r", "\f", "\\", "\"" ] | "\\" <NL> | <ESCAPE> )* >
- | < #INVALID2 : "\'" ( ~[ "\n", "\r", "\f", "\\", "\'" ] | "\\" <NL> | <ESCAPE> )* >
- | < #_IDENT : ( <MINUS> )? <NMSTART> ( <NMCHAR> )* >
- | < #NAME : ( <NMCHAR> )+ >
- | < #NUM : ( ["0"-"9"] )+ | ( ["0"-"9"] )* "." ( ["0"-"9"] )+ >
- | < #_STRING : <STRING1> | <STRING2> >
- | < #_INVALID : <INVALID1> | <INVALID2> >
- | < #_URL : ( [ "!", "#", "$", "%", "&", "*"-"[", "]"-"~" ] | <NONASCII> | <ESCAPE> )* >
- | < #_S : ( [ " ", "\t" , "\n" , "\r", "\f" ] ) ( <COMMENT> | [ " ", "\t" , "\n" , "\r", "\f" ] )* >
- | < #_W : ( <_S> )? >
- | < #NL : ( "\n" | "\r\n" | "\r" | "\f" ) >
-}
-/*
- * The _S definition is not ( [ " ", "\t" , "\n" , "\r", "\f" ] ) + as we need to add support
- * for the unput(' ') (see http://www.w3.org/TR/CSS21/grammar.html#scanner )
- */
-
-<DEFAULT>
-TOKEN :
-{
- < S : ( <_S> ) >
-}
-
-<DEFAULT>
- TOKEN :
-{
- < CDO : "<!--" >
- | < CDC : "-->" >
- | < INCLUDES : <TILDE> "=" >
- | < DASHMATCH : "|=" >
-}
-
-<DEFAULT>
-TOKEN :
-{
- < LBRACE : <_W> "{" >
- | < PLUS : <_W> "+" >
- | < GREATER : <_W> ">" >
- | < COMMA : <_W> "," >
- | < TILDE : <_W> "~" >
-}
-
-<DEFAULT>
-TOKEN [IGNORE_CASE] :
-{
- < AND : "and" >
-}
-
-<DEFAULT>
-TOKEN :
-{
- <STRING : <_STRING> >
- | <INVALID : <_INVALID> >
- | <IDENT : <_IDENT> >
- | <HASHIDENT : "#" <_IDENT> >
- | <HASH : "#" <NAME> >
-}
-
-<DEFAULT>
-TOKEN :
-{
- < RBRACE : "}">
- | < PREFIXMATCH : "^=" >
- | < SUFFIXMATCH : "$=" >
- | < SUBSTRINGMATCH : "*=" >
- | < EQ : "=" >
- | < MINUS : "-" >
- | < SEMICOLON : ";" >
- | < DIV : "/" >
- | < LBRACKET : "[" >
- | < RBRACKET : "]" >
- | < ANY : "*" >
- | < DOT : "." >
- | < LPARAN : ")" >
- | < RPARAN : "(">
-}
-
-<DEFAULT>
- TOKEN :
-{
- < COLON : ":" >
-}
-
-<DEFAULT>
-TOKEN [IGNORE_CASE] :
-{
- < MEDIARESTRICTOR : "only" | "not" >
-}
-
-<DEFAULT>
-TOKEN [IGNORE_CASE] :
-{
- < URL : "url(" ( <S> )* ( <STRING> | <_URL> ) ( <S> )* ")" >
-}
-
-<DEFAULT>
-TOKEN [IGNORE_CASE] :
-{
- < LENGTH : <NUM> "pt"
- | <NUM> "mm"
- | <NUM> "cm"
- | <NUM> "pc"
- | <NUM> "in"
- | <NUM> "gd"
- | <NUM> "px" >
- | < EMS : <NUM> "em" >
- | < EXS : <NUM> "ex" >
- | < ANGLE : <NUM> ( "deg" | "grad" | "rad" ) >
- | < TIME : <NUM> ( "ms" | "s" ) >
- | < FREQ : <NUM> "Hz" | <NUM> "kHz" >
- | < RESOLUTION : <NUM> "dpi" | <NUM> "dpcm" >
- | < DATE : <NUM> "/" <NUM> "/" <NUM> >
- | < DIMEN : <NUM> <NMSTART> ( <NMCHAR> )* >
- | < PERCENTAGE : <NUM> "%" >
- | < NUMBER : <NUM> >
-}
-
-<DEFAULT>
-TOKEN [IGNORE_CASE] :
-{
- < IMPORTANT_SYM : "!" ( <_W> )* "important" >
-}
-
-<DEFAULT>
-TOKEN :
-{
- <PSEUDOELEMENT_SYM : "::" >
-}
-
-/* RESERVED ATRULE WORDS */
-<DEFAULT>
-TOKEN :
-{
- < CHARSET_SYM : "@charset" >
-}
-
-<DEFAULT>
-TOKEN [IGNORE_CASE] :
-{
- < IMPORT_SYM : "@import">
- | < NAMESPACE_SYM : "@namespace">
- | < MEDIA_SYM : "@media" >
- | < PAGE_SYM : "@page" >
- | < FONT_FACE_SYM : "@font-face" >
- | < PREF_SYM : "@preference" >
- | < COLOR_PROFILE : "@color-profile" >
- | < ATTOP : "@top" >
- | < ATRIGHT : "@right" >
- | < ATBOTTOM : "@bottom" >
- | < ATLEFT : "@left" >
- | < ATCOUNTER : "@counter" >
- | < PHONETIC_ALPHABET_SYM : "@phonetic-alphabet" >
- | < ATKEYWORD : "@" <IDENT> >
-}
-
-<DEFAULT>
-TOKEN [IGNORE_CASE] :
-{
- < #RANGE0 : <H> <H> <H> <H> <H> <H> >
- | < #RANGE1 : <H> <H> <H> <H> <H> ( "?" )? >
- | < #RANGE2 : <H> <H> <H> <H> ( "?" )? ( "?" )? >
- | < #RANGE3 : <H> <H> <H> ( "?" )? ( "?" )? ( "?" )? >
- | < #RANGE4 : <H> <H> ( "?" )? ( "?" )? ( "?" )? ( "?" )? >
- | < #RANGE5 : <H> ( "?" )? ( "?" )? ( "?" )? ( "?" )? ( "?" )? >
- | < #RANGE6 : "?" ( "?" )? ( "?" )? ( "?" )? ( "?" )? ( "?" )? >
- | < #RANGE : <RANGE0> | <RANGE1> | <RANGE2>
- | <RANGE3> | <RANGE4> | <RANGE5> | <RANGE6> >
- | < #UNI : <H> ( <H> )? ( <H> )? ( <H> )? ( <H> )? ( <H> )? >
- | < UNICODERANGE : "U+" <RANGE> | "U+" <UNI> "-" <UNI> >
-}
-
-<DEFAULT>
- TOKEN:
-{
- < CLASS : "." <IDENT> >
-}
-
-/* FIXED, added a spacial case for lang pseudoclass */
-<DEFAULT>
-TOKEN [IGNORE_CASE] :
-{
- < FUNCTIONLANG : "lang(" >
-}
-
-<DEFAULT>
-TOKEN [IGNORE_CASE] :
-{
- < FUNCTIONNOT : ":not(" >
-}
-
-
-<DEFAULT>
- TOKEN :
-{
- < FUNCTION : <IDENT> "(" >
-}
-
-/* Quick and dirty way to catch HTML tags starting CSS documents
- (common mistake) */
-<DEFAULT>
- TOKEN:
-{
- <HTMLSTARTTAG : "<" ( <S> )* <IDENT> ( <S> )*
- ( <IDENT> "=" ( <IDENT> | <STRING> ) ( <S> )* )*
- ">" >
- | <HTMLENDTAG : "</" ( <S> )* <IDENT> ( <S> )* ">" >
-}
-
-//<DEFAULT, IN_COMMENT>
-//TOKEN :
-//{ /* avoid token manager error */
-// < UNKNOWN : ~[] >
-//}
-
-/*
- * The grammar of CSS2
- */
-
-/**
- * The main entry for the parser.
- *
- * @exception ParseException exception during the parse
- */
-void parserUnit() :
-{
- Token n = null;
-}
-{
- try {
- // used as an error recovery for HTML tags in CSS pages
- ( ( n=<HTMLSTARTTAG> | n=<HTMLENDTAG> ) {
- addError (
-new ParseException(ac.getMsg().getString("generator.dontmixhtml")), n.image);
- }
- )*
- ( charset() )* // * instead of ? to capture the reinit part
- ( <S> | <CDO> | <CDC> )*
- ( importDeclaration() ( ignoreStatement() ) )*
- ( namespaceDeclaration() ( ignoreStatement() ) )*
- afterImportDeclaration()
- <EOF>
- } catch (TokenMgrError err) {
- addError (new ParseException(ac.getMsg().getString("generator.unrecognize")),
- err.getMessage());
- }
-}
-
-void charset() :
-{
- Token n = null;
- Token charsetToken = null;
- Token space1Token = null;
- Token space2Token = null;
- Token semicolonToken = null;
- int nb_S = 0;
-}
-{
- try {
- charsetToken=<CHARSET_SYM> ( space1Token=<S> { nb_S++;} )*
- n=<STRING> ( space2Token=<S> )* semicolonToken=<SEMICOLON>
- {
- if (charsetdeclared && !reinited) {
- throw new ParseException(
- ac.getMsg().getString("parser.charset"));
- }
- // the @charset must be at the beginning of the document
- if(charsetToken.beginLine != 1 ||
- charsetToken.beginColumn != 1) {
- throw new ParseException(
- ac.getMsg().getString("parser.charset"));
- }
- if ("css1".equals(ac.getCssVersion())) {
- throw new ParseException(ac.getMsg().getString(
- "parser.charsetcss1"));
- }
- // stricter rule for CSS21 and soon for CSS3
- if ("css21".equals(ac.getCssVersion())) {
- // single space before
- // case sensitive
- // no space before ;
- // no comments
- // string must start with "
- if ( (nb_S != 1) ||
- (!"@charset".equals(charsetToken.image)) ||
- (!" ".equals(space1Token.image)) ||
- (space2Token != null &&
- !"".equals(space2Token.image)) ||
- (space1Token.specialToken != null) ||
- (n.specialToken != null) ||
- (semicolonToken.specialToken != null) ||
- (n.image.charAt(0) != '\"')
- ) {
- throw new ParseException(ac.getMsg().getString(
- "parser.charsetspecial"));
- }
- }
- if (!charsetdeclared) {
- addCharSet(n.image.substring(1, n.image.length()-1));
- charsetdeclared = true;
- } else {
- reinited = false;
- }
- }
- } catch (Exception e) {
- String skip = charsetToken +
- ((space1Token == null) ? "" : space1Token.image) +
- n +
- ((space2Token == null) ? "" : space2Token.image) +
- ";";
- addError(e, skip);
- }
-}
-
-void afterImportDeclaration() :
-{String ret; }
-{
- ( ( ruleSet() | media() | page() | fontFace() | preference() |
- colorprofile() | phoneticAlphabet() | ret=skipStatement()
- { if ((ret == null) || (ret.length() == 0)) {
- return;
- }
- // quite ugly but necessary to avoid probably a lot of changes in the
- // grammar, still having a beautiful error message
- else if (ret.startsWith("@charset")) {
- ParseException e =
- new ParseException(ac.getMsg().getString("parser.charset"));
- addError(e, ret);
- } else if (ret.startsWith("@import")) {
- ParseException e =
- new ParseException(ac.getMsg().getString("parser.import_not_allowed"));
- addError(e, ret);
- } else {
- ParseException e =
- new ParseException(ac.getMsg().getString("generator.unrecognize"));
- addError(e, ret);
- }
- }
- ) ignoreStatement() )*
-}
-
-void ignoreStatement() :
-{}
-{
- ( ( <CDO> | <CDC> | atRuleDeclaration() ) ( <S> )* )*
-}
-
-void namespaceDeclaration() :
-{
- Token n=null;
- Token v=null;
- boolean is_url; /* for formatting */
- String nsname;
- String prefix = null;
- CssValue val;
-}
-{
- // FIXME add namespaces in context to match when a definition happens
- ( <NAMESPACE_SYM>
- ( <S> )*
- ( n=<IDENT> {
- prefix = convertIdent(n.image);
- }
- ( <S> )* )?
- ( v=<STRING> {
- is_url = false;
- nsname = v.image.substring(1, v.image.length()-1);
- }
- | v=<URL> {
- is_url = true;
- val = new CssURL();
- ((CssURL) val).set(v.image, ac, url);
- nsname = (String) val.get();
- if ((nsname.charAt(0) == '"')
- || (nsname.charAt(0) == '\'')) {
- nsname = nsname.substring(1, nsname.length()-1);
- }
- }
- )
- ( <S> )*
- <SEMICOLON>
- ( <S> )*
- ) {
- if (!ac.getCssVersion().equals("css3")) {
- addError(new InvalidParamException("at-rule", "@namespace", ac),
- (n==null)?"default":n.toString());
- } else {
- if (v != null) {
- handleNamespaceDeclaration(getURL(), prefix, nsname, is_url);
- }
- }
- }
-}
-/**
- * The import statement
- *
- * @exception ParseException exception during the parse
- */
-void importDeclaration() :
-{Token n;
- AtRuleMedia media = new AtRuleMedia();
- CssValue val;
- String importFile;
- boolean is_url = false;
-}
-{
- try {
- <IMPORT_SYM> ( <S> )*
- ( n=<STRING> {
- importFile = n.image.substring(1, n.image.length() -1);
- is_url = false;
- }
- | n=<URL> {
- val = new CssURL();
- ((CssURL) val).set(n.image, ac, url);
- importFile = (String) val.get();
- if ((importFile.charAt(0) == '"')
- || (importFile.charAt(0) == '\'')) {
- importFile = importFile.substring(1, importFile.length()-1);
- }
- is_url = true;
- }
- )
- ( <S> )*
- ( medium(media)
- ( <COMMA> ( <S> )* medium(media)
- )* )? <SEMICOLON>
- ( <S> )*
- {
- handleImport(getURL(), importFile, is_url, media);
- }
- } catch (ParseException e) {
- addError(e, skipStatement());
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void media() :
-{
- AtRule old = getAtRule();
- AtRuleMedia newRule = new AtRuleMedia();
- setAtRule(newRule);
- Token n;
- CssProperty p = null;
-}
-{
- try {
- <MEDIA_SYM> ( <S> )*
- // <CSS3>
- (n=<MEDIARESTRICTOR> { newRule.addMediaRestrictor(convertIdent(n.image), ac); } ( <S> )+)?
- medium(newRule)
- // </CSS3>
- ( <COMMA> ( <S> )* medium(newRule) )*
- // <CSS3>
- (<AND> ( <S> )* <RPARAN> ( <S> )* p=mediadeclaration() { newRule.addMediaFeature(p); } <LPARAN> ( <S> )* )*
- // </CSS3>
-
- {
- String media = getAtRule().toString();
- if (ac.getMedium() != null &&
- !(media.equals(ac.getMedium())) &&
- !(ac.getMedium().equals("all"))) {
-
- ac.getFrame().addWarning("noothermedium",
- getAtRule().toString());
- }
- if (ac.getCssVersion().equals("css1")) {
- skipStatement();
- addError(new InvalidParamException("noatruleyet", "", ac),
- getAtRule().toString());
- }
- if (!ac.getCssVersion().equals("css1")) {
- newAtRule(getAtRule());
- }
- }
- <LBRACE> ( <S> )* ( ruleSet() )* <RBRACE> ( <S> )*
- {
- if (!ac.getCssVersion().equals("css1")) {
- endOfAtRule();
- }
- }
- } catch (ParseException e) {
- if (!ac.getCssVersion().equals("css1")) {
- addError(e, skipStatement());
- }
- } finally {
- setAtRule(old);
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void medium(AtRuleMedia media) : /* tv, projection, screen, ... */
-{Token n;}
-{
- n=<IDENT> ( <S> )*
- {
- try {
- media.addMedia(convertIdent(n.image), ac);
- } catch (InvalidParamException e) {
- CssError error = new CssError(getSourceFile(), getLine(), e);
- ac.getFrame().addError(error);
- }
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void page() :
-{
- Vector v ;
- Token n = null ;
- Vector collectv = new Vector() ;
- CssSelectors s = new CssSelectors(ac);
- AtRule old = getAtRule() ;
- AtRulePage newRule = new AtRulePage() ;
- setAtRule(newRule);
- s.setAtRule(getAtRule());
-}
-{
- try {
- <PAGE_SYM> ( <S> )*
- // FIXME <CSS3> ?
- ( n=<IDENT> { newRule.setIdent(convertIdent(n.image)); }
- ( <S> )* )?
- // </CSS3>
- ( pseudo_page(newRule) )? <LBRACE> ( <S> )* ( v=pageContent()
- {
- collectv = v;
- }
- ) <RBRACE> ( <S> )*
- {
- if (!ac.getCssVersion().equals("css1")) {
- newAtRule(getAtRule());
- }
-
- if (!ac.getCssVersion().equals("css1")) {
- addProperty(collectv);
- endOfRule();
- endOfAtRule();
- }
- if (v == null) {
- ac.getFrame().addWarning("no-declaration");
- } else {
- handleRule(s, collectv);
- }
- }
- } catch (InvalidParamException ie) {
- if (!ac.getCssVersion().equals("css1")) {
- skipStatement();
- removeThisAtRule();
- ac.getFrame().addError(new CssError(ie));
- }
- } catch (ParseException e) {
- if (!ac.getCssVersion().equals("css1")) {
- removeThisAtRule();
- addError(e, skipStatement());
- }
- } finally {
- setAtRule(old);
- }
-}
-
-Vector pageContent() :
-{ CssProperty prop;
- Vector v = new Vector();
-}
-{
- // <CSS3> ?? FIXME
- v=prefAtRule() { return v;}
- // </CSS3>
- |
- v=declarations() { return v;} /* FIXME moved here as it can match empty string */
-}
-
-Vector prefAtRule() :
-{ Token n;
- Vector v;
-}
-{
- try {
- (n=<ATTOP> | n=<ATBOTTOM> | n=<ATLEFT> | n=<ATRIGHT> ) ( <S> )*
- <LBRACE> ( <S> )* v=declarations() <RBRACE> ( <S> )*
- {
- return v;
- }
- } catch (ParseException e) {
- addError(e, skipStatement());
- }
-}
-
-void pseudo_page(AtRulePage page) :
-{ Token n; }
-{
- ":" n=<IDENT> ( <S> )*
- {
- try {
- page.setName(":" + convertIdent(n.image), ac);
- } catch (InvalidParamException e) {
- throw new InvalidParamException("pseudo", n.image, ac );
- /*CssError error = new CssError(getSourceFile(), getLine(), e);
- ac.getFrame().addError(error); */
- }
- }
-}
-
-void fontFace() :
-{
- Vector v;
- AtRule old = getAtRule();
- setAtRule(new AtRuleFontFace());
- CssSelectors s = new CssSelectors(ac);
- s.setAtRule(getAtRule());
-}
-{
- try {
- <FONT_FACE_SYM> ( <S> )*
- {
- if (ac.getCssVersion().equals("css1")) {
- skipStatement();
- addError(new InvalidParamException("noatruleyet", "", ac),
- getAtRule().toString());
- }
- if (!ac.getCssVersion().equals("css1")) {
- newAtRule(getAtRule());
- }
-
- }
- <LBRACE> ( <S> )* v=declarations() <RBRACE> ( <S> )*
- {
- if (!ac.getCssVersion().equals("css1")) {
- addProperty(v);
- endOfRule();
- endOfAtRule();
- }
- if (v == null) {
- ac.getFrame().addWarning("no-declaration");
- } else {
- handleRule(s, v);
- }
- }
- } catch (ParseException e) {
- if (!ac.getCssVersion().equals("css1")) {
- addError(e, skipStatement());
- }
- } finally {
- setAtRule(old);
- }
-}
-
-void colorprofile() :
-{
- Vector v;
- AtRule old = getAtRule();
- setAtRule(new AtRuleColorProfile());
- CssSelectors s = new CssSelectors(ac);
- s.setAtRule(getAtRule());
-}
-{
- try {
- <COLOR_PROFILE> ( <S> )*
- {
- if (!ac.getCssVersion().equals("svg")) {
- skipStatement();
- addError(new InvalidParamException("onlysvg", "", ac),
- getAtRule().toString());
- }
- if (ac.getCssVersion().equals("svg")) {
- newAtRule(getAtRule());
- }
-
- }
- <LBRACE> ( <S> )* v=declarations() <RBRACE> ( <S> )*
- {
- if (ac.getCssVersion().equals("svg")) {
- addProperty(v);
- endOfRule();
- endOfAtRule();
- }
-
- if (v == null) {
- //ac.getFrame().addWarning("medialist");
- } else {
- handleRule(s, v);
- }
- }
- }
- catch (ParseException e) {
- if (ac.getCssVersion().equals("svg")) {
- addError(e, skipStatement());
- }
- } finally {
- setAtRule(old);
- }
-}
-
-
-void preference() :
-{
- Vector v;
- AtRule old = getAtRule();
- setAtRule(new AtRulePreference());
- CssSelectors s = new CssSelectors(ac);
- s.setAtRule(getAtRule());
-}
-{
- try {
- <PREF_SYM> ( <S> )*
- {
- if (ac.getCssVersion().equals("css1")) {
- skipStatement();
- addError(new InvalidParamException("noatruleyet", "", ac),
- getAtRule().toString());
- }
- if (!ac.getCssVersion().equals("css1")) {
- newAtRule(getAtRule());
- }
-
- }
- <LBRACE> ( <S> )* v=declarations() <RBRACE> ( <S> )*
- {
- if (!ac.getCssVersion().equals("css1")) {
- addProperty(v);
- endOfRule();
- endOfAtRule();
- }
-
- if (v == null) {
- ac.getFrame().addWarning("medialist");
- } else {
- handleRule(s, v);
- }
- }
- }
- catch (ParseException e) {
- if (!ac.getCssVersion().equals("css1")) {
- addError(e, skipStatement());
- }
- } finally {
- setAtRule(old);
- }
-}
-
-void phoneticAlphabet() :
-{
- Vector v;
- AtRule old = getAtRule();
- AtRulePhoneticAlphabet alphabetrule = new AtRulePhoneticAlphabet();
- setAtRule(alphabetrule);
- Token n;
-}
-{
- try {
- <PHONETIC_ALPHABET_SYM> ( <S> )* n=<STRING> ( <S> )* ";"
- {
- if (!ac.getCssVersion().equals("css3")) {
- skipStatement();
- addError(new InvalidParamException("noatruleyet", "", ac),
- getAtRule().toString());
- }
-
- alphabetrule.addAlphabet(convertIdent(n.image), ac);
-
- if (!ac.getCssVersion().equals("css1") && !ac.getCssVersion().equals("css2")) {
- newAtRule(getAtRule());
- }
-
- }
- } catch (ParseException e) {
- if (!ac.getCssVersion().equals("css1")) {
- addError(e, skipStatement());
- }
- } finally {
- setAtRule(old);
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void atRuleDeclaration() :
-{Token n;}
-{
- n=<ATKEYWORD>
- {
- //ac.getFrame().addWarning("at-rule", token.toString());
- ac.getFrame().addError(
- new CssError(new InvalidParamException("at-rule",
- token, ac)));
- skipStatement();
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void operator(CssExpression expr) :
-{}
-{
- ( ( <DIV> { if (expr.getCount() > 0) expr.setOperator('/'); }
- | <COMMA> { if (expr.getCount() > 0) expr.setOperator(','); }
- ) ( <S> )* )?
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-char combinator() :
-{
- char connector = ' ';
-}
-{
- ( ( <PLUS> { connector = '+' ; }
- | <GREATER> { connector = '>' ; }
- | <TILDE> { connector = '~' ; }
- ) ( <S> )*
- | ( <S> )+ { connector = ' ' ; }
- )
- {
- return connector;
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-char unaryOperator() :
-{}
-{
- // FIXME <MINUS> | <PLUS> ? warning as <PLUS> is <_W>? "+"
- "-" { return '-'; }
- | <PLUS> { return '+'; }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-String property() :
-{Token n; }
-{
- n=<IDENT> ( <S> )* { currentProperty = convertIdent(n.image);
- return currentProperty; }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void ruleSet() :
-{ CssSelectors contextual;
- Vector<CssSelectors> context_set = new Vector<CssSelectors>();
- Vector<CssProperty> value_set = null;
- currentContext = context_set;
-}
-{
- try {
- contextual=selector()
- {
- if (contextual != null) {
- context_set.addElement(contextual);
- }
- }
-
- ( <COMMA> ( <S> )*
- contextual=selector()
- {
- if (contextual != null) {
- context_set.addElement(contextual);
- }
- }
- )*
- <LBRACE> {
- validSelector = (context_set.size() > 0);
- }
- ( <S> )*
- value_set=declarations()
- <RBRACE> ( <S> )*
- {
- markRule = true;
-
- /* if (value_set == null) {
- ac.getFrame().addWarning("no-declaration");
- } else {*/
- if (value_set != null) {
- boolean first = true;
- CssSelectors sel = null;
- Enumeration<CssSelectors> e = context_set.elements();
- while (e.hasMoreElements()) {
- sel = e.nextElement();
- if (first) {
- handleRule(sel, value_set);
- first = false;
- } else {
- // we need to duplicate properties in that case
- // as property holds reference to the selectors and it interact
- // badly with conflict detection
- int vsize = value_set.size();
- Vector<CssProperty> v = new Vector<CssProperty>(vsize);
- for (int i=0; i<vsize; i++) {
- v.addElement(value_set.elementAt(i).duplicate());
- }
- handleRule(sel, v);
- }
- }
- setSelectorList(context_set);
- endOfRule();
- }
- currentContext = null;
- }
- } catch (ParseException e) {
- if (ac.getProfile() != null) {
- if (!ac.getProfile().equals("mobile") && !context_set.isEmpty()) {
- addError(e, skipStatement());
- }
- }
- } catch (TokenMgrError e) {
- addError(new ParseException(e.getMessage()), skipStatement());
- }
-}
-
-Vector<CssProperty> declarations() :
-{
- if(!validSelector) {
- validSelector = true;
- skip_to_matching_brace();
- return null;
- }
-
- CssProperty values;
- Vector<CssProperty> value_set = new Vector<CssProperty>();
- boolean wrong_value = true;
-}
-{
- ( values=declaration()
- { if (values != null) {
- value_set.addElement(values);
- wrong_value = false;
- } /* else {
- wrong_value = true;
- } */
- currentProperty = null;
- }
- )?
- ( ";" ( <S> )*
- ( values=declaration()
- { if (values != null) {
- value_set.addElement(values);
- wrong_value = false;
- }/* else {
- wrong_value = true;
- }*/
- currentProperty = null;
- }
- )? )*
- {
- if (!wrong_value) {
- addProperty(value_set);
- return value_set;
- } else {
- return null;
- }
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-CssSelectors selector() :
-{ char comb;
- CssSelectors current; }
-{
- try {
- current=simple_selector(null)
- (
- comb=combinator() {
- if (ac.getProfile() != null) {
- if (ac.getProfile().equals("mobile") ||
- getAtRule().toString().equals("@media atsc-tv") ||
- ac.getCssVersion().equals("css1")) {
- if (comb == '+')
- throw new InvalidParamException("nocomb", "+", ac);
- if (comb == '>')
- throw new InvalidParamException("nocomb", ">", ac);
- } else if (ac.getProfile().equals("tv")) {
- if (comb == '+')
- throw new InvalidParamException("nocomb", "+", ac);
-
- }
- }
- if (!ac.getCssVersion().equals("css3")) {
- if (comb == '~') {
- throw new InvalidParamException("nocomb", "~", ac);
- }
- }
- switch(comb) {
- case '+':
- current.addAdjacentSibling(new AdjacentSiblingSelector());
- break;
- case '>':
- current.addChild(new ChildSelector());
- break;
- case '~':
- current.addGeneralSibling(new GeneralSiblingSelector());
- break;
- default:
- current.addDescendant(new DescendantSelector());
- }
- //current.setConnector(comb);
- }
- current=simple_selector(current)
- )*
- { return current; }
- }
- catch (InvalidParamException ie) {
- // skipStatement();
- // removeThisRule();
- ac.getFrame().addError(new CssError(ie));
- Token t = getToken(1);
- StringBuilder s = new StringBuilder();
- s.append(getToken(0).image);
- // eat until , { or EOF
- while ((t.kind != COMMA) && (t.kind != LBRACE) && (t.kind != EOF)) {
- s.append(t.image);
- getNextToken();
- t = getToken(1);
- }
- return null;
- }
- catch (ParseException e) {
- // validSelector = false;
- Token t = getToken(1);
- StringBuilder s = new StringBuilder("[");
- s.append(getToken(0).image);
- // eat until , { or EOF
- while ((t.kind != COMMA) && (t.kind != LBRACE) && (t.kind != EOF)) {
- s.append(t.image);
- getNextToken();
- t = getToken(1);
- }
- s.append(']');
- // if (validSelector) {
- addError(e, s.toString());
- // } else {
- // addError(e,"");
- // }
- validSelector = true;
- return null;
- }
-}
-
-/**
- * I made this rule to parse a selector from a document. Combinator are avoid.
- * @exception ParseException exception during the parse
- */
-CssSelectors externalSelector() :
-{
- CssSelectors current; }
-{
- current=simple_selector(null)
- ( ( <S> )+
- current=simple_selector(current)
- )*
- { return current; }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-CssSelectors simple_selector(CssSelectors next) :
-{ CssSelectors selector = new CssSelectors(ac, next);
- selector.setAtRule(getAtRule());
- //selector.setUserMedium(getUserMedium());
-}
-{
-
- element_name(selector) ( hash(selector) | _class(selector)
- | attrib(selector) | pseudo(selector)
- | negation(selector) )*
- {
- return selector;
- }
- | ( hash(selector) | _class(selector) | attrib(selector)
- | pseudo(selector) | negation(selector) )+
- {
- return selector;
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void _class(CssSelectors s) :
-{Token n; }
-{
- /* "." n=<IDENT> { */
- n=<CLASS> {
- try {
- s.addClass(new ClassSelector(convertClassIdent(n.image.substring(1))));
- // s.addAttribute("class", convertIdent(n.image.substring(1)),
- // CssSelectors.ATTRIBUTE_CLASS_SEL);
- } catch (InvalidParamException e) {
- // removeThisRule();
- ac.getFrame().addError(new CssError(e));
- throw new ParseException(e.getMessage());
- }
- }
- /* FIXME <DOT> n=deprecated_class() ... ?? (DONE-> to be tested) */
- | ( n=deprecated_class() ) {
- if (n.image.charAt(0) == '.') {
- n.image = n.image.substring(1);
-
- // the class with the first digit escaped
- String cl = "."+hexEscapeFirst(n.image);
-
- String profile = ac.getProfile();
- if(profile == null || profile.equals("") || profile.equals("none")) {
- profile = ac.getCssVersion();
- }
-
- if(!profile.equals("css1")) {
- StringBuilder sb = new StringBuilder();
- Vector<String> param_err = new Vector<String>(2);
- param_err.add(n.image);
- param_err.add(cl);
- sb.append(ac.getMsg().getString("parser.old_class", param_err));
- throw new ParseException(sb.toString());
- // s.addClass(new ClassSelector(n.image));
- // removeThisRule();
- }
- else {
- CssLength length = new CssLength();
- boolean isLength = false;
- try {
- length.set(n.image, ac);
- isLength = true;
- }
- catch(Exception e) {
- isLength = false;
- }
- if(isLength) {
- StringBuilder sb = new StringBuilder();
- sb.append(ac.getMsg().getString("parser.class_dim"));
- sb.append(n.image);
- throw new ParseException(sb.toString());
- // s.addClass(new ClassSelector(n.image));
- // removeThisRule();
- }
- else {
- try {
- // for css > 1, we add the rule to have a context,
- // and we then remove it
- s.addClass(new ClassSelector(n.image));
- ac.getFrame().addWarning("old_class");
- } catch (InvalidParamException e) {
- throw new ParseException(e.getMessage());
- //ac.getFrame().addError(new CssError(e));
- //removeThisRule();
- }
- }
- }
- } else {
- throw new ParseException("Unrecognized ");
- }
- }
-}
-
-Token deprecated_class() :
-{
- Token n;
-}
-{
- ( n=<LENGTH>
- | n=<EMS>
- | n=<EXS>
- | n=<ANGLE>
- | n=<TIME>
- | n=<FREQ>
- | n=<RESOLUTION>
- | n=<DIMEN> )
- {
- return n;
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void element_name(CssSelectors s) :
-{
- Token n=null;
- Token p=null;
- String prefix = null;
-}
-{
- ( LOOKAHEAD(2) (n=<IDENT> | n=<ANY>)? p="|" )? {
- // FIXME namespace, check versions of CSS in a better way.
- if (p != null) {
- if (!ac.getCssVersion().equals("css3")) {
- StringBuilder sb = new StringBuilder("namespace \"");
- if (n != null) sb.append(n.toString());
- sb.append("\"");
- ac.getFrame().addError(new CssError(new
- InvalidParamException("notversion",
- "namespace",
- ac.getCssVersion(),
- ac)));
- removeThisRule();
- } else if (n!=null) {
- prefix = convertIdent(n.image);
- if (!ac.isNamespaceDefined(getURL(), prefix)) {
- // ns is not defined
- addError(new ParseException("Undefined namespace"),
- ": The namespace \""+prefix
- +"\" is not defined. "
- + prefix );
- removeThisRule();
- }
- } else {
- prefix = "";
- }
- }
- }
- ( n=<IDENT> { // s.setElement(convertIdent(n.image), ac);
- s.addType(new TypeSelector(prefix, convertIdent(n.image)));
- }
- | <ANY> {
- if (!ac.getCssVersion().equals("css1")) {
- // s.setElement(null);
- s.addUniversal(new UniversalSelector(prefix));
- } else {
- ac.getFrame().addError(new CssError(new InvalidParamException("notversion",
- "*", ac.getCssVersion(), ac)));
- }
- }
- )
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void attrib(CssSelectors s) :
-{
- Token att = null;
- Token val = null;
- int selectorType = CssSelectors.ATTRIBUTE_ANY;
-}
-{
- <LBRACKET> ( <S> )* att=<IDENT> ( <S> )*
- ( (<EQ> { selectorType = CssSelectors.ATTRIBUTE_EXACT; }
- | <INCLUDES> { selectorType = CssSelectors.ATTRIBUTE_ONE_OF; }
- | <DASHMATCH> { selectorType = CssSelectors.ATTRIBUTE_BEGIN; }
- | <PREFIXMATCH> { selectorType = CssSelectors.ATTRIBUTE_START; }
- | <SUFFIXMATCH> { selectorType = CssSelectors.ATTRIBUTE_SUFFIX; }
- | <SUBSTRINGMATCH> { selectorType = CssSelectors.ATTRIBUTE_SUBSTR; }
- ) ( <S> )*
- ( val=<IDENT>
- { val.image = convertIdent(val.image); }
- | val=<STRING>
- { val.image = convertStringIndex(val.image, 1, val.image.length() -1, false);}
- )
- ( <S> )* )?
- <RBRACKET>
- {
- if ("css1".equals(ac.getCssVersion())) {
- StringBuilder reason;
- CssParseException cp;
- ParseException p;
- reason = new StringBuilder(" [");
- if (att != null) {
- reason.append(convertIdent(att.image));
- }
- if (val != null ) {
- reason.append('=').append(val.image);
- }
- reason.append(']');
- p = new ParseException(ac.getMsg().getString("parser.attrcss1")+
- reason.toString());
- cp = new CssParseException(p);
- ac.getFrame().addError(new CssError(cp));
- removeThisRule();
- }
- if (selectorType == CssSelectors.ATTRIBUTE_ANY) {
- try {
- s.addAttribute(new AttributeAny(att.image.toLowerCase()));
-// s.addAttribute(att.image.toLowerCase(), null, selectorType);
- } catch (InvalidParamException e) {
- removeThisRule();
- ac.getFrame().addError(new CssError(e));
- }
- } else {
- AttributeSelector attribute;
- switch(selectorType) {
- case CssSelectors.ATTRIBUTE_BEGIN:
- attribute = new AttributeBegin(att.image.toLowerCase(),
- val.image);
- break;
- case CssSelectors.ATTRIBUTE_EXACT:
- attribute = new AttributeExact(att.image.toLowerCase(),
- val.image);
- break;
- case CssSelectors.ATTRIBUTE_ONE_OF:
- attribute = new AttributeOneOf(att.image.toLowerCase(),
- val.image);
- break;
- case CssSelectors.ATTRIBUTE_START:
- attribute = new AttributeStart(att.image.toLowerCase(),
- val.image);
- break;
- case CssSelectors.ATTRIBUTE_SUBSTR:
- attribute = new AttributeSubstr(att.image.toLowerCase(),
- val.image);
- break;
- case CssSelectors.ATTRIBUTE_SUFFIX:
- attribute = new AttributeSuffix(att.image.toLowerCase(),
- val.image);
- break;
- default:
- attribute = new AttributeExact(att.image.toLowerCase(),
- val.image);
- break;
- }
- try {
- s.addAttribute(attribute);
-// s.addAttribute(att.image.toLowerCase(), val.image,
-// selectorType);
- } catch (InvalidParamException e) {
- removeThisRule();
- ac.getFrame().addError(new CssError(e));
- }
- }
- }
-}
-
-void negation(CssSelectors s) :
-{
- Token n;
- CssSelectors ns = new CssSelectors(ac, null);
-}
-{ // S* negation_arg S* ')'
- // type_selector | universal | HASH | class | attrib | pseudo
-
- <FUNCTIONNOT> ( <S> )*
- (
- element_name(ns) |
- hash(ns) |
- _class(ns) |
- attrib(ns) |
- pseudo(ns)
- )
- ( <S> )* <LPARAN>
- {
- s.setPseudoFun("not", ns.toString());
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void pseudo(CssSelectors s) :
-{Token n;
-Token language = null;
-CssExpression param = null;
-}
-{
- <PSEUDOELEMENT_SYM> ( ( n=<IDENT>
- {
- try {
- if (ac.getCssVersion().equals("css3")) {
- s.addPseudoElement(convertIdent(n.image).toLowerCase());
- } else {
- throw new InvalidParamException("pseudo-element",
- "::" + convertIdent(n.image).toLowerCase() ,
- ac.getCssVersion() ,ac);
- }
- } catch(InvalidParamException e) {
- // removeThisRule();
- // ac.getFrame().addError(new CssError(e));
- validSelector = false;
- throw new ParseException(e.getMessage());
- }
- } ) )
- |
- <COLON> ( ( n=<IDENT>
- {
- try {
- s.addPseudoClass(convertIdent(n.image).toLowerCase());
- } catch(InvalidParamException e) {
- removeThisRule();
- ac.getFrame().addError(new CssError(e));
- }
- } )
- // FXIXME rewrite to make :lang( use a special case
- | ( ( n=<FUNCTIONLANG> ( <S> )* (language=<NUMBER> | language=<IDENT> | language=<STRING> ) ( <S> )* ) {
- try {
- s.setPseudoFun(convertStringIndex(n.image, 0,
- n.image.length() -1, false).toLowerCase(),
- convertIdent(language.image));
- } catch(InvalidParamException e) {
- removeThisRule();
- ac.getFrame().addError(new CssError(e));
- }
- }
- | ( n=<FUNCTION> ( <S> )* param=expression() ) {
- try {
- s.setPseudoFun(convertStringIndex(n.image, 0,
- n.image.length() -1,
- false).toLowerCase(),
- param.toString());
- } catch(InvalidParamException e) {
- removeThisRule();
- ac.getFrame().addError(new CssError(e));
- }
- }
- ) <LPARAN>
- )
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void hash(CssSelectors s) :
-{Token n; }
-{
- n=<HASHIDENT> {
- n.image = n.image.substring(1);
- if(Character.isDigit(n.image.charAt(0))) {
- String profile = ac.getProfile();
- if(profile == null || profile.equals("") || profile.equals("none")) {
- profile = ac.getCssVersion();
- }
-
- if(!profile.equals("css1")) {
- // the id with the first digit escaped
- String cl = "\\" + Integer.toString(n.image.charAt(0), 16);
- cl += n.image.substring(1);
-
- addError(new ParseException(ac.getMsg().getString(
- "parser.old_id")),
- "To make \"." + n.image + "\" a valid id, CSS2" +
- " requires the first digit to be escaped " +
- "(\"#" + cl + "\")");
- // for css > 1, we add the rule to have a context,
- // and we then remove it
- s.addId(new IdSelector(n.image));
- removeThisRule();
- }
- else {
- CssLength length = new CssLength();
- boolean isLength = false;
- try {
- length.set(n.image, ac);
- isLength = true;
- }
- catch(Exception e) {
- isLength = false;
- }
- if(isLength) {
- addError(new ParseException(ac.getMsg().getString(
- "parser.id_dim")), n.image);
- // we add the rule to have a context, and then we remove it
- s.addId(new IdSelector(n.image));
- removeThisRule();
- }
- else {
- try {
- s.addId(new IdSelector(n.image));
- ac.getFrame().addWarning("old_id");
- } catch (InvalidParamException e) {
- ac.getFrame().addError(new CssError(e));
- removeThisRule();
- }
- }
- }
- }
- else {
- try {
- s.addId(new IdSelector(n.image));
- } catch (InvalidParamException e) {
- ac.getFrame().addError(new CssError(e));
- removeThisRule();
- }
- }
- }
- | n=<HASH> {
- throw new ParseException(ac.getMsg().getString("parser.invalid_id_selector"));
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-CssProperty mediadeclaration() :
-{ String string_property;
- CssExpression values = null;
- boolean important = false;
- setMediaDeclaration("on");
-}
-{
-try {
- string_property=property() (":" ( <S> )*
- values=expr() ( important=prio() )? )?
- {
-
- try {
-
- setImportant(important);
-
- if (incompatible_error) {
- throw new InvalidParamException("notforcss1", "inherit", ac);
- }
-
- CssProperty p = handleDeclaration(string_property.toLowerCase(),
- values, important);
- return p;
-
- } catch (InvalidParamException e) {
- incompatible_error = false;
- if (null != values) {
- values.starts();
- }
- addError(e, (CssExpression) values);
- }
- return null;
- }
- } catch (NumberFormatException e) {
- skipAfterExpression(e);
- return null;
- } catch (ParseException e) {
- skipAfterExpression(e);
- return null;
- } finally {
- setMediaDeclaration("off");
- }
-}
-
-
-/**
- * @exception ParseException exception during the parse
- */
-CssProperty declaration() :
-{ String string_property;
- CssExpression values;
- boolean important = false;
-}
-{
-try {
- string_property=property() ":" ( <S> )*
- values=expr() ( important=prio() )?
- {
- try {
-
- setImportant(important);
-
- if (incompatible_error) {
- throw new InvalidParamException("notforcss1", "inherit", ac);
- }
-
- if (values.getCount() != 0) {
- CssProperty p = handleDeclaration(string_property.toLowerCase(),
- values, important);
- // Did the property recognize all values in the expression ?
-
- if (!values.end() && ac.getMedium() == null) {
- addError(new InvalidParamException("unrecognize", "", ac),
- values);
- } else {
- // ok, return the new property
- return p;
- }
- }
- } catch (InvalidParamException e) {
- incompatible_error = false;
- values.starts();
- addError(e, (CssExpression) values);
- }
- return null;
- }
- } catch (NumberFormatException e) {
- skipAfterExpression(e);
- return null;
- } catch (ParseException e) {
- skipAfterExpression(e);
- return null;
- } catch (NullPointerException e) {
- // NullPointerException happen if in handling a property
- // something bad happen (like setting values on sub properties
- // that had not been initialized (for an unknown reason yet).
- skipAfterExpression(e);
- return null;
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-boolean prio() :
-{}
-{
- <IMPORTANT_SYM> ( <S> )* { return true; }
-}
-
-CssExpression expression() :
-{
- CssExpression exp = new CssExpression();
- char operator = ' ';
- Token n = null;
-}
-{
- ( ( <PLUS> { operator = '+' ; }
- | <MINUS> { operator = '-'; }
- | n=<NUMBER> { setValue(new CssNumber(), exp, operator, n, NUMBER); }
- // FIXME dimen should be a CssDimension()
- | n=<DIMEN> { setValue(new CssIdent(), exp, operator, n, IDENT); }
- | n=<STRING> { setValue(new CssString(), exp, operator, n, STRING); }
- | n=<IDENT> { setValue(new CssIdent(), exp, operator, n, IDENT); }
- ) ( <S> )* )+
- { return exp; }
-}
-/**
- * @exception ParseException exception during the parse
- */
-CssExpression expr() :
-{
- CssExpression values = new CssExpression();
-}
-{
- term(values) ( operator(values) term(values) )*
- { return values; }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void term(CssExpression exp) :
-{ Token n;
- char operator = ' ';
- CssValue func;
-}
-{
- ( ( operator=unaryOperator() )?
- ( n=<NUMBER> { setValue(new CssNumber(), exp, operator, n, NUMBER); }
- | n=<PERCENTAGE> { setValue(new CssPercentage(), exp, operator, n,
- PERCENTAGE); }
- | n=<LENGTH> { setValue(new CssLength(), exp, operator, n, LENGTH); }
- | n=<EMS> { setValue(new CssLength(), exp, operator, n, EMS); }
- | n=<EXS> { setValue(new CssLength(), exp, operator, n, EXS); }
- | n=<ANGLE> { setValue(new CssAngle(), exp, operator, n, ANGLE);}
- | n=<TIME> { setValue(new CssTime(), exp, operator, n, TIME); }
- | n=<FREQ> { setValue(new CssFrequency(), exp, operator, n, FREQ); }
- | n=<RESOLUTION> { setValue(new CssResolution(), exp, operator, n, RESOLUTION); }
- | n=<DATE> { setValue(new CssDate(), exp, operator, n, DATE); }
- | n=<DIMEN> {
- addError(new ParseException(ac.getMsg().getString("parser.unknown-dimension")), n.image); }
- | func=function() { setValue(func, exp, operator, null, FUNCTION); }
- ) ( <S> )* )
- | (( n=<STRING> { setValue(new CssString(), exp, operator, n, STRING); }
- | n=<IDENT>
- {
- /*
- * Common error :
- * H1 {
- * color : black
- * background : white
- * }
- */
- Token t = getToken(1);
- Token semicolon = new Token();
- semicolon.kind = SEMICOLON;
- semicolon.image = ";";
- if (t.kind == COLON) {
- /* @@SEEME. (generate a warning?) */
- /* @@SEEME if expression is a single ident,
- generate an error ? */
- addError(new ParseException(ac.getMsg().getString("parser.semi-colon")),
- (CssExpression) null);
- rejectToken(semicolon);
- } else {
- setValue(new CssIdent(), exp, operator, n, IDENT);
- }
- }
- | hexcolor(exp)
- | n=<URL> {
- CssURL _u = new CssURL();
- _u.set(n.image, ac, url);
- exp.addValue(_u);
- }
- | n=<UNICODERANGE> { setValue(new CssUnicodeRange(), exp, operator, n,
- UNICODERANGE); }
- ) ( <S> )* )
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-CssValue function() :
-{Token n;
- CssExpression exp;
- org.w3c.css.values.CssColor color = new org.w3c.css.values.CssColor();
- org.w3c.css.values.ATSCColor colorATSC = new org.w3c.css.values.ATSCColor();
-}
-{
- n=<FUNCTION> ( <S> )* exp=expr()
- ")" {
- String funcname = n.image.toLowerCase();
- if (funcname.equals("rgb(")) {
- if (!getAtRule().toString().equals("@media atsc-tv")) {
- color.setRGBColor(exp, ac);
- return color;
- } else {
- colorATSC.setRGBColor(exp, ac);
- return colorATSC;
- }
- } else if (n.image.toLowerCase().equals("atsc-rgba(")) {
- if (getAtRule().toString().equals("@media atsc-tv")) {
- colorATSC.setATSCrgba(exp, ac);
- return colorATSC;
- } else {
- addError(new InvalidParamException("onlyATSC", "", ac),
- getAtRule().toString());
- return null;
- }
- } else {
- CssFunction f = new CssFunction();
- f.set(n.image.substring(0, n.image.length() - 1),
- exp);
- return f;
- }
- }
-}
-
-/**
- * @exception ParseException exception during the parse
- */
-void hexcolor(CssExpression exp) :
-{Token n;
-}
-{
- ( n=<HASHIDENT> | n=<HASH> ) {
- n.image = Util.strip(n.image);
- setValue(new org.w3c.css.values.CssColor(), exp, ' ', n, HASH);
- }
-}
-
-/*
- * @@SEEME EOF
- */
-
-JAVACODE
-String skipStatement() {
- StringBuilder s = new StringBuilder();
- Token tok = getToken(0);
- boolean first = true;
-
- if (tok.image != null) {
- s.append(tok.image);
- }
- /* FIXME here, two option, we skip during an error, or outside
- an error, currently both can fail with a TokenMgrError, should
- we catch all, or only when filling message for errors?
-
- -> taking the "always skip" approach.
- */
- while (true) {
- try {
- tok = getToken(1);
- if (tok.kind == EOF) {
- if (first) {
- return null;
- } else {
- break;
- }
- }
- s.append(tok.image);
- if (tok.kind == LBRACE) {
- getNextToken();
- s.append(skip_to_matching_brace());
- getNextToken();
- tok = getToken(1);
- break;
- } else if ((tok.kind == RBRACE) || (tok.kind == SEMICOLON)) {
- getNextToken();
- tok = getToken(1);
- break;
- }
- getNextToken();
- } catch (TokenMgrError tokenerror) {
- // read one char at a time, and loop
- try {
- s.append(jj_input_stream.readChar());
- continue;
- } catch (java.io.IOException ioex) {
- return s.toString().trim();
- }
- }
- first = false;
- }
-
- // skip white space
- while (tok.kind == S) {
- getNextToken();
- tok = getToken(1);
- }
- String statement = s.toString().trim();
- return statement;
-}
-
-JAVACODE
-String skip_to_matching_brace() {
- StringBuilder s = new StringBuilder();
- Token tok;
- int nesting = 1;
- /* FIXME
- same as above */
- while (true) {
- tok = getToken(1);
- if (tok.kind == EOF) {
- break;
- }
- s.append(tok.image);
- if (tok.kind == LBRACE) {
- nesting++;
- } else if (tok.kind == RBRACE) {
- nesting--;
- if (nesting == 0) {
- break;
- }
- }
- getNextToken();
- }
- return s.toString();
-}
-
-/*
- * @@HACK
- * I can't insert a token into the tokens flow.
- * It's jj_consume_token implementation dependant! :-(
- */
-JAVACODE
-void rejectToken(Token t) {
- Token fakeToken = new Token();
- t.next = token;
- fakeToken.next = t;
- token = fakeToken;
-}
-
-/** skip after an expression
- */
-JAVACODE
-void skipAfterExpression(Exception e) {
- StringBuilder s = new StringBuilder();
- s.append(getToken(0).image);
- while (true) {
- try {
- Token t = getToken(1);
- if (t.kind == LBRACE) {
- s.append(t.image);
- getNextToken();
- s.append(skip_to_matching_brace());
- getNextToken();
- t = getToken(1);
- continue;
- }
- if ((t.kind == SEMICOLON) || (t.kind == RBRACE)
- || (t.kind == EOF)) {
- break;
- }
- s.append(t.image);
- getNextToken();
- t = getToken(1);
- } catch (TokenMgrError tmerr) {
- try {
- s.append(jj_input_stream.readChar());
- continue;
- } catch (java.io.IOException ioex) {
- ioex.printStackTrace();
- break;
- }
- }
- }
- String statement = s.toString().trim();
- addError(e, s.toString());
-}
-
-JAVACODE
-String convertStringIndex(String s, int start, int len, boolean escapeFirst) {
- int index = start;
- int t;
- int maxCount = 0;
- if ((start == 0) && (len == s.length()) && (s.indexOf('\\') == -1)) {
- return s;
- }
- StringBuilder buf = new StringBuilder(len);
-
- while (index < len) {
- char c = s.charAt(index);
- if (c == '\\') {
- if (++index < len) {
- c = s.charAt(index);
- switch (c) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- int numValue = Character.digit(c, 16);
- int count = 1;
- if (maxCount == 0) {
- maxCount = (ac.getCssVersion().equals("css1") ?
- 4 : 6);
- }
- while (index + 1 < len) {
- c = s.charAt(index+1);
- t = Character.digit(c, 16);
- if (t != -1 && count++ < maxCount) {
- numValue = (numValue<<4) | t;
- index++;
- } else {
- if (c == ' ' || c == '\t' ||
- c == '\n' || c == '\f' ) {
- // skip the latest white space
- index++;
- } else if ( c == '\r' ) {
- index++;
- // special case for \r\n
- if (index+1 < len) {
- if (s.charAt(index + 1) == '\n') {
- index++;
- }
- }
- }
- break;
- }
- }
- if (!escapeFirst && numValue < 255 && numValue>31) {
- if (! ( (numValue>96 && numValue<123) // [a-z]
- || (numValue>64 && numValue<91) // [A-Z]
- || (numValue>47 && numValue<58) // [0-9]
- || (numValue == 95) // _
- || (numValue == 45) // -
- )
- ) {
- buf.append('\\');
- }
- buf.append((char) numValue);
- break;
- }
- char b[] = new char[maxCount];
- t = maxCount;
- while (t > 0) {
- b[--t] = hexdigits[numValue & 0xF];
- numValue >>>= 4;
- }
- buf.append('\\').append(b);
- break;
- case '\n':
- case '\f':
- break;
- case '\r':
- if (index + 1 < len) {
- if (s.charAt(index + 1) == '\n') {
- index ++;
- }
- }
- break;
- case '-' : case '_' : case 'g' : case 'G' :
- case 'h' : case 'H' : case 'i' : case 'I' :
- case 'j' : case 'J' : case 'k' : case 'K' :
- case 'l' : case 'L' : case 'm' : case 'M' :
- case 'n' : case 'N' : case 'o' : case 'O' :
- case 'p' : case 'P' : case 'q' : case 'Q' :
- case 'r' : case 'R' : case 's' : case 'S' :
- case 't' : case 'T' : case 'u' : case 'U' :
- case 'v' : case 'V' : case 'w' : case 'W' :
- case 'x' : case 'X' : case 'y' : case 'Y' :
- case 'z' : case 'Z' :
- buf.append(c);
- break;
- default:
- buf.append('\\').append(c);
- }
- } else {
- throw new ParseException("invalid string");
- }
- } else {
- buf.append(c);
- }
- escapeFirst = false;
- index++;
- }
- return buf.toString();
-}
-
-JAVACODE
-String convertIdent(String s) {
- return convertStringIndex(s, 0, s.length(), false);
-}
-
-JAVACODE
-String convertClassIdent(String s) {
- return convertStringIndex(s, 0, s.length(), true);
-}
-
-JAVACODE
-String convertString(String s) {
- return convertStringIndex(s, 0, s.length(), false);
-}
-
-JAVACODE
-String hexEscapeFirst(String s) {
- StringBuilder sb = new StringBuilder();
- sb.append('\\').append(Integer.toString(s.charAt(0), 16));
- char c = s.charAt(1);
- if (((c >= '0') && (c <= '9')) ||
- ((c >= 'A') && (c <= 'F')) ||
- ((c >= 'a') && (c <= 'f'))) {
- sb.append(' ');
- }
- sb.append(s.substring(1));
- return sb.toString();
-}
-/*
- * compile-command: javacc CssParser.jj & jc CssParser.java
- */