// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/web/js_messaging/web_view_web_state_map.h"
#import "base/memory/ptr_util.h"
#import "ios/web/public/browser_state.h"
#import "ios/web/public/web_state.h"
namespace {
const char kWebViewWebStateMapKeyName[] = "web_view_web_state_map";
} // namespace
namespace web {
WebViewWebStateMap::WebViewWebStateMap(BrowserState* browser_state) {}
WebViewWebStateMap::~WebViewWebStateMap() {
for (const WebViewWebStateAssociation& association : mappings_) {
association.web_state->RemoveObserver(this);
}
}
WebViewWebStateMap* WebViewWebStateMap::FromBrowserState(
BrowserState* browser_state) {
DCHECK(browser_state);
WebViewWebStateMap* web_view_web_state_map = static_cast<WebViewWebStateMap*>(
browser_state->GetUserData(kWebViewWebStateMapKeyName));
if (!web_view_web_state_map) {
web_view_web_state_map = new WebViewWebStateMap(browser_state);
browser_state->SetUserData(kWebViewWebStateMapKeyName,
base::WrapUnique(web_view_web_state_map));
}
return web_view_web_state_map;
}
void WebViewWebStateMap::SetAssociatedWebViewForWebState(WKWebView* web_view,
WebState* web_state) {
DCHECK(web_state);
auto it = mappings_.begin();
while (it != mappings_.end()) {
if (it->web_state == web_state) {
if (web_view) {
// Update existing entry with new webview.
it->web_view = web_view;
} else {
// Remove mapping since no web view is assocaited.
mappings_.erase(it);
web_state->RemoveObserver(this);
}
return;
}
it++;
}
web_state->AddObserver(this);
mappings_.push_back(WebViewWebStateAssociation(web_view, web_state));
}
WebState* WebViewWebStateMap::GetWebStateForWebView(WKWebView* web_view) {
for (const WebViewWebStateAssociation& association : mappings_) {
if (association.web_view == web_view) {
return association.web_state;
}
}
return nullptr;
}
void WebViewWebStateMap::WebStateDestroyed(WebState* web_state) {
auto it = mappings_.begin();
while (it != mappings_.end()) {
if (it->web_state == web_state) {
mappings_.erase(it);
web_state->RemoveObserver(this);
break;
}
it++;
}
}
WebViewWebStateMap::WebViewWebStateAssociation::WebViewWebStateAssociation(
WKWebView* web_view,
WebState* web_state)
: web_view(web_view), web_state(web_state) {}
WebViewWebStateMap::WebViewWebStateAssociation::~WebViewWebStateAssociation() =
default;
} // namespace web