| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef CHROME_FRAME_CHROME_FRAME_NPAPI_H_ | |
| 6 #define CHROME_FRAME_CHROME_FRAME_NPAPI_H_ | |
| 7 | |
| 8 #include <atlbase.h> | |
| 9 #include <atlwin.h> | |
| 10 #include <string> | |
| 11 | |
| 12 #include "chrome_frame/chrome_frame_automation.h" | |
| 13 #include "chrome_frame/chrome_frame_plugin.h" | |
| 14 #include "chrome_frame/np_browser_functions.h" | |
| 15 #include "chrome_frame/npapi_url_request.h" | |
| 16 | |
| 17 class MessageLoop; | |
| 18 class nsICookieService; | |
| 19 class nsIURI; | |
| 20 | |
| 21 // ChromeFrameNPAPI: Implementation of the NPAPI plugin, which is responsible | |
| 22 // for hosting a chrome frame, i.e. an iframe like widget which hosts the the | |
| 23 // chrome window. This object delegates to Chrome.exe (via the Chrome | |
| 24 // IPC-based automation mechanism) for the actual rendering. | |
| 25 class ChromeFrameNPAPI | |
| 26 : public CWindowImpl<ChromeFrameNPAPI>, | |
| 27 public ChromeFramePlugin<ChromeFrameNPAPI> { | |
| 28 public: | |
| 29 typedef ChromeFramePlugin<ChromeFrameNPAPI> Base; | |
| 30 | |
| 31 // NPObject structure which is exposed by us. | |
| 32 struct ChromeFrameNPObject : public NPObject { | |
| 33 NPP npp; | |
| 34 ChromeFrameNPAPI* chrome_frame_plugin_instance; | |
| 35 }; | |
| 36 | |
| 37 typedef enum { | |
| 38 PLUGIN_PROPERTY_VERSION, | |
| 39 PLUGIN_PROPERTY_SRC, | |
| 40 PLUGIN_PROPERTY_ONLOAD, | |
| 41 PLUGIN_PROPERTY_ONERROR, | |
| 42 PLUGIN_PROPERTY_ONMESSAGE, | |
| 43 PLUGIN_PROPERTY_READYSTATE, | |
| 44 PLUGIN_PROPERTY_USECHROMENETWORK, | |
| 45 PLUGIN_PROPERTY_ONCLOSE, | |
| 46 PLUGIN_PROPERTY_COUNT // must be last | |
| 47 } PluginPropertyId; | |
| 48 | |
| 49 static const int kWmSwitchFocusToChromeFrame = WM_APP + 0x100; | |
| 50 | |
| 51 static NPClass plugin_class_; | |
| 52 static NPClass* PluginClass() { | |
| 53 return &plugin_class_; | |
| 54 } | |
| 55 | |
| 56 ChromeFrameNPAPI(); | |
| 57 ~ChromeFrameNPAPI(); | |
| 58 | |
| 59 bool Initialize(NPMIMEType mime_type, NPP instance, uint16 mode, | |
| 60 int16 argc, char* argn[], char* argv[]); | |
| 61 void Uninitialize(); | |
| 62 | |
| 63 bool SetWindow(NPWindow* window_info); | |
| 64 void UrlNotify(const char* url, NPReason reason, void* notify_data); | |
| 65 NPError NewStream(NPMIMEType type, NPStream* stream, NPBool seekable, | |
| 66 uint16* stream_type); | |
| 67 int32 WriteReady(NPStream* stream); | |
| 68 int32 Write(NPStream* stream, int32 offset, int32 len, void* buffer); | |
| 69 NPError DestroyStream(NPStream* stream, NPReason reason); | |
| 70 | |
| 71 void Print(NPPrint* print_info); | |
| 72 void URLRedirectNotify(const char* url, int status, void* notify_data); | |
| 73 | |
| 74 // NPObject functions, which ensure that the plugin object is scriptable. | |
| 75 static bool HasMethod(NPObject* obj, NPIdentifier name); | |
| 76 static bool Invoke(NPObject* header, NPIdentifier name, | |
| 77 const NPVariant* args, uint32_t arg_count, | |
| 78 NPVariant* result); | |
| 79 static NPObject* AllocateObject(NPP instance, NPClass* class_name); | |
| 80 static void DeallocateObject(NPObject* header); | |
| 81 | |
| 82 // Called by the scripting environment when the native code is shutdown. | |
| 83 // Any attempt to message a NPObject instance after the invalidate callback | |
| 84 // has been called will result in undefined behavior, even if the native code | |
| 85 // is still retaining those NPObject instances. | |
| 86 static void Invalidate(NPObject* header); | |
| 87 | |
| 88 // The following functions need to be implemented to ensure that FF3 | |
| 89 // invokes methods on the plugin. If these methods are not implemented | |
| 90 // then invokes on the plugin NPObject from the script fail with a | |
| 91 // bad NPObject error. | |
| 92 static bool HasProperty(NPObject* obj, NPIdentifier name); | |
| 93 static bool GetProperty(NPObject* obj, NPIdentifier name, NPVariant *variant); | |
| 94 static bool SetProperty(NPObject* obj, NPIdentifier name, | |
| 95 const NPVariant *variant); | |
| 96 | |
| 97 // Returns the ChromeFrameNPAPI object pointer from the NPP instance structure | |
| 98 // passed in by the browser. | |
| 99 static ChromeFrameNPAPI* ChromeFrameInstanceFromPluginInstance(NPP instance); | |
| 100 | |
| 101 // Returns the ChromeFrameNPAPI object pointer from the NPObject structure | |
| 102 // which represents our plugin class. | |
| 103 static ChromeFrameNPAPI* ChromeFrameInstanceFromNPObject(void* object); | |
| 104 | |
| 105 BEGIN_MSG_MAP(ChromeFrameNPAPI) | |
| 106 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) | |
| 107 CHAIN_MSG_MAP(Base) | |
| 108 END_MSG_MAP() | |
| 109 | |
| 110 LRESULT OnSetFocus(UINT message, WPARAM wparam, LPARAM lparam, | |
| 111 BOOL& handled); // NO_LINT | |
| 112 // Implementation of SetProperty, public to allow unittesting. | |
| 113 bool SetProperty(NPIdentifier name, const NPVariant *variant); | |
| 114 // Implementation of GetProperty, public to allow unittesting. | |
| 115 bool GetProperty(NPIdentifier name, NPVariant *variant); | |
| 116 | |
| 117 // Initialize string->identifier mapping, public to allow unittesting. | |
| 118 static void InitializeIdentifiers(); | |
| 119 | |
| 120 bool PreProcessContextMenu(HMENU menu); | |
| 121 bool HandleContextMenuCommand(UINT cmd, const MiniContextMenuParams& params); | |
| 122 protected: | |
| 123 // Handler for accelerator messages passed on from the hosted chrome | |
| 124 // instance. | |
| 125 virtual void OnAcceleratorPressed(const MSG& accel_message); | |
| 126 virtual void OnTabbedOut(bool reverse); | |
| 127 virtual void OnOpenURL(const GURL& url, const GURL& referrer, | |
| 128 int open_disposition); | |
| 129 virtual void OnLoad(const GURL& url); | |
| 130 virtual void OnMessageFromChromeFrame(const std::string& message, | |
| 131 const std::string& origin, | |
| 132 const std::string& target); | |
| 133 // ChromeFrameDelegate overrides | |
| 134 virtual void OnLoadFailed(int error_code, const std::string& url); | |
| 135 virtual void OnAutomationServerReady(); | |
| 136 virtual void OnAutomationServerLaunchFailed( | |
| 137 AutomationLaunchResult reason, const std::string& server_version); | |
| 138 virtual void OnCloseTab(); | |
| 139 | |
| 140 private: | |
| 141 // Equivalent of: | |
| 142 // event = window.document.createEvent("Event"); | |
| 143 // event.initEvent(type, bubbles, cancelable); | |
| 144 // and then returns the event object. | |
| 145 bool CreateEvent(const std::string& type, bool bubbles, bool cancelable, | |
| 146 NPObject** basic_event); | |
| 147 | |
| 148 // Creates and initializes an event object of type "message". | |
| 149 // Used for postMessage. | |
| 150 bool CreateMessageEvent(bool bubbles, bool cancelable, | |
| 151 const std::string& data, const std::string& origin, | |
| 152 NPObject** message_event); | |
| 153 | |
| 154 // Calls chrome_frame.dispatchEvent to fire events to event listeners. | |
| 155 void DispatchEvent(NPObject* event); | |
| 156 | |
| 157 // Prototype for all methods that can be invoked from script. | |
| 158 typedef bool (ChromeFrameNPAPI::*PluginMethod)(NPObject* npobject, | |
| 159 const NPVariant* args, | |
| 160 uint32_t arg_count, | |
| 161 NPVariant* result); | |
| 162 | |
| 163 // Implementations of scriptable methods. | |
| 164 | |
| 165 bool NavigateToURL(const NPVariant* args, uint32_t arg_count, | |
| 166 NPVariant* result); | |
| 167 | |
| 168 bool postMessage(NPObject* npobject, const NPVariant* args, | |
| 169 uint32_t arg_count, NPVariant* result); | |
| 170 | |
| 171 // Pointers to method implementations. | |
| 172 static PluginMethod plugin_methods_[]; | |
| 173 | |
| 174 // NPObject method ids exposed by the plugin. | |
| 175 static NPIdentifier plugin_method_identifiers_[]; | |
| 176 | |
| 177 // NPObject method names exposed by the plugin. | |
| 178 static const NPUTF8* plugin_method_identifier_names_[]; | |
| 179 | |
| 180 // NPObject property ids exposed by the plugin. | |
| 181 static NPIdentifier plugin_property_identifiers_[]; | |
| 182 | |
| 183 // NPObject property names exposed by the plugin. | |
| 184 static const NPUTF8* | |
| 185 plugin_property_identifier_names_[]; | |
| 186 | |
| 187 virtual void OnFinalMessage(HWND window); | |
| 188 | |
| 189 // Helper function to invoke a function on a NPObject. | |
| 190 bool InvokeDefault(NPObject* object, const std::string& param, | |
| 191 NPVariant* result); | |
| 192 | |
| 193 bool InvokeDefault(NPObject* object, const NPVariant& param, | |
| 194 NPVariant* result); | |
| 195 | |
| 196 bool InvokeDefault(NPObject* object, unsigned param_count, | |
| 197 const NPVariant* params, NPVariant* result); | |
| 198 | |
| 199 // Helper function to convert javascript code to a NPObject we can | |
| 200 // invoke on. | |
| 201 virtual NPObject* JavascriptToNPObject(const std::string& function_name); | |
| 202 | |
| 203 // Helper function to execute a script. | |
| 204 // Returns S_OK on success. | |
| 205 bool ExecuteScript(const std::string& script, NPVariant* result); | |
| 206 | |
| 207 // Returns true if the script passed in is a valid function in the DOM. | |
| 208 bool IsValidJavascriptFunction(const std::string& script); | |
| 209 | |
| 210 // Converts the data parameter to an NPVariant and forwards the call to the | |
| 211 // other FireEvent method. | |
| 212 void FireEvent(const std::string& event_type, const std::string& data); | |
| 213 | |
| 214 // Creates an event object, assigns the data parameter to a |data| property | |
| 215 // on the event object and then calls DispatchEvent to fire the event to | |
| 216 // listeners. event_type is the name of the event being fired. | |
| 217 void FireEvent(const std::string& event_type, const NPVariant& data); | |
| 218 | |
| 219 // Returns our associated windows' location. | |
| 220 virtual std::string GetLocation(); | |
| 221 | |
| 222 // Returns true iff we're successfully able to query for the browser's | |
| 223 // incognito mode, and the browser returns true. | |
| 224 virtual bool GetBrowserIncognitoMode(); | |
| 225 | |
| 226 // Returns the window script object for the page. | |
| 227 // This function will cache the window object to avoid calling | |
| 228 // npapi::GetValue which can cause problems in Opera. | |
| 229 NPObject* GetWindowObject() const; | |
| 230 | |
| 231 virtual void SetReadyState(READYSTATE new_state) { | |
| 232 ready_state_ = new_state; | |
| 233 NPVariant var; | |
| 234 INT32_TO_NPVARIANT(ready_state_, var); | |
| 235 FireEvent("readystatechanged", var); | |
| 236 } | |
| 237 | |
| 238 // Host function to compile-time asserts over members of this class. | |
| 239 static void CompileAsserts(); | |
| 240 | |
| 241 static LRESULT CALLBACK DropKillFocusHook(int code, WPARAM wparam, | |
| 242 LPARAM lparam); // NO_LINT | |
| 243 | |
| 244 // The plugins opaque instance handle | |
| 245 NPP instance_; | |
| 246 | |
| 247 // The plugin instantiation mode (NP_FULL or NP_EMBED) | |
| 248 int16 mode_; | |
| 249 // The plugins mime type. | |
| 250 std::string mime_type_; | |
| 251 | |
| 252 // Set to true if we need a full page plugin. | |
| 253 bool force_full_page_plugin_; | |
| 254 | |
| 255 // In some cases the IPC channel proxy object is instantiated on the UI | |
| 256 // thread in FF. It then tries to use the IPC logger, which relies on | |
| 257 // the message loop being around. Declaring a dummy message loop | |
| 258 // is a hack to get around this. Eventually the automation code needs to | |
| 259 // be fixed to ensure that the channel proxy always gets created on a thread | |
| 260 // with a message loop. | |
| 261 static MessageLoop* message_loop_; | |
| 262 static int instance_count_; | |
| 263 | |
| 264 // The following members contain the NPObject pointers representing the | |
| 265 // onload/onerror/onmessage handlers on the page. | |
| 266 ScopedNpObject<NPObject> onerror_handler_; | |
| 267 ScopedNpObject<NPObject> onmessage_handler_; | |
| 268 ScopedNpObject<NPObject> onprivatemessage_handler_; | |
| 269 ScopedNpObject<NPObject> onclose_handler_; | |
| 270 | |
| 271 // As a workaround for a problem in Opera we cache the window object. | |
| 272 // The problem stems from two things: window messages aren't always removed | |
| 273 // from the message queue and messages can be pumped inside GetValue. | |
| 274 // This can cause an infinite recursion of processing the same message | |
| 275 // repeatedly. | |
| 276 mutable ScopedNpObject<NPObject> window_object_; | |
| 277 | |
| 278 // Note since 'onload' is a registered event name, the browser will | |
| 279 // automagically create a code block for the handling code and hook it | |
| 280 // up to the CF object via addEventListener. | |
| 281 // See this list of known event types: | |
| 282 // http://www.w3.org/TR/DOM-Level-3-Events/events.html#Event-types | |
| 283 | |
| 284 READYSTATE ready_state_; | |
| 285 | |
| 286 // Popups are enabled | |
| 287 bool enabled_popups_; | |
| 288 | |
| 289 // The value of src property keeping the current URL. | |
| 290 std::string src_; | |
| 291 // Used to fetch network resources when host network stack is in use. | |
| 292 NPAPIUrlRequestManager url_fetcher_; | |
| 293 | |
| 294 // Set if we receive a navigation request before initializing Chrome. | |
| 295 bool navigate_after_initialization_; | |
| 296 }; | |
| 297 | |
| 298 #endif // CHROME_FRAME_CHROME_FRAME_NPAPI_H_ | |
| OLD | NEW |