Skip to content

Commit

Permalink
[CHU] Feed renderer heuristics from component to ChromeCart [2]
Browse files Browse the repository at this point in the history
Bug: 1300332
Change-Id: I7eee52d99146a7c0ea275c5852c9a9fa65ec1a25
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3533547
Reviewed-by: Wei-Yin Chen <wychen@chromium.org>
Commit-Queue: Yue Zhang <yuezhanggg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#984103}
  • Loading branch information
Yue Zhang authored and Chromium LUCI CQ committed Mar 23, 2022
1 parent 2eb6c28 commit f1f49d9
Show file tree
Hide file tree
Showing 5 changed files with 384 additions and 145 deletions.
278 changes: 155 additions & 123 deletions chrome/renderer/cart/commerce_hint_agent.cc
Expand Up @@ -332,65 +332,173 @@ const re2::RE2& GetAddToCartPattern() {
return *instance;
}

const std::map<std::string, std::string>& GetCartPatternMapping() {
static base::NoDestructor<std::map<std::string, std::string>> pattern_map([] {
const base::Value json(
base::JSONReader::Read(
kCartPatternMapping.Get().empty()
? ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
IDR_CART_DOMAIN_CART_URL_REGEX_JSON)
: kCartPatternMapping.Get())
.value());
DCHECK(json.is_dict());
std::map<std::string, std::string> map;
for (auto item : json.DictItems()) {
map.insert({std::move(item.first), std::move(item.second.GetString())});
}
return map;
}());
return *pattern_map;
}

const std::map<std::string, std::string>& GetCheckoutPatternMapping() {
static base::NoDestructor<std::map<std::string, std::string>> pattern_map([] {
const base::Value json(
base::JSONReader::Read(
kCheckoutPatternMapping.Get().empty()
? ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
IDR_CHECKOUT_URL_REGEX_DOMAIN_MAPPING_JSON)
: kCheckoutPatternMapping.Get())
.value());
DCHECK(json.is_dict());
std::map<std::string, std::string> map;
for (const auto item : json.DictItems()) {
map.insert({std::move(item.first), std::move(item.second.GetString())});
}
return map;
}());
return *pattern_map;
}

const std::map<std::string, std::string>& GetPurchaseURLPatternMapping() {
static base::NoDestructor<std::map<std::string, std::string>> pattern_map([] {
const base::Value json(
base::JSONReader::Read(
kPurchaseURLPatternMapping.Get().empty()
? ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
IDR_PURCHASE_URL_REGEX_DOMAIN_MAPPING_JSON)
: kPurchaseURLPatternMapping.Get())
.value());
DCHECK(json.is_dict());
std::map<std::string, std::string> map;
for (const auto item : json.DictItems()) {
map.insert({std::move(item.first), std::move(item.second.GetString())});
}
return map;
}());
return *pattern_map;
}

const std::map<std::string, std::string>& GetPurchaseButtonPatternMapping() {
static base::NoDestructor<std::map<std::string, std::string>> pattern_map([] {
const base::Value json(
base::JSONReader::Read(kPurchaseButtonPatternMapping.Get()).value());
DCHECK(json.is_dict());
std::map<std::string, std::string> map;
for (const auto item : json.DictItems()) {
map.insert({std::move(item.first), std::move(item.second.GetString())});
}
return map;
}());
return *pattern_map;
}

// TODO(crbug.com/1189786): Using per-site pattern and full URL matching could
// be unnecessary. Improve this later by using general pattern if possible and
// more flexible matching.
const re2::RE2& GetVisitCartPattern(const GURL& url) {
static base::NoDestructor<std::map<std::string, std::string>>
heuristic_string_map([] {
const base::StringPiece json_resource(
ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
IDR_CART_DOMAIN_CART_URL_REGEX_JSON));
const std::string& finch_param = kCartPatternMapping.Get();
const base::Value json(base::JSONReader::Read(finch_param.empty()
? json_resource
: finch_param)
.value());
DCHECK(json.is_dict());
std::map<std::string, std::string> map;
for (auto item : json.DictItems()) {
map.insert(
{std::move(item.first), std::move(item.second.GetString())});
}
return map;
}());
const re2::RE2* GetVisitCartPattern(const GURL& url) {
std::string domain = eTLDPlusOne(url);
auto* pattern_from_component =
commerce_heuristics::CommerceHeuristicsData::GetInstance()
.GetCartPageURLPatternForDomain(domain);
if (pattern_from_component &&
kCartPatternMapping.Get() == kCartPatternMapping.default_value) {
return pattern_from_component;
}
const std::map<std::string, std::string>& cart_string_map =
GetCartPatternMapping();
static base::NoDestructor<std::map<std::string, std::unique_ptr<re2::RE2>>>
heuristic_regex_map;
cart_regex_map;
static re2::RE2::Options options;
options.set_case_sensitive(false);
const std::string& domain = eTLDPlusOne(url);
if (heuristic_string_map->find(domain) == heuristic_string_map->end()) {
if (cart_string_map.find(domain) == cart_string_map.end()) {
auto* pattern_from_component =
commerce_heuristics::CommerceHeuristicsData::GetInstance()
.GetCartPageURLPattern();
if (pattern_from_component &&
kCartPattern.Get() == kCartPattern.default_value) {
return *pattern_from_component;
return pattern_from_component;
}
static base::NoDestructor<re2::RE2> instance(kCartPattern.Get(), options);
return *instance;
return instance.get();
}
if (heuristic_regex_map->find(domain) == heuristic_regex_map->end()) {
heuristic_regex_map->insert(
{domain, std::make_unique<re2::RE2>(heuristic_string_map->at(domain),
options)});
if (cart_regex_map->find(domain) == cart_regex_map->end()) {
cart_regex_map->insert({domain, std::make_unique<re2::RE2>(
cart_string_map.at(domain), options)});
}
return *heuristic_regex_map->at(domain);
return cart_regex_map->at(domain).get();
}

// TODO(crbug/1164236): cover more shopping sites.
const re2::RE2& GetVisitCheckoutPattern() {
const re2::RE2* GetVisitCheckoutPattern(const GURL& url) {
std::string domain = eTLDPlusOne(url);
auto* pattern_from_component =
commerce_heuristics::CommerceHeuristicsData::GetInstance()
.GetCheckoutPageURLPattern();
.GetCheckoutPageURLPatternForDomain(domain);
if (pattern_from_component &&
kCheckoutPattern.Get() == kCheckoutPattern.default_value) {
return *pattern_from_component;
kCheckoutPatternMapping.Get() == kCheckoutPatternMapping.default_value) {
return pattern_from_component;
}
re2::RE2::Options options;
const std::map<std::string, std::string>& checkout_string_map =
GetCheckoutPatternMapping();
static base::NoDestructor<std::map<std::string, std::unique_ptr<re2::RE2>>>
checkout_regex_map;
static re2::RE2::Options options;
options.set_case_sensitive(false);
static base::NoDestructor<re2::RE2> instance(kCheckoutPattern.Get(), options);
return *instance;
if (checkout_string_map.find(domain) == checkout_string_map.end()) {
auto* pattern_from_component =
commerce_heuristics::CommerceHeuristicsData::GetInstance()
.GetCheckoutPageURLPattern();
if (pattern_from_component &&
kCheckoutPattern.Get() == kCheckoutPattern.default_value) {
return pattern_from_component;
}
static base::NoDestructor<re2::RE2> instance(kCheckoutPattern.Get(),
options);
return instance.get();
}
if (checkout_regex_map->find(domain) == checkout_regex_map->end()) {
checkout_regex_map->insert(
{domain,
std::make_unique<re2::RE2>(checkout_string_map.at(domain), options)});
}
return checkout_regex_map->at(domain).get();
}

const re2::RE2* GetVisitPurchasePattern(const GURL& url) {
std::string domain = eTLDPlusOne(url);
auto* pattern_from_component =
commerce_heuristics::CommerceHeuristicsData::GetInstance()
.GetPurchasePageURLPatternForDomain(domain);
if (pattern_from_component && kPurchaseURLPatternMapping.Get() ==
kPurchaseURLPatternMapping.default_value) {
return pattern_from_component;
}
const std::map<std::string, std::string>& purchase_string_map =
GetPurchaseURLPatternMapping();
if (purchase_string_map.find(domain) == purchase_string_map.end()) {
return nullptr;
}
static base::NoDestructor<std::map<std::string, std::unique_ptr<re2::RE2>>>
purchase_regex_map;
static re2::RE2::Options options;
options.set_case_sensitive(false);
if (purchase_regex_map->find(domain) == purchase_regex_map->end()) {
purchase_regex_map->insert(
{domain,
std::make_unique<re2::RE2>(purchase_string_map.at(domain), options)});
}
return purchase_regex_map->at(domain).get();
}

const re2::RE2& GetSkipPattern() {
Expand Down Expand Up @@ -465,58 +573,6 @@ const std::map<std::string, std::string>& GetSkipAddToCartMapping() {
return *skip_map;
}

const std::map<std::string, std::string>& GetCheckoutPatternMapping() {
static base::NoDestructor<std::map<std::string, std::string>> pattern_map([] {
const base::Value json(
base::JSONReader::Read(
kCheckoutPatternMapping.Get().empty()
? ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
IDR_CHECKOUT_URL_REGEX_DOMAIN_MAPPING_JSON)
: kCheckoutPatternMapping.Get())
.value());
DCHECK(json.is_dict());
std::map<std::string, std::string> map;
for (const auto item : json.DictItems()) {
map.insert({std::move(item.first), std::move(item.second.GetString())});
}
return map;
}());
return *pattern_map;
}

const std::map<std::string, std::string>& GetPurchaseURLPatternMapping() {
static base::NoDestructor<std::map<std::string, std::string>> pattern_map([] {
const base::Value json(
base::JSONReader::Read(
kPurchaseURLPatternMapping.Get().empty()
? ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
IDR_PURCHASE_URL_REGEX_DOMAIN_MAPPING_JSON)
: kPurchaseURLPatternMapping.Get())
.value());
DCHECK(json.is_dict());
std::map<std::string, std::string> map;
for (const auto item : json.DictItems()) {
map.insert({std::move(item.first), std::move(item.second.GetString())});
}
return map;
}());
return *pattern_map;
}

const std::map<std::string, std::string>& GetPurchaseButtonPatternMapping() {
static base::NoDestructor<std::map<std::string, std::string>> pattern_map([] {
const base::Value json(
base::JSONReader::Read(kPurchaseButtonPatternMapping.Get()).value());
DCHECK(json.is_dict());
std::map<std::string, std::string> map;
for (const auto item : json.DictItems()) {
map.insert({std::move(item.first), std::move(item.second.GetString())});
}
return map;
}());
return *pattern_map;
}

bool DetectAddToCart(content::RenderFrame* render_frame,
const blink::WebURLRequest& request) {
blink::WebLocalFrame* frame = render_frame->GetWebFrame();
Expand Down Expand Up @@ -686,48 +742,24 @@ bool CommerceHintAgent::IsAddToCart(base::StringPiece str,
}

bool CommerceHintAgent::IsVisitCart(const GURL& url) {
return PartialMatch(CanonicalURL(url).substr(0, kLengthLimit),
GetVisitCartPattern(url));
auto* pattern = GetVisitCartPattern(url);
if (!pattern)
return false;
return PartialMatch(CanonicalURL(url).substr(0, kLengthLimit), *pattern);
}

bool CommerceHintAgent::IsVisitCheckout(const GURL& url) {
const std::map<std::string, std::string>& checkout_string_map =
GetCheckoutPatternMapping();
static base::NoDestructor<std::map<std::string, std::unique_ptr<re2::RE2>>>
checkout_regex_map;
std::string domain = eTLDPlusOne(url);
std::string url_string = CanonicalURL(url).substr(0, kLengthLimit);
if (checkout_string_map.find(domain) == checkout_string_map.end()) {
return PartialMatch(url_string, GetVisitCheckoutPattern());
}
static re2::RE2::Options options;
options.set_case_sensitive(false);
if (checkout_regex_map->find(domain) == checkout_regex_map->end()) {
checkout_regex_map->insert(
{domain,
std::make_unique<re2::RE2>(checkout_string_map.at(domain), options)});
}
return PartialMatch(url_string, *checkout_regex_map->at(domain));
auto* pattern = GetVisitCheckoutPattern(url);
if (!pattern)
return false;
return PartialMatch(CanonicalURL(url).substr(0, kLengthLimit), *pattern);
}

bool CommerceHintAgent::IsPurchase(const GURL& url) {
const std::map<std::string, std::string>& purchase_string_map =
GetPurchaseURLPatternMapping();
static base::NoDestructor<std::map<std::string, std::unique_ptr<re2::RE2>>>
purchase_regex_map;
std::string domain = eTLDPlusOne(url);
std::string url_string = CanonicalURL(url).substr(0, kLengthLimit);
if (purchase_string_map.find(domain) == purchase_string_map.end()) {
auto* pattern = GetVisitPurchasePattern(url);
if (!pattern)
return false;
}
static re2::RE2::Options options;
options.set_case_sensitive(false);
if (purchase_regex_map->find(domain) == purchase_regex_map->end()) {
purchase_regex_map->insert(
{domain,
std::make_unique<re2::RE2>(purchase_string_map.at(domain), options)});
}
return PartialMatch(url_string, *purchase_regex_map->at(domain));
return PartialMatch(CanonicalURL(url).substr(0, kLengthLimit), *pattern);
}

bool CommerceHintAgent::IsPurchase(const GURL& url,
Expand Down

0 comments on commit f1f49d9

Please sign in to comment.