summaryrefslogtreecommitdiff
path: root/core/fxcrt/css/cfx_cssselector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxcrt/css/cfx_cssselector.cpp')
-rw-r--r--core/fxcrt/css/cfx_cssselector.cpp87
1 files changed, 87 insertions, 0 deletions
diff --git a/core/fxcrt/css/cfx_cssselector.cpp b/core/fxcrt/css/cfx_cssselector.cpp
new file mode 100644
index 0000000000..6ee81f5610
--- /dev/null
+++ b/core/fxcrt/css/cfx_cssselector.cpp
@@ -0,0 +1,87 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fxcrt/css/cfx_cssselector.h"
+
+#include <utility>
+
+#include "core/fxcrt/fx_extension.h"
+#include "third_party/base/ptr_util.h"
+
+namespace {
+
+int32_t GetCSSNameLen(const wchar_t* psz, const wchar_t* pEnd) {
+ const wchar_t* pStart = psz;
+ while (psz < pEnd) {
+ wchar_t wch = *psz;
+ if (!FXSYS_iswalnum(wch) && wch != '_' && wch != '-')
+ break;
+ ++psz;
+ }
+ return psz - pStart;
+}
+
+} // namespace
+
+CFX_CSSSelector::CFX_CSSSelector(CFX_CSSSelectorType eType,
+ const wchar_t* psz,
+ int32_t iLen,
+ bool bIgnoreCase)
+ : m_eType(eType),
+ m_dwHash(FX_HashCode_GetW(CFX_WideStringC(psz, iLen), bIgnoreCase)) {}
+
+CFX_CSSSelector::~CFX_CSSSelector() {}
+
+CFX_CSSSelectorType CFX_CSSSelector::GetType() const {
+ return m_eType;
+}
+
+uint32_t CFX_CSSSelector::GetNameHash() const {
+ return m_dwHash;
+}
+
+CFX_CSSSelector* CFX_CSSSelector::GetNextSelector() const {
+ return m_pNext.get();
+}
+
+// static.
+std::unique_ptr<CFX_CSSSelector> CFX_CSSSelector::FromString(
+ const CFX_WideStringC& str) {
+ ASSERT(!str.IsEmpty());
+
+ const wchar_t* psz = str.unterminated_c_str();
+ const wchar_t* pStart = psz;
+ const wchar_t* pEnd = psz + str.GetLength();
+ for (; psz < pEnd; ++psz) {
+ switch (*psz) {
+ case '>':
+ case '[':
+ case '+':
+ return nullptr;
+ }
+ }
+
+ std::unique_ptr<CFX_CSSSelector> pFirst = nullptr;
+ for (psz = pStart; psz < pEnd;) {
+ wchar_t wch = *psz;
+ if (FXSYS_iswalpha(wch) || wch == '*') {
+ int32_t iNameLen = wch == '*' ? 1 : GetCSSNameLen(psz, pEnd);
+ auto p = pdfium::MakeUnique<CFX_CSSSelector>(CFX_CSSSelectorType::Element,
+ psz, iNameLen, true);
+ if (pFirst) {
+ pFirst->SetType(CFX_CSSSelectorType::Descendant);
+ p->SetNext(std::move(pFirst));
+ }
+ pFirst = std::move(p);
+ psz += iNameLen;
+ } else if (wch == ' ') {
+ psz++;
+ } else {
+ return nullptr;
+ }
+ }
+ return pFirst;
+}