| OLD | NEW |
| (Empty) | |
| 1 library selector; |
| 2 |
| 3 import 'package:html5lib/dom.dart'; |
| 4 |
| 5 class ContainsSelector { |
| 6 String selector; |
| 7 RegExp regexp; |
| 8 |
| 9 ContainsSelector(this.selector, regexp) { |
| 10 this.regexp = new RegExp(regexp); |
| 11 } |
| 12 } |
| 13 |
| 14 RegExp _SELECTOR_REGEXP = new RegExp(r'^(?:([\w\-]+)|(?:\.([\w\-]+))|(?:\[([\w\-
]+)(?:=([^\]]*))?\]))'); |
| 15 RegExp _COMMENT_COMPONENT_REGEXP = new RegExp(r'^\[([\w\-]+)(?:\=(.*))?\]$'); |
| 16 RegExp _CONTAINS_REGEXP = new RegExp(r'^:contains\(\/(.+)\/\)$'); // |
| 17 RegExp _ATTR_CONTAINS_REGEXP = new RegExp(r'^\[\*=\/(.+)\/\]$'); // |
| 18 |
| 19 class _SelectorPart { |
| 20 final String element; |
| 21 final String className; |
| 22 final String attrName; |
| 23 final String attrValue; |
| 24 |
| 25 const _SelectorPart.fromElement(String this.element) |
| 26 : className = null, attrName = null, attrValue = null; |
| 27 |
| 28 const _SelectorPart.fromClass(String this.className) |
| 29 : element = null, attrName = null, attrValue = null; |
| 30 |
| 31 |
| 32 const _SelectorPart.fromAttribute(String this.attrName, String this.attrValue) |
| 33 : element = null, className = null; |
| 34 |
| 35 toString() => |
| 36 element == null |
| 37 ? (className == null |
| 38 ? (attrValue == '' ? '[$attrName]' : '[$attrName=$attrValue]') |
| 39 : '.$className') |
| 40 : element; |
| 41 } |
| 42 |
| 43 List<_SelectorPart> _splitCss(String selector) { |
| 44 List<_SelectorPart> parts = []; |
| 45 var remainder = selector; |
| 46 var match; |
| 47 while (!remainder.isEmpty) { |
| 48 if ((match = _SELECTOR_REGEXP.firstMatch(remainder)) != null) { |
| 49 if (match[1] != null) { |
| 50 parts.add(new _SelectorPart.fromElement(match[1].toLowerCase())); |
| 51 } else if (match[2] != null) { |
| 52 parts.add(new _SelectorPart.fromClass(match[2].toLowerCase())); |
| 53 } else if (match[3] != null) { |
| 54 var attrValue = match[4] == null ? '' : match[4].toLowerCase(); |
| 55 parts.add(new _SelectorPart.fromAttribute(match[3].toLowerCase(), |
| 56 attrValue)); |
| 57 } else { |
| 58 throw "Missmatched RegExp $_SELECTOR_REGEXP on $remainder"; |
| 59 } |
| 60 } else { |
| 61 throw "Unknown selector format '$remainder'."; |
| 62 } |
| 63 remainder = remainder.substring(match.end); |
| 64 } |
| 65 return parts; |
| 66 } |
| 67 |
| 68 bool matchesNode(Node node, String selector) { |
| 69 var match, selectorParts; |
| 70 if ((match = _CONTAINS_REGEXP.firstMatch(selector)) != null) { |
| 71 if (node is! Text) { |
| 72 return false; |
| 73 } |
| 74 return new RegExp(match.group(1)).hasMatch((node as Text).value); |
| 75 } else if ((match = _ATTR_CONTAINS_REGEXP.firstMatch(selector)) != null) { |
| 76 if (node is! Element) { |
| 77 return false; |
| 78 } |
| 79 var regexp = new RegExp(match.group(1)); |
| 80 for (String attrName in node.attributes.keys) { |
| 81 if (regexp.hasMatch(node.attributes[attrName])) { |
| 82 return true; |
| 83 } |
| 84 } |
| 85 return false; |
| 86 } else if ((selectorParts = _splitCss(selector)) != null) { |
| 87 if (node is! Element) { |
| 88 return false; |
| 89 } |
| 90 String nodeName = node.tagName.toLowerCase(); |
| 91 |
| 92 bool stillGood = true; |
| 93 selectorParts.forEach((_SelectorPart part) { |
| 94 if (part.element != null) { |
| 95 if (nodeName != part.element) { |
| 96 stillGood = false; |
| 97 } |
| 98 } else if (part.className != null) { |
| 99 if (node.attributes['class'] == null || |
| 100 !node.attributes['class'].split(' ').contains(part.className)) { |
| 101 stillGood = false; |
| 102 } |
| 103 } else if (part.attrName != null) { |
| 104 if (part.attrValue == '' ? |
| 105 node.attributes[part.attrName] == null : |
| 106 node.attributes[part.attrName] != part.attrValue) { |
| 107 stillGood = false; |
| 108 } |
| 109 } |
| 110 }); |
| 111 |
| 112 return stillGood; |
| 113 } else { |
| 114 throw new ArgumentError('Unsupported Selector: $selector'); |
| 115 } |
| 116 |
| 117 switch(node.nodeType) { |
| 118 case 1: // Element |
| 119 break; |
| 120 case 3: // Text Node |
| 121 break; |
| 122 } |
| 123 return false; |
| 124 } |
| OLD | NEW |