use of com.gargoylesoftware.css.parser.CSSException 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.CSSException in project htmlunit by HtmlUnit.
the class DomNode method closest.
/**
* @param selectorString the selector to test
* @return true if the element would be selected by the specified selector string; otherwise, returns false.
*/
public DomElement closest(final String selectorString) {
try {
final BrowserVersion browserVersion = getPage().getWebClient().getBrowserVersion();
final SelectorList selectorList = getSelectorList(selectorString, browserVersion);
DomNode current = this;
if (selectorList != null) {
do {
for (final Selector selector : selectorList) {
final DomElement elem = (DomElement) current;
if (CSSStyleSheet.selects(browserVersion, selector, elem, null, true)) {
return elem;
}
}
do {
current = current.getParentNode();
} while (current != null && !(current instanceof DomElement));
} while (current != null);
}
return null;
} catch (final IOException e) {
throw new CSSException("Error parsing CSS selectors from '" + selectorString + "': " + e.getMessage());
}
}
use of com.gargoylesoftware.css.parser.CSSException in project htmlunit by HtmlUnit.
the class Element method closest.
@JsxFunction({ CHROME, EDGE, FF, FF_ESR })
public static Element closest(final Context context, final Scriptable thisObj, final Object[] args, final Function function) {
if (!(thisObj instanceof Element)) {
throw ScriptRuntime.typeError("Illegal invocation");
}
final String selectorString = (String) args[0];
try {
final DomNode domNode = ((Element) thisObj).getDomNodeOrNull();
if (domNode == null) {
return null;
}
final DomElement elem = domNode.closest(selectorString);
if (elem == null) {
return null;
}
return elem.getScriptableObject();
} catch (final CSSException e) {
throw ScriptRuntime.constructError("SyntaxError", "An invalid or illegal selector was specified (selector: '" + selectorString + "' error: " + e.getMessage() + ").");
}
}
use of com.gargoylesoftware.css.parser.CSSException 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.CSSException 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