| OLD | NEW | 
|---|
| 1 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file | 
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a | 
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 class Validate { | 5 class Validate { | 
| 6   static int _classNameCheck(var selector, int matches) { | 6   static int _classNameCheck(var selector, int matches) { | 
| 7     if (selector.isCombinatorDescendant() || | 7     if (selector.isCombinatorDescendant() || | 
| 8         (selector.isCombinatorNone() && matches == 0)) { | 8         (selector.isCombinatorNone() && matches == 0)) { | 
| 9       if (matches < 0) { | 9       if (matches < 0) { | 
| 10         String tooMany = selector.toString(); | 10         String tooMany = selector.simpleSelector.toString(); | 
| 11         throw new CssSelectorException( | 11         throw new CssSelectorException( | 
| 12             'Can not mix Id selector with class selector(s). Id ' + | 12             'Can not mix Id selector with class selector(s). Id ' + | 
| 13             'selector must be singleton too many starting at $tooMany'); | 13             'selector must be singleton too many starting at $tooMany'); | 
| 14       } | 14       } | 
| 15 | 15 | 
| 16       return matches + 1; | 16       return matches + 1; | 
| 17     } else { | 17     } else { | 
| 18       String error = selector.toString(); | 18       String error = selector.toString(); | 
| 19       throw new CssSelectorException( | 19       throw new CssSelectorException( | 
| 20           'Selectors can not have combinators (>, +, or ~) before $error'); | 20           'Selectors can not have combinators (>, +, or ~) before $error'); | 
| 21     } | 21     } | 
| 22   } | 22   } | 
| 23 | 23 | 
| 24   static int _elementIdCheck(var selector, int matches) { | 24   static int _elementIdCheck(var selector, int matches) { | 
| 25     if (selector.isCombinatorNone() && matches == 0) { | 25     if (selector.isCombinatorNone() && matches == 0) { | 
| 26       // Perfect just one element id returns matches of -1. | 26       // Perfect just one element id returns matches of -1. | 
| 27       return -1; | 27       return -1; | 
| 28     } else if (selector.isCombinatorDescendant()) { | 28     } else if (selector.isCombinatorDescendant()) { | 
| 29         String tooMany = selector.toString(); | 29         String tooMany = selector.simpleSelector.toString(); | 
| 30         throw new CssSelectorException( | 30         throw new CssSelectorException( | 
| 31             'Use of Id selector must be singleton starting at $tooMany'); | 31             'Use of Id selector must be singleton starting at $tooMany'); | 
| 32     } else { | 32     } else { | 
| 33       String error = selector.toString(); | 33       String error = selector.simpleSelector.toString(); | 
| 34       throw new CssSelectorException( | 34       throw new CssSelectorException( | 
| 35           'Selectors can not have combinators (>, +, or ~) before $error'); | 35           'Selectors can not have combinators (>, +, or ~) before $error'); | 
| 36     } | 36     } | 
| 37   } | 37   } | 
| 38 | 38 | 
| 39   // Validate the @{css expression} only .class and #elementId are valid inside | 39   // Validate the @{css expression} only .class and #elementId are valid inside | 
| 40   // of @{...}. | 40   // of @{...}. | 
| 41   static template(List<lang.Node> selectors, CssWorld cssWorld) { | 41   static template(List<lang.Node> selectors, CssWorld cssWorld) { | 
| 42     var errorSelector;                  // signal which selector didn't match. | 42     var errorSelector;                  // signal which selector didn't match. | 
| 43     bool found = false;                 // signal if a selector is matched. | 43     bool found = false;                 // signal if a selector is matched. | 
| 44     int matches = 0;                    // < 0 IdSelectors, > 0 ClassSelector | 44     int matches = 0;                    // < 0 IdSelectors, > 0 ClassSelector | 
| 45     for (var sels in selectors) { | 45 | 
| 46       for (var selector in sels.simpleSelectorSequences) { | 46     // At most one selector group (any number of simple selector sequences). | 
|  | 47     assert(selectors.length <= 1); | 
|  | 48 | 
|  | 49     for (final sels in selectors) { | 
|  | 50       for (final selector in sels.simpleSelectorSequences) { | 
| 47         found = false; | 51         found = false; | 
| 48         var simpleSelector = selector.simpleSelector; | 52         var simpleSelector = selector.simpleSelector; | 
| 49         if (simpleSelector is ClassSelector) { | 53         if (simpleSelector is ClassSelector) { | 
| 50           // Any class name starting with an underscore is a private class name | 54           // Any class name starting with an underscore is a private class name | 
| 51           // that doesn't have to match the world of known classes. | 55           // that doesn't have to match the world of known classes. | 
| 52           if (!simpleSelector.name.startsWith('_')) { | 56           if (!simpleSelector.name.startsWith('_')) { | 
| 53             // TODO(terry): For now iterate through all classes look for faster | 57             // TODO(terry): For now iterate through all classes look for faster | 
| 54             //              mechanism hash map, etc. | 58             //              mechanism hash map, etc. | 
| 55             var className; | 59             var className; | 
| 56             for (var className in cssWorld.classes) { | 60             for (final className in cssWorld.classes) { | 
| 57               if (selector.simpleSelector.name == className) { | 61               if (selector.simpleSelector.name == className) { | 
| 58                 matches = _classNameCheck(selector, matches); | 62                 matches = _classNameCheck(selector, matches); | 
| 59                 found = true;              // .class found. | 63                 found = true;              // .class found. | 
| 60                 break; | 64                 break; | 
| 61               } | 65               } | 
| 62               for (var className2 in cssWorld.classes) { | 66               for (final className2 in cssWorld.classes) { | 
| 63                 print(className2); | 67                 print(className2); | 
| 64               } | 68               } | 
| 65             } | 69             } | 
| 66 | 70 | 
| 67           } else { | 71           } else { | 
| 68             // Don't check any class name that is prefixed with an underscore. | 72             // Don't check any class name that is prefixed with an underscore. | 
| 69             // However, signal as found and bump up matches; it's a valid class | 73             // However, signal as found and bump up matches; it's a valid class | 
| 70             // name. | 74             // name. | 
| 71             matches = _classNameCheck(selector, matches); | 75             matches = _classNameCheck(selector, matches); | 
| 72             found = true;                 // ._class are always okay. | 76             found = true;                 // ._class are always okay. | 
| 73           } | 77           } | 
| 74         } else if (simpleSelector is IdSelector) { | 78         } else if (simpleSelector is IdSelector) { | 
| 75           // Any element id starting with an underscore is a private element id | 79           // Any element id starting with an underscore is a private element id | 
| 76           // that doesn't have to match the world of known elemtn ids. | 80           // that doesn't have to match the world of known elemtn ids. | 
| 77           if (!simpleSelector.name.startsWith('_')) { | 81           if (!simpleSelector.name.startsWith('_')) { | 
| 78             for (var id in cssWorld.ids) { | 82             for (final id in cssWorld.ids) { | 
| 79               if (simpleSelector.name == id) { | 83               if (simpleSelector.name == id) { | 
| 80                 matches = _elementIdCheck(selector, matches); | 84                 matches = _elementIdCheck(selector, matches); | 
| 81                 found = true;             // #id found. | 85                 found = true;             // #id found. | 
| 82                 break; | 86                 break; | 
| 83               } | 87               } | 
| 84             } | 88             } | 
| 85           } else { | 89           } else { | 
| 86             // Don't check any element ID that is prefixed with an underscore. | 90             // Don't check any element ID that is prefixed with an underscore. | 
| 87             // However, signal as found and bump up matches; it's a valid elemen
     t | 91             // Signal as found and bump up matches; it's a valid element ID. | 
| 88             // ID. |  | 
| 89             matches = _elementIdCheck(selector, matches); | 92             matches = _elementIdCheck(selector, matches); | 
| 90             found = true;                 // #_id are always okay | 93             found = true;                 // #_id are always okay | 
| 91           } | 94           } | 
| 92         } else { | 95         } else { | 
| 93           String badSelector = simpleSelector.toString(); | 96           String badSelector = simpleSelector.toString(); | 
| 94           throw new CssSelectorException( | 97           throw new CssSelectorException( | 
| 95               'Invalid template selector $badSelector'); | 98               'Invalid template selector $badSelector'); | 
| 96         } | 99         } | 
| 97 | 100 | 
| 98         if (!found) { | 101         if (!found) { | 
| 99           String unknownName = simpleSelector.toString(); | 102           String unknownName = simpleSelector.toString(); | 
| 100           throw new CssSelectorException('Unknown selector name $unknownName'); | 103           throw new CssSelectorException('Unknown selector name $unknownName'); | 
| 101         } | 104         } | 
| 102       } | 105       } | 
| 103     } | 106     } | 
| 104 | 107 | 
| 105     // Every selector must match. | 108     // Every selector must match. | 
| 106     assert((matches >= 0 ? matches : -matches) == selectors.length); | 109     assert((matches >= 0 ? matches : -matches) == | 
|  | 110         selectors[0].simpleSelectorSequences.length); | 
| 107   } | 111   } | 
| 108 } | 112 } | 
| 109 | 113 | 
| OLD | NEW | 
|---|