* ''Firebug.proxy.connection'' should refer to an object that is responsible for sending/receiving packets

-

* A ''connection'' should be per context since one context can be connected to a local browser and another one to a remote browser.

-

* ''firebug/lib/tool'' should be ''firebug/bti/tool''

-

-

== BTI & RDP ==

-

This section summarizes the relation between '''BTI''' (Browser Toool Interface) and '''RDP''' (Remote Debugging Protocol). The diagram below is built on top of the previous diagrams on this page (see [[#Proxy|Proxy]], [[#Connection|Connection]] and [[#JavaScriptTool|JavaScriptTool]])

-

-

Before digging deep in how the remoting concept is designed, let's see what objects (entities) are already presented in the current architecture.

-

Check out the red boxes in the diagram.

-

-

* ''NetMonitorModule'' This object is derived from ''Firebug.ActivableModule'' and represents the back-end service for Network Monitor tool (note that this object is called just ''NetMonitor'' in the current architecture).

-

* ''NetPanel'' This object is derived from ''Firebug.ActivablePanel'' and represent the front-end for Network Monitor tool.

-

* ''ScriptPanel'' Is derived from ''Firebug.ActivablePanel'' and represent the front-end for Script Debugger. The diagram doesn't show ''Debugger'' module, which represents the back-end based on JSD1. This module won't be necessary anymore since it'll be replaced by JSD2 API, JSD2 Actors and RDP (all already built-in Firefox platform).

-

* ''Context'' This is the document containing all data collected about the current page (debugged target). You can clearly notice the document-view pattern in the concept (context-panel).

-

-

The red-dashed line on the right side of the diagram shows the previous local access to the back-end services. In case of local debugging front-end and back-end are in the same process and there is no need for proxies. The rest of the diagram is about introducing these proxies.

-

-

[[image:Bti-rdp.png]]

-

-

* ''NetMonitorTool'' The ''NetPanel'' is consuming the backed service through a new object called ''NetMonitorTool''. This tool object is coming from BTI. It has the same interface as the back-end service (''INetMonitor'') and represents a ''proxy'' for it. The tool is not the only object that composes the whole proxy, there can be also a ''client''

-

* ''NetMonitorClient'' that sends proper packet types to the server and handles received packets. If the implementation of the client is too simple, it can be part of the ''tool'' itself, but the important thing is that all state data are stored in the ''context'' object. The ''tool'' object is state less just like the corresponding part on the server side, the ''module'' object.

-

* ''NetMonitorActor'' this object handles incoming packet from the client side, specifically from the ''NetMonitorClient'' object. Packet's are routed automatially and RDP ensures that packets from a ''client'' reach the corresponding ''actor''.

-

* ''Connection'' this layer ensures safe sending and receiving packets between a tool and a client.

-

* ''Server'' This object represents Firebug server side. It's mostly based on RDP server that is available in Firefox platform. However Firebug needs to be able to run as a server. Firebug running in a server mode doesn't have UI and only exposes all its services through RDP actors so, BTI tools can connect it.

-

* ''ScriptPanel'' is again consuming JSD2 API through a proxy - a ''DebuggerTool''. Since the ''DebuggerTool'' requires complicated interaction when setting breakpoints and debugging, there is whole set of clients that ensure communication with proper actors. There is typically one client per actor. State of all these clients is again stored within ''context''.

First of all, see the following diagram that explains how the Watch panel (child of the Scrip panel) is populated with data coming asynchronously from the back-and (as a set of [https://wiki.mozilla.org/Remote_Debugging_Protocol#Grips grips]) and cached on the client side.

+

The concept is based on:

+

* Viewer & Provider pattern

+

* Promise pattern

+

+

+

First of all, see the following diagram that explains how the Watch panel (child of the Scrip panel) is populated with data coming asynchronously from the back-and (as a set of [https://wiki.mozilla.org/Remote_Debugging_Protocol#Grips grips]) and cached on the client side (orange boxes represent the concept).

[[image:async-data-providers.png‎]]

[[image:async-data-providers.png‎]]

Line 146:

Line 113:

* Evaluation of custom expression in the Watch panel is not covered in this scenario, but would be implemented using same technique.

* Evaluation of custom expression in the Watch panel is not covered in this scenario, but would be implemented using same technique.

* The Watch panel is essentially a tree and so, it embeds a Tree widget based on Domplate - ''DomTree''. Set of domplate templates in this widget are responsible for HTML generation.

* The Watch panel is essentially a tree and so, it embeds a Tree widget based on Domplate - ''DomTree''. Set of domplate templates in this widget are responsible for HTML generation.

-

* The widget uses standard Provider interface to get data. The interface look like as follows:

+

* The widget (a viewer) uses standard Provider interface to get data. See more about [[Data Providers]].

* The provider uses a cache to get all objects. If an object is cached on the client side it's returned synchronously. If it isn't cached it needs to be fetched from the server and so, returns asynchronously.

* The provider uses a cache to get all objects. If an object is cached on the client side it's returned synchronously. If it isn't cached it needs to be fetched from the server and so, returns asynchronously.

+

* [http://blogs.msdn.com/b/ie/archive/2011/09/11/asynchronous-programming-in-javascript-with-promises.aspx Promise] [https://addons.mozilla.org/en-US/developers/docs/sdk/latest/packages/api-utils/promise.html object] is returned by the cache in both cases (sync and async).

* Children objects are returned immediately, in the synchronous case.

* Children objects are returned immediately, in the synchronous case.

-

* An empty array is returned if children need to be fetched from the back-end. When they are received, the Provider sends an event to the associated UI Widget. The widget needs to implement following interface.

-

-

<source lang="javascript">

-

var ProviderListener =

-

{

-

updateObject: function(object) {},

-

}

-

</source>

-

* It's responsibility of the widget to update itself and re-request the object again from the provider. The object is already cached at that point and so, returned synchronously.

* It's responsibility of the widget to update itself and re-request the object again from the provider. The object is already cached at that point and so, returned synchronously.

* Of course, the cache is part of the ''Context'' object that collects all data about the debugging target.

* Of course, the cache is part of the ''Context'' object that collects all data about the debugging target.

Connection object is responsible for sending properly setup packets to the server and handling all response packets. This object is also responsible for handling any errors (or error packets) that can occur during the communication.

Remote proxies should always use the connection object to send JSON packets

The connection to the backend is currently maintained by DebuggerClient object. This object comes from built-in dbg-client.jsm module.

Firebug also needs its server side implementation that will be used if Firebug is running in a server mode (on the remote browser). In such cases only back-end services like: NetMonitor or Debugger modules will be loaded and activated. UI overlays (i.e. browserOverlay.js) shouldn't be loaded at all since it isn't necessary and e.g. Fennec UI doesn't even have expected XUL elements to be overlayed.

Individual services should be always loaded on-demand at the time when appropriate actor is requested by the client side. For example, when the client side requests a net actor then NetMonitor module should be loaded and activated.

Only actors are registered on the server side by default

Actors are responsible for loading and activating back-end services

Extensions should be able to create and register custom actors

In order not to delay server side browser start-up time, we should delay loading of AMD modules till they are really requested by actors (e.g. the Net and Script panels don't have to be even enabled).

Firebug TabWatcher is responsible for watching browser tabs events (open, close, switch) and firing further events to make sure that Firebug UI is properly updated and showing information related to the current page.

TabWatcher is clearly a server side component and as such it also needs a proxy. In case of JSD2 some events like tabNavigate might be server by API built-in in the platform.

BTI is implementing TabWatchListener (see browser.js file), which is listening to TabWatcher and forwarding all events to Firebug infrastructure. This object should be reused or removed not duplicated.

Local TabWatcher must be disabled when Firebug is connected to a remote browser instance

Proxy to a debuggable web browser. A browser may be remote and contain one or more JavaScript execution contexts. Each JavaScript execution context may contain one or more compilation units. A browser provides notification to registered listeners describing events that occur in the browser.

WebApp represents a browsing context. Browsing context is an environment in which Document objects are presented to the user. Instance of this object is associated with top level page window (it's on the same level as the context object).

This object doesn't implement any logic it's there only to demonstrate the concept.

Describes a compilation unit in a browser context. A compilation unit may originate from a JavaScript source file or a script element in HTML. It's currently created when a new script is compiled (JSD).

One of the challenges for consuming JSD back-end API through RDP is picking the right way for asynchronous consuming of back-end data. This chapter is suggesting Asynchronous Data Providers to solve the problem.

First of all, see the following diagram that explains how the Watch panel (child of the Scrip panel) is populated with data coming asynchronously from the back-and (as a set of grips) and cached on the client side (orange boxes represent the concept).

The Watch panel update starts when a selection (or navigation) event is sent to it. It usually happens when JS execution is paused. Note that the current implementation of the panel displays the global object (window) if the execution is not paused so, it's never empty and useless.

Evaluation of custom expression in the Watch panel is not covered in this scenario, but would be implemented using same technique.

The Watch panel is essentially a tree and so, it embeds a Tree widget based on Domplate - DomTree. Set of domplate templates in this widget are responsible for HTML generation.

The widget (a viewer) uses standard Provider interface to get data. See more about Data Providers.

The provider uses a cache to get all objects. If an object is cached on the client side it's returned synchronously. If it isn't cached it needs to be fetched from the server and so, returns asynchronously.

Promiseobject is returned by the cache in both cases (sync and async).

Children objects are returned immediately, in the synchronous case.

It's responsibility of the widget to update itself and re-request the object again from the provider. The object is already cached at that point and so, returned synchronously.

Of course, the cache is part of the Context object that collects all data about the debugging target.