// Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Copyright (c) 2007, 2008 Novell, Inc. // // Authors: // Andreia Gaita (avidigal@novell.com) // #undef debug using System; using System.Collections; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Diagnostics; using Mono.WebBrowser; using Mono.WebBrowser.DOM; namespace Mono.Mozilla { internal class WebBrowser : IWebBrowser { bool loaded; internal bool created = false; bool creating = false; internal DOM.Document document; internal DOM.Navigation navigation; internal Platform platform; internal Platform enginePlatform; internal Callback callbacks; System.ComponentModel.EventHandlerList events; System.ComponentModel.EventHandlerList domEvents; string statusText; bool streamingMode; internal Hashtable documents; int width; int height; bool isDirty; public WebBrowser (Platform platform) { this.platform = platform; callbacks = new Callback(this); loaded = Base.Init (this, platform); documents = new Hashtable (); } public bool Load (IntPtr handle, int width, int height) { loaded = Base.Bind (this, handle, width, height); return loaded; } bool Created { get { if (!creating && !created) { creating = true; created = Base.Create (this); if (created && isDirty) { isDirty = false; Base.Resize (this, width, height); } } return created; } } public void Shutdown () { Base.Shutdown (this); } internal void Reset () { this.document = null; this.DomEvents.Dispose (); this.domEvents = null; this.documents.Clear (); } public bool Initialized { get { return this.loaded; } } public IWindow Window { get { if (Navigation != null) { nsIWebBrowserFocus webBrowserFocus = (nsIWebBrowserFocus) (navigation.navigation); nsIDOMWindow window; webBrowserFocus.getFocusedWindow (out window); if (window == null) ((nsIWebBrowser) navigation.navigation).getContentDOMWindow (out window); if (window != null) return new DOM.Window (this, window) as IWindow; } return null; } } public IDocument Document { get { if (Navigation != null && document == null) { document = navigation.Document; } return document as IDocument; } } public INavigation Navigation { get { if (!Created) return null; if (navigation == null) { nsIWebNavigation webNav = Base.GetWebNavigation (this); navigation = new DOM.Navigation (this, webNav); } return navigation as INavigation; } } public string StatusText { get { return statusText; } } public bool Offline { get { bool ret; if (!Created) return true; IOService.getOffline (out ret); return ret; } set { IOService.setOffline (value); } } internal System.ComponentModel.EventHandlerList DomEvents { get { if (domEvents == null) domEvents = new System.ComponentModel.EventHandlerList(); return domEvents; } } internal System.ComponentModel.EventHandlerList Events { get { if (events == null) events = new System.ComponentModel.EventHandlerList(); return events; } } Mono.Mozilla.DOM.ContentListener contentListener; Mono.Mozilla.DOM.ContentListener ContentListener { get { if (contentListener == null) contentListener = new Mono.Mozilla.DOM.ContentListener (this); return contentListener; } } nsIServiceManager servMan; internal nsIServiceManager ServiceManager { get { if (servMan == null) { servMan = Base.GetServiceManager (this); } return servMan; } } nsIIOService ioService; internal nsIIOService IOService { get { if (ioService == null) { IntPtr ioServicePtr = IntPtr.Zero; ServiceManager.getServiceByContractID ("@mozilla.org/network/io-service;1", typeof (nsIIOService).GUID, out ioServicePtr); if (ioServicePtr == IntPtr.Zero) throw new Mono.WebBrowser.Exception (Mono.WebBrowser.Exception.ErrorCodes.IOService); try { ioService = (nsIIOService)Marshal.GetObjectForIUnknown (ioServicePtr); } catch (System.Exception ex) { throw new Mono.WebBrowser.Exception (Mono.WebBrowser.Exception.ErrorCodes.IOService, ex); } } return ioService; } } nsIAccessibilityService accessibilityService; internal nsIAccessibilityService AccessibilityService { get { if (accessibilityService == null) { IntPtr accessibilityServicePtr = IntPtr.Zero; ServiceManager.getServiceByContractID ("@mozilla.org/accessibilityService;1", typeof (nsIAccessibilityService).GUID, out accessibilityServicePtr); if (accessibilityServicePtr == IntPtr.Zero) { throw new Mono.WebBrowser.Exception (Mono.WebBrowser.Exception.ErrorCodes.AccessibilityService); } try { accessibilityService = (nsIAccessibilityService)Marshal.GetObjectForIUnknown (accessibilityServicePtr); } catch (System.Exception ex) { throw new Mono.WebBrowser.Exception (Mono.WebBrowser.Exception.ErrorCodes.AccessibilityService, ex); } } return accessibilityService; } } nsIErrorService errorService; internal nsIErrorService ErrorService { get { if (errorService == null) { IntPtr errorServicePtr = IntPtr.Zero; ServiceManager.getServiceByContractID ("@mozilla.org/xpcom/error-service;1", typeof (nsIErrorService).GUID, out errorServicePtr); if (errorServicePtr == IntPtr.Zero) return null; try { errorService = (nsIErrorService)Marshal.GetObjectForIUnknown (errorServicePtr); } catch (System.Exception ex) { return null; } } return errorService; } } DocumentEncoder docEncoder; internal DocumentEncoder DocEncoder { get { if (docEncoder == null) { docEncoder = new DocumentEncoder (this); } return docEncoder; } } #region Layout public void FocusIn (FocusOption focus) { if (!created) return; Base.Focus (this, focus); } public void FocusOut () { if (!created) return; Base.Blur (this); } public void Activate () { if (!Created) return; Base.Activate (this); } public void Deactivate () { if (!created) return; Base.Deactivate (this); } public void Resize (int width, int height) { this.width = width; this.height = height; isDirty = true; if (!created) return; Base.Resize (this, width, height); } public void Render (byte[] data) { if (!Created) return; if (data == null) throw new ArgumentNullException ("data"); string html = System.Text.ASCIIEncoding.UTF8.GetString (data); Render (html); } public void Render (string html) { if (!Created) return; Render (html, "file:///", "text/html"); } public void Render (string html, string uri, string contentType) { if (!Created) return; nsIWebBrowserStream stream; if (Navigation != null) { stream = (nsIWebBrowserStream) navigation.navigation; } else throw new Mono.WebBrowser.Exception (Mono.WebBrowser.Exception.ErrorCodes.Navigation); AsciiString asciiUri = new AsciiString (uri); nsIURI ret; IOService.newURI (asciiUri.Handle, null, null, out ret); AsciiString ctype = new AsciiString(contentType); HandleRef han = ctype.Handle; stream.openStream (ret, han); IntPtr native_html = Marshal.StringToHGlobalAnsi (html); stream.appendToStream (native_html, (uint)html.Length); Marshal.FreeHGlobal (native_html); stream.closeStream (); } public void ExecuteScript (string script) { if (!Created) return; Base.EvalScript (this, script); } internal void AttachEvent (INode node, string eve, EventHandler handler) { string key = String.Intern (node.GetHashCode() + ":" + eve); #if debug Console.Error.WriteLine ("Event Attached: " + key); #endif DomEvents.AddHandler (key, handler); } internal void DetachEvent (INode node, string eve, EventHandler handler) { string key = String.Intern (node.GetHashCode() + ":" + eve); #if debug Console.Error.WriteLine ("Event Detached: " + key); #endif DomEvents.RemoveHandler (key, handler); } #endregion #region Events internal static object KeyDownEvent = new object (); internal static object KeyPressEvent = new object (); internal static object KeyUpEvent = new object (); internal static object MouseClickEvent = new object (); internal static object MouseDoubleClickEvent = new object (); internal static object MouseDownEvent = new object (); internal static object MouseEnterEvent = new object (); internal static object MouseLeaveEvent = new object (); internal static object MouseMoveEvent = new object (); internal static object MouseUpEvent = new object (); internal static object FocusEvent = new object (); internal static object BlurEvent = new object (); internal static object CreateNewWindowEvent = new object (); internal static object AlertEvent = new object (); internal static object LoadStartedEvent = new object (); internal static object LoadCommitedEvent = new object (); internal static object ProgressChangedEvent = new object (); internal static object LoadFinishedEvent = new object (); internal static object LoadEvent = new object (); internal static object UnloadEvent = new object (); internal static object StatusChangedEvent = new object (); internal static object SecurityChangedEvent = new object (); internal static object ProgressEvent = new object (); internal static object ContextMenuEvent = new object (); internal static object NavigationRequestedEvent = new object (); public event NodeEventHandler KeyDown { add { Events.AddHandler (KeyDownEvent, value); } remove { Events.RemoveHandler (KeyDownEvent, value); } } public event NodeEventHandler KeyPress { add { Events.AddHandler (KeyPressEvent, value); } remove { Events.RemoveHandler (KeyPressEvent, value); } } public event NodeEventHandler KeyUp { add { Events.AddHandler (KeyUpEvent, value); } remove { Events.RemoveHandler (KeyUpEvent, value); } } public event NodeEventHandler MouseClick { add { Events.AddHandler (MouseClickEvent, value); } remove { Events.RemoveHandler (MouseClickEvent, value); } } public event NodeEventHandler MouseDoubleClick { add { Events.AddHandler (MouseDoubleClickEvent, value); } remove { Events.RemoveHandler (MouseDoubleClickEvent, value); } } public event NodeEventHandler MouseDown { add { Events.AddHandler (MouseDownEvent, value); } remove { Events.RemoveHandler (MouseDownEvent, value); } } public event NodeEventHandler MouseEnter { add { Events.AddHandler (MouseEnterEvent, value); } remove { Events.RemoveHandler (MouseEnterEvent, value); } } public event NodeEventHandler MouseLeave { add { Events.AddHandler (MouseLeaveEvent, value); } remove { Events.RemoveHandler (MouseLeaveEvent, value); } } public event NodeEventHandler MouseMove { add { Events.AddHandler (MouseMoveEvent, value); } remove { Events.RemoveHandler (MouseMoveEvent, value); } } public event NodeEventHandler MouseUp { add { Events.AddHandler (MouseUpEvent, value); } remove { Events.RemoveHandler (MouseUpEvent, value); } } public event EventHandler Focus { add { Events.AddHandler (FocusEvent, value); } remove { Events.RemoveHandler (FocusEvent, value); } } public event EventHandler Blur { add { Events.AddHandler (BlurEvent, value); } remove { Events.RemoveHandler (BlurEvent, value); } } public event CreateNewWindowEventHandler CreateNewWindow { add { Events.AddHandler (CreateNewWindowEvent, value); } remove { Events.RemoveHandler (CreateNewWindowEvent, value); } } public event AlertEventHandler Alert { add { Events.AddHandler (AlertEvent, value); } remove { Events.RemoveHandler (AlertEvent, value); } } public event EventHandler Loaded { add { Events.AddHandler (LoadEvent, value); } remove { Events.RemoveHandler (LoadEvent, value); } } public event EventHandler Unloaded { add { Events.AddHandler (UnloadEvent, value); } remove { Events.RemoveHandler (UnloadEvent, value); } } public event StatusChangedEventHandler StatusChanged { add { Events.AddHandler (StatusChangedEvent, value); } remove { Events.RemoveHandler (StatusChangedEvent, value); } } public event SecurityChangedEventHandler SecurityChanged { add { Events.AddHandler (SecurityChangedEvent, value); } remove { Events.RemoveHandler (SecurityChangedEvent, value); } } public event LoadStartedEventHandler LoadStarted { add { Events.AddHandler (LoadStartedEvent, value); } remove { Events.RemoveHandler (LoadStartedEvent, value); } } public event LoadCommitedEventHandler LoadCommited { add { Events.AddHandler (LoadCommitedEvent, value); } remove { Events.RemoveHandler (LoadCommitedEvent, value); } } public event ProgressChangedEventHandler ProgressChanged { add { Events.AddHandler (ProgressChangedEvent, value); } remove { Events.RemoveHandler (ProgressChangedEvent, value); } } public event LoadFinishedEventHandler LoadFinished { add { Events.AddHandler (LoadFinishedEvent, value); } remove { Events.RemoveHandler (LoadFinishedEvent, value); } } public event ContextMenuEventHandler ContextMenuShown { add { Events.AddHandler (ContextMenuEvent, value); } remove { Events.RemoveHandler (ContextMenuEvent, value); } } public event NavigationRequestedEventHandler NavigationRequested { add { ContentListener.AddHandler (value); } remove { ContentListener.RemoveHandler (value); } } internal static object GenericEvent = new object (); internal event EventHandler Generic { add { Events.AddHandler (GenericEvent, value); } remove { Events.RemoveHandler (GenericEvent, value); } } #endregion } }