OLD | NEW |
1 library selector; | 1 library selector; |
2 | 2 |
3 import 'package:html5lib/dom.dart'; | 3 import 'package:html5lib/dom.dart'; |
4 | 4 |
5 class ContainsSelector { | 5 class ContainsSelector { |
6 String selector; | 6 String selector; |
7 RegExp regexp; | 7 RegExp regexp; |
8 | 8 |
9 ContainsSelector(this.selector, regexp) { | 9 ContainsSelector(this.selector, regexp) { |
10 this.regexp = new RegExp(regexp); | 10 this.regexp = new RegExp(regexp); |
11 } | 11 } |
12 } | 12 } |
13 | 13 |
14 RegExp _SELECTOR_REGEXP = new RegExp(r'^(?:([\w\-]+)|(?:\.([\w\-]+))|(?:\[([\w\-
\*]+)(?:=([^\]]*))?\]))'); | 14 RegExp _SELECTOR_REGEXP = new RegExp(r'^(?:([\w\-]+)|(?:\.([\w\-]+))|(?:\[([\w\-
\*]+)(?:=([^\]]*))?\]))'); |
15 RegExp _COMMENT_COMPONENT_REGEXP = new RegExp(r'^\[([\w\-]+)(?:\=(.*))?\]$'); | 15 RegExp _COMMENT_COMPONENT_REGEXP = new RegExp(r'^\[([\w\-]+)(?:\=(.*))?\]$'); |
16 RegExp _CONTAINS_REGEXP = new RegExp(r'^:contains\(\/(.+)\/\)$'); // | 16 RegExp _CONTAINS_REGEXP = new RegExp(r'^:contains\(\/(.+)\/\)$'); // |
17 RegExp _ATTR_CONTAINS_REGEXP = new RegExp(r'^\[\*=\/(.+)\/\]$'); // | 17 RegExp _ATTR_CONTAINS_REGEXP = new RegExp(r'^\[\*=\/(.+)\/\]$'); // |
18 | 18 |
19 class _SelectorPart { | 19 class _SelectorPart { |
20 final String element; | 20 final String element; |
21 final String className; | 21 final String className; |
22 final String attrName; | 22 final String attrName; |
23 final String attrValue; | 23 final String attrValue; |
24 | 24 |
25 const _SelectorPart.fromElement(String this.element) | 25 const _SelectorPart.fromElement(this.element) |
26 : className = null, attrName = null, attrValue = null; | 26 : className = null, attrName = null, attrValue = null; |
27 | 27 |
28 const _SelectorPart.fromClass(String this.className) | 28 const _SelectorPart.fromClass(this.className) |
29 : element = null, attrName = null, attrValue = null; | 29 : element = null, attrName = null, attrValue = null; |
30 | 30 |
31 | 31 |
32 const _SelectorPart.fromAttribute(String this.attrName, String this.attrValue) | 32 const _SelectorPart.fromAttribute(this.attrName, this.attrValue) |
33 : element = null, className = null; | 33 : element = null, className = null; |
34 | 34 |
35 toString() => | 35 String toString() => |
36 element == null | 36 element == null |
37 ? (className == null | 37 ? (className == null |
38 ? (attrValue == '' ? '[$attrName]' : '[$attrName=$attrValue]') | 38 ? (attrValue == '' ? '[$attrName]' : '[$attrName=$attrValue]') |
39 : '.$className') | 39 : '.$className') |
40 : element; | 40 : element; |
41 } | 41 } |
42 | 42 |
43 List<_SelectorPart> _splitCss(String selector) { | 43 List<_SelectorPart> _splitCss(String selector) { |
44 List<_SelectorPart> parts = []; | 44 List<_SelectorPart> parts = []; |
45 var remainder = selector; | 45 var remainder = selector; |
(...skipping 18 matching lines...) Expand all Loading... |
64 } | 64 } |
65 return parts; | 65 return parts; |
66 } | 66 } |
67 | 67 |
68 bool matchesNode(Node node, String selector) { | 68 bool matchesNode(Node node, String selector) { |
69 var match, selectorParts; | 69 var match, selectorParts; |
70 if ((match = _CONTAINS_REGEXP.firstMatch(selector)) != null) { | 70 if ((match = _CONTAINS_REGEXP.firstMatch(selector)) != null) { |
71 if (node is! Text) { | 71 if (node is! Text) { |
72 return false; | 72 return false; |
73 } | 73 } |
74 return new RegExp(match.group(1)).hasMatch((node as Text).value); | 74 return new RegExp(match.group(1)).hasMatch((node as Text).text); |
75 } else if ((match = _ATTR_CONTAINS_REGEXP.firstMatch(selector)) != null) { | 75 } else if ((match = _ATTR_CONTAINS_REGEXP.firstMatch(selector)) != null) { |
76 if (node is! Element) { | 76 if (node is! Element) { |
77 return false; | 77 return false; |
78 } | 78 } |
79 var regexp = new RegExp(match.group(1)); | 79 var regexp = new RegExp(match.group(1)); |
80 for (String attrName in node.attributes.keys) { | 80 for (String attrName in node.attributes.keys) { |
81 if (regexp.hasMatch(node.attributes[attrName])) { | 81 if (regexp.hasMatch(node.attributes[attrName])) { |
82 return true; | 82 return true; |
83 } | 83 } |
84 } | 84 } |
85 return false; | 85 return false; |
86 } else if ((selectorParts = _splitCss(selector)) != null) { | 86 } else if ((selectorParts = _splitCss(selector)) != null) { |
87 if (node is! Element) { | 87 if (node is! Element) return false; |
88 return false; | 88 String nodeName = (node as Element).localName.toLowerCase(); |
89 } | |
90 String nodeName = node.tagName.toLowerCase(); | |
91 | 89 |
92 bool stillGood = true; | 90 bool stillGood = true; |
93 selectorParts.forEach((_SelectorPart part) { | 91 selectorParts.forEach((_SelectorPart part) { |
94 if (part.element != null) { | 92 if (part.element != null) { |
95 if (nodeName != part.element) { | 93 if (nodeName != part.element) { |
96 stillGood = false; | 94 stillGood = false; |
97 } | 95 } |
98 } else if (part.className != null) { | 96 } else if (part.className != null) { |
99 if (node.attributes['class'] == null || | 97 if (node.attributes['class'] == null || |
100 !node.attributes['class'].split(' ').contains(part.className)) { | 98 !node.attributes['class'].split(' ').contains(part.className)) { |
101 stillGood = false; | 99 stillGood = false; |
102 } | 100 } |
103 } else if (part.attrName != null) { | 101 } else if (part.attrName != null) { |
104 String matchingKey = _matchingKey(node.attributes.keys, part.attrName); | 102 String matchingKey = _matchingKey(node.attributes.keys, part.attrName); |
105 if (matchingKey == null || part.attrValue == '' ? | 103 if (matchingKey == null || part.attrValue == '' ? |
106 node.attributes[matchingKey] == null : | 104 node.attributes[matchingKey] == null : |
107 node.attributes[matchingKey] != part.attrValue) { | 105 node.attributes[matchingKey] != part.attrValue) { |
108 stillGood = false; | 106 stillGood = false; |
109 } | 107 } |
110 } | 108 } |
111 }); | 109 }); |
112 | 110 |
113 return stillGood; | 111 return stillGood; |
114 } | 112 } |
115 | 113 |
116 throw new ArgumentError('Unsupported Selector: $selector'); | 114 throw new ArgumentError('Unsupported Selector: $selector'); |
117 } | 115 } |
118 | 116 |
119 String _matchingKey(Iterable keys, String attrName) => | 117 String _matchingKey(Iterable keys, String attrName) => |
120 keys.firstWhere( | 118 keys.firstWhere( |
121 (key) => new RegExp('^${attrName.replaceAll('*', r'[\w\-]+')}\$').hasMat
ch(key.toString()), | 119 (key) => new RegExp('^${attrName.replaceAll('*', r'[\w\-]+')}\$').hasMat
ch(key.toString()), |
122 orElse: () => null); | 120 orElse: () => null); |
OLD | NEW |