Reputation:
For my eclipse plugin I want to track every URL that is opened with the internal (and if possible also external) Eclipse browser.
So far I use
org.eclipse.swt.browser.Browser;
and
addLocationListener(...)
But I would prefer that it works also for the internal Eclipse browser. How can I achieve that?
Upvotes: 1
Views: 1177
Reputation: 5310
One possible solution for the Eclipse Internal Browser would be to create an eclipse plugin that registers an IStartup extension. In your earlyStartup() method you would register an IPartListener on the workbenchPage. Then when the internal browser part is created, you will receive a callback with a reference to the WebBrowserEditor (or WebBrowserView). Since there is no direct API you will have to hack a bit and use reflection to grab the internal SWT Browser instance. Once you have that, you can add your location listener.
Sometimes during early startup there is no active Workbench window yet so you have to loop through all existing workbench windows (usually just one) and each of their workbench pages to add part listeners also.
Here is the snippet of code for the earlyStartup() routine. Note that I have omitted any cleanup of listeners during dispose for windows/pages so that still needs to be done.
//Add this code to an IStartup.earlyStartup() method
final IPartListener partListener = new IPartListener() {
@Override
public void partOpened(IWorkbenchPart part) {
if (part instanceof WebBrowserEditor)
{
WebBrowserEditor editor = (WebBrowserEditor) part;
try {
Field webBrowser = editor.getClass().getDeclaredField("webBrowser");
webBrowser.setAccessible(true);
BrowserViewer viewer = (BrowserViewer)webBrowser.get(editor);
Field browser = viewer.getClass().getDeclaredField("browser");
browser.setAccessible(true);
Browser swtBrowser = (Browser) browser.get(viewer);
swtBrowser.addLocationListener(new LocationListener() {
@Override
public void changed(LocationEvent event) {
System.out.println(event.location);
}
});
} catch (Exception e) {
}
}
else if (part instanceof WebBrowserView)
{
WebBrowserView view = (WebBrowserView) part;
try {
Field webBrowser = editor.getClass().getDeclaredField("viewer");
webBrowser.setAccessible(true);
BrowserViewer viewer = (BrowserViewer)webBrowser.get(view);
Field browser = viewer.getClass().getDeclaredField("browser");
browser.setAccessible(true);
Browser swtBrowser = (Browser) browser.get(viewer);
swtBrowser.addLocationListener(new LocationListener() {
@Override
public void changed(LocationEvent event) {
System.out.println(event.location);
}
});
} catch (Exception e) {
}
}
}
...
};
final IPageListener pageListener = new IPageListener() {
@Override
public void pageOpened(IWorkbenchPage page) {
page.addPartListener(partListener);
}
...
};
final IWindowListener windowListener = new IWindowListener() {
@Override
public void windowOpened(IWorkbenchWindow window) {
window.addPageListener(pageListener);
}
...
};
IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (activeWindow != null)
{
IWorkbenchPage activePage = activeWindow.getActivePage();
if (activePage != null)
{
activePage.addPartListener(partListener);
}
else
{
activeWindow.addPageListener(pageListener);
}
}
else
{
for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows())
{
for (IWorkbenchPage page : window.getPages()) {
page.addPartListener(partListener);
}
window.addPageListener(pageListener);
}
PlatformUI.getWorkbench().addWindowListener(windowListener);
}
One last detail about this code snippet is that it requires a dependency on the org.eclipse.ui.browser plugin to have access to the WebBrowserEditor class.
Upvotes: 2