diff --git a/include/cef_nplugin.h b/include/cef_nplugin.h index 9d94e9f7e..59f314455 100644 --- a/include/cef_nplugin.h +++ b/include/cef_nplugin.h @@ -71,8 +71,11 @@ public: { cef_string_clear(&unique_name); cef_string_clear(&display_name); + cef_string_clear(&version); cef_string_clear(&description); - cef_string_clear(&mime_type); + cef_string_clear(&mime_types); + cef_string_clear(&file_extensions); + cef_string_clear(&type_descriptions); Init(); } @@ -96,8 +99,13 @@ public: { cef_string_copy(r.unique_name.str, r.unique_name.length, &unique_name); cef_string_copy(r.display_name.str, r.display_name.length, &display_name); + cef_string_copy(r.version.str, r.version.length, &version); cef_string_copy(r.description.str, r.description.length, &description); - cef_string_copy(r.mime_type.str, r.mime_type.length, &mime_type); + cef_string_copy(r.mime_types.str, r.mime_types.length, &mime_types); + cef_string_copy(r.file_extensions.str, r.file_extensions.length, + &file_extensions); + cef_string_copy(r.type_descriptions.str, r.type_descriptions.length, + &type_descriptions); #if !defined(OS_POSIX) || defined(OS_MACOSX) np_getentrypoints = r.np_getentrypoints; #endif diff --git a/include/internal/cef_nplugin_types.h b/include/internal/cef_nplugin_types.h index fc61d0c1b..21a09e53e 100644 --- a/include/internal/cef_nplugin_types.h +++ b/include/internal/cef_nplugin_types.h @@ -56,11 +56,23 @@ typedef struct _cef_plugin_info_t { // The friendly display name of the plugin. cef_string_t display_name; + // The version string of the plugin. + cef_string_t version; + // A description of the plugin. cef_string_t description; - // The mime type that the plugin supports. - cef_string_t mime_type; + // A pipe (|) delimited list of mime type values that the plugin supports. + cef_string_t mime_types; + + // A pipe (|) delimited list of extension values. Each value is associated + // with the mime type value at the same position. Multiple file extensions + // for the same mime type may be delimited with commas (,). + cef_string_t file_extensions; + + // A pipe (|) delimited list of description values. Each value is associated + // with the mime type value at the same position. + cef_string_t type_descriptions; // Entry point function pointers. #if !defined(OS_POSIX) || defined(OS_MACOSX) diff --git a/libcef/cef_context.cc b/libcef/cef_context.cc index e71c54f8b..d6a961a33 100644 --- a/libcef/cef_context.cc +++ b/libcef/cef_context.cc @@ -15,7 +15,9 @@ #include "base/bind.h" #include "base/file_util.h" #include "base/stringprintf.h" +#include "base/string_split.h" #include "base/synchronization/waitable_event.h" +#include "base/utf_string_conversions.h" #include "net/base/cookie_monster.h" #include "webkit/plugins/npapi/plugin_list.h" @@ -38,10 +40,37 @@ void UIT_RegisterPlugin(CefPluginInfo* plugin_info) webkit::WebPluginInfo info; - FilePath filename = FilePath(CefString(&plugin_info->unique_name)); - std::string name = CefString(&plugin_info->display_name); - std::string description = CefString(&plugin_info->description); - std::string mime_type = CefString(&plugin_info->mime_type); + info.path = FilePath(CefString(&plugin_info->unique_name)); + info.name = CefString(&plugin_info->display_name); + info.version = CefString(&plugin_info->version); + info.desc = CefString(&plugin_info->description); + + typedef std::vector VectorType; + VectorType mime_types, file_extensions, descriptions, file_extensions_parts; + base::SplitString(CefString(&plugin_info->mime_types), '|', &mime_types); + base::SplitString(CefString(&plugin_info->file_extensions), '|', + &file_extensions); + base::SplitString(CefString(&plugin_info->type_descriptions), '|', + &descriptions); + + for (size_t i = 0; i < mime_types.size(); ++i) { + webkit::WebPluginMimeType mimeType; + + mimeType.mime_type = mime_types[i]; + + if (file_extensions.size() > i) { + base::SplitString(file_extensions[i], ',', &file_extensions_parts); + VectorType::const_iterator it = file_extensions_parts.begin(); + for(; it != file_extensions_parts.end(); ++it) + mimeType.file_extensions.push_back(*(it)); + file_extensions_parts.clear(); + } + + if (descriptions.size() > i) + mimeType.description = UTF8ToUTF16(descriptions[i]); + + info.mime_types.push_back(mimeType); + } webkit::npapi::PluginEntryPoints entry_points; #if !defined(OS_POSIX) || defined(OS_MACOSX) @@ -50,8 +79,8 @@ void UIT_RegisterPlugin(CefPluginInfo* plugin_info) entry_points.np_initialize = plugin_info->np_initialize; entry_points.np_shutdown = plugin_info->np_shutdown; - webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin(filename, - name, description, mime_type, entry_points); + webkit::npapi::PluginList::Singleton()->RegisterInternalPlugin( + info, entry_points, true); delete plugin_info; } diff --git a/patch/patch.cfg b/patch/patch.cfg index f4122f7ec..08d6da207 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -21,6 +21,11 @@ patches = [ 'name': 'tools_gyp', 'path': '../tools/gyp/', }, + { + # http://codereview.chromium.org/8386002/ + 'name': 'webkit_plugins_npapi', + 'path': '../webkit/plugins/npapi/', + }, { # http://code.google.com/p/chromiumembedded/issues/detail?id=364 'name': 'spi_webcore_364', diff --git a/patch/patches/webkit_plugins_npapi.patch b/patch/patches/webkit_plugins_npapi.patch new file mode 100644 index 000000000..a8bdf8e98 --- /dev/null +++ b/patch/patches/webkit_plugins_npapi.patch @@ -0,0 +1,72 @@ +Index: plugin_list.cc +=================================================================== +--- plugin_list.cc (revision 107708) ++++ plugin_list.cc (working copy) +@@ -223,26 +223,22 @@ + default_plugin_enabled_ = true; + } + +-void PluginList::RegisterInternalPlugin(const FilePath& filename, +- const std::string& name, +- const std::string& description, +- const std::string& mime_type_str, +- const PluginEntryPoints& entry_points) { +- InternalPlugin plugin; +- plugin.info.path = filename; +- plugin.info.name = ASCIIToUTF16(name); +- plugin.info.version = ASCIIToUTF16("1"); +- plugin.info.desc = ASCIIToUTF16(description); ++void PluginList::RegisterInternalPlugin(const webkit::WebPluginInfo& info, ++ const PluginEntryPoints& entry_points, ++ bool add_at_beginning) { ++ InternalPlugin plugin = { info, entry_points }; + +- webkit::WebPluginMimeType mime_type; +- mime_type.mime_type = mime_type_str; +- plugin.info.mime_types.push_back(mime_type); ++ base::AutoLock lock(lock_); + +- plugin.entry_points = entry_points; ++ if (add_at_beginning) { ++ // Newer registrations go earlier in the list so they can override the MIME ++ // types of older registrations. ++ internal_plugins_.insert(internal_plugins_.begin(), plugin); ++ } else { ++ internal_plugins_.push_back(plugin); ++ } + +- base::AutoLock lock(lock_); +- internal_plugins_.push_back(plugin); +- if (filename.value() == kDefaultPluginLibraryName) ++ if (info.path.value() == kDefaultPluginLibraryName) + default_plugin_enabled_ = true; + } + +Index: plugin_list.h +=================================================================== +--- plugin_list.h (revision 107708) ++++ plugin_list.h (working copy) +@@ -85,16 +85,13 @@ + // be loaded using PluginList::LoadPlugin(). + void RegisterInternalPlugin(const webkit::WebPluginInfo& info); + +- // This second version is for "plugins" that have been compiled +- // directly into the binary -- callers must provide the metadata and +- // the entry points. +- // TODO(evan): we use file names here, but they're not really files, they're +- // actually a string that uniquely identifies the plugin. +- void RegisterInternalPlugin(const FilePath& filename, +- const std::string& name, +- const std::string& description, +- const std::string& mime_type, +- const PluginEntryPoints& entry_points); ++ // This second version is for "plugins" that have been compiled directly into ++ // the binary -- callers must provide the plugin information and the entry ++ // points. If |add_at_beginning| is true the plugin will be added earlier in ++ // the list so that it can override the MIME types of older registrations. ++ void RegisterInternalPlugin(const webkit::WebPluginInfo& info, ++ const PluginEntryPoints& entry_points, ++ bool add_at_beginning); + + // Removes a specified internal plugin from the list. The search will match + // on the path from the version info previously registered. diff --git a/tests/cefclient/client_handler_win.cpp b/tests/cefclient/client_handler_win.cpp index eed894484..2db190dc2 100644 --- a/tests/cefclient/client_handler_win.cpp +++ b/tests/cefclient/client_handler_win.cpp @@ -99,6 +99,21 @@ bool ClientHandler::OnBeforeResourceLoad(CefRefPtr browser, resourceStream = GetBinaryResourceReader(IDS_TRANSPARENCY); response->SetMimeType("text/html"); response->SetStatus(200); + } else if(url == "http://tests/plugin") { + std::string html = + "\n" + "Client Plugin loaded by Mime Type:
\n" + "\n" + "

Client Plugin loaded by File Extension:
\n" + "\n" + // Add some extra space below the plugin to allow scrolling. + "
 
\n" + ""; + + resourceStream = + CefStreamReader::CreateForData((void*)html.c_str(), html.size()); + response->SetMimeType("text/html"); + response->SetStatus(200); } return false; diff --git a/tests/cefclient/osrplugin_test.cpp b/tests/cefclient/osrplugin_test.cpp index 451dc8fb2..5f1f2e985 100644 --- a/tests/cefclient/osrplugin_test.cpp +++ b/tests/cefclient/osrplugin_test.cpp @@ -15,7 +15,7 @@ void InitOSRPluginTest() CefString(&plugin_info.display_name).FromASCII("Client OSR Plugin"); CefString(&plugin_info.unique_name).FromASCII("client_osr_plugin"); CefString(&plugin_info.description).FromASCII("My Example Client OSR Plugin"); - CefString(&plugin_info.mime_type).FromASCII( + CefString(&plugin_info.mime_types).FromASCII( "application/x-client-osr-plugin"); plugin_info.np_getentrypoints = NP_OSRGetEntryPoints; diff --git a/tests/cefclient/plugin_test.cpp b/tests/cefclient/plugin_test.cpp index 02d554a47..5b0fb4651 100644 --- a/tests/cefclient/plugin_test.cpp +++ b/tests/cefclient/plugin_test.cpp @@ -12,7 +12,8 @@ void InitPluginTest() CefString(&plugin_info.display_name).FromASCII("Client Plugin"); CefString(&plugin_info.unique_name).FromASCII("client_plugin"); CefString(&plugin_info.description).FromASCII("My Example Client Plugin"); - CefString(&plugin_info.mime_type).FromASCII("application/x-client-plugin"); + CefString(&plugin_info.mime_types).FromASCII("application/x-client-plugin"); + CefString(&plugin_info.file_extensions).FromASCII("xcp"); plugin_info.np_getentrypoints = NP_ClientGetEntryPoints; plugin_info.np_initialize = NP_ClientInitialize; @@ -24,11 +25,6 @@ void InitPluginTest() void RunPluginTest(CefRefPtr browser) { - // Add some extra space below the plugin to allow scrolling. - std::string html = - "Client Plugin:
" - "" - "
 
" - ""; - browser->GetMainFrame()->LoadString(html, "about:blank"); + // Page content is provided in ClientHandler::OnBeforeResourceLoad(). + browser->GetMainFrame()->LoadURL("http://tests/plugin"); } diff --git a/tests/cefclient/uiplugin_test.cpp b/tests/cefclient/uiplugin_test.cpp index 7e9c12f28..f7b8cd8a5 100644 --- a/tests/cefclient/uiplugin_test.cpp +++ b/tests/cefclient/uiplugin_test.cpp @@ -63,7 +63,8 @@ void InitUIPluginTest() CefString(&plugin_info.display_name).FromASCII("Client UI Plugin"); CefString(&plugin_info.unique_name).FromASCII("client_ui_plugin"); CefString(&plugin_info.description).FromASCII("My Example Client UI Plugin"); - CefString(&plugin_info.mime_type).FromASCII("application/x-client-ui-plugin"); + CefString(&plugin_info.mime_types).FromASCII( + "application/x-client-ui-plugin"); plugin_info.np_getentrypoints = NP_UIGetEntryPoints; plugin_info.np_initialize = NP_UIInitialize;