LiveReload

Automatic page reloading in browser

Author: Denis Anisimov
Version: draft 0.0.1

Disclaimer: The content of this NetBeans development wiki page is intended for pre-planning purposes ONLY. The development, release, and timing of any feature or functionality described here should not be treated as final, and is subject to change at any time at the sole discretion of Oracle. For information about NetBeans software releases please visit the NetBeans Roadmap or the NetBeans Release Planning wiki.

Purpose: refresh-on-save feature for web pages. Very useful in case user has two monitors. The page could be automatically refreshed in the browser on the other monitor after saving the file in the IDE shown on the other monitor.

Implementation suggestion: browser plugin which communicates with NB via network. NB asks the plugin to refresh appropriate browser tab.

There are number of already available similar functionalities. All of them requires some browser plugin and OS side FS monitor. See f.e. http://xrefresh.binaryage.com/ and http://livereload.com/.

LiveReload has separate browser extensions part which can be reused with custom server that monitors local files. See http://help.livereload.com/kb/general-use/browser-extensions. These extensions could be installed into the browser from IDE ( if not yet installed ). They communicate with local FS monitor server via WebSocket LiveReload protocol. See http://help.livereload.com/kb/ecosystem/livereload-protocol. NB could implement WebSocket server with LiveReload protocol support and send commands to the plugin for reloading.

Current knowledge : LiveReload cannot be used for our purposes. Fist of all it requires "enabling" on each tab where reload is supposed. So user needs to perform special action ( press toggle button in the add-on browser tab ) for EACH tab where he expects reloading. So instead of automatic association some file inside NB with browser tab (that's requested functionality) LiveReload reassign this task to the user. The second problem is sending "reload" request for all tabs where LiveReload is enabled. It uses "path" (as reload command attribute) to find "referenced" sub-resource in the reloaded tab ( f.e. only stylesheets could be reloaded to avoid full page reloading ). So it is intended actually reload single page (inside one dedicated tab) with partial reloading feature. This is not what we want. So LiveReload cannot be used and it is out of question.

Xrefresh is old (it is superseded by LiveReload ) and requires FireBug add-on for its work. Probably it also has limited functionality around the single tab.

As result current suggestion is custom browser plugin. It is not clear how it should exactly works actually. There are two approaches :

  • map local file opened in the IDE with URL in the opened browser tab.
  • browser remembers tab, that was open after initial action and IDE can refresh the tab via communication with browser plugin .

The first approach has advantage to eliminate involving "Run" and other actions ( which context could be out of local file ) to IDE<->browser plugin communication. So the reload action will reload tab based on local file and some additional project information if any. But it has a number of disadvantages. The most obvious is tricky way to identify local file(s) with remote URL.

The second approach require involving special IDE browser related actions (like "Run") at the initial stage of open file. At the same time IDE<->browser communication should work also each time of file change. It is also not clear how browser tab could be associated with local file: open file request is not synchronous. Browser is executed as a different process. So it is possible that user ( or other application ) opens absolutely different unrelated URL in new tab in the interval between IDE request for open ( "Run" f.e. ) and when tab will be really opened. So this approach is also not so straight. Probably some mixed approach should be chosen : associate file with tab but this association should care about all opened tab in the interval of requesting. Try to find appropriate tab based on the file and project information in case there are multiple tabs was opened .

Current prototype: two modules web.common and web.project are affected . The first one contains custom WebSocket server implementation and an entry point class BrowserReload for browser plugin communication.

BrowserReload is used from ant task "nbbregister" which should be called before "nbbrowse" task ( or other url browser opening task ). "nbbregister" task store association with file on the local filesystem and requested URL to open ( url-> local file ). The URL could be modified (with some nb identifier) before opening it in the browser.

Browser plugin should send WebSocket handshake to the server (that is implemented on the IDE side) on each URL opening in the new tab. Other option: send WebSocket handshake only for URLs with some special (nb) identifier (handshake should contain requested URL) . In case if server accept connection and replies on handshake tab becomes associated as WebSocket client with original file on the local filesystem. If server refuses WebSocket connection (closes connection, there is not such URL associated with local file on the IDE side) browser plugin mark the tab just out of functionality. So each tab that has been opened from the IDE have network WebSocket and should uses commands gotten from the socket to reload this tab (only this tab). As result there is no need to perform search against all opened tabs in the browser. We have local file <-> browser tab mapping via WebSocket.

web.project module is modified in order to initialize ant properties with local file path and url to open on "Run" action. build-impl.xml script is also modified with nbbregister task to call.

Reload is performed as separated client via BrowserReload.reload() method. Client calls it with local file as argument. Currently WebProject class is modified with changes in the inner CopyOnSaveSupport class. In case when "deploy on save" feature is enabled BrowserReload.reload() is called on file modification. BrowserReload.reload() implementation check the presence of the file in its "file->web socket" mapping and send the reload command if socket exists.

Described prototype is inside easel_css_72 branch and has no "application layer protocol" implemented. It means that IDE<->browser plugin language is not yet defined so IDE WebSocket server doesn't have handshake and send command format handling implementation. This protocol should be defined.

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo