Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API to set arbitrary WebContents as devtools #11300

Merged
merged 8 commits into from Dec 5, 2017
Merged

Conversation

zcbenz
Copy link
Member

@zcbenz zcbenz commented Dec 1, 2017

Close #3177.

contents.setDevToolsWebContents(devToolsWebContents)

  • devToolsWebContents WebContents

Uses the devToolsWebContents as the target WebContents to show devtools.

The devToolsWebContents must not have done any navigation, and it should not
be used for other purposes after the call.

By default Electron manages the devtools by creating an internal WebContents
with native view, which developers have very limited control of. With the
setDevToolsWebContents method, developers can use any WebContents to show
the devtools in it, including BrowserWindow, BrowserView and <webview>
tag.

An example of showing devtools in a <webview> tag:

<html>
<head>
  <style type="text/css">
    * { margin: 0; }
    #browser { height: 70%; }
    #devtools { height: 30%; }
  </style>
</head>
<body>
  <webview id="browser" src="https://github.com"></webview>
  <webview id="devtools"></webview>
  <script>
    const browserView = document.getElementById('browser')
    const devtoolsView = document.getElementById('devtools')
    browserView.addEventListener('dom-ready', () => {
      const browser = browserView.getWebContents()
      browser.setDevToolsWebContents(devtoolsView.getWebContents())
      browser.openDevTools()
    })
  </script>
</body>
</html>

An example of showing devtools in a BrowserWindow:

const {app, BrowserWindow} = require('electron')

let win = null
let devtools = null

app.once('ready', () => {
  win = new BrowserWindow()
  win.loadURL('https://github.com')
  win.show()
  devtools = new BrowserWindow({show: false})
  devtools.show()
  win.webContents.setDevToolsWebContents(devtools.webContents)
  win.webContents.openDevTools({mode: 'detach'})
})

screen shot 2017-12-01 at 11 59 10

@zcbenz zcbenz requested review from a team December 1, 2017 03:05
@deepak1556
Copy link
Member

deepak1556 commented Dec 1, 2017

Should we trigger the destruction of external_web_contents when managed_web_contents is destroyed, so that it follows the default devtools behavior which closes when the inspected window is destroyed.

I guess this also enabled inspecting devtools window #2835 , LGTM 👍

@zcbenz
Copy link
Member Author

zcbenz commented Dec 1, 2017

Should we trigger the destruction of external_web_contents when managed_web_contents is destroyed, so that it follows the default devtools behavior which closes when the inspected window is destroyed.

The external_web_contents is usually managed by some wrapper classes like BrowserWindow or <webview>, having external_web_contents destroyed would leave the wrappers in a corrupted state. I think it is fine to have developers handle the lifetime of devtools, I'll make it clear in the docs.

@@ -1089,6 +1089,9 @@ with native view, which developers have very limited control of. With the
the devtools in it, including `BrowserWindow`, `BrowserView` and `<webview>`
tag.

Note that closing the devtools does not destory the `devToolsWebContents`, it
is caller's responsibility to close `devToolsWebContents`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zcbenz shouldn't this be:
Note that closing the devtools does not destroy the devToolsWebContents, it
is caller's responsibility to destroy devToolsWebContents.

@LeoMartinDev
Copy link

When is it available on npm ?

@zcbenz
Copy link
Member Author

zcbenz commented Dec 7, 2017

@LeoMartinDev It will be in next minor/major release, which can take some time since the master branch is not very stable yet.

@jacklovepdf
Copy link

jacklovepdf commented Jun 12, 2018

@zcbenz @MarshallOfSound
I develop a tool with electron. There are two webview components in the app. One shows the html page, another one shows the chrome devtools which debug the page. The current solution is:

const browserContents = browserView.getWebContents() // browserView--a simulator
const devtoolsContents = devtoolsView.getWebContents() //devtoolsView -- a devtools

browserContents.setDevToolsWebContents(devtoolsContents)
browserContents.openDevTools({
     detach: true
})

browserContents.debugger.attach();
browserContents.debugger.sendCommand(    // not work
          'Emulation.setTouchEmulationEnabled', 
  {
    enabled: true,
    configuration: 'mobile',
  }, function(err){
     if(err){console.log("Emulation err:", err);}
  }
);

The code above can solve the problem, but the browserContents.debugger.sendCommand does not work. So, I want to ask if there are any good ideas about how to solve this question?( I want the browserView support touch events by using browserContents.debugger.sendCommand api)

@lishoulong
Copy link

lishoulong commented Jun 12, 2018

I also encounter the same question, looking for @MarshallOfSound your help.

As I know, from chrome 63, the chrome support multiple debugger for one target, So, When we can update to support chrome 63?

https://developers.google.com/web/updates/2017/10/devtools-release-notes

@zcbenz
Copy link
Member Author

zcbenz commented Jun 17, 2018

The only work around I can think of, is to execute the command in Devtools WebContents with executeJavaScript directly:

devtoolsContents.executeJavaScript('...')

But you have to figure out which devtools JavaScript API to use.

I don't know much about the multiple debugger support of devtools, so I'm not sure if it can solve this problem.

@jacklovepdf
Copy link

thanks a lot , i have solve the problem.

@xyt0110
Copy link

xyt0110 commented Nov 26, 2018

thanks a lot , i have solve the problem.
I have the same question, how did you solved it?

@jacklovepdf
Copy link

jacklovepdf commented Dec 4, 2018

Just create a websocket server between chrome devtools and debugger server, then you can send any cmd you want;

@cyqresig
Copy link

cyqresig commented Jan 8, 2019

@jacklovepdf
can u describe how to solve the problem much more detailed?

@xyt0110
Copy link

xyt0110 commented Jan 11, 2019

thanks @jacklovepdf, I have solve the problem with electron3
1.on the main process, add this code: app.commandLine.appendSwitch('remote-debugging-port', '8400');
2.<webview id="browserView" src="about:blank" webPreferences="scrollBounce=1,enableBlinkFeatures=OverlayScrollbars" plugins></webview>
3.when the browserWebview ready:

browserView.addEventListener('dom-ready', () => {
  if (isBrowserWebviewReady) return
  isBrowserWebviewReady = true
  fetch('http://127.0.0.1:8400/json')
    .then(res => res.json())
    .then(res => {
      const target = res.find(child => child.type === 'webview' && child.url === 'about:blank')
      if (target) {
        devtoolsView.setAttribute('src', `http://127.0.0.1:8400${target.devtoolsFrontendUrl}`)
        const ws = new WebSocket(target.webSocketDebuggerUrl)
        ws.onopen = () => {
          ws.send(JSON.stringify({
            id: 1,
            method: 'Emulation.setEmitTouchEventsForMouse',
            params: {
              enabled: true,
              configuration: 'mobile'
            }
          }))
        }
        devtoolsView.addEventListener('dom-ready', () => {
          browserView.setAttribute('src', 'http://xxxx.com')
        })
      }
    })
})

@Nashorn
Copy link

Nashorn commented May 29, 2019

Hi,
there is a problem with contents.setDevToolsWebContents(devToolsWebContents) and the example screenshot above. The dev tools pane is not resizable like the default devtools allows. Any way to fix this?

@zhaomenghuan
Copy link

thanks @jacklovepdf and @xyytech,I have solve the some problem。

main.js:

app.commandLine.appendSwitch('remote-debugging-port', '8090');

renderer.js:

const baseUrl = 'http://127.0.0.1:8090';
const simulatorView = document.getElementById('simulator');
const devtoolsView = document.getElementById('devtools');
simulatorView.addEventListener('dom-ready', () => {
  fetch(`${baseUrl}/json`)
    .then(res => res.json())
    .then(res => {
      const target = res.find(child => child.type === 'webview' && child.url === simulatorView.src);
      if (target) {
      devtoolsView.setAttribute('src', `${baseUrl}${target.devtoolsFrontendUrl}`);
      const simulatorContents = simulatorView.getWebContents();
      const devtoolsContents = devtoolsView.getWebContents();
      simulatorContents.setDevToolsWebContents(devtoolsContents);
      simulatorContents.debugger.attach();
      simulatorContents.openDevTools({
        mode: 'detach'
      });
    }
  });
});

@Nashorn
Copy link

Nashorn commented Mar 3, 2021

thanks @jacklovepdf and @xyytech,I have solve the some problem。

main.js:

app.commandLine.appendSwitch('remote-debugging-port', '8090');

renderer.js:

const baseUrl = 'http://127.0.0.1:8090';
const simulatorView = document.getElementById('simulator');
const devtoolsView = document.getElementById('devtools');
simulatorView.addEventListener('dom-ready', () => {
  fetch(`${baseUrl}/json`)
    .then(res => res.json())
    .then(res => {
      const target = res.find(child => child.type === 'webview' && child.url === simulatorView.src);
      if (target) {
      devtoolsView.setAttribute('src', `${baseUrl}${target.devtoolsFrontendUrl}`);
      const simulatorContents = simulatorView.getWebContents();
      const devtoolsContents = devtoolsView.getWebContents();
      simulatorContents.setDevToolsWebContents(devtoolsContents);
      simulatorContents.debugger.attach();
      simulatorContents.openDevTools({
        mode: 'detach'
      });
    }
  });
});

Has anyone tried this solution successfully?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

can we have dockable developer tool bar for webview in atom - Browser-Plus
10 participants