Home | History | Annotate | Download | only in css
      1 // Copyright 2017 PDFium Authors. All rights reserved.
      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/ptr_util.h"
     13 
     14 namespace {
     15 
     16 int32_t GetCSSNameLen(const wchar_t* psz, const wchar_t* pEnd) {
     17   const wchar_t* pStart = psz;
     18   while (psz < pEnd) {
     19     wchar_t wch = *psz;
     20     if (!FXSYS_iswalnum(wch) && wch != '_' && wch != '-')
     21       break;
     22     ++psz;
     23   }
     24   return psz - pStart;
     25 }
     26 
     27 }  // namespace
     28 
     29 CFX_CSSSelector::CFX_CSSSelector(CFX_CSSSelectorType eType,
     30                                  const wchar_t* psz,
     31                                  int32_t iLen,
     32                                  bool bIgnoreCase)
     33     : m_eType(eType),
     34       m_dwHash(FX_HashCode_GetW(WideStringView(psz, iLen), bIgnoreCase)) {}
     35 
     36 CFX_CSSSelector::~CFX_CSSSelector() {}
     37 
     38 CFX_CSSSelectorType CFX_CSSSelector::GetType() const {
     39   return m_eType;
     40 }
     41 
     42 uint32_t CFX_CSSSelector::GetNameHash() const {
     43   return m_dwHash;
     44 }
     45 
     46 CFX_CSSSelector* CFX_CSSSelector::GetNextSelector() const {
     47   return m_pNext.get();
     48 }
     49 
     50 // static.
     51 std::unique_ptr<CFX_CSSSelector> CFX_CSSSelector::FromString(
     52     const WideStringView& str) {
     53   ASSERT(!str.IsEmpty());
     54 
     55   const wchar_t* psz = str.unterminated_c_str();
     56   const wchar_t* pStart = psz;
     57   const wchar_t* pEnd = psz + str.GetLength();
     58   for (; psz < pEnd; ++psz) {
     59     switch (*psz) {
     60       case '>':
     61       case '[':
     62       case '+':
     63         return nullptr;
     64     }
     65   }
     66 
     67   std::unique_ptr<CFX_CSSSelector> pFirst = nullptr;
     68   for (psz = pStart; psz < pEnd;) {
     69     wchar_t wch = *psz;
     70     if (FXSYS_iswalpha(wch) || wch == '*') {
     71       int32_t iNameLen = wch == '*' ? 1 : GetCSSNameLen(psz, pEnd);
     72       auto p = pdfium::MakeUnique<CFX_CSSSelector>(CFX_CSSSelectorType::Element,
     73                                                    psz, iNameLen, true);
     74       if (pFirst) {
     75         pFirst->SetType(CFX_CSSSelectorType::Descendant);
     76         p->SetNext(std::move(pFirst));
     77       }
     78       pFirst = std::move(p);
     79       psz += iNameLen;
     80     } else if (wch == ' ') {
     81       psz++;
     82     } else {
     83       return nullptr;
     84     }
     85   }
     86   return pFirst;
     87 }
     88