How to set up a basic JBCefBrowser instance for running JavaScript?

I’m trying to improve the Markdown preview in IntelliJ IDEA Community Edition. The project uses Java and Kotlin but I want to use highlight.js which is JavaScript-based. I’ve got a workaround but it’s not great. I’m looking for a better way to run JavaScript in this environment.

Here’s what I’ve tried:

val browser = JBCefBrowser()

browser.jbCefClient.addDisplayHandler(object: CefDisplayHandlerAdapter() {
  override fun onConsoleMessage(browser: CefBrowser, level: CefSettings.LogSeverity,
    message: String, source: String, line: Int
  ): Boolean {
    println(message)
    return false
  }
}, browser.cefBrowser)

browser.executeJavaScript("console.log('Test')")

But nothing happens. No errors, just silence. The browser seems unresponsive. Does it need to be attached to a view? Or registered somewhere?

browser.cefBrowser.hasDocument() is always false which seems bad.

I feel like I’m missing some key setup step. Any ideas on how to get this JBCefBrowser working properly?

hey, have u tried loading a URL first? like browser.loadURL(‘about:blank’). That usually helps. also, wait for the page to load before running js. try this:

browser.jbCefClient.addLoadHandler(object : CefLoadHandlerAdapter() {
override fun onLoadEnd(browser: CefBrowser, frame: CefFrame, httpStatusCode: Int) {
if (frame.isMain) {
browser.executeJavaScript(‘console.log(“Test”)’, frame.url, 0)
}
}
}, browser.cefBrowser)

hope that helps!

Based on my experience with JBCefBrowser in IntelliJ plugins, there are a few crucial steps you’re missing. First, you need to load a URL into the browser, even if it’s just ‘about:blank’. This gives the browser a document to work with.

Secondly, timing is key. The browser needs time to load before executing JavaScript. I’d recommend using a load handler to ensure your script runs after the page is ready. Here’s a snippet that should help:

browser.loadURL("about:blank")
browser.jbCefClient.addLoadHandler(object : CefLoadHandlerAdapter() {
    override fun onLoadEnd(browser: CefBrowser, frame: CefFrame, httpStatusCode: Int) {
        if (frame.isMain) {
            browser.executeJavaScript("console.log('Test')", frame.url, 0)
        }
    }
}, browser.cefBrowser)

This approach should resolve the unresponsiveness you’re experiencing and allow you to execute JavaScript successfully.

I’ve worked with JBCefBrowser for JavaScript execution in IntelliJ plugins before, and there are a few key things to keep in mind. First, make sure you’re initializing the browser correctly. The browser needs a context to run in, so you should attach it to a component in your UI.

Secondly, timing is crucial. The browser needs time to load before you can execute JavaScript. I’d recommend using a load handler to ensure your script runs after the page is ready. Something like this worked for me:

browser.jbCefClient.addLoadHandler(object : CefLoadHandlerAdapter() {
    override fun onLoadEnd(browser: CefBrowser, frame: CefFrame, httpStatusCode: Int) {
        if (frame.isMain) {
            browser.executeJavaScript("console.log('Page loaded')", frame.url, 0)
        }
    }
}, browser.cefBrowser)

Also, don’t forget to load a URL into the browser, even if it’s just about:blank. This gives the browser a document to work with. Hope this helps!