This topic summarizes prototyping efforts started in 2007.
This is not a plan document.
See EmbeddedBrowserPlan68 for the most recent plans.
With the advent of Web 2.0 it is obvious that a first grade support for HTML/CSS/Javascript application development is required in NetBeans IDE. One of the critical components (among others) for such a support is a first grade component that supports the current standards in HTML/CSS/Javascript. Such a component needs to be most likely available as a Java component so that it will integrate well with the Netbeans Platform and IDE. It is conceivable to develop such a component from scratch, however it will be a massive undertaking. It may require a state of the art expertise in many areas such as HTML, CSS, Javascript and windowing systems and so on... on all the platforms and OSes on which NetBeans Platform and IDE runs. As it turns out there are several browser component technologies available. For example:
Some of these are open source technologies. Out of these the XULRunner is the most promising technology as it is supported on all the platforms and OSes on which Netbeans Platform and IDE runs. Being at the heart of the very popular Firefox Browser it supports the latest HTML, CSS and Javascript standards. It is likely to do so in the future. Thus a safe horse to bet on.
It turns out that XULRunner component technology is designed to be embedded in other applications. The XULRuner Embedding API is available with multiple language bindings through the technology called XPCOM. The Java based binding to XPCOM is also available and is called JavaXPCOM. In fact, there are several projects based on XPCOM, JavaXPCOM or an abstraction layer above these for embedding XULRunner is a Java application. For example:
The first three are open source projects. The last one is a commercial product and thus is out of question or at least least preferred. That leaves us with the first three. There is an issue with these components. They are all based on embedding XULRUnner in a so called heavyweight component such as java.awt.Canvas. This is so because the embedding of XULRunner is based on the native window handle. And heavyweight components do have a native window handle. There is a problem in terms of embedding in the Netbeans Platform and IDE, because Netbeans is based on Java Swing components which are so called lightweight components. There are well known issues with respect to mixing heavyweight and lightweight components as described here. Therefore we have started investigating other approaches to embed XULRunner in a lightweight Swing component.
(AFAIK) The approach taken by the projects such as Webclient, JRex and JDIC has been to embed XULRunner inside a java.awt.Canvas. This is has been so for the want of a native window handle - which is a requirement for embedding XULRunner. However this causes problems for embedding those inside Swing components based applications. It turns out that every swing applications is ultimatley hosted in or subclasses of java.awt.Window or java.applet.Applet both of which are heavyweigh components and thus have an associated native window handle. The first approach is based on exploiting that fact. In other words making use of the native window handle of the top level heavyweight container of a Swing application to embed the XULRunner but somehow restricting the rendering of the embedded XULRunner to ther sub area that corresponds to some lightweight Swing component. It remains to be seen if such an approach could work. However if it works we think that is the most preferred approach as this approach has several advantages.
Actually it turns out this approach may not work as is. This is because the embedded XULRunner simply uses the top level window's native window handle as the parent of a native window that it creates. This native window is heavy weight. See the "Transparent window based approach" below.
I am not sure if it will work but the following needs to be tried out - by hacking the native code of XULRunner is it possible to tell it to not create it's own window but instead make it use the real estate of the native window handle of the top level window of embedding component.
This approach is based on embedding XULRunner inside an offscreen heavyweight component and copying the rendered output to the onscreen lightweight Swing component. This of course involves forwarding of coordinate translated input events from the onscreen lightweight component to the offscreen heavyweight component in which the XULRunner is embedded. This is a less preferred approach for obvious reasons however has a higher likelyhood of working because in some sense it is based on an approach that is used by remote desktop trechnologies such as VNC, Remote desktop, NetMeeting application sharing or WebEx.
This approach is basically a hybrid of the first approach and the approach taken by embedded IE project. In this approach the embedded browser window is made a child window of the top level window's native window. The embedded browser window is positioned at the same location as the embedding lightweight container where it is embedded. The size and location of the embedded browser window is updated as the size and location of the embedding lightweight container changes. The native painting of the embedded browser window is turned off and/or it's window (and it's children recursively) is(are) made transparent. When the embedding lightweight container's paint(Graphics g) method is called the embedded browser window is asked to paint itself in a BuffredImage and that BuffredImage is drawn in embedding lightweight container's graphics. With this approach no input handling is required as the embedded browser is actually there at the right location.
This approach depends on the ability to:
With this approach there is still a concern with respect to input event handling for any other lightweight components (such as drop down menus) that paint on top of embedding lightweight container. That is because even though the transparent heavyweight window will make it possible to show the other light weight components (such as drop down menus) that paint on top of embedding lightweight container it will block the input events from being received.
For the above reason we may have to try out yet another approach.
In this approach the XULRunner is embedded inside a non-modal JDialog with no decorations that is positioned exactly at the same location/size as the embedding lightweight container. The JDialog is always hidden behind the top level window of the embedding lightweight container. This ofcourse means that input event forwarding will have to be performed by the embedding lightweight container. So in effect this is similar to Off screen window based approach above. The only advantage is that because the embedded XULRunner is exactly at the same location/size as the embedding lightweight container a simple bitblit of it's window will work. We will not have to worry about the possibility of not being able to take XULRunner screenshot because it is offscreen. Moreover the mouse coordinates will also match. Thus in essence we are keeping the control of rendering as well as input event handling on the Java side of embedding.
I am proposing JDialog for embedding XULRunner because:
In fact I have already implemented such a component - which has a JDialog hosted shadow component that can track the location and size of itself at a specified (x,y) offset. Download the attached DopplegangerPanel
NetBeans project and try it. HOORAY! I got some basic input event forwarding working.
NOTE: The form submission does/may not work in JEditorPane if it is invoked using javascript. Therefore Google Search will not work. Only hyperlinks work.
We have been able to get the embedded XULRunner working - only the rendering part - and only on windows. Next step is to implement input event forwarding for XULRunner. This will have to be done at native level.
The window on the top is showing the embedding lightweight panel inside a NetBeans RCP which is using the lightweight rendering as evident from the overlapping Dropdown Menu. The window at the bottom, without any window decorations is the actual Webclient based embedded XULRunner in a model less decorationless JDialog. In the real implementation this window will not be visible to the user. Instead it will be always behind the embedding application window. It is being shown here for debugging purposes only.
It has been pointed out or observed that this approach may run into several issues:
This is yet another approach we are trying. In fact the following zip implements this approach:
In this approach the XULRunner is embedded in an undecorated non-modal dialog (just like the previous approach). This dialog is behind the main application window at exactly the same location and of same size of the embedding lightweight container. So far this is same as the last approach. The only difference is that as soon as the user clicks in the embedding lightweight container the dialog is brought to the front and the mouse event is forwarded to it. A similar thing happens when the embedding lightweight container gains the focus due to tabbing. (that is the reason the input events also work in this approach). Then, the XULRunner continues to handle the input events until such time that the user clicks elsewhere e.g. user clicks on a help menu. Then the XULRunner dialog is pushed back again. Now the lightweight drop down menu works correctly as the heavyweight XULRunner dialog is out of the way again. There is a little bit of flicker when the dialog moves to the front and back. Another drawback with this approach is that as the heavy weight XULRunner is in front when the user is interacting with it - the transparent component based editing layer may not work. However if the transparent editing layer is going to handle all the input events then we could leave the XULRunner dialog in the back. Some of the issues of cursor image management do apply to this approach also. Some of these issues could be solved by detecting the cursor position and querying the DOM to see if the cursor is over a hyperlink and change the cursor accordingly to Hand cursor. Another issue will be how to make the key board accelerators for menu and other actions (e.g. switching multiview tabs) as well as menu item mnemonic work when the dialog is in the front. Yet another issue will be how the bringing to front interacts with other non-modal children of main window.
Here is a screen shot of the running NetBeans RCP. It also shows the DOM in a tree view. It must be noted that the DOM was obtained using direct Java API (in this case Webclient) and can be programmatically manipulated.
visualweb.next.embeddedxulrunnnerplusfirefox.pdf
Here is the list of Phobos Debugger APIs:
Here is the list of XULRUnner Debugger APIs:
XULRunner Javascript Debugger API
Even from the names you can tell some of them are analogous.
Webclient needs to expose the second set as Java API through Webclient's BrowserControl.
Then basically we have to adapt (wrap) those set of classes into the first set if we want to make use of the work done by Phobos team for plugging into NetBeans debugger infrastructure. That implementation is here:
Phobos Javascript Debugger integration into NetBeans IDE
Ed Burns is working on accessing the Firebug debugger interface using Java XPCOM. Once he has that in place he will wrap it in Phobos debugger API so that it will be easily integrated into NetBeans debugger UI.
Ed Burns is trying out Sandip's HWND idea on webclient. You can read about it at http://developer.mozilla.org/en/docs/Webclient_Roadmap
EmbeddedBrowserMeeting10172007
EmbeddedBrowserMeeting10182007
During the discussions in this meeting with AWT team members Oleg and Artem, we learned that JDK7 in fact has a multiplatform (Windows, Linux and Solaris) solution for mixing heavyweight and lightweight components. We tried it and it works. I have built the RCP zip
for you to try. Just download the following RCP zip
, download the JDK7 (build b22 and above) and try the RCP using the --jdkhome command line option. This is the real deal - there is no separate window hosting the XULRunner. The XULRunner is actually embedded in NetBeans RCP. According to Oleg it should be possible to port it back to JDK 6 also.
| Link | Description |
|---|---|
| Javascript Debugger Interface | Interface for listening to Javascript debugging |
| All XPCOM | All frozen XPCOM interfaces |
| XULRunner/Webclient Build instructions | We must use these instructions |
| XULRunner download | XULRunner binaries for various platforms |
| irc://irc.mozilla.org/xulrunner | IRC Channel for XULRunner |
Venkman Javascript Debgugger Guide
| Priority | Task | Description | Confirmed |
| P1 | 1.1 | Windows XP, Windows Vista, Linux (versions?) , Mac 10.4, 10.5, Solaris 10 | |
| P1 | 1.2 | Source license compatible with CDDL & GPLv2 with ClassPath Exception | |
| P1 | 1.3 | Ant-based build structure for generating XulRunner & MozSwing binaries from source | |
| P1 | 1.4 | Resolve event loop issues on Linux [1][4] | |
| P1 | 1.5 | API to determine which element(s) (node(s)) correspond(s) to certain point on canvas, and vice versa, i.e the locations of the generated boxes for a specific element | Yes, it can be delivered [2] |
| P1 | 1.6 | Ability to control the user events, e.g. if the user clicks on a link, need to be able to be notified BEFORE the event is processed and also be able to decide whether the event will be processed or not (the actual follow of the link in this case) | Yes, it can be delivered [2] |
| P1 | 1.7 | Ability to attach the component to the WebBrowser before it is displayed, retrieve its modifiable document, be able to alter it, and just after then add (to the UI) and display the component | Yes, it can be delivered |
| P1 | 1.8 | Ability to maintain the same instance of the document across changes in the UI hierarchy [3] | Yes, it can be delivered |
| p1 | 1.9 | Ability to specify base URL to obtained DOM, so that relative URL can be resolved (See UseCase #1) | |
| P1 | 1.10 | API to parse URL and get DOM with out need to open Window [3] (See UseCase #2) | |
| p1 | 1.11 | Ability to set "user data" to the DOM node (See UseCase #3) | |
| P2 | 2.1 | Ability to build MozSwing on XulRunner binaries | |
| p2 | 2.2 | Ability to access underlying JavaXPCOM API via Mozswing API (See UseCase #4) |
| DopplegangerPanel.zip | ![]() |
13165 bytes |
| Embedded XULRunner.png | ![]() |
64783 bytes |
| EmbeddedBrowserAPI.zip | ![]() |
22660250 bytes |
| EmbeddedBrowserSuite.zip | ![]() |
50858194 bytes |
| Firebug.png | ![]() |
119806 bytes |
| Integrated.png | ![]() |
155873 bytes |
| MozSwing datasheet.pdf | ![]() |
508908 bytes |
| NetBeansEmbeddedXULRunnerWithFirebug.png | ![]() |
126081 bytes |
| embeddedbrowserrcpsuite.zip | ![]() |
12047686 bytes |
| embeddedbrowserrcpsuiteJDK7.zip | ![]() |
16827456 bytes |
| embeddedbrowsersuite.zip | ![]() |
13021860 bytes |
| embeddedxulrunner.jpg | ![]() |
83272 bytes |
| embeddedxulrunnerfrontback.jpg | ![]() |
65093 bytes |
| visualweb.next.embeddedxulrunnnerplusfirefox.pdf | ![]() |
124364 bytes |