blob: f10bf5f743f23900140c2c17ba63b3bb90e59df4 [file] [log] [blame] [edit]
// Copyright 2017 The PDFium Authors
// 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/check.h"
namespace {
size_t GetCSSNameLen(WideStringView str) {
for (size_t i = 0; i < str.GetLength(); ++i) {
wchar_t wch = str[i];
if (!isascii(wch) || (!isalnum(wch) && wch != '_' && wch != '-'))
return i;
}
return str.GetLength();
}
} // namespace
CFX_CSSSelector::CFX_CSSSelector(WideStringView str,
std::unique_ptr<CFX_CSSSelector> next)
: name_hash_(FX_HashCode_GetLoweredW(str)), next_(std::move(next)) {}
CFX_CSSSelector::~CFX_CSSSelector() = default;
// static.
std::unique_ptr<CFX_CSSSelector> CFX_CSSSelector::FromString(
WideStringView str) {
DCHECK(!str.IsEmpty());
for (wchar_t wch : str) {
switch (wch) {
case '>':
case '[':
case '+':
return nullptr;
}
}
std::unique_ptr<CFX_CSSSelector> head;
for (size_t i = 0; i < str.GetLength();) {
wchar_t wch = str[i];
if (wch == ' ') {
++i;
continue;
}
const bool is_star = wch == '*';
const bool is_valid_char = is_star || (isascii(wch) && isalpha(wch));
if (!is_valid_char)
return nullptr;
if (head)
head->set_is_descendant();
size_t len = is_star ? 1 : GetCSSNameLen(str.Last(str.GetLength() - i));
auto new_head =
std::make_unique<CFX_CSSSelector>(str.Substr(i, len), std::move(head));
head = std::move(new_head);
i += len;
}
return head;
}