All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.zkoss.zk.ui.select.impl.BasicPseudoClassDefs Maven / Gradle / Ivy
/**
*
*/
package org.zkoss.zk.ui.select.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import org.zkoss.lang.Strings;
import org.zkoss.zk.ui.sys.ComponentCtrl;
/**
* The default set of pseudo classes in Selector.
* @since 6.0.0
* @author simonpai
*/
public class BasicPseudoClassDefs {
private static final Map _defs = new HashMap();
static {
// TODO: rethink about :root
// :root
_defs.put("root", new PseudoClassDef() {
public boolean accept(ComponentMatchCtx ctx, String... parameters) {
if (parameters.length > 0)
return false;
return ctx.getComponent().getParent() == null;
}
});
// :first-child
_defs.put("first-child", new PseudoClassDef() {
public boolean accept(ComponentMatchCtx ctx, String... parameters) {
if (parameters.length > 0)
return false;
return ctx.getComponentChildIndex() == 0;
}
});
// :last-child
_defs.put("last-child", new PseudoClassDef() {
public boolean accept(ComponentMatchCtx ctx, String... parameters) {
if (parameters.length > 0)
return false;
return ctx.getComponentChildIndex() + 1 == ctx.getComponentSiblingSize();
}
});
// :only-child
_defs.put("only-child", new PseudoClassDef() {
public boolean accept(ComponentMatchCtx ctx, String... parameters) {
if (parameters.length > 0)
return false;
return ctx.getComponentSiblingSize() == 1;
}
});
// :empty
_defs.put("empty", new PseudoClassDef() {
public boolean accept(ComponentMatchCtx ctx, String... parameters) {
if (parameters.length > 0)
return false;
return ctx.getComponent().getChildren().isEmpty();
}
});
// :nth-child(n)
_defs.put("nth-child", new PseudoClassDef() {
public boolean accept(ComponentMatchCtx ctx, String... parameters) {
return parameters.length == 1 && acceptNthPattern(ctx.getComponentChildIndex() + 1, parameters[0]);
}
});
// :nth-last-child(n)
_defs.put("nth-last-child", new PseudoClassDef() {
public boolean accept(ComponentMatchCtx ctx, String... parameters) {
return parameters.length == 1 && acceptNthPattern(
ctx.getComponentSiblingSize() - ctx.getComponentChildIndex(), parameters[0]);
}
});
// ZK-2944: added support shadow host
// :host
// :host(selector)
_defs.put("host", new PseudoClassDef() {
public boolean accept(ComponentMatchCtx ctx, String... parameters) {
ComponentCtrl comp = (ComponentCtrl) ctx.getComponent();
if (comp.getShadowRoots().isEmpty()) {
return false; // not a shadow host
}
if (parameters.length == 0) { // select all hosts
return true;
} else { // select the hosts that match the selector
ComponentIterator compIter = new ComponentIterator(ctx.getComponent(), parameters[0]);
// only run once, since we only handle type, #id, or .class, no need to traverse component tree
if (compIter.hasNext() && ctx.getComponent() == compIter.next()) {
return true;
}
}
return false;
}
});
}
/**
* Returns the pseudo class definition associated with the given name
* @param name the pseudo class name
* @return a pseudo class definition
*/
public static PseudoClassDef getDefinition(String name) {
return _defs.get(name);
}
// helper //
private static boolean acceptNthPattern(int index, String pattern) {
return "odd".equals(pattern) && index % 2 == 1 || "even".equals(pattern) && index % 2 == 0
|| new NthChildPattern(pattern).accept(index);
}
private static class NthChildPattern {
private final int _preNum;
private final int _postNum;
private final boolean _valid;
private NthChildPattern(String pattern) {
int npos = pattern.indexOf('n');
String preStr = npos < 0 ? "" : pattern.substring(0, npos);
String postStr = npos < 0 ? pattern : pattern.substring(npos + 1);
_valid = Pattern.matches("(?:\\+|-)?\\d*", preStr) && Pattern.matches("(?:(?:\\+|-)?\\d+)?", postStr);
_preNum = _valid ? value(preStr, npos < 0 ? 0 : 1) : -1;
_postNum = _valid ? value(postStr, 0) : -1;
}
private boolean accept(int index) {
if (!_valid)
return false;
if (_preNum == 0)
return index == _postNum;
int diff = index - _postNum;
return diff % _preNum == 0 && diff / _preNum >= 0;
}
private int value(String str, int defValue) {
if (Strings.isEmpty(str))
return defValue;
char p = str.charAt(0);
String s = (p == '+' || p == '-') ? str.substring(1) : str;
return (p == '-' ? -1 : 1) * (Strings.isEmpty(s) ? defValue : Integer.valueOf(s));
}
}
}