Accessing objects defined in main addon script from content and page scripts in Firefox addons - firefox

I am making bootstrapped extension for Firefox (actually, trying to port working Chrome extension).
In Chrome it was:
Background page holds backgroundApp which is an instance of Marionette.Application and its modules hold Backbone models of data and do storage and sync stuff.
Popup page holds popupApp which is another instance of Marionette.Application and its modules take care of UI with views and routers defined in them. To get data, popup uses reference to backgroundApp accessed via chrome.extension.getBackgroundPage().
Now I am having a really hard time finding how I can pass models to popup panel code in Firefox, all messaging mechanisms I've encountered so far only take JSONable data.

You will have no joy if you're trying to use javascript frameworks in firefox addons. At least if you're using them beyond the scope of a single window object.
There are multiple different, fairly isolated environments in which scripts run. If we take e10s (multi-process firefox) into consideration then the addon main code will run in the parent process while anything that interacts with page content will run in the content process(es).
Message-passing is the only way to interact between those environments, and while it is possible to have remote proxies for complex objects those cause some considerable performance penalty and their usage is discouraged.
So you can have your backbone/marionette stuff run in a panel or in an invisible page (that's what the background page API does?) but if you want to have them communicate with each other you will have to get your data into some serialiazable shape.
Depending on your needs it might be sufficient if you implement copy constructors for your models. I.e. constructors which optionally take plain javascript objects (bags of values) and re-create the properly typed models from that. This requires that the objects can be fully reconstructed based on their enumerable own-properties.

Related

Angularjs and MDI SPA application with many tabs

We have to implement multiple-document-interface web application. Each document has to live in a separate tab (but on the same page, it has to be SPA). There may be up to 50 opened tabs simultaneously and application should give ability to group tab panes by modules.
One of our options were to use AngularJS for this task. We like the way Angular handles partial views, structures application by using modules/controllers and performs dependency injection.
After digging in for couple of days, we've figured out that there may be some problems with the way bindings work: there is no easy way to prevent angular from watching tabs, which contents are not currently displayed to the user. You can imagine situation when user will have around 20 opened tabs and this whole thing becomes slow as hell! Also our application is very grid-heavy, so for grids I think we should avoid ng bindings at all.
We were thinking about ng-view and the way it recreates DOM on each activation ... this looks overkill and will force us to put all UI state into the view-models, even for scroll-bars :)
Can you suggest some possible ways to improve performance with Angular and MDI? Maybe we should even consider using some other ui-framework/set of tools to achieve same results?
What's important:
modularity (AMD)
dependency injection
declarative bindings (we do like how angular and knockout solved those problems)
MVVM/MVC
ability to create multiple instances of the same controller (open multiple "details" tabs for each specific item from the grid, for example)
modularity - Angular has it's own modularity rules/patterns which are good if you want to conform to them, but if you want to make something modular in a different way, eg... allow forms to be self contained so that multiple instances of them can dynamically be opened concurrently it's quite difficult
dependency injection - Angular allows you to write code that you can inject other into, but you cannot inject Angular, it seems an oversight that you cannot test your code isolated from Angulars?
declarative bindings - yep, the way Angular binds literals within HTML with the JS code makes it really hard to create MDIs with multiple concurrent instances of a single form. You really need to dynamically create your form instances with their own identifiers (in addition to Angulars) then scope your own identifiers within the bounds of a shared set of JS files (which is what you want), however then Angular's binding will get in the way of each instance if you continue to use Angular's bindings - alternatively you can try modify the HTML dynamically get Angular to refresh it's bindings.
Basically anything to do with MDI is harder than it needs to be with Angular and it's worth looking at alternatives for such projects before hand.
AngularJS can indeed be heavy on a big application, but only when you make a change inside the $scope. The bigger part of this time is spent looking for modification by dirty checking.
If you keep an AngularJS application inside a non active tab, a dirty checking can only happen after a outside event (like a WebSocket message). You can optimize your application to remove those listener when the tab is not focused.
If you follow the best practice of AngularJS, performance issues with a lot of pages opened should not be a problem. The bigger performance problem of AngularJS come with very big amount of data inside its $scope, but there is a lot of solutions proposed all over the internet.

CanJS multiple page app

The tutorials and example I've seen are all single page application.
Can anyone give an idea or point to a resource showing how a multiple page app can be developed with CanJS?
You should be able to create a new page in whatever app framework you are using or even just static pages, and then hookup your new control and view to any element on that new page.
You want to have a separate control for each module, so you might have separate controls even on a single page if you have, for example, a filterable dropdown list, a todo list, and a login. So, in your canjs directory for your app you will have separate sub-directories for each module which will contain your control, view/s, model/s, and observe/s and unit tests. This makes them re-usable, easier to test, and since they are modular if one part of your app breaks it won't take down all functionality. Once you get the hang of that incorporate AMD style loading of your assets with stealJS which is made by Bitovi - the CanJS creators.
https://github.com/bitovi/steal
If you want to manipulate the location.hash without actually changing pages or manaage browser history and client state you should check out can.route:
http://canjs.com/docs/can.route.html

When to use more than one Sammy.js application?

As I'm learning about Sammy.js I read that you can have several Sammy.js applications in the same page, each bound to a different element (i.e. div). I would like to understand why would this be useful.
I read in another post that only forms inside a bound element will trigger the route change, I'm thinking this could be used to modularize your application. Is there another use case beside this? Could you provide an example of how to modularize your application in this way?
We implemented a component similar to Sammy in our Silverlight application some time ago. The similarity is in that both represent a kind of a simple browser that can be bound to a UI region. The approach gave us several benefits:
We had an extensible way to add new content implementations. I mean that we could add plugins to our app that contained new forms/views which the application core had no knowledge about.
We could easily implement composite views, e.g. dashboard that were able to show any view implemented in any module. Including themselves. (A-ha, we had created recursive dashboards that worked until the app hit the memory limit. Kind of Inception. :))
Sammy can be used to reach these goals as well.
However, you must understand that from all Sammy applications running on a page, only one can be bound to the browser location bar. Others will have their location visible only to javascript, or you'll need to render location bars for them on the page.

specific limitations of AJAX?

I'm still pretty new to AJAX and javascript, but I'm getting there slowly.
I have a web-based application that relies heavily on mySQL and there are individual user accounts that are accessed and the UI is populated with user specific data.
I'm working on getting rid of a tabbed navigation bar that currently loads new pages because all that changes from page to page is information within one box.
The thing is that box needs to reload info from the database, etc.
I have had great help from users here showing that I need to call the database within the php page that ajax is calling.
OK-so pardon the lengthy intro-what I'm wondering is are there any specific limitations to what ajax can call that I need to know about? IE: someone mentioned that it's best not to call script files and that I should remove scripts from the php page that is being called and keep those in the 'parent' page. Any other things like this I need to keep in mind?
To clarify: I'm not looking to discuss the merits/drawbacks of the technology. I'm wondering about specific coding implementation that I need to be aware of (for example-I didn't until yesterday realize that if even if I had established a mySQL connection on the page, that I would need to re establish that connection in my called page as well...makes perfect sense now).
XMLHttpRequest which powers ajax has a number of limitations. I recommend brushing up on the same origin policy. This is a pivotal rule because it limits where AJAX calls can be made.
First, you can't have Javascript embedded in the HTTP response to an AJAX call. That's a security issue.
No mention of the dynamics of the database, but if the data to be displayed in tabs doesn't have to be real-time, why not cache it server-side?
I find that like any other protocol, Ajax works best in tightly controlled conditions. It wouldn't make much sense for updating nearly the whole page, unless you find that the user experience is improved with an on-page 'loader'. Without going into workarounds, disadvantages will include losing the browser back button / history, issues such as the one your friend mentioned, and also embedded resources and other rich content can suffer as well, and just having an extra layer of complexity to deal with in your app. Don't treat it as magic sauce for your app - make sure every use delivers specific results that benefit your client / audience.
IMHO, it's best to put your client side javascript in a separate page and then import it - neater container. one thing I've faced before is how to call xml back which contains code to run such as more javascript - it's worth checking if this is likely earlier on and avoiding, than having to look at evals.
Mildly interesting.

How to create a Tabbed interface for two different web applications to be displayed as a single page

We have two separate web-apps, say 'retailUI' and 'bulkUI'. These two are basically two separate web applications (within the same business domain). Now, the requirement has been given to us to make the two work together in one page with a Tabbed interface (as a PoC).
My problem is that both the applications span over a number of JSP pages for navigation.
Is there a way that I can achieve this using some framework or some other approach?
If you want to keep the two applications as much as possible the way they are now, without rewriting them entirely, you gotta use iframes. That means the content of each tab is actually an iframe.
For such cases I found of great use a ExtJS user developed component, ManagedIFrame which as it's names suggested is a managed iframe. Using it, your iframes can interact with each other(for instance sendind messages from one to another, listeners etc.)
Carefully planing the listeners and their registering by checking whether the peer is there you could build this integrated application without rendering the two separate applications unoperational when ran standalone.
Sounds like your easiest bet is to use Frames. For this, each of your two web apps will be frames of a wrapper web app. You would then hide or show the frames based on which one you want to be active.
This would allow you to have seperate navigation in each, and the two apps don't necessarily have to know anything about one another.

Resources