using System.Windows.Browser; using System.Windows; using System.Windows.Controls; using System.Collections.Generic; using System; using System.Windows.Media; namespace Blois.Utils { public class ContextMenuEventArgs : BubblingEventArgs { private Point pluginPosition; public ContextMenuEventArgs(Point pluginPosition, object source) : base(source) { this.pluginPosition = pluginPosition; } public Point GetPosition(UIElement element) { GeneralTransform transform = element.TransformToVisual((UIElement)Application.Current.RootVisual); return transform.Transform(this.pluginPosition); } } /// /// Need to add the context menu handler onto document for Firefox support /// Need to add plugin blocker over the div for Firefox support to block SL control from displaying it's context menu /// /// [ScriptableType] public class ContextMenuGenerator { public static readonly BubblingEvent ContextMenuEvent = new BubblingEvent("ContextMenu", RoutingStrategy.Bubble); private static ContextMenuGenerator helper = new ContextMenuGenerator(); private HtmlElement pluginBlocker; private ContextMenuGenerator() { HtmlPage.RegisterScriptableObject("RightMouseClickWorker", this); this.pluginBlocker = HtmlPage.Document.CreateElement("div"); this.pluginBlocker.SetStyleAttribute("width", "100%"); this.pluginBlocker.SetStyleAttribute("height", "100%"); this.pluginBlocker.SetStyleAttribute("position", "absolute"); this.pluginBlocker.SetStyleAttribute("top", "0px"); this.pluginBlocker.SetStyleAttribute("left", "0px"); this.pluginBlocker.SetStyleAttribute("zIndex", "100"); this.pluginBlocker.SetStyleAttribute("display", "none"); HtmlPage.Plugin.Parent.AppendChild(this.pluginBlocker); ScriptObject delegateCreator = (ScriptObject)HtmlPage.Window.Eval(ContextMenuGenerator.mouseHelperScript); delegateCreator.Invoke("createCallback", HtmlPage.Plugin); HtmlPage.Document.AttachEvent("oncontextmenu", this.OnContextMenu); } [ScriptableMember] public void OnGeckoMouse(ScriptObject e) { int button = (int)(double)e.GetProperty("button"); if (button == 2) { if (e.GetProperty("stopPropagation") != null) e.Invoke("stopPropagation"); if (e.GetProperty("preventDefault") != null) e.Invoke("preventDefault"); this.pluginBlocker.SetStyleAttribute("display", ""); } } private void OnContextMenu(object sender, HtmlEventArgs e) { this.pluginBlocker.SetStyleAttribute("display", "none"); UIElement rootVisual = (UIElement)Application.Current.RootVisual; UIElement firstElement = null; foreach (UIElement element in rootVisual.HitTest(new Point(e.OffsetX, e.OffsetY))) { firstElement = element; break; } if (firstElement != null) { e.PreventDefault(); FrameworkElement source = (FrameworkElement)firstElement; ContextMenuGenerator.ContextMenuEvent.RaiseEvent(new ContextMenuEventArgs(new Point(e.OffsetX, e.OffsetY), source), source); } } private const string mouseHelperScript = @"({ createCallback: function(plugin) { if (window.addEventListener) { var pluginReference = plugin; window.addEventListener( 'mousedown', function(ev) { pluginReference.content.RightMouseClickWorker.OnGeckoMouse(ev); return true; }, true ); } } });"; } }