Skip to content

Commit f4d0999

Browse files
committed
SelectorSpecificity is not part of the css model
1 parent 7e8b717 commit f4d0999

File tree

12 files changed

+557
-67
lines changed

12 files changed

+557
-67
lines changed

src/main/java/com/gargoylesoftware/css/dom/CSSStyleSheetImpl.java

Lines changed: 153 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
import java.io.ObjectOutputStream;
2020
import java.io.Serializable;
2121
import java.io.StringReader;
22-
import java.net.URI;
23-
import java.net.URISyntaxException;
22+
import java.util.ArrayList;
23+
import java.util.HashMap;
24+
import java.util.Iterator;
25+
import java.util.List;
26+
import java.util.Map;
2427

2528
import org.w3c.dom.DOMException;
2629
import org.w3c.dom.Node;
27-
import org.w3c.dom.css.CSSImportRule;
2830
import org.w3c.dom.css.CSSRule;
2931
import org.w3c.dom.css.CSSRuleList;
3032
import org.w3c.dom.css.CSSStyleSheet;
@@ -35,6 +37,7 @@
3537
import com.gargoylesoftware.css.parser.CSSOMParser;
3638
import com.gargoylesoftware.css.parser.InputSource;
3739
import com.gargoylesoftware.css.parser.media.MediaQueryList;
40+
import com.gargoylesoftware.css.parser.selector.Selector;
3841
import com.gargoylesoftware.css.util.LangUtils;
3942
import com.gargoylesoftware.css.util.ThrowCssExceptionErrorHandler;
4043

@@ -53,20 +56,12 @@ public class CSSStyleSheetImpl implements CSSStyleSheet, Serializable {
5356
private CSSRule ownerRule_;
5457
private boolean readOnly_;
5558
private CSSRuleList cssRules_;
56-
private String baseUri_;
59+
private CSSStyleSheetRuleIndex index_;
5760

5861
public void setMedia(final MediaList media) {
5962
media_ = media;
6063
}
6164

62-
private String getBaseUri() {
63-
return baseUri_;
64-
}
65-
66-
public void setBaseUri(final String baseUri) {
67-
baseUri_ = baseUri;
68-
}
69-
7065
public CSSStyleSheetImpl() {
7166
super();
7267
}
@@ -307,7 +302,6 @@ public boolean equals(final Object obj) {
307302
@Override
308303
public int hashCode() {
309304
int hash = LangUtils.HASH_SEED;
310-
hash = LangUtils.hashCode(hash, baseUri_);
311305
hash = LangUtils.hashCode(hash, cssRules_);
312306
hash = LangUtils.hashCode(hash, disabled_);
313307
hash = LangUtils.hashCode(hash, href_);
@@ -319,7 +313,6 @@ public int hashCode() {
319313
}
320314

321315
private void writeObject(final ObjectOutputStream out) throws IOException {
322-
out.writeObject(baseUri_);
323316
out.writeObject(cssRules_);
324317
out.writeBoolean(disabled_);
325318
out.writeObject(href_);
@@ -329,7 +322,6 @@ private void writeObject(final ObjectOutputStream out) throws IOException {
329322
}
330323

331324
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
332-
baseUri_ = (String) in.readObject();
333325
cssRules_ = (CSSRuleList) in.readObject();
334326
if (cssRules_ != null) {
335327
for (int i = 0; i < cssRules_.getLength(); i++) {
@@ -346,41 +338,156 @@ private void readObject(final ObjectInputStream in) throws IOException, ClassNot
346338
title_ = (String) in.readObject();
347339
}
348340

349-
/**
350-
* Imports referenced CSSStyleSheets.
351-
*
352-
* @param recursive <code>true</code> if the import should be done
353-
* recursively, <code>false</code> otherwise
354-
*/
355-
public void importImports(final boolean recursive) throws DOMException {
356-
for (int i = 0; i < getCssRules().getLength(); i++) {
357-
final CSSRule cssRule = getCssRules().item(i);
358-
if (cssRule.getType() == CSSRule.IMPORT_RULE) {
359-
final CSSImportRule cssImportRule = (CSSImportRule) cssRule;
360-
try {
361-
final URI importURI = new URI(getBaseUri()).resolve(cssImportRule.getHref());
362-
final CSSStyleSheetImpl importedCSS = (CSSStyleSheetImpl)
363-
new CSSOMParser().parseStyleSheet(
364-
new InputSource(importURI.toString()), importURI.toString());
365-
if (recursive) {
366-
importedCSS.importImports(recursive);
367-
}
368-
final MediaList mediaList = cssImportRule.getMedia();
369-
if (mediaList.getLength() == 0) {
370-
mediaList.appendMedium("all");
371-
}
372-
final CSSMediaRuleImpl cssMediaRule = new CSSMediaRuleImpl(this, null, mediaList);
373-
cssMediaRule.setRuleList((CSSRuleListImpl) importedCSS.getCssRules());
374-
deleteRule(i);
375-
((CSSRuleListImpl) getCssRules()).insert(cssMediaRule, i);
341+
public CSSStyleSheetRuleIndex getRuleIndex() {
342+
return index_;
343+
}
344+
345+
public void setRuleIndex(final CSSStyleSheetRuleIndex index) {
346+
index_ = index;
347+
}
348+
349+
public void resetRuleIndex() {
350+
index_ = null;
351+
}
352+
353+
public static final class SelectorEntry {
354+
private Selector selector_;
355+
private CSSStyleRuleImpl rule_;
356+
357+
SelectorEntry(final Selector selector, final CSSStyleRuleImpl rule) {
358+
selector_ = selector;
359+
rule_ = rule;
360+
}
361+
362+
public Selector getSelector() {
363+
return selector_;
364+
}
365+
366+
public CSSStyleRuleImpl getRule() {
367+
return rule_;
368+
}
369+
}
370+
371+
public static class CSSStyleSheetRuleIndex {
372+
373+
private static final MediaList DEFAULT_MEDIA_LIST = new MediaListImpl(null);
374+
375+
private final List<CSSStyleSheetRuleIndex> children_ = new ArrayList<>();
376+
377+
private MediaList mediaList_ = DEFAULT_MEDIA_LIST;
378+
private final Map<String, List<SelectorEntry>> elementSelectors_ = new HashMap<>();
379+
private final List<SelectorEntry> otherSelectors_ = new ArrayList<>();
380+
381+
public void addElementSelector(final String name, final Selector s, final CSSStyleRuleImpl styleRule) {
382+
List<SelectorEntry> entries = elementSelectors_.get(name);
383+
if (entries == null) {
384+
entries = new ArrayList<SelectorEntry>();
385+
elementSelectors_.put(name, entries);
386+
}
387+
final SelectorEntry selectorEntry = new SelectorEntry(s, styleRule);
388+
entries.add(selectorEntry);
389+
}
390+
391+
public void addOtherSelector(final Selector s, final CSSStyleRuleImpl styleRule) {
392+
final SelectorEntry selectorEntry = new SelectorEntry(s, styleRule);
393+
otherSelectors_.add(selectorEntry);
394+
}
395+
396+
public CSSStyleSheetRuleIndex addMedia(final MediaList mediaList) {
397+
final CSSStyleSheetRuleIndex index = new CSSStyleSheetRuleIndex();
398+
index.mediaList_ = mediaList;
399+
400+
children_.add(index);
401+
return index;
402+
}
403+
404+
public MediaList getMediaList() {
405+
return mediaList_;
406+
}
407+
408+
public List<CSSStyleSheetRuleIndex> getChildren() {
409+
return children_;
410+
}
411+
412+
public Iterator<SelectorEntry> getSelectorEntriesIteratorFor(final String elementName) {
413+
return new SelectorEntriesIterator(this, elementName);
414+
}
415+
}
416+
417+
static final class SelectorEntriesIterator implements Iterator<SelectorEntry> {
418+
private Iterator<SelectorEntry> anyElementSelectors_;
419+
private Iterator<SelectorEntry> elementSelectors_;
420+
private Iterator<SelectorEntry> otherSelectors_;
421+
422+
SelectorEntriesIterator(final CSSStyleSheetRuleIndex index, final String elementName) {
423+
List<SelectorEntry> sel = index.elementSelectors_.get("*");
424+
if (sel != null && !sel.isEmpty()) {
425+
anyElementSelectors_ = sel.iterator();
426+
}
427+
else {
428+
anyElementSelectors_ = null;
429+
}
430+
431+
sel = index.elementSelectors_.get(elementName);
432+
if (sel != null && !sel.isEmpty()) {
433+
elementSelectors_ = sel.iterator();
434+
}
435+
else {
436+
elementSelectors_ = null;
437+
}
438+
439+
if (index.otherSelectors_ != null && !index.otherSelectors_.isEmpty()) {
440+
otherSelectors_ = index.otherSelectors_.iterator();
441+
}
442+
else {
443+
otherSelectors_ = null;
444+
}
445+
}
446+
447+
@Override
448+
public SelectorEntry next() {
449+
if (anyElementSelectors_ != null) {
450+
if (anyElementSelectors_.hasNext()) {
451+
return anyElementSelectors_.next();
376452
}
377-
catch (final URISyntaxException e) {
378-
throw new DOMException(DOMException.SYNTAX_ERR, e.getLocalizedMessage());
453+
anyElementSelectors_ = null;
454+
}
455+
if (elementSelectors_ != null) {
456+
if (elementSelectors_.hasNext()) {
457+
return elementSelectors_.next();
379458
}
380-
catch (final IOException e) {
381-
// TODO handle exception
459+
elementSelectors_ = null;
460+
}
461+
if (otherSelectors_ != null) {
462+
if (otherSelectors_.hasNext()) {
463+
return otherSelectors_.next();
382464
}
465+
otherSelectors_ = null;
383466
}
467+
return null;
468+
}
469+
470+
@Override
471+
public boolean hasNext() {
472+
if (anyElementSelectors_ != null) {
473+
if (anyElementSelectors_.hasNext()) {
474+
return true;
475+
}
476+
anyElementSelectors_ = null;
477+
}
478+
if (elementSelectors_ != null) {
479+
if (elementSelectors_.hasNext()) {
480+
return true;
481+
}
482+
elementSelectors_ = null;
483+
}
484+
if (otherSelectors_ != null) {
485+
if (otherSelectors_.hasNext()) {
486+
return true;
487+
}
488+
otherSelectors_ = null;
489+
}
490+
return false;
384491
}
385492
}
386493
}

src/main/java/com/gargoylesoftware/css/parser/CSSOMParser.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ public void startDocument(final InputSource source) throws CSSException {
170170
if (nodeStack_.empty()) {
171171
final CSSStyleSheetImpl ss = new CSSStyleSheetImpl();
172172
CSSOMParser.this.setParentStyleSheet(ss);
173-
ss.setBaseUri(source.getURI());
174173
ss.setHref(getHref());
175174
ss.setMediaText(source.getMedia());
176175
ss.setTitle(source.getTitle());
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2018 Ronald Brill.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
package com.gargoylesoftware.css.parser.selector;
16+
17+
import java.io.Serializable;
18+
19+
import com.gargoylesoftware.css.parser.AbstractLocatable;
20+
21+
/**
22+
* @author Ronald Brill
23+
*/
24+
public abstract class AbstractSelector extends AbstractLocatable implements Selector, Serializable {
25+
26+
private SelectorSpecificity specificity_;
27+
28+
@Override
29+
public SelectorSpecificity getSelectorSpecificity() {
30+
if (specificity_ == null) {
31+
specificity_ = new SelectorSpecificity(this);
32+
}
33+
return specificity_;
34+
}
35+
}

src/main/java/com/gargoylesoftware/css/parser/selector/ChildSelector.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616

1717
import java.io.Serializable;
1818

19-
import com.gargoylesoftware.css.parser.AbstractLocatable;
20-
2119
/**
2220
* @author Ronald Brill
2321
*/
24-
public class ChildSelector extends AbstractLocatable implements Selector, Serializable {
22+
public class ChildSelector extends AbstractSelector implements Serializable {
2523

2624
private Selector ancestorSelector_;
2725
private SimpleSelector simpleSelector_;

src/main/java/com/gargoylesoftware/css/parser/selector/DescendantSelector.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616

1717
import java.io.Serializable;
1818

19-
import com.gargoylesoftware.css.parser.AbstractLocatable;
20-
2119
/**
2220
* @author Ronald Brill
2321
*/
24-
public class DescendantSelector extends AbstractLocatable implements Selector, Serializable {
22+
public class DescendantSelector extends AbstractSelector implements Serializable {
2523

2624
private final Selector ancestorSelector_;
2725
private final SimpleSelector simpleSelector_;

src/main/java/com/gargoylesoftware/css/parser/selector/DirectAdjacentSelector.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616

1717
import java.io.Serializable;
1818

19-
import com.gargoylesoftware.css.parser.AbstractLocatable;
20-
2119
/**
2220
* @author Ronald Brill
2321
*/
24-
public class DirectAdjacentSelector extends AbstractLocatable implements Selector, Serializable {
22+
public class DirectAdjacentSelector extends AbstractSelector implements Serializable {
2523

2624
private final Selector selector_; // child
2725
private final SimpleSelector simpleSelector_;

src/main/java/com/gargoylesoftware/css/parser/selector/ElementSelector.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,13 @@
1818
import java.util.ArrayList;
1919
import java.util.List;
2020

21-
import com.gargoylesoftware.css.parser.AbstractLocatable;
2221
import com.gargoylesoftware.css.parser.Locator;
2322
import com.gargoylesoftware.css.parser.condition.Condition;
2423

2524
/**
2625
* @author Ronald Brill
2726
*/
28-
public class ElementSelector extends AbstractLocatable implements SimpleSelector, Serializable {
27+
public class ElementSelector extends AbstractSelector implements SimpleSelector, Serializable {
2928

3029
private final String localName_;
3130
private List<Condition> conditions_;
@@ -49,6 +48,14 @@ public String getLocalName() {
4948
return localName_;
5049
}
5150

51+
public String getElementName() {
52+
final String localeName = getLocalName();
53+
if (localeName == null) {
54+
return "*";
55+
}
56+
return localeName;
57+
}
58+
5259
public List<Condition> getConditions() {
5360
return conditions_;
5461
}
@@ -62,10 +69,7 @@ public void addCondition(final Condition condition) {
6269

6370
@Override
6471
public String toString() {
65-
String localeName = getLocalName();
66-
if (localeName == null) {
67-
localeName = "*";
68-
}
72+
String localeName = getElementName();
6973

7074
// TODO use StringBuilder
7175
if (conditions_ != null) {

0 commit comments

Comments
 (0)