6

I am loading a particular url

For eg.

webview.loadUrl("some.domain.com")

Afterwords I am redirecting it to some other domain and then coming back to my domain. Then I try to close the window in my javascript (window.close()). I get the below error while debugging remotely on chrome developer tools

Scripts may close only the windows that were opened by it.

I am getting the above error even though I am on the same domain with which I opened it.

Any help would be very much appreciated. Thank you.

Binary Baba
  • 1,953
  • 2
  • 16
  • 23

1 Answers1

11

This answer will be from Android App Developer perspective. I hope it will help someone.

The problem was very similar for me: I was opening a web site via webview, and some of the links were opening in a new window. The thing is that webview cannot work with web windows out of the box. I mean, it can be possible, but not as expected (in my case, when a link was opened in a separate window from javascript perspective, it were overriding previously opened page, and cannot be closed with a window.close() from javascript, which eventually were causing a state loss on a previous page).

So the task in my case was to open a single link in a window and go back to previous page without any state loss. That was my solution. I had two separate WebViews - one as a main one, and one for links in window. To be able to react on a "link in new window" event, I'll configured main webView with this code:

    webView.settings.javaScriptEnabled = true
    webView.settings.javaScriptCanOpenWindowsAutomatically = true
    webView.settings.setSupportMultipleWindows(true)

    webView.webChromeClient = object : WebChromeClient() {

    override fun onCreateWindow(view: WebView?, isDialog: Boolean, isUserGesture: Boolean,
                                resultMsg: Message?): Boolean {
        handleCreateWebWindowRequest(resultMsg)
        return true
    }
}

We need only onCreateWindow callback to override in main webView chrome client, since it will only open new windows. And also allow a multiwindow support in webView.settings. When an onCreateWindow callback triggers, do the following:

@SuppressLint("SetJavaScriptEnabled")
override fun handleCreateWebWindowRequest(resultMsg: Message?) {
    if (resultMsg == null) return
    if (resultMsg.obj != null && resultMsg.obj is WebView.WebViewTransport) 
        {
        val transport = resultMsg.obj as WebView.WebViewTransport
        windowWebView = WebView(this)
        windowWebView?.layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, 
        ViewGroup.LayoutParams.MATCH_PARENT)

        windowWebView?.settings?.javaScriptEnabled = true
        windowWebView?.settings?.javaScriptCanOpenWindowsAutomatically = true
        windowWebView?.settings?.setSupportMultipleWindows(true)
        windowWebView?.webViewClient = WebViewClient()
        windowWebView?.webChromeClient = object : WebChromeClient() {
            override fun onCloseWindow(window: WebView?) {
                super.onCloseWindow(window)
                handleCloseWebWindowRequest()
            }
        }

        container.addView(windowWebView)
        webView.visibility = View.GONE
        transport.webView = windowWebView
        resultMsg.sendToTarget()
    }
}

Basically we're sending this (create window) request to a separate webView. In it we should also allow a multiwindow support and attach a chrome client, in wich we should listen only onCloseWindow event, since this webView should behave as a window. When onCloseWindow triggers, we're just closing (hiding/removing) webView that should act as a window, and returning to the main one. Here isWebWindowOpened method call just checks if the windowWebView is not null and visible.

private fun handleCloseWebWindowRequest() {
    if (!isWebWindowOpened()) return

    container.removeView(windowWebView)
    webView.visibility = View.VISIBLE
    windowWebView = null
}

The only thing I can mention, is that when a windowWebView is opened, onBackPressed action should close it calling handleCloseWebWindowRequest.

Demigod
  • 5,073
  • 3
  • 31
  • 49