1 // Copyright 2017 The PDFium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "core/fxcrt/css/cfx_cssselector.h" 8 9 #include <utility> 10 11 #include "core/fxcrt/fx_extension.h" 12 #include "third_party/base/check.h" 13 14 namespace { 15 GetCSSNameLen(WideStringView str)16size_t GetCSSNameLen(WideStringView str) { 17 for (size_t i = 0; i < str.GetLength(); ++i) { 18 wchar_t wch = str[i]; 19 if (!isascii(wch) || (!isalnum(wch) && wch != '_' && wch != '-')) 20 return i; 21 } 22 return str.GetLength(); 23 } 24 25 } // namespace 26 CFX_CSSSelector(WideStringView str,std::unique_ptr<CFX_CSSSelector> next)27CFX_CSSSelector::CFX_CSSSelector(WideStringView str, 28 std::unique_ptr<CFX_CSSSelector> next) 29 : name_hash_(FX_HashCode_GetLoweredW(str)), next_(std::move(next)) {} 30 31 CFX_CSSSelector::~CFX_CSSSelector() = default; 32 33 // static. FromString(WideStringView str)34std::unique_ptr<CFX_CSSSelector> CFX_CSSSelector::FromString( 35 WideStringView str) { 36 DCHECK(!str.IsEmpty()); 37 38 for (wchar_t wch : str) { 39 switch (wch) { 40 case '>': 41 case '[': 42 case '+': 43 return nullptr; 44 } 45 } 46 47 std::unique_ptr<CFX_CSSSelector> head; 48 for (size_t i = 0; i < str.GetLength();) { 49 wchar_t wch = str[i]; 50 if (wch == ' ') { 51 ++i; 52 continue; 53 } 54 55 const bool is_star = wch == '*'; 56 const bool is_valid_char = is_star || (isascii(wch) && isalpha(wch)); 57 if (!is_valid_char) 58 return nullptr; 59 60 if (head) 61 head->set_is_descendant(); 62 size_t len = is_star ? 1 : GetCSSNameLen(str.Last(str.GetLength() - i)); 63 auto new_head = 64 std::make_unique<CFX_CSSSelector>(str.Substr(i, len), std::move(head)); 65 head = std::move(new_head); 66 i += len; 67 } 68 return head; 69 } 70