use of com.helger.css.parser.CSSNode in project ph-css by phax.
the class CSSReaderDeclarationList method readFromReader.
/**
* Read the CSS from the passed {@link Reader}.
*
* @param aReader
* The reader to use. Will be closed automatically after reading -
* independent of success or error. May not be <code>null</code>.
* @param aSettings
* The settings to be used for reading the CSS. May not be
* <code>null</code>.
* @return <code>null</code> if reading failed, the CSS declarations
* otherwise.
* @since 3.8.2
*/
@Nullable
public static CSSDeclarationList readFromReader(@Nonnull @WillClose final Reader aReader, @Nonnull final CSSReaderSettings aSettings) {
ValueEnforcer.notNull(aReader, "Reader");
ValueEnforcer.notNull(aSettings, "Settings");
final ECSSVersion eVersion = aSettings.getCSSVersion();
try {
final CSSCharStream aCharStream = new CSSCharStream(aReader);
// Use the default CSS parse error handler if none is provided
ICSSParseErrorHandler aRealParseErrorHandler = aSettings.getCustomErrorHandler();
if (aRealParseErrorHandler == null)
aRealParseErrorHandler = getDefaultParseErrorHandler();
// Use the default CSS exception handler if none is provided
ICSSParseExceptionCallback aRealParseExceptionHandler = aSettings.getCustomExceptionHandler();
if (aRealParseExceptionHandler == null)
aRealParseExceptionHandler = getDefaultParseExceptionHandler();
final CSSNode aNode = _readStyleDeclaration(aCharStream, eVersion, aRealParseErrorHandler, aRealParseExceptionHandler);
// Failed to parse content as CSS?
if (aNode == null)
return null;
// Get the interpret error handler
ICSSInterpretErrorHandler aRealInterpretErrorHandler = aSettings.getInterpretErrorHandler();
if (aRealInterpretErrorHandler == null)
aRealInterpretErrorHandler = getDefaultInterpretErrorHandler();
// Convert the AST to a domain object
return CSSHandler.readDeclarationListFromNode(eVersion, aNode, aRealInterpretErrorHandler);
} finally {
StreamHelper.close(aReader);
}
}
use of com.helger.css.parser.CSSNode in project ph-css by phax.
the class CSSReader method readFromStream.
/**
* Read the CSS from the passed {@link IHasInputStream}. If the CSS contains
* an explicit charset, the whole CSS is parsed again, with the charset found
* inside the file, so the passed {@link IHasInputStream} must be able to
* create a new input stream on second invocation!
*
* @param aISP
* The input stream provider to use. Must be able to create new input
* streams on every invocation, in case an explicit charset node was
* found. May not be <code>null</code>.
* @param aSettings
* The settings to be used for reading the CSS. May not be
* <code>null</code>.
* @return <code>null</code> if reading failed, the CSS declarations
* otherwise.
* @since 3.8.2
*/
@Nullable
public static CascadingStyleSheet readFromStream(@Nonnull final IHasInputStream aISP, @Nonnull final CSSReaderSettings aSettings) {
ValueEnforcer.notNull(aISP, "InputStreamProvider");
ValueEnforcer.notNull(aSettings, "Settings");
Charset aCharsetToUse;
// Check if the CSS contains a declared charset or as an alternative use the
// Charset from the BOM
Charset aDeclaredCharset;
try {
aDeclaredCharset = getCharsetDeclaredInCSS(aISP);
} catch (final IllegalStateException ex) {
// Failed to parse CSS at a very low level
return null;
}
if (aDeclaredCharset != null) {
if (s_aLogger.isDebugEnabled())
s_aLogger.debug("Reading CSS definition again with explicit charset '" + aDeclaredCharset.name() + "'");
aCharsetToUse = aDeclaredCharset;
} else {
// No charset declared - use fallback
aCharsetToUse = aSettings.getFallbackCharset();
}
// Try to open input stream
final InputStream aISOrig = aISP.getInputStream();
if (aISOrig == null)
return null;
// Open input stream
final InputStreamAndCharset aISAndBOM = CharsetHelper.getInputStreamAndCharsetFromBOM(aISOrig);
final InputStream aIS = aISAndBOM.getInputStream();
final Reader aReader = StreamHelper.createReader(aIS, aCharsetToUse);
final ECSSVersion eVersion = aSettings.getCSSVersion();
try {
final CSSCharStream aCharStream = new CSSCharStream(aReader);
aCharStream.setTabSize(aSettings.getTabSize());
// Use the default CSS parse error handler if none is provided
ICSSParseErrorHandler aRealParseErrorHandler = aSettings.getCustomErrorHandler();
if (aRealParseErrorHandler == null)
aRealParseErrorHandler = getDefaultParseErrorHandler();
// Use the default CSS exception handler if none is provided
ICSSParseExceptionCallback aRealParseExceptionHandler = aSettings.getCustomExceptionHandler();
if (aRealParseExceptionHandler == null)
aRealParseExceptionHandler = getDefaultParseExceptionHandler();
final boolean bBrowserCompliantMode = aSettings.isBrowserCompliantMode();
final CSSNode aNode = _readStyleSheet(aCharStream, eVersion, aRealParseErrorHandler, aRealParseExceptionHandler, bBrowserCompliantMode);
// Failed to parse content as CSS?
if (aNode == null)
return null;
// Get the interpret error handler
ICSSInterpretErrorHandler aRealInterpretErrorHandler = aSettings.getInterpretErrorHandler();
if (aRealInterpretErrorHandler == null)
aRealInterpretErrorHandler = getDefaultInterpretErrorHandler();
// Convert the AST to a domain object
return CSSHandler.readCascadingStyleSheetFromNode(eVersion, aNode, aRealInterpretErrorHandler);
} finally {
StreamHelper.close(aReader);
}
}
use of com.helger.css.parser.CSSNode in project ph-css by phax.
the class CSSReaderDeclarationList method isValidCSS.
/**
* Check if the passed reader can be resembled to valid CSS content. This is
* accomplished by fully parsing the CSS each time the method is called. This
* is similar to calling
* {@link #readFromStream(IHasInputStream, Charset, ECSSVersion)} and checking
* for a non-<code>null</code> result.
*
* @param aReader
* The reader to use. May not be <code>null</code>.
* @param eVersion
* The CSS version to use. May not be <code>null</code>.
* @return <code>true</code> if the CSS is valid according to the version,
* <code>false</code> if not
*/
public static boolean isValidCSS(@Nonnull @WillClose final Reader aReader, @Nonnull final ECSSVersion eVersion) {
ValueEnforcer.notNull(aReader, "Reader");
ValueEnforcer.notNull(eVersion, "Version");
try {
final CSSCharStream aCharStream = new CSSCharStream(aReader);
final CSSNode aNode = _readStyleDeclaration(aCharStream, eVersion, getDefaultParseErrorHandler(), new DoNothingCSSParseExceptionCallback());
return aNode != null;
} finally {
StreamHelper.close(aReader);
}
}
use of com.helger.css.parser.CSSNode in project ph-css by phax.
the class CSSNodeToDomainObject method _createMediaRule.
@Nonnull
private CSSMediaRule _createMediaRule(@Nonnull final CSSNode aNode) {
_expectNodeType(aNode, ECSSNodeType.MEDIARULE);
final CSSMediaRule ret = new CSSMediaRule();
ret.setSourceLocation(aNode.getSourceLocation());
for (final CSSNode aChildNode : aNode) {
if (ECSSNodeType.MEDIALIST.isNode(aChildNode, m_eVersion)) {
for (final CSSNode aMediaListChildNode : aChildNode) ret.addMediaQuery(_createMediaQuery(aMediaListChildNode));
} else if (ECSSNodeType.STYLERULE.isNode(aChildNode, m_eVersion)) {
final CSSStyleRule aStyleRule = _createStyleRule(aChildNode);
if (aStyleRule != null)
ret.addRule(aStyleRule);
} else if (ECSSNodeType.MEDIARULE.isNode(aChildNode, m_eVersion)) {
// Nested media rules are OK!
ret.addRule(_createMediaRule(aChildNode));
} else if (ECSSNodeType.PAGERULE.isNode(aChildNode, m_eVersion))
ret.addRule(_createPageRule(aChildNode));
else if (ECSSNodeType.FONTFACERULE.isNode(aChildNode, m_eVersion))
ret.addRule(_createFontFaceRule(aChildNode));
else if (ECSSNodeType.KEYFRAMESRULE.isNode(aChildNode, m_eVersion))
ret.addRule(_createKeyframesRule(aChildNode));
else if (ECSSNodeType.VIEWPORTRULE.isNode(aChildNode, m_eVersion))
ret.addRule(_createViewportRule(aChildNode));
else if (ECSSNodeType.SUPPORTSRULE.isNode(aChildNode, m_eVersion))
ret.addRule(_createSupportsRule(aChildNode));
else if (!ECSSNodeType.isErrorNode(aChildNode, m_eVersion))
m_aErrorHandler.onCSSInterpretationError("Unsupported media-rule child: " + ECSSNodeType.getNodeName(aChildNode, m_eVersion));
}
return ret;
}
use of com.helger.css.parser.CSSNode in project ph-css by phax.
the class CSSNodeToDomainObject method _createSelectorAttribute.
@Nonnull
private CSSSelectorAttribute _createSelectorAttribute(@Nonnull final CSSNode aNode) {
_expectNodeType(aNode, ECSSNodeType.ATTRIB);
final int nChildren = aNode.jjtGetNumChildren();
// Check if a namespace prefix is present
String sNamespacePrefix = null;
int nOperatorIndex = 0;
if (nChildren > 0 && ECSSNodeType.NAMESPACEPREFIX.isNode(aNode.jjtGetChild(0), m_eVersion)) {
sNamespacePrefix = aNode.jjtGetChild(0).getText();
nOperatorIndex = 1;
}
final String sAttrName = aNode.getText();
CSSSelectorAttribute ret;
if (nChildren == nOperatorIndex) {
// Just check for existence of the attribute
ret = new CSSSelectorAttribute(sNamespacePrefix, sAttrName);
} else {
final int nExpectedChildCount = nOperatorIndex + 2;
if (nChildren != nExpectedChildCount)
_throwUnexpectedChildrenCount(aNode, "Illegal number of children present (" + nChildren + ") - expected " + nExpectedChildCount);
// With operator...
final CSSNode aOperator = aNode.jjtGetChild(nOperatorIndex);
_expectNodeType(aOperator, ECSSNodeType.ATTRIBOPERATOR);
// ...and value
final CSSNode aAttrValue = aNode.jjtGetChild(nOperatorIndex + 1);
_expectNodeType(aAttrValue, ECSSNodeType.ATTRIBVALUE);
ret = new CSSSelectorAttribute(sNamespacePrefix, sAttrName, ECSSAttributeOperator.getFromNameOrNull(aOperator.getText()), aAttrValue.getText());
}
ret.setSourceLocation(aNode.getSourceLocation());
return ret;
}
Aggregations