private void getEmptyPseudo(JsNodeArray previousMatch, JsNodeArray matchingElms) { Node previous; for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) { previous = previousMatch.getNode(q); if (!previous.hasChildNodes()) { matchingElms.addNode(previous); } } }
private void getEnabledPseudo(JsNodeArray previousMatch, JsNodeArray matchingElms) { Node previous; for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) { previous = previousMatch.getNode(q); if (enabled(previous)) { matchingElms.addNode(previous); } } }
private void getDefaultPseudo( JsNodeArray previousMatch, String pseudoClass, String pseudoValue, JsNodeArray matchingElms) { Node previous; for (int w = 0, wlen = previousMatch.size(); w < wlen; w++) { previous = previousMatch.getElement(w); if (JsUtils.eq(((Element) previous).getAttribute(pseudoClass), pseudoValue)) { matchingElms.addNode(previous); } } }
private void getContainsPseudo( JsNodeArray previousMatch, String pseudoValue, JsNodeArray matchingElms) { Node previous; for (int q = 0, qlen = previousMatch.size(); q < qlen; q++) { previous = previousMatch.getNode(q); if (!isAdded(previous)) { if (((Element) previous).getInnerText().indexOf(pseudoValue) != -1) { setAdded(previous, true); matchingElms.addNode(previous); } } } }
private JsNodeArray getNotPseudo( JsNodeArray previousMatch, String pseudoValue, JsNodeArray matchingElms) { if (new JsRegexp("(:\\w+[\\w\\-]*)$").test(pseudoValue)) { matchingElms = subtractArray( previousMatch, getElementsByPseudo(previousMatch, pseudoValue.substring(1), "")); } else { pseudoValue = pseudoValue.replace("^\\[#([\\w\\u00C0-\\uFFFF\\-\\_]+)\\]$", "[id=$1]"); JsObjectArray<String> notTag = new JsRegexp("^(\\w+)").exec(pseudoValue); JsObjectArray<String> notClass = new JsRegexp("^\\.([\\w\u00C0-\uFFFF\\-_]+)").exec(pseudoValue); JsObjectArray<String> notAttr = new JsRegexp("\\[(\\w+)(\\^|\\$|\\*|\\||~)?=?([\\w\\u00C0-\\uFFFF\\s\\-_\\.]+)?\\]") .exec(pseudoValue); JsRegexp notRegExp = new JsRegexp( "(^|\\s)" + (JsUtils.truth(notTag) ? notTag.get(1) : JsUtils.truth(notClass) ? notClass.get(1) : "") + "(\\s|$)", "i"); if (JsUtils.truth(notAttr)) { String notAttribute = JsUtils.truth(notAttr.get(3)) ? notAttr.get(3).replace("\\.", "\\.") : null; String notMatchingAttrVal = attrToRegExp(notAttribute, notAttr.get(2)); notRegExp = new JsRegexp(notMatchingAttrVal, "i"); } for (int v = 0, vlen = previousMatch.size(); v < vlen; v++) { Element notElm = previousMatch.getElement(v); Element addElm = null; if (JsUtils.truth(notTag) && !notRegExp.test(notElm.getNodeName())) { addElm = notElm; } else if (JsUtils.truth(notClass) && !notRegExp.test(notElm.getClassName())) { addElm = notElm; } else if (JsUtils.truth(notAttr)) { String att = getAttr(notElm, notAttr.get(1)); if (!JsUtils.truth(att) || !notRegExp.test(att)) { addElm = notElm; } } if (JsUtils.truth(addElm) && !isAdded(addElm)) { setAdded(addElm, true); matchingElms.addNode(addElm); } } } return matchingElms; }
private void getFirstChildPseudo( JsNodeArray previousMatch, boolean previousDir, JsNodeArray matchingElms) { Node next; Node previous; for (int j = 0, jlen = previousMatch.size(); j < jlen; j++) { previous = next = previousMatch.getElement(j); if (previousDir) { while (JsUtils.truth((next = SelectorEngine.getPreviousSibling(next))) && next.getNodeType() != Node.ELEMENT_NODE) {} } else { while (JsUtils.truth((next = SelectorEngine.getNextSibling(next))) && next.getNodeType() != Node.ELEMENT_NODE) {} } if (!JsUtils.truth(next)) { matchingElms.addNode(previous); } } }
private void getOnlyOfTypePseudo(JsNodeArray previousMatch, JsNodeArray matchingElms) { Node previous; Node next; Node prev; Node oParent = null; for (int o = 0, olen = previousMatch.size(); o < olen; o++) { prev = next = previous = previousMatch.getNode(o); Node prevParent = previous.getParentNode(); if (prevParent != oParent) { while (JsUtils.truth(prev = SelectorEngine.getPreviousSibling(prev)) && !JsUtils.eq(prev.getNodeName(), previous.getNodeName())) {} while (JsUtils.truth(next = SelectorEngine.getNextSibling(next)) && !JsUtils.eq(next.getNodeName(), previous.getNodeName())) {} if (!JsUtils.truth(prev) && !JsUtils.truth(next)) { matchingElms.addNode(previous); } oParent = prevParent; } } }
private void getOnlyChildPseudo(JsNodeArray previousMatch, JsNodeArray matchingElms) { Node previous; Node next; Node prev; Node kParent = null; for (int k = 0, klen = previousMatch.size(); k < klen; k++) { prev = next = previous = previousMatch.getNode(k); Node prevParent = previous.getParentNode(); if (prevParent != kParent) { while (JsUtils.truth(prev = SelectorEngine.getPreviousSibling(prev)) && prev.getNodeType() != Node.ELEMENT_NODE) {} while (JsUtils.truth(next = SelectorEngine.getNextSibling(next)) && next.getNodeType() != Node.ELEMENT_NODE) {} if (!JsUtils.truth(prev) && !JsUtils.truth(next)) { matchingElms.addNode(previous); } kParent = prevParent; } } }
private void getFirstOfTypePseudo( JsNodeArray previousMatch, boolean previousDir, JsNodeArray matchingElms) { Node previous; Node next; for (int n = 0, nlen = previousMatch.size(); n < nlen; n++) { next = previous = previousMatch.getNode(n); if (previousDir) { while (JsUtils.truth(next = SelectorEngine.getPreviousSibling(next)) && !JsUtils.eq(next.getNodeName(), previous.getNodeName())) {} } else { while (JsUtils.truth(next = SelectorEngine.getNextSibling(next)) && !JsUtils.eq(next.getNodeName(), previous.getNodeName())) {} } if (!JsUtils.truth(next)) { matchingElms.addNode(previous); } } }
private JsNodeArray getNthChildPseudo( JsNodeArray previousMatch, String pseudoValue, JsNodeArray prevParents, JsNodeArray matchingElms) { Node previous; if (JsUtils.eq(pseudoValue, "n")) { matchingElms = previousMatch; } else { Sequence sequence = getSequence(pseudoValue); if (sequence != null) { for (int l = 0, llen = previousMatch.size(); l < llen; l++) { previous = previousMatch.getNode(l); Node prevParent = previous.getParentNode(); if (!hasChildElms(prevParent)) { int iteratorNext = sequence.start; int childCount = 0; Node childElm = prevParent.getFirstChild(); while (childElm != null && (sequence.max < 0 || iteratorNext <= sequence.max)) { if (childElm.getNodeType() == Node.ELEMENT_NODE) { if (++childCount == iteratorNext) { if (JsUtils.eq(childElm.getNodeName(), previous.getNodeName())) { matchingElms.addNode(childElm); } iteratorNext += sequence.add; } } childElm = SelectorEngine.getNextSibling(childElm); } setHasChildElms(prevParent, true); prevParents.addNode(prevParent); } } clearChildElms(prevParents); } } return matchingElms; }
public NodeList<Element> select(String sel, Node ctx) { String selectors[] = sel.replace("\\s*(,)\\s*", "$1").split(","); boolean identical = false; JsNodeArray elm = JsNodeArray.create(); for (int a = 0, len = selectors.length; a < len; a++) { if (a > 0) { identical = false; for (int b = 0, bl = a; b < bl; b++) { if (JsUtils.eq(selectors[a], selectors[b])) { identical = true; break; } } if (identical) { continue; } } String currentRule = selectors[a]; JsObjectArray<String> cssSelectors = selectorSplitRegExp.match(currentRule); JsNodeArray prevElem = JsNodeArray.create(ctx); for (int i = 0, slen = cssSelectors.length(); i < slen; i++) { JsNodeArray matchingElms = JsNodeArray.create(); String rule = cssSelectors.get(i); if (i > 0 && childOrSiblingRefRegExp.test(rule)) { JsObjectArray<String> childOrSiblingRef = childOrSiblingRefRegExp.exec(rule); if (JsUtils.truth(childOrSiblingRef)) { JsObjectArray<String> nextTag = new JsRegexp("^\\w+").exec(cssSelectors.get(i + 1)); JsRegexp nextRegExp = null; String nextTagStr = null; if (JsUtils.truth(nextTag)) { nextTagStr = nextTag.get(0); nextRegExp = new JsRegexp("(^|\\s)" + nextTagStr + "(\\s|$)", "i"); } for (int j = 0, jlen = prevElem.size(); j < jlen; j++) { Node prevRef = prevElem.getNode(j); String ref = childOrSiblingRef.get(0); if (JsUtils.eq(">", ref)) { getDescendantNodes(matchingElms, nextTagStr, prevRef); } else if (JsUtils.eq("+", ref)) { getSiblingNodes(matchingElms, nextTag, nextRegExp, prevRef); } else if (JsUtils.eq("~", ref)) { getGeneralSiblingNodes(matchingElms, nextTag, nextRegExp, prevRef); } } prevElem = matchingElms; clearAdded(prevElem); rule = cssSelectors.get(++i); if (new JsRegexp("^\\w+$").test(rule)) { continue; } setSkipTag(prevElem, true); } } JsObjectArray<String> cssSelector = cssSelectorRegExp.exec(rule); SplitRule splitRule = new SplitRule( !JsUtils.truth(cssSelector.get(1)) || JsUtils.eq(cssSelector.get(3), "*") ? "*" : cssSelector.get(1), !JsUtils.eq(cssSelector.get(3), "*") ? cssSelector.get(2) : null, cssSelector.get(4), cssSelector.get(6), cssSelector.get(10)); if (JsUtils.truth(splitRule.id)) { Element domelem = Document.get().getElementById(splitRule.id.substring(1)); if (JsUtils.truth(domelem)) { matchingElms = JsNodeArray.create(domelem); } prevElem = matchingElms; } else if (JsUtils.truth(splitRule.tag) && !isSkipped(prevElem)) { if (i == 0 && matchingElms.size() == 0 && prevElem.size() == 1) { prevElem = matchingElms = JsNodeArray.create(getElementsByTagName(splitRule.tag, prevElem.getNode(0))); } else { NodeList<Element> tagCollectionMatches; for (int l = 0, ll = prevElem.size(); l < ll; l++) { tagCollectionMatches = getElementsByTagName(splitRule.tag, prevElem.getNode(l)); for (int m = 0, mlen = tagCollectionMatches.getLength(); m < mlen; m++) { Node tagMatch = tagCollectionMatches.getItem(m); if (!isAdded(tagMatch)) { setAdded(tagMatch, true); matchingElms.addNode(tagMatch); } } } prevElem = matchingElms; clearAdded(prevElem); } if (matchingElms.size() == 0) { break; } setSkipTag(prevElem, false); if (JsUtils.truth(splitRule.allClasses)) { String[] allClasses = splitRule.allClasses.replaceFirst("^\\.", "").split("\\."); JsRegexp[] regExpClassNames = new JsRegexp[allClasses.length]; for (int n = 0, nl = allClasses.length; n < nl; n++) { regExpClassNames[n] = new JsRegexp("(^|\\s)" + allClasses[n] + "(\\s|$)"); } JsNodeArray matchingClassElms = JsNodeArray.create(); for (int o = 0, olen = prevElem.size(); o < olen; o++) { Element current = prevElem.getElement(o); String elmClass = current.getClassName(); boolean addElm = false; if (JsUtils.truth(elmClass) && !isAdded(current)) { for (int p = 0, pl = regExpClassNames.length; p < pl; p++) { addElm = regExpClassNames[p].test(elmClass); if (!addElm) { break; } } if (addElm) { setAdded(current, true); matchingClassElms.addNode(current); } } } clearAdded(prevElem); prevElem = matchingElms = matchingClassElms; } if (JsUtils.truth(splitRule.allAttr)) { JsObjectArray<String> allAttr = JsRegexp.match("\\[[^\\]]+\\]", "g", splitRule.allAttr); JsRegexp[] regExpAttributes = new JsRegexp[allAttr.length()]; String[] regExpAttributesStr = new String[allAttr.length()]; JsRegexp attributeMatchRegExp = new JsRegexp("(\\w+)(\\^|\\$|\\*|\\||~)?=?[\"']?([\\w\u00C0-\uFFFF\\s\\-_\\.]+)?"); for (int q = 0, ql = allAttr.length(); q < ql; q++) { JsObjectArray<String> attributeMatch = attributeMatchRegExp.exec(allAttr.get(q)); String attributeValue = JsUtils.truth(attributeMatch.get(3)) ? attributeMatch.get(3).replaceAll("\\.", "\\.") : null; String attrVal = attrToRegExp(attributeValue, (JsUtils.or(attributeMatch.get(2), null))); regExpAttributes[q] = (JsUtils.truth(attrVal) ? new JsRegexp(attrVal) : null); regExpAttributesStr[q] = attributeMatch.get(1); } JsNodeArray matchingAttributeElms = JsNodeArray.create(); for (int r = 0, rlen = matchingElms.size(); r < rlen; r++) { Element current = matchingElms.getElement(r); boolean addElm = false; for (int s = 0, sl = regExpAttributes.length; s < sl; s++) { addElm = false; JsRegexp attributeRegexp = regExpAttributes[s]; String currentAttr = getAttr(current, regExpAttributesStr[s]); if (JsUtils.truth(currentAttr) && currentAttr.length() != 0) { if (attributeRegexp == null || attributeRegexp.test(currentAttr)) { addElm = true; } } if (!addElm) { break; } } if (addElm) { matchingAttributeElms.addNode(current); } } prevElem = matchingElms = matchingAttributeElms; } if (JsUtils.truth(splitRule.allPseudos)) { JsRegexp pseudoSplitRegExp = new JsRegexp(":(\\w[\\w\\-]*)(\\(([^\\)]+)\\))?"); JsObjectArray<String> allPseudos = JsRegexp.match("(:\\w+[\\w\\-]*)(\\([^\\)]+\\))?", "g", splitRule.allPseudos); for (int t = 0, tl = allPseudos.length(); t < tl; t++) { JsObjectArray<String> pseudo = pseudoSplitRegExp.match(allPseudos.get(t)); String pseudoClass = JsUtils.truth(pseudo.get(1)) ? pseudo.get(1).toLowerCase() : null; String pseudoValue = JsUtils.truth(pseudo.get(3)) ? pseudo.get(3) : null; matchingElms = getElementsByPseudo(matchingElms, pseudoClass, pseudoValue); clearAdded(matchingElms); } prevElem = matchingElms; } } } elm.pushAll(prevElem); } return JsUtils.unique(elm.<JsArray<Element>>cast()).cast(); }
private static void clearChildElms(JsNodeArray prevParents) { for (int n = 0, nl = prevParents.size(); n < nl; n++) { setHasChildElms(prevParents.getNode(n), false); } }
public static void clearAdded(JsNodeArray a) { for (int i = 0, len = a.size(); i < len; i++) { clearAdded(a.getNode(i)); } }