Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

542 lines
15 KiB
C#

// 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) {
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
}
}