blob: e20075f9a40643dd4d769d36c60a5d5f8c9ca798 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ios/web/web_state/web_frames_manager_impl.h"
#include "base/strings/utf_string_conversions.h"
#include "ios/web/public/web_state/web_frame.h"
#import "ios/web/public/web_state/web_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Matcher for finding a WebFrame object with the given |frame_id|.
struct FrameIdMatcher {
explicit FrameIdMatcher(const std::string& frame_id) : frame_id_(frame_id) {}
// Returns true if the receiver was initialized with the same frame id as
// |web_frame|.
bool operator()(web::WebFrame* web_frame) {
return web_frame->GetFrameId() == frame_id_;
}
private:
// The frame id to match against.
const std::string frame_id_;
};
} // namespace
namespace web {
// static
void WebFramesManagerImpl::CreateForWebState(WebState* web_state) {
DCHECK(web_state);
if (!FromWebState(web_state))
web_state->SetUserData(
UserDataKey(), base::WrapUnique(new WebFramesManagerImpl(web_state)));
}
// static
WebFramesManagerImpl* WebFramesManagerImpl::FromWebState(WebState* web_state) {
return static_cast<WebFramesManagerImpl*>(
WebFramesManager::FromWebState(web_state));
}
WebFramesManagerImpl::~WebFramesManagerImpl() {
RemoveAllWebFrames();
}
WebFramesManagerImpl::WebFramesManagerImpl(web::WebState* web_state)
: web_state_(web_state) {}
void WebFramesManagerImpl::AddFrame(std::unique_ptr<WebFrame> frame) {
DCHECK(frame);
DCHECK(!frame->GetFrameId().empty());
if (frame->IsMainFrame()) {
DCHECK(!main_web_frame_);
main_web_frame_ = frame.get();
}
DCHECK(web_frames_.count(frame->GetFrameId()) == 0);
std::string frame_id = frame->GetFrameId();
web_frames_[frame_id] = std::move(frame);
}
void WebFramesManagerImpl::RemoveFrameWithId(const std::string& frame_id) {
DCHECK(!frame_id.empty());
// If the removed frame is a main frame, it should be the current one.
DCHECK(web_frames_.count(frame_id) == 0 ||
!web_frames_[frame_id]->IsMainFrame() ||
main_web_frame_ == web_frames_[frame_id].get());
if (main_web_frame_ && main_web_frame_->GetFrameId() == frame_id) {
main_web_frame_ = nullptr;
}
web_frames_.erase(frame_id);
}
void WebFramesManagerImpl::RemoveAllWebFrames() {
main_web_frame_ = nullptr;
web_frames_.clear();
}
WebFrame* WebFramesManagerImpl::GetFrameWithId(const std::string& frame_id) {
DCHECK(!frame_id.empty());
auto web_frames_it = web_frames_.find(frame_id);
return web_frames_it == web_frames_.end() ? nullptr
: web_frames_it->second.get();
}
std::set<WebFrame*> WebFramesManagerImpl::GetAllWebFrames() {
std::set<WebFrame*> frames;
for (const auto& it : web_frames_) {
frames.insert(it.second.get());
}
return frames;
}
WebFrame* WebFramesManagerImpl::GetMainWebFrame() {
return main_web_frame_;
}
void WebFramesManagerImpl::RegisterExistingFrames() {
web_state_->ExecuteJavaScript(
base::UTF8ToUTF16("__gCrWeb.message.getExistingFrames();"));
}
} // namespace