Implementing User Extensions for Sencha Architect 3.0 Preview
This article discusses some specific technical challenges that we faced and overcame during the development of the User Extensions feature in Architect 3.
A Brief Introduction To Sencha Architect
First, a little background: Sencha Architect is a visual tool for building HTML5 applications using Ext JS and Sencha Touch frameworks. Three of our main goals for Architect are: to be the best way to build a Sencha app; to generate clean code exhibiting the best practices for using our frameworks; and to be enable developers and designers to work together closely.
Architect 3 advances all of these goals, as you can see in the Architect 3 preview which we first announced at SenchaCon 2013 and then released as a public preview in early August. The major new features we introduced in the preview are: Application Templates and User Extensions, which strongly address our first two goals; and Theming Support, which addresses the third goal.
Theming Support is all about empowering designers to work alongside developers to create visually appealing applications that match a company’s style guidelines and align with their sense of style. Too often the feedback loop between designers and developers takes too long. We knew we could improve this process.
We wanted to create a single tool that allowed each of these parties to collaborate and contribute in their area of expertise. Application Templates and User Extensions advance the first two goals by increasing the reach of Architect and helping to ensure good code generation. We wanted to make sure that the code generated from the design view is very clean and looks like an advanced developer may have written it. We have had experiences working with many tools that generate unreadable code, and we know it doesn’t have to be this way. The basic idea of User Extensions is to bring code created elsewhere into Architect in an easy and useful way while maintaining full design-time support. The core idea of Application Templates is to allow the user to select from common application patterns when creating a new project. Note that the preview build doesn’t yet allow creation of user defined Application Templates, but the final 3.0 version will. All of these features have been requested by users, and we’re pleased to deliver them.
Our Experience Implementing User Extensions
Adding support for User Extensions proved to be quite a challenge for the Sencha Architect architecture, and we hope you learn from our experience.
Stepping back for a moment: the entire Architect user interface is an HTML5 application built using Ext JS. We distribute Architect as a binary executable/installer that we have wrapped up with Sencha Desktop Packager, our own special version of Chromium which adds in APIs to access native functionality. Some of the native system functionality we use is: reading, writing, and deleting files from the filesystem and manipulating the native window menu. By actually using a browser to render our controls, we are able to provide the rich fidelity that many design tools lack. And because we know the application will be running in a specific browser, we can leverage all of the latest HTML5 features that are available.
“We distribute Architect as a binary executable/installer that we have wrapped up with Sencha Desktop Packager, our own special version of Chromium which adds in APIs to access native functionality.”
Getting back to our experience of enabling user extensions in Architect, we needed to run user-provided code within the application. This user code could literally be anything. We knew this code would have to be sandboxed from our privileged APIs. Imagine installing a user extension that suddenly deleted files in your home directory!
In order to isolate the code which is running in the design view (which we call the canvas), we used an iframe along with the HTML5 sandbox attribute. The sandbox attribute enables users to configure how the iframe will behave. In our case, we set it to allow-scripts, so JavaScript can execute within the iframe. Check out this section of HTML5 Rocks which explains the granular controls provided by the sandbox attribute. By default, when setting the sandbox attribute, the iframe cannot reach out to the parent or top level frames. This allows us to load code into the canvas iframe and disallow access to our privileged APIs. In our application, the frames still need to communicate in some way because they will not be able to access any properties stored on the frame. We are using the HTML5 standard Web Messaging (or cross-document messaging) to communicate back and forth via window.postMessage. We created a CrossWindowMessaging class to abstract all of the communication between the frames.
The CrossWindowMessaging class allowed us to easily do eventing between frames while still supporting most of the features available in Ext.util.Observable. Below is brief glimpse at the interface by way of code:
The messaging class also allowed us to invoke functions between the two frames asynchronously.
Because this approach made all of our previously synchronous APIs become asynchronous, we quickly ran into deeply nested sets of function callbacks. This required a shift in our development paradigm, so we began returning promises from all of our cross frame method invocations. We encountered this issue at about the same time as the Sencha Touch team. Interestingly, each of our teams independently chose to use promises, and these implementations should see a convergence in the near future. Promises make it easy to express all of the necessary steps required in a very procedural manner when you need to take the return values from a number of asynchronous calls and do something with them in a series. Anyone who has done a bit of development with Node.js will recognize this problem which quickly surfaces when doing a lot of asynchronous development.
Below is a small snippet of code from Architect that illustrates the use of promises.
Imagine what this would look like if we used nested callbacks for each one of these function calls. It would be completely unmanageable! Promises has helped us clean up our code base and solve the problem of organizing our asynchronous calls which constantly go back and forth between the iframes.
We hope that this insight into the challenges we encountered while developing User Extensions in Architect can help you in your own projects.
Lastly, we know that there is a rich community of users that has developed user extensions for Ext JS and Touch. We would love if you followed the Creating User Extensions and Integrating User Extensions guides to make your user extensions available as .aux files (Architect User Extension) and share them with the community. Please provide any feedback that you may have with us at the Architect 3.0 Forum.
We’re excited to announce the official release of Rapid Ext JS 1.0, a revolutionary low-code…
The Sencha team is pleased to announce the availability of Sencha Architect version 4.3.6. Building…
Sencha, a leader in JavaScript developer tools for building cross-platform and enterprise web applications, is…