use of com.gargoylesoftware.css.parser.CSSOMParser in project htmlunit by HtmlUnit.
the class DomNode method getSelectorList.
/**
* Returns the {@link SelectorList}.
* @param selectors the selectors
* @param browserVersion the {@link BrowserVersion}
* @return the {@link SelectorList}
* @throws IOException if an error occurs
*/
protected SelectorList getSelectorList(final String selectors, final BrowserVersion browserVersion) throws IOException {
final CSSOMParser parser = new CSSOMParser(new CSS3Parser());
final CheckErrorHandler errorHandler = new CheckErrorHandler();
parser.setErrorHandler(errorHandler);
final SelectorList selectorList = parser.parseSelectors(selectors);
// in case of error parseSelectors returns null
if (errorHandler.errorDetected()) {
throw new CSSException("Invalid selectors: " + selectors);
}
if (selectorList != null) {
int documentMode = 9;
if (browserVersion.hasFeature(QUERYSELECTORALL_NOT_IN_QUIRKS)) {
final Object sobj = getPage().getScriptableObject();
if (sobj instanceof HTMLDocument) {
documentMode = ((HTMLDocument) sobj).getDocumentMode();
}
}
CSSStyleSheet.validateSelectors(selectorList, documentMode, this);
}
return selectorList;
}
use of com.gargoylesoftware.css.parser.CSSOMParser in project htmlunit by HtmlUnit.
the class CSSStyleSheet method selectsPseudoClass.
private static boolean selectsPseudoClass(final BrowserVersion browserVersion, final Condition condition, final DomElement element, final boolean fromQuerySelectorAll) {
if (browserVersion.hasFeature(QUERYSELECTORALL_NOT_IN_QUIRKS)) {
final Object sobj = element.getPage().getScriptableObject();
if (sobj instanceof HTMLDocument && ((HTMLDocument) sobj).getDocumentMode() < 8) {
return false;
}
}
final String value = condition.getValue();
switch(value) {
case "root":
return element == element.getPage().getDocumentElement();
case "enabled":
return element instanceof DisabledElement && !((DisabledElement) element).isDisabled();
case "disabled":
return element instanceof DisabledElement && ((DisabledElement) element).isDisabled();
case "focus":
final HtmlPage htmlPage = element.getHtmlPageOrNull();
if (htmlPage != null) {
final DomElement focus = htmlPage.getFocusedElement();
return element == focus;
}
return false;
case "checked":
return (element instanceof HtmlCheckBoxInput && ((HtmlCheckBoxInput) element).isChecked()) || (element instanceof HtmlRadioButtonInput && ((HtmlRadioButtonInput) element).isChecked() || (element instanceof HtmlOption && ((HtmlOption) element).isSelected()));
case "required":
return element instanceof HtmlElement && ((HtmlElement) element).isRequired();
case "optional":
return element instanceof HtmlElement && ((HtmlElement) element).isOptional();
case "first-child":
for (DomNode n = element.getPreviousSibling(); n != null; n = n.getPreviousSibling()) {
if (n instanceof DomElement) {
return false;
}
}
return true;
case "last-child":
for (DomNode n = element.getNextSibling(); n != null; n = n.getNextSibling()) {
if (n instanceof DomElement) {
return false;
}
}
return true;
case "first-of-type":
final String firstType = element.getNodeName();
for (DomNode n = element.getPreviousSibling(); n != null; n = n.getPreviousSibling()) {
if (n instanceof DomElement && n.getNodeName().equals(firstType)) {
return false;
}
}
return true;
case "last-of-type":
final String lastType = element.getNodeName();
for (DomNode n = element.getNextSibling(); n != null; n = n.getNextSibling()) {
if (n instanceof DomElement && n.getNodeName().equals(lastType)) {
return false;
}
}
return true;
case "only-child":
for (DomNode n = element.getPreviousSibling(); n != null; n = n.getPreviousSibling()) {
if (n instanceof DomElement) {
return false;
}
}
for (DomNode n = element.getNextSibling(); n != null; n = n.getNextSibling()) {
if (n instanceof DomElement) {
return false;
}
}
return true;
case "only-of-type":
final String type = element.getNodeName();
for (DomNode n = element.getPreviousSibling(); n != null; n = n.getPreviousSibling()) {
if (n instanceof DomElement && n.getNodeName().equals(type)) {
return false;
}
}
for (DomNode n = element.getNextSibling(); n != null; n = n.getNextSibling()) {
if (n instanceof DomElement && n.getNodeName().equals(type)) {
return false;
}
}
return true;
case "valid":
return element instanceof HtmlElement && ((HtmlElement) element).isValid();
case "invalid":
return element instanceof HtmlElement && !((HtmlElement) element).isValid();
case "empty":
return isEmpty(element);
case "target":
final String ref = element.getPage().getUrl().getRef();
return StringUtils.isNotBlank(ref) && ref.equals(element.getId());
case "hover":
return element.isMouseOver();
case "placeholder-shown":
if (browserVersion.hasFeature(CSS_PSEUDO_SELECTOR_PLACEHOLDER_SHOWN)) {
return element instanceof HtmlInput && StringUtils.isEmpty(((HtmlInput) element).getValueAttribute()) && StringUtils.isNotEmpty(((HtmlInput) element).getPlaceholder());
}
case "-ms-input-placeholder":
if (browserVersion.hasFeature(CSS_PSEUDO_SELECTOR_MS_PLACEHHOLDER)) {
return element instanceof HtmlInput && StringUtils.isEmpty(((HtmlInput) element).getValueAttribute()) && StringUtils.isNotEmpty(((HtmlInput) element).getPlaceholder());
}
default:
if (value.startsWith("nth-child(")) {
final String nth = value.substring(value.indexOf('(') + 1, value.length() - 1);
int index = 0;
for (DomNode n = element; n != null; n = n.getPreviousSibling()) {
if (n instanceof DomElement) {
index++;
}
}
return getNth(nth, index);
} else if (value.startsWith("nth-last-child(")) {
final String nth = value.substring(value.indexOf('(') + 1, value.length() - 1);
int index = 0;
for (DomNode n = element; n != null; n = n.getNextSibling()) {
if (n instanceof DomElement) {
index++;
}
}
return getNth(nth, index);
} else if (value.startsWith("nth-of-type(")) {
final String nthType = element.getNodeName();
final String nth = value.substring(value.indexOf('(') + 1, value.length() - 1);
int index = 0;
for (DomNode n = element; n != null; n = n.getPreviousSibling()) {
if (n instanceof DomElement && n.getNodeName().equals(nthType)) {
index++;
}
}
return getNth(nth, index);
} else if (value.startsWith("nth-last-of-type(")) {
final String nthLastType = element.getNodeName();
final String nth = value.substring(value.indexOf('(') + 1, value.length() - 1);
int index = 0;
for (DomNode n = element; n != null; n = n.getNextSibling()) {
if (n instanceof DomElement && n.getNodeName().equals(nthLastType)) {
index++;
}
}
return getNth(nth, index);
} else if (value.startsWith("not(")) {
final String selectors = value.substring(value.indexOf('(') + 1, value.length() - 1);
final AtomicBoolean errorOccured = new AtomicBoolean(false);
final CSSErrorHandler errorHandler = new CSSErrorHandler() {
@Override
public void warning(final CSSParseException exception) throws CSSException {
// ignore
}
@Override
public void fatalError(final CSSParseException exception) throws CSSException {
errorOccured.set(true);
}
@Override
public void error(final CSSParseException exception) throws CSSException {
errorOccured.set(true);
}
};
final CSSOMParser parser = new CSSOMParser(new CSS3Parser());
parser.setErrorHandler(errorHandler);
try {
final SelectorList selectorList = parser.parseSelectors(selectors);
if (errorOccured.get() || selectorList == null || selectorList.size() != 1) {
throw new CSSException("Invalid selectors: " + selectors);
}
validateSelectors(selectorList, 9, element);
return !selects(browserVersion, selectorList.get(0), element, null, fromQuerySelectorAll);
} catch (final IOException e) {
throw new CSSException("Error parsing CSS selectors from '" + selectors + "': " + e.getMessage());
}
}
return false;
}
}
use of com.gargoylesoftware.css.parser.CSSOMParser in project LoboEvolution by LoboEvolution.
the class HTMLElementImpl method getStyle.
/**
* Gets the local style object associated with the element. The properties
* object returned only includes properties from the local style attribute. It
* may return null only if the type of element does not handle stylesheets.
*
* @return a {@link org.loboevolution.html.style.AbstractCSSProperties} object.
*/
public AbstractCSSProperties getStyle() {
AbstractCSSProperties sds;
synchronized (this) {
sds = this.localStyleDeclarationState;
if (sds != null) {
return sds;
}
sds = new AbstractCSSProperties(this);
// Add any declarations in style attribute (last takes precedence).
final String style = getAttribute("style");
if (Strings.isNotBlank(style)) {
final CSSOMParser parser = new CSSOMParser(new CSS3Parser());
try {
final CSSStyleDeclarationImpl sd = parser.parseStyleDeclaration(style);
sds.addStyleDeclaration(sd);
} catch (final Exception err) {
final String id = getId();
final String withId = id == null ? "" : " with ID '" + id + "'";
this.warn("Unable to parse style attribute value for element " + getTagName() + withId + " in " + getDocumentURL() + ".", err);
}
}
this.localStyleDeclarationState = sds;
}
// Synchronization note: Make sure getStyle() does not return multiple values.
return sds;
}
use of com.gargoylesoftware.css.parser.CSSOMParser in project LoboEvolution by LoboEvolution.
the class CSSStyleDeclarationImpl method setProperty.
/**
* Set a property.
*
* @param propertyName the name of the property
* @param value the new value
* @param priority the priority
* @throws org.w3c.dom.DOMException in case of error
*/
public void setProperty(final String propertyName, final String value, final String priority) throws DOMException {
try {
CSSValueImpl expr = null;
if (!value.isEmpty()) {
final CSSOMParser parser = new CSSOMParser();
expr = parser.parsePropertyValue(value);
}
Property p = getPropertyDeclaration(propertyName);
final boolean important = PRIORITY_IMPORTANT.equalsIgnoreCase(priority);
if (p == null) {
p = new Property(propertyName, expr, important);
addProperty(p);
} else {
p.setValue(expr);
p.setImportant(important);
}
} catch (final Exception e) {
throw new DOMException(DOMException.SYNTAX_ERR, DOMException.SYNTAX_ERROR, e.getMessage());
}
}
use of com.gargoylesoftware.css.parser.CSSOMParser in project LoboEvolution by LoboEvolution.
the class CSSStyleSheetImpl method insertRule.
/**
* inserts a new rule.
*
* @param rule the rule to insert
* @param index the insert pos
* @throws org.w3c.dom.DOMException in case of error
* @throws DOMException in case of error
*/
public void insertRule(final String rule, final int index) throws DOMException {
try {
final CSSOMParser parser = new CSSOMParser();
parser.setParentStyleSheet(this);
parser.setErrorHandler(ThrowCssExceptionErrorHandler.INSTANCE);
final AbstractCSSRuleImpl r = parser.parseRule(rule);
if (r == null) {
// this should neven happen because of the ThrowCssExceptionErrorHandler
throw new DOMException(DOMException.SYNTAX_ERR, DOMException.SYNTAX_ERROR, "Parsing rule '" + rule + "' failed.");
}
if (getCssRules().getLength() > 0) {
// We need to check that this type of rule can legally go into
// the requested position.
int msg = -1;
if (r instanceof CSSCharsetRuleImpl) {
// Index must be 0, and there can be only one charset rule
if (index != 0) {
msg = DOMException.CHARSET_NOT_FIRST;
} else if (getCssRules().getRules().get(0) instanceof CSSCharsetRuleImpl) {
msg = DOMException.CHARSET_NOT_UNIQUE;
}
} else if (r instanceof CSSImportRuleImpl) {
// charset rules)
if (index <= getCssRules().getLength()) {
for (int i = 0; i < index; i++) {
final AbstractCSSRuleImpl ri = getCssRules().getRules().get(i);
if (!(ri instanceof CSSCharsetRuleImpl) && !(ri instanceof CSSImportRuleImpl)) {
msg = DOMException.IMPORT_NOT_FIRST;
break;
}
}
}
} else {
if (index <= getCssRules().getLength()) {
for (int i = index; i < getCssRules().getLength(); i++) {
final AbstractCSSRuleImpl ri = getCssRules().getRules().get(i);
if ((ri instanceof CSSCharsetRuleImpl) || (ri instanceof CSSImportRuleImpl)) {
msg = DOMException.INSERT_BEFORE_IMPORT;
break;
}
}
}
}
if (msg > -1) {
throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, msg);
}
}
// Insert the rule into the list of rules
getCssRules().insert(r, index);
} catch (final IndexOutOfBoundsException e) {
throw new DOMException(DOMException.INDEX_SIZE_ERR, DOMException.INDEX_OUT_OF_BOUNDS, e.getMessage());
} catch (final CSSException e) {
throw new DOMException(DOMException.SYNTAX_ERR, DOMException.SYNTAX_ERROR, e.getMessage());
} catch (final IOException e) {
throw new DOMException(DOMException.SYNTAX_ERR, DOMException.SYNTAX_ERROR, e.getMessage());
}
}
Aggregations