summaryrefslogtreecommitdiffstats
path: root/chrome_frame/chrome_frame_npapi.h
diff options
context:
space:
mode:
authorslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
committerslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
commitf781782dd67077478e117c61dca4ea5eefce3544 (patch)
tree4801f724123cfdcbb69c4e7fe40a565b331723ae /chrome_frame/chrome_frame_npapi.h
parent63cf4759efa2373e33436fb5df6849f930081226 (diff)
downloadchromium_src-f781782dd67077478e117c61dca4ea5eefce3544.zip
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.gz
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.bz2
Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming in a separate CL.
BUG=None TEST=None Review URL: http://codereview.chromium.org/218019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/chrome_frame_npapi.h')
-rw-r--r--chrome_frame/chrome_frame_npapi.h333
1 files changed, 333 insertions, 0 deletions
diff --git a/chrome_frame/chrome_frame_npapi.h b/chrome_frame/chrome_frame_npapi.h
new file mode 100644
index 0000000..005d72f
--- /dev/null
+++ b/chrome_frame/chrome_frame_npapi.h
@@ -0,0 +1,333 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_FRAME_CHROME_FRAME_NPAPI_H_
+#define CHROME_FRAME_CHROME_FRAME_NPAPI_H_
+
+#include <atlbase.h>
+#include <atlwin.h>
+#include <string>
+
+#include "chrome_frame/chrome_frame_automation.h"
+#include "chrome_frame/chrome_frame_plugin.h"
+#include "chrome_frame/np_browser_functions.h"
+#include "chrome_frame/np_event_listener.h"
+#include "chrome_frame/np_proxy_service.h"
+#include "chrome_frame/npapi_url_request.h"
+
+class MessageLoop;
+
+// ChromeFrameNPAPI: Implementation of the NPAPI plugin, which is responsible
+// for hosting a chrome frame, i.e. an iframe like widget which hosts the the
+// chrome window. This object delegates to Chrome.exe (via the Chrome
+// IPC-based automation mechanism) for the actual rendering.
+class ChromeFrameNPAPI
+ : public CWindowImpl<ChromeFrameNPAPI>,
+ public ChromeFramePlugin<ChromeFrameNPAPI>,
+ public NpEventDelegate {
+ public:
+ typedef ChromeFramePlugin<ChromeFrameNPAPI> Base;
+
+ // NPObject structure which is exposed by us.
+ struct ChromeFrameNPObject : public NPObject {
+ NPP npp;
+ ChromeFrameNPAPI* chrome_frame_plugin_instance;
+ };
+
+ typedef enum {
+ PLUGIN_PROPERTY_VERSION,
+ PLUGIN_PROPERTY_SRC,
+ PLUGIN_PROPERTY_ONLOAD,
+ PLUGIN_PROPERTY_ONERROR,
+ PLUGIN_PROPERTY_ONMESSAGE,
+ PLUGIN_PROPERTY_READYSTATE,
+ PLUGIN_PROPERTY_ONPRIVATEMESSAGE,
+ PLUGIN_PROPERTY_USECHROMENETWORK,
+ PLUGIN_PROPERTY_COUNT // must be last
+ } PluginPropertyId;
+
+ static const int kWmSwitchFocusToChromeFrame = WM_APP + 0x100;
+
+ static NPClass plugin_class_;
+ static NPClass* PluginClass() {
+ return &plugin_class_;
+ }
+
+ ChromeFrameNPAPI();
+ ~ChromeFrameNPAPI();
+
+ bool Initialize(NPMIMEType mime_type, NPP instance, uint16 mode,
+ int16 argc, char* argn[], char* argv[]);
+ void Uninitialize();
+
+ bool SetWindow(NPWindow* window_info);
+ void UrlNotify(const char* url, NPReason reason, void* notify_data);
+ bool NewStream(NPMIMEType type, NPStream* stream, NPBool seekable,
+ uint16* stream_type);
+
+ void Print(NPPrint* print_info);
+
+ // NPObject functions, which ensure that the plugin object is scriptable.
+ static bool HasMethod(NPObject* obj, NPIdentifier name);
+ static bool Invoke(NPObject* header, NPIdentifier name,
+ const NPVariant* args, uint32_t arg_count,
+ NPVariant* result);
+ static NPObject* AllocateObject(NPP instance, NPClass* class_name);
+ static void DeallocateObject(NPObject* header);
+
+ // Called by the scripting environment when the native code is shutdown.
+ // Any attempt to message a NPObject instance after the invalidate callback
+ // has been called will result in undefined behavior, even if the native code
+ // is still retaining those NPObject instances.
+ static void Invalidate(NPObject* header);
+
+ // The following functions need to be implemented to ensure that FF3
+ // invokes methods on the plugin. If these methods are not implemented
+ // then invokes on the plugin NPObject from the script fail with a
+ // bad NPObject error.
+ static bool HasProperty(NPObject* obj, NPIdentifier name);
+ static bool GetProperty(NPObject* obj, NPIdentifier name, NPVariant *variant);
+ static bool SetProperty(NPObject* obj, NPIdentifier name,
+ const NPVariant *variant);
+
+ // Returns the ChromeFrameNPAPI object pointer from the NPP instance structure
+ // passed in by the browser.
+ static ChromeFrameNPAPI* ChromeFrameInstanceFromPluginInstance(NPP instance);
+
+ // Returns the ChromeFrameNPAPI object pointer from the NPObject structure
+ // which represents our plugin class.
+ static ChromeFrameNPAPI* ChromeFrameInstanceFromNPObject(void* object);
+
+ // Return a UrlRequest instance associated with the given instance and
+ // stream combination.
+ static NPAPIUrlRequest* ValidateRequest(NPP instance, void* notify_data);
+
+BEGIN_MSG_MAP(ChromeFrameNPAPI)
+ MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
+ CHAIN_MSG_MAP(Base)
+END_MSG_MAP()
+
+ LRESULT OnSetFocus(UINT message, WPARAM wparam, LPARAM lparam,
+ BOOL& handled); // NO_LINT
+
+ // Implementation of NpEventDelegate
+ virtual void OnEvent(const char* event_name);
+
+ void OnFocus();
+ void OnBlur();
+
+ // Implementation of SetProperty, public to allow unittesting.
+ bool SetProperty(NPIdentifier name, const NPVariant *variant);
+ // Implementation of GetProperty, public to allow unittesting.
+ bool GetProperty(NPIdentifier name, NPVariant *variant);
+
+ // Initialize string->identifier mapping, public to allow unittesting.
+ static void InitializeIdentifiers();
+
+ bool HandleContextMenuCommand(UINT cmd);
+ protected:
+ // Handler for accelerator messages passed on from the hosted chrome
+ // instance.
+ virtual void OnAcceleratorPressed(int tab_handle, const MSG& accel_message);
+ virtual void OnTabbedOut(int tab_handle, bool reverse);
+ virtual void OnOpenURL(int tab_handle, const GURL& url, int open_disposition);
+ virtual void OnLoad(int tab_handle, const GURL& url);
+ virtual void OnMessageFromChromeFrame(int tab_handle,
+ const std::string& message,
+ const std::string& origin,
+ const std::string& target);
+ virtual void OnRequestStart(int tab_handle, int request_id,
+ const IPC::AutomationURLRequest& request);
+ virtual void OnRequestRead(int tab_handle, int request_id,
+ int bytes_to_read);
+ virtual void OnRequestEnd(int tab_handle, int request_id,
+ const URLRequestStatus& status);
+ virtual void OnSetCookieAsync(int tab_handle, const GURL& url,
+ const std::string& cookie);
+
+ // ChromeFrameDelegate overrides
+ virtual void OnLoadFailed(int error_code, const std::string& url);
+ virtual void OnAutomationServerReady();
+ virtual void OnAutomationServerLaunchFailed(
+ AutomationLaunchResult reason, const std::string& server_version);
+
+ private:
+ void SubscribeToFocusEvents();
+ void UnsubscribeFromFocusEvents();
+
+ // Equivalent of:
+ // event = window.document.createEvent("Event");
+ // event.initEvent(type, bubbles, cancelable);
+ // and then returns the event object.
+ bool CreateEvent(const std::string& type, bool bubbles, bool cancelable,
+ NPObject** basic_event);
+
+ // Creates and initializes an event object of type "message".
+ // Used for postMessage.
+ bool CreateMessageEvent(bool bubbles, bool cancelable,
+ const std::string& data, const std::string& origin,
+ NPObject** message_event);
+
+ // Calls chrome_frame.dispatchEvent to fire events to event listeners.
+ void DispatchEvent(NPObject* event);
+
+ // Returns a pointer to the <object> element in the page that
+ // hosts the plugin. Note that this is the parent element of the <embed>
+ // element. The <embed> element doesn't support some of the events that
+ // we require, so we use the object element for receiving events.
+ bool GetObjectElement(nsIDOMElement** element);
+
+ // Prototype for all methods that can be invoked from script.
+ typedef bool (ChromeFrameNPAPI::*PluginMethod)(NPObject* npobject,
+ const NPVariant* args,
+ uint32_t arg_count,
+ NPVariant* result);
+
+ // Implementations of scriptable methods.
+
+ bool NavigateToURL(const NPVariant* args, uint32_t arg_count,
+ NPVariant* result);
+
+ bool postMessage(NPObject* npobject, const NPVariant* args,
+ uint32_t arg_count, NPVariant* result);
+
+ // This method is only available when the control is in privileged mode.
+ bool postPrivateMessage(NPObject* npobject, const NPVariant* args,
+ uint32_t arg_count, NPVariant* result);
+
+ // Pointers to method implementations.
+ static PluginMethod plugin_methods_[];
+
+ // NPObject method ids exposed by the plugin.
+ static NPIdentifier plugin_method_identifiers_[];
+
+ // NPObject method names exposed by the plugin.
+ static const NPUTF8* plugin_method_identifier_names_[];
+
+ // NPObject property ids exposed by the plugin.
+ static NPIdentifier plugin_property_identifiers_[];
+
+ // NPObject property names exposed by the plugin.
+ static const NPUTF8*
+ plugin_property_identifier_names_[];
+
+ virtual void OnFinalMessage(HWND window);
+
+ // Helper function to invoke a function on a NPObject.
+ bool InvokeDefault(NPObject* object, const std::string& param,
+ NPVariant* result);
+
+ bool InvokeDefault(NPObject* object, const NPVariant& param,
+ NPVariant* result);
+
+ bool InvokeDefault(NPObject* object, unsigned param_count,
+ const NPVariant* params, NPVariant* result);
+
+ // Helper function to convert javascript code to a NPObject we can
+ // invoke on.
+ virtual NPObject* JavascriptToNPObject(const std::string& function_name);
+
+ // Helper function to execute a script.
+ // Returns S_OK on success.
+ bool ExecuteScript(const std::string& script, NPVariant* result);
+
+ // Returns true if the script passed in is a valid function in the DOM.
+ bool IsValidJavascriptFunction(const std::string& script);
+
+ // Converts the data parameter to an NPVariant and forwards the call to the
+ // other FireEvent method.
+ void FireEvent(const std::string& event_type, const std::string& data);
+
+ // Creates an event object, assigns the data parameter to a |data| property
+ // on the event object and then calls DispatchEvent to fire the event to
+ // listeners. event_type is the name of the event being fired.
+ void FireEvent(const std::string& event_type, const NPVariant& data);
+
+ // Returns a new prefs service. Virtual to allow overriding in unittests.
+ virtual NpProxyService* CreatePrefService();
+
+ // Returns our associated windows' location.
+ virtual std::string GetLocation();
+
+ // Returns true iff we're successfully able to query for the browser's
+ // incognito mode, and the browser returns true.
+ virtual bool GetBrowserIncognitoMode();
+
+ // Returns the window script object for the page.
+ // This function will cache the window object to avoid calling
+ // npapi::GetValue which can cause problems in Opera.
+ NPObject* GetWindowObject() const;
+
+ virtual void SetReadyState(READYSTATE new_state) {
+ ready_state_ = new_state;
+ NPVariant var;
+ INT32_TO_NPVARIANT(ready_state_, var);
+ FireEvent("readystatechanged", var);
+ }
+
+ // Host function to compile-time asserts over members of this class.
+ static void CompileAsserts();
+
+ // Get request from the stream notify data
+ NPAPIUrlRequest* RequestFromNotifyData(void* notify_data) const;
+
+ static LRESULT CALLBACK DropKillFocusHook(int code, WPARAM wparam,
+ LPARAM lparam); // NO_LINT
+
+ // The plugins opaque instance handle
+ NPP instance_;
+
+ // The plugin instantiation mode (NP_FULL or NP_EMBED)
+ int16 mode_;
+ // The plugins mime type.
+ std::string mime_type_;
+
+ // Set to true if we need a full page plugin.
+ bool force_full_page_plugin_;
+
+ scoped_refptr<NpProxyService> pref_service_;
+
+ // Used to receive focus and blur events from the object element
+ // that hosts the plugin.
+ scoped_refptr<NpEventListener> focus_listener_;
+
+ // In some cases the IPC channel proxy object is instantiated on the UI
+ // thread in FF. It then tries to use the IPC logger, which relies on
+ // the message loop being around. Declaring a dummy message loop
+ // is a hack to get around this. Eventually the automation code needs to
+ // be fixed to ensure that the channel proxy always gets created on a thread
+ // with a message loop.
+ static MessageLoop* message_loop_;
+ static int instance_count_;
+
+ // The following members contain the NPObject pointers representing the
+ // onload/onerror/onmessage handlers on the page.
+ ScopedNpObject<NPObject> onerror_handler_;
+ ScopedNpObject<NPObject> onmessage_handler_;
+ ScopedNpObject<NPObject> onprivatemessage_handler_;
+
+ // As a workaround for a problem in Opera we cache the window object.
+ // The problem stems from two things: window messages aren't always removed
+ // from the message queue and messages can be pumped inside GetValue.
+ // This can cause an infinite recursion of processing the same message
+ // repeatedly.
+ mutable ScopedNpObject<NPObject> window_object_;
+
+ // Note since 'onload' is a registered event name, the browser will
+ // automagically create a code block for the handling code and hook it
+ // up to the CF object via addEventListener.
+ // See this list of known event types:
+ // http://www.w3.org/TR/DOM-Level-3-Events/events.html#Event-types
+
+ READYSTATE ready_state_;
+
+
+ // Popups are enabled
+ bool enabled_popups_;
+
+ // The value of src property keeping the current URL.
+ std::string src_;
+};
+
+#endif // CHROME_FRAME_CHROME_FRAME_NPAPI_H_