Search in sources :

Example 1 with CSSException

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;
}
Also used : HTMLDocument(com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument) CSSOMParser(com.gargoylesoftware.css.parser.CSSOMParser) CSS3Parser(com.gargoylesoftware.css.parser.javacc.CSS3Parser) SelectorList(com.gargoylesoftware.css.parser.selector.SelectorList) CSSException(com.gargoylesoftware.css.parser.CSSException) ScriptableObject(net.sourceforge.htmlunit.corejs.javascript.ScriptableObject)

Example 2 with CSSException

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());
    }
}
Also used : SelectorList(com.gargoylesoftware.css.parser.selector.SelectorList) CSSException(com.gargoylesoftware.css.parser.CSSException) IOException(java.io.IOException) BrowserVersion(com.gargoylesoftware.htmlunit.BrowserVersion) Selector(com.gargoylesoftware.css.parser.selector.Selector)

Example 3 with CSSException

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() + ").");
    }
}
Also used : ProxyDomNode(com.gargoylesoftware.htmlunit.javascript.host.html.HTMLElement.ProxyDomNode) DomNode(com.gargoylesoftware.htmlunit.html.DomNode) DomElement(com.gargoylesoftware.htmlunit.html.DomElement) DomElement(com.gargoylesoftware.htmlunit.html.DomElement) HTMLScriptElement(com.gargoylesoftware.htmlunit.javascript.host.html.HTMLScriptElement) HtmlElement(com.gargoylesoftware.htmlunit.html.HtmlElement) HTMLTemplateElement(com.gargoylesoftware.htmlunit.javascript.host.html.HTMLTemplateElement) HTMLStyleElement(com.gargoylesoftware.htmlunit.javascript.host.html.HTMLStyleElement) HTMLElement(com.gargoylesoftware.htmlunit.javascript.host.html.HTMLElement) CSSException(com.gargoylesoftware.css.parser.CSSException) JsxFunction(com.gargoylesoftware.htmlunit.javascript.configuration.JsxFunction)

Example 4 with CSSException

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;
    }
}
Also used : DisabledElement(com.gargoylesoftware.htmlunit.html.DisabledElement) HtmlPage(com.gargoylesoftware.htmlunit.html.HtmlPage) HTMLDocument(com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument) HtmlElement(com.gargoylesoftware.htmlunit.html.HtmlElement) CSSOMParser(com.gargoylesoftware.css.parser.CSSOMParser) IOException(java.io.IOException) HtmlInput(com.gargoylesoftware.htmlunit.html.HtmlInput) HtmlCheckBoxInput(com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) DomNode(com.gargoylesoftware.htmlunit.html.DomNode) DomElement(com.gargoylesoftware.htmlunit.html.DomElement) CSSParseException(com.gargoylesoftware.css.parser.CSSParseException) CSSErrorHandler(com.gargoylesoftware.css.parser.CSSErrorHandler) CSS3Parser(com.gargoylesoftware.css.parser.javacc.CSS3Parser) SelectorList(com.gargoylesoftware.css.parser.selector.SelectorList) CSSException(com.gargoylesoftware.css.parser.CSSException) HtmlOption(com.gargoylesoftware.htmlunit.html.HtmlOption) HtmlRadioButtonInput(com.gargoylesoftware.htmlunit.html.HtmlRadioButtonInput)

Example 5 with CSSException

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());
    }
}
Also used : CSSOMParser(com.gargoylesoftware.css.parser.CSSOMParser) CSSException(com.gargoylesoftware.css.parser.CSSException) IOException(java.io.IOException)

Aggregations

CSSException (com.gargoylesoftware.css.parser.CSSException)18 IOException (java.io.IOException)16 CSSOMParser (com.gargoylesoftware.css.parser.CSSOMParser)13 SelectorList (com.gargoylesoftware.css.parser.selector.SelectorList)5 CSSErrorHandler (com.gargoylesoftware.css.parser.CSSErrorHandler)3 CSSParseException (com.gargoylesoftware.css.parser.CSSParseException)3 CSS3Parser (com.gargoylesoftware.css.parser.javacc.CSS3Parser)3 Selector (com.gargoylesoftware.css.parser.selector.Selector)3 BrowserVersion (com.gargoylesoftware.htmlunit.BrowserVersion)3 DomElement (com.gargoylesoftware.htmlunit.html.DomElement)2 DomNode (com.gargoylesoftware.htmlunit.html.DomNode)2 HtmlElement (com.gargoylesoftware.htmlunit.html.HtmlElement)2 HtmlPage (com.gargoylesoftware.htmlunit.html.HtmlPage)2 HTMLDocument (com.gargoylesoftware.htmlunit.javascript.host.html.HTMLDocument)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 IncorrectnessListener (com.gargoylesoftware.htmlunit.IncorrectnessListener)1 ScriptException (com.gargoylesoftware.htmlunit.ScriptException)1 WebClient (com.gargoylesoftware.htmlunit.WebClient)1 WebClientOptions (com.gargoylesoftware.htmlunit.WebClientOptions)1 DisabledElement (com.gargoylesoftware.htmlunit.html.DisabledElement)1