Example #1
0
        public override void AttachEvent(string handler)
        {
            switch (handler)
            {
            case WebView.DocumentLoadedEvent:
                this.Control.FinishedLoad += delegate(object sender, MonoMac.WebKit.WebFrameEventArgs e) {
                    Widget.OnDocumentLoaded(new WebViewLoadedEventArgs(this.Url));
                };
                break;

            case WebView.DocumentLoadingEvent:
                this.Control.DecidePolicyForNavigation += (sender, e) => {
                    var args = new WebViewLoadingEventArgs(new Uri(e.Request.Url.AbsoluteString), e.Frame == Control.MainFrame);
                    Widget.OnDocumentLoading(args);
                    if (args.Cancel)
                    {
                        e.DecisionToken.PerformSelector(new Selector("ignore"), null, 0);
                    }
                    else
                    {
                        e.DecisionToken.PerformSelector(new Selector("use"), null, 0);
                    }
                };
                break;

            case WebView.OpenNewWindowEvent:
                this.Control.UICreateWebView = new MonoMac.WebKit.CreateWebViewFromRequest((sender, e) => {
                    newWindowHandler = new NewWindowHandler {
                        Handler = this
                    };
                    return(newWindowHandler.WebView);
                });
                this.Control.DecidePolicyForNewWindow += (sender, e) => {
                    var args = new WebViewNewWindowEventArgs(new Uri(e.Request.Url.AbsoluteString), e.NewFrameName);
                    Widget.OnOpenNewWindow(args);
                    if (!args.Cancel)
                    {
                        NSWorkspace.SharedWorkspace.OpenUrl(e.Request.Url);
                    }
                    e.DecisionToken.PerformSelector(new Selector("ignore"), null, 0);
                };
                break;

            case WebView.DocumentTitleChangedEvent:
                this.Control.ReceivedTitle += delegate(object sender, MonoMac.WebKit.WebFrameTitleEventArgs e) {
                    Widget.OnDocumentTitleChanged(new WebViewTitleEventArgs(e.Title));
                };
                break;

            default:
                base.AttachEvent(handler);
                break;
            }
        }
Example #2
0
        /**
         * Sets up a new native browser.
         * If newBrowserId is zero, allocates a new browser and sets it up.
         * If newBrowserId is nonzero, takes ownership of that allocated browser and sets it up.
         */
        private void RequestNativeBrowser(int newBrowserId = 0)
        {
            if (browserId != 0 || browserIdRequested)
            {
                return;
            }

            browserIdRequested = true;

            try {
                BrowserNative.LoadNative();
            } catch {
                gameObject.SetActive(false);
                throw;
            }

            int newId;

            if (newBrowserId == 0)
            {
                var settings = new BrowserNative.ZFBSettings()
                {
                    bgR       = backgroundColor.r,
                    bgG       = backgroundColor.g,
                    bgB       = backgroundColor.b,
                    bgA       = backgroundColor.a,
                    offscreen = 1,
                };
                newId = BrowserNative.zfb_createBrowser(settings);
            }
            else
            {
                newId = newBrowserId;
            }

            unsafeBrowserId = newId;

            //Debug.Log("Requested browser for " + name + " " + newId);

            //We have a native browser, but it is invalid to do anything with it until it's ready.
            //Therefore, we don't set browserId until it's ready.

            //But we will put all our callbacks in place.

            //Don't let our remember list get destroyed until we are ready for that.
            lock (allThingsToRemember) allThingsToRemember[newId] = thingsToRemember;

            BrowserNative.ForwardJSCallFunc forwardCall = (bId, id, data, size) => {
                lock (thingsToDo) thingsToDo.Add(() => {
                        if (id < 0 || id >= registeredCallbacks.Count)
                        {
                            Debug.LogWarning("Got a JS callback for event " + id + ", but no such event is registered.");
                            return;
                        }

                        try {
                            var node = JSONNode.Parse(data);
                            registeredCallbacks[id](node);
                        } catch (SerializationException) {
                            Debug.LogWarning("Invalid JSON sent from browser: " + data);
                        }
                    });
            };
            thingsToRemember.Add(forwardCall);
            BrowserNative.zfb_registerJSCallback(newId, forwardCall);


            BrowserNative.ChangeFunc changeCall = (id, type, arg1) => {
                //(Note: we may have been Object.Destroy'd at this point, so guard against that.)

                if (type == BrowserNative.ChangeType.CHT_BROWSER_CLOSE)
                {
                    //We can't continue if the browser is closed, so goodbye.

                    //At this point, we may or may not be destroyed, but if not, become destroyed.
                    //Debug.Log("Got close notification for " + unsafeBrowserId);
                    if (this)
                    {
                        //Need to be destroyed.
                        lock (thingsToDo) thingsToDo.Add(() => {
                                Destroy(gameObject);
                            });
                    }
                    else
                    {
                        //If we are (Unity) destroyed, we won't get another update, so we can't rely on thingsToDo
                        //That said, there's not anything else for us to do but step out of allThingsToRemember.
                    }

                    //The native side has acknowledged it's done, now we can finally let the native trampolines be GC'd
                    lock (allThingsToRemember) {
                        allThingsToRemember.Remove(unsafeBrowserId);
                    }

                    //Just in case someone tries to call something, make sure CheckSanity and such fail.
                    browserId = 0;
                }
                else if (this)
                {
                    lock (thingsToDo) thingsToDo.Add(() => OnItemChange(type, arg1));
                }
            };
            thingsToRemember.Add(changeCall);
            BrowserNative.zfb_registerChangeCallback(newId, changeCall);

            BrowserNative.DisplayDialogFunc dialogCall = (id, type, text, promptText, url) => {
                lock (thingsToDo) thingsToDo.Add(() => {
                        CreateDialogHandler();
                        dialogHandler.HandleDialog(type, text, promptText);
                    });
            };
            thingsToRemember.Add(dialogCall);
            BrowserNative.zfb_registerDialogCallback(newId, dialogCall);

            BrowserNative.ShowContextMenuFunc contextCall = (id, json, x, y, origin) => {
                if (json != null && (allowContextMenuOn & origin) == 0)
                {
                    //ignore this
                    BrowserNative.zfb_sendContextMenuResults(browserId, -1);
                    return;
                }

                lock (thingsToDo) thingsToDo.Add(() => {
                        if (json != null)
                        {
                            CreateDialogHandler();
                        }
                        if (dialogHandler != null)
                        {
                            dialogHandler.HandleContextMenu(json, x, y);
                        }
                    });
            };
            thingsToRemember.Add(contextCall);
            BrowserNative.zfb_registerContextMenuCallback(newId, contextCall);

            BrowserNative.NewWindowFunc popupCall = (int id, IntPtr urlPtr, bool userInvoked, int possibleId, ref BrowserNative.ZFBSettings possibleSettings) => {
                if (!userInvoked)
                {
                    return(BrowserNative.NewWindowAction.NWA_IGNORE);
                }

                switch (newWindowAction)
                {
                default:
                case NewWindowAction.Ignore:
                    return(BrowserNative.NewWindowAction.NWA_IGNORE);

                case NewWindowAction.Redirect:
                    return(BrowserNative.NewWindowAction.NWA_REDIRECT);

                case NewWindowAction.NewBrowser:
                    if (NewWindowHandler != null)
                    {
                        possibleSettings.bgR = backgroundColor.r;
                        possibleSettings.bgG = backgroundColor.g;
                        possibleSettings.bgB = backgroundColor.b;
                        possibleSettings.bgA = backgroundColor.a;

                        lock (thingsToDo) {
                            thingsToDo.Add(() => {
                                var newBrowser = NewWindowHandler.CreateBrowser(this);
                                newBrowser.RequestNativeBrowser(possibleId);
                            });
                            return(BrowserNative.NewWindowAction.NWA_NEW_BROWSER);
                        }
                    }
                    else
                    {
                        Debug.LogError("Missing NewWindowHandler, can't open new window", this);
                        return(BrowserNative.NewWindowAction.NWA_IGNORE);
                    }

                case NewWindowAction.NewWindow:
                    return(BrowserNative.NewWindowAction.NWA_NEW_WINDOW);
                }
            };
            thingsToRemember.Add(popupCall);
            BrowserNative.zfb_registerPopupCallback(newId, popupCall);

            BrowserNative.ConsoleFunc consoleCall = (id, message, source, line) => {
                lock (thingsToDo) thingsToDo.Add(() => {
                        onConsoleMessage(message, source + ":" + line);
                    });
            };
            thingsToRemember.Add(consoleCall);
            BrowserNative.zfb_registerConsoleCallback(newId, consoleCall);


            BrowserNative.ReadyFunc readyCall = id => {
                Assert.AreEqual(newId, id);
                //We could be on any thread at this time, so schedule the callbacks to fire during the next InputUpdate
                lock (thingsToDo) thingsToDo.Add(() => {
                        browserId = newId;

                        // ReSharper disable once PossibleNullReferenceException
                        onNativeReady(browserId);
                    });
            };
            thingsToRemember.Add(readyCall);
            BrowserNative.zfb_setReadyCallback(newId, readyCall);
        }