#include "config.h"
#include "PluginData.h"
#include "Document.h"
#include "LocalizedStrings.h"
#include "Page.h"
#include "PluginInfoProvider.h"
namespace WebCore {
PluginData::PluginData(Page& page)
: m_page(page)
{
initPlugins();
}
const Vector<PluginInfo>& PluginData::webVisiblePlugins() const
{
auto documentURL = m_page.mainFrame().document() ? m_page.mainFrame().document()->url() : URL { };
if (!documentURL.isNull() && !protocolHostAndPortAreEqual(m_cachedVisiblePlugins.pageURL, documentURL)) {
m_cachedVisiblePlugins.pageURL = WTFMove(documentURL);
m_cachedVisiblePlugins.pluginList = WTF::nullopt;
}
if (!m_cachedVisiblePlugins.pluginList)
m_cachedVisiblePlugins.pluginList = m_page.pluginInfoProvider().webVisiblePluginInfo(m_page, m_cachedVisiblePlugins.pageURL);
return *m_cachedVisiblePlugins.pluginList;
}
#if PLATFORM(COCOA)
static inline bool isBuiltInPDFPlugIn(const PluginInfo& plugin)
{
return equalLettersIgnoringASCIICase(plugin.bundleIdentifier, "com.apple.webkit.builtinpdfplugin");
}
#else
static inline bool isBuiltInPDFPlugIn(const PluginInfo&)
{
return false;
}
#endif
static bool shouldBePubliclyVisible(const PluginInfo& plugin)
{
return plugin.name.containsIgnoringASCIICase("Shockwave")
|| plugin.name.containsIgnoringASCIICase("QuickTime")
|| plugin.name.containsIgnoringASCIICase("Java")
|| isBuiltInPDFPlugIn(plugin);
}
Vector<PluginInfo> PluginData::publiclyVisiblePlugins() const
{
auto plugins = webVisiblePlugins();
if (m_page.showAllPlugins())
return plugins;
plugins.removeAllMatching([](auto& plugin) {
return !shouldBePubliclyVisible(plugin);
});
std::sort(plugins.begin(), plugins.end(), [](const PluginInfo& a, const PluginInfo& b) {
return codePointCompareLessThan(a.name, b.name);
});
return plugins;
}
void PluginData::getWebVisibleMimesAndPluginIndices(Vector<MimeClassInfo>& mimes, Vector<size_t>& mimePluginIndices) const
{
getMimesAndPluginIndiciesForPlugins(webVisiblePlugins(), mimes, mimePluginIndices);
}
void PluginData::getMimesAndPluginIndices(Vector<MimeClassInfo>& mimes, Vector<size_t>& mimePluginIndices) const
{
getMimesAndPluginIndiciesForPlugins(plugins(), mimes, mimePluginIndices);
}
void PluginData::getMimesAndPluginIndiciesForPlugins(const Vector<PluginInfo>& plugins, Vector<MimeClassInfo>& mimes, Vector<size_t>& mimePluginIndices) const
{
ASSERT_ARG(mimes, mimes.isEmpty());
ASSERT_ARG(mimePluginIndices, mimePluginIndices.isEmpty());
for (unsigned i = 0; i < plugins.size(); ++i) {
const PluginInfo& plugin = plugins[i];
for (auto& mime : plugin.mimes) {
mimes.append(mime);
mimePluginIndices.append(i);
}
}
}
bool PluginData::supportsWebVisibleMimeTypeForURL(const String& mimeType, const AllowedPluginTypes allowedPluginTypes, const URL& url) const
{
if (!protocolHostAndPortAreEqual(m_cachedVisiblePlugins.pageURL, url))
m_cachedVisiblePlugins = { url, m_page.pluginInfoProvider().webVisiblePluginInfo(m_page, url) };
if (!m_cachedVisiblePlugins.pluginList)
return false;
return supportsWebVisibleMimeType(mimeType, allowedPluginTypes, *m_cachedVisiblePlugins.pluginList);
}
bool PluginData::supportsWebVisibleMimeType(const String& mimeType, const AllowedPluginTypes allowedPluginTypes) const
{
return supportsWebVisibleMimeType(mimeType, allowedPluginTypes, webVisiblePlugins());
}
bool PluginData::supportsWebVisibleMimeType(const String& mimeType, const AllowedPluginTypes allowedPluginTypes, const Vector<PluginInfo>& plugins) const
{
Vector<MimeClassInfo> mimes;
Vector<size_t> mimePluginIndices;
getMimesAndPluginIndiciesForPlugins(plugins, mimes, mimePluginIndices);
for (unsigned i = 0; i < mimes.size(); ++i) {
if (mimes[i].type == mimeType && (allowedPluginTypes == AllPlugins || plugins[mimePluginIndices[i]].isApplicationPlugin))
return true;
}
return false;
}
bool PluginData::getPluginInfoForWebVisibleMimeType(const String& mimeType, PluginInfo& pluginInfoRef) const
{
Vector<MimeClassInfo> mimes;
Vector<size_t> mimePluginIndices;
const Vector<PluginInfo>& plugins = webVisiblePlugins();
getWebVisibleMimesAndPluginIndices(mimes, mimePluginIndices);
for (unsigned i = 0; i < mimes.size(); ++i) {
const MimeClassInfo& info = mimes[i];
if (info.type == mimeType) {
pluginInfoRef = plugins[mimePluginIndices[i]];
return true;
}
}
return false;
}
String PluginData::pluginFileForWebVisibleMimeType(const String& mimeType) const
{
PluginInfo info;
if (getPluginInfoForWebVisibleMimeType(mimeType, info))
return info.file;
return String();
}
bool PluginData::supportsMimeType(const String& mimeType, const AllowedPluginTypes allowedPluginTypes) const
{
Vector<MimeClassInfo> mimes;
Vector<size_t> mimePluginIndices;
const Vector<PluginInfo>& plugins = this->plugins();
getMimesAndPluginIndices(mimes, mimePluginIndices);
for (unsigned i = 0; i < mimes.size(); ++i) {
if (mimes[i].type == mimeType && (allowedPluginTypes == AllPlugins || plugins[mimePluginIndices[i]].isApplicationPlugin))
return true;
}
return false;
}
void PluginData::initPlugins()
{
ASSERT(m_plugins.isEmpty());
m_plugins = m_page.pluginInfoProvider().pluginInfo(m_page, m_supportedPluginIdentifiers);
}
}