UserContentController.cpp [plain text]
#include "config.h"
#include "UserContentController.h"
#include "DOMWrapperWorld.h"
#include "Document.h"
#include "MainFrame.h"
#include "Page.h"
#include "UserScript.h"
#include "UserStyleSheet.h"
#if ENABLE(USER_MESSAGE_HANDLERS)
#include "UserMessageHandlerDescriptor.h"
#endif
namespace WebCore {
RefPtr<UserContentController> UserContentController::create()
{
return adoptRef(new UserContentController);
}
UserContentController::UserContentController()
{
}
UserContentController::~UserContentController()
{
}
void UserContentController::addPage(Page& page)
{
ASSERT(!m_pages.contains(&page));
m_pages.add(&page);
}
void UserContentController::removePage(Page& page)
{
ASSERT(m_pages.contains(&page));
m_pages.remove(&page);
}
void UserContentController::addUserScript(DOMWrapperWorld& world, std::unique_ptr<UserScript> userScript)
{
if (!m_userScripts)
m_userScripts = std::make_unique<UserScriptMap>();
auto& scriptsInWorld = m_userScripts->add(&world, nullptr).iterator->value;
if (!scriptsInWorld)
scriptsInWorld = std::make_unique<UserScriptVector>();
scriptsInWorld->append(WTF::move(userScript));
}
void UserContentController::removeUserScript(DOMWrapperWorld& world, const URL& url)
{
if (!m_userScripts)
return;
auto it = m_userScripts->find(&world);
if (it == m_userScripts->end())
return;
auto scripts = it->value.get();
for (int i = scripts->size() - 1; i >= 0; --i) {
if (scripts->at(i)->url() == url)
scripts->remove(i);
}
if (scripts->isEmpty())
m_userScripts->remove(it);
}
void UserContentController::removeUserScripts(DOMWrapperWorld& world)
{
if (!m_userScripts)
return;
m_userScripts->remove(&world);
}
void UserContentController::addUserStyleSheet(DOMWrapperWorld& world, std::unique_ptr<UserStyleSheet> userStyleSheet, UserStyleInjectionTime injectionTime)
{
if (!m_userStyleSheets)
m_userStyleSheets = std::make_unique<UserStyleSheetMap>();
auto& styleSheetsInWorld = m_userStyleSheets->add(&world, nullptr).iterator->value;
if (!styleSheetsInWorld)
styleSheetsInWorld = std::make_unique<UserStyleSheetVector>();
styleSheetsInWorld->append(WTF::move(userStyleSheet));
if (injectionTime == InjectInExistingDocuments)
invalidateInjectedStyleSheetCacheInAllFrames();
}
void UserContentController::removeUserStyleSheet(DOMWrapperWorld& world, const URL& url)
{
if (!m_userStyleSheets)
return;
auto it = m_userStyleSheets->find(&world);
if (it == m_userStyleSheets->end())
return;
auto& stylesheets = *it->value;
bool sheetsChanged = false;
for (int i = stylesheets.size() - 1; i >= 0; --i) {
if (stylesheets[i]->url() == url) {
stylesheets.remove(i);
sheetsChanged = true;
}
}
if (!sheetsChanged)
return;
if (stylesheets.isEmpty())
m_userStyleSheets->remove(it);
invalidateInjectedStyleSheetCacheInAllFrames();
}
void UserContentController::removeUserStyleSheets(DOMWrapperWorld& world)
{
if (!m_userStyleSheets)
return;
if (!m_userStyleSheets->remove(&world))
return;
invalidateInjectedStyleSheetCacheInAllFrames();
}
#if ENABLE(USER_MESSAGE_HANDLERS)
void UserContentController::addUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
{
if (!m_userMessageHandlerDescriptors)
m_userMessageHandlerDescriptors = std::make_unique<UserMessageHandlerDescriptorMap>();
m_userMessageHandlerDescriptors->add(std::make_pair(descriptor.name(), &descriptor.world()), &descriptor);
}
void UserContentController::removeUserMessageHandlerDescriptor(UserMessageHandlerDescriptor& descriptor)
{
if (!m_userMessageHandlerDescriptors)
return;
m_userMessageHandlerDescriptors->remove(std::make_pair(descriptor.name(), &descriptor.world()));
}
#endif
void UserContentController::removeAllUserContent()
{
m_userScripts = nullptr;
if (m_userStyleSheets) {
m_userStyleSheets = nullptr;
invalidateInjectedStyleSheetCacheInAllFrames();
}
}
void UserContentController::invalidateInjectedStyleSheetCacheInAllFrames()
{
for (auto& page : m_pages) {
for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
frame->document()->styleSheetCollection().invalidateInjectedStyleSheetCache();
frame->document()->styleResolverChanged(DeferRecalcStyle);
}
}
}
}