Skip to content

Commit

Permalink
for radkovo#17: Implemented API to check for pseudo selectors
Browse files Browse the repository at this point in the history
* Refactored some of the previous implementations into a pure static
class, keeping the existing API intact.

s* mall optimisation: use array instead of array list
  • Loading branch information
hrj committed Jul 7, 2015
1 parent 431c88c commit 136b435
Show file tree
Hide file tree
Showing 5 changed files with 519 additions and 335 deletions.
6 changes: 6 additions & 0 deletions src/main/java/cz/vutbr/web/css/Selector.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ private PseudoDeclaration(String value, boolean isElement) {
*/
public PseudoDeclaration getPseudoElement();

/**
* Checks where the specified pseudo declaration is in this selector
* @return <code>true</code> if the selector has the specified pseudo declaration
*/
public boolean hasPseudoDeclaration(final PseudoDeclaration pd);

/**
* Modifies specificity according to CSS standard
* @param spec Specificity to be modified
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/cz/vutbr/web/csskit/SelectorImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,19 @@ public PseudoDeclaration getPseudoElement() {
return ret;
}

public boolean hasPseudoDeclaration(final PseudoDeclaration pd) {
for(SelectorPart item : list) {
if(item instanceof PseudoPage)
{
final PseudoDeclaration ret = ((PseudoPage)item).getDeclaration();
if (ret == pd) {
return true;
}
}
}
return false;
}

public boolean matches(Element e) {

// check other items of simple selector
Expand Down
146 changes: 10 additions & 136 deletions src/main/java/cz/vutbr/web/domassign/Analyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,8 @@
import cz.vutbr.web.css.CombinedSelector;
import cz.vutbr.web.css.Declaration;
import cz.vutbr.web.css.MatchCondition;
import cz.vutbr.web.css.MediaQuery;
import cz.vutbr.web.css.MediaSpec;
import cz.vutbr.web.css.NodeData;
import cz.vutbr.web.css.Rule;
import cz.vutbr.web.css.RuleMedia;
import cz.vutbr.web.css.RuleSet;
import cz.vutbr.web.css.Selector;
import cz.vutbr.web.css.Selector.PseudoDeclaration;
Expand Down Expand Up @@ -388,139 +385,10 @@ protected boolean matchSelector(CombinedSelector sel, Element e, TreeWalker w) {
protected void classifyAllSheets(MediaSpec mediaspec)
{
rules = new Holder();
for (StyleSheet sheet : sheets)
classifyRules(sheet, mediaspec);
}

/**
* Divides rules in sheet into different categories to be easily and more
* quickly parsed afterward
*
* @param sheet The style sheet to be classified
* @param mediaspec The specification of the media for evaluating the media queries.
*/
protected void classifyRules(StyleSheet sheet, MediaSpec mediaspec) {

// create a new holder if it does not exist
if (rules == null) {
rules = new Holder();
}

for (Rule<?> rule : sheet) {
// this rule conforms to all media
if (rule instanceof RuleSet) {
RuleSet ruleset = (RuleSet) rule;
for (CombinedSelector s : ruleset.getSelectors()) {
insertClassified(rules, classifySelector(s), ruleset);
}
}
// this rule conforms to different media
else if (rule instanceof RuleMedia) {
RuleMedia rulemedia = (RuleMedia) rule;

boolean mediaValid = false;
if(rulemedia.getMediaQueries()==null || rulemedia.getMediaQueries().isEmpty()) {
//no media queries actually
mediaValid = mediaspec.matchesEmpty();
} else {
//find a matching query
for (MediaQuery media : rulemedia.getMediaQueries()) {
if (mediaspec.matches(media)) {
mediaValid = true;
break;
}
}
}

if (mediaValid)
{
// for all rules in media set
for (RuleSet ruleset : rulemedia) {
// for all selectors in there
for (CombinedSelector s : ruleset.getSelectors()) {
insertClassified(rules, classifySelector(s), ruleset);
}
}
}
}
}

// logging
if (log.isDebugEnabled()) {
log.debug("For media \"{}\" we have {} rules", mediaspec, rules.contentCount());
if(log.isTraceEnabled()) {
log.trace("Detailed view: \n{}", rules);
}
}

}

/**
* Classify CSS rule according its selector for to be of specified item(s)
*
* @param selector
* CombinedSelector of rules
* @return List of HolderSelectors to which selectors conforms
*/
private List<HolderSelector> classifySelector(CombinedSelector selector) {

List<HolderSelector> hs = new ArrayList<HolderSelector>();

try {
// last simple selector decided about all selector
Selector last = selector.getLastSelector();

// is element or other (wildcard)
String element = last.getElementName();
if (element != null) {
// wildcard
if (Selector.ElementName.WILDCARD.equals(element))
hs.add(new HolderSelector(HolderItem.OTHER, null));
// element
else
hs.add(new HolderSelector(HolderItem.ELEMENT, element
.toLowerCase()));
}

// is class name
String className = last.getClassName();
if (className != null)
hs.add(new HolderSelector(HolderItem.CLASS, className
.toLowerCase()));

// is id
String id = last.getIDName();
if (id != null)
hs.add(new HolderSelector(HolderItem.ID, id.toLowerCase()));

// is in others
if (hs.size() == 0)
hs.add(new HolderSelector(HolderItem.OTHER, null));

return hs;

} catch (UnsupportedOperationException e) {
log
.error("CombinedSelector does not include any selector, this should not happen!");
return Collections.emptyList();
}
AnalyzerUtil.classifyAllSheets(sheets, rules, mediaspec);
}

/**
* Inserts rules into holder
*
* @param holder
* Wrap to be inserted
* @param hs
* Wrap's selector and key
* @param value
* Value to be inserted
*/
private void insertClassified(Holder holder, List<HolderSelector> hs, RuleSet value) {
for (HolderSelector h : hs)
holder.insert(h.item, h.key, new OrderedRule(value, currentOrder++));
}


/**
* Decides about holder item
*
Expand All @@ -547,7 +415,7 @@ public int type() {
* @author kapy
*
*/
protected class HolderSelector {
protected static class HolderSelector {
public HolderItem item;
public String key;

Expand All @@ -562,7 +430,7 @@ public HolderSelector(HolderItem item, String key) {
*
* @author burgetr
*/
protected final class OrderedRule implements Comparable<OrderedRule> {
public static final class OrderedRule implements Comparable<OrderedRule> {
private final RuleSet rule;
private final int order;

Expand All @@ -582,6 +450,12 @@ public int getOrder() {
public int compareTo(OrderedRule o) {
return getOrder() - o.getOrder();
}

@Override
public String toString() {
return "OR" + order + ", " + rule;
}

}

/**
Expand Down
Loading

0 comments on commit 136b435

Please sign in to comment.