As we constantly strive to make the Nuxeo Platform better and more efficient than ever, we turned our attention to the Nuxeo Platform UI this time. The Nuxeo Platform UI has used the Seam/JSF components architecture and we have started to migrate to something better - something that allows encapsulation and interoperability, uses better design elements and is incredibly fast and efficient!

Of course, we decided to use one of the latest and coolest technologies to start this change - ‘Polymers’ - an implementation of Web Components. Since its inception, web components revolutionized web development by providing reusable components for the web based on interoperable custom elements that extent HTML itself! Polymer is a library for building web components and makes it faster and easier to build standard web components that you can use everywhere. You can create anything from a button to a complete application across multiple platforms. Pretty cool right! So this definitely was a great choice for us to migrate to.

Seam/JSF to Polymer Refactoring


In order to successfully apply a potential Polymer replacement of Seam/JSF, we had to try, investigate and test a first approach of this refactoring. One of the solutions was to replace a functional UI part of the Nuxeo Platform which is not customized by Nuxeo Studio. So we chose the rights panel of a common Nuxeo document (ACLs Manager screen) for the first approach.

The main tasks we had to implement were:


  • Replacing the current JSF elements

  • Switching from Seam bindings for the business logic to Nuxeo REST API calls

  • Using nuxeo-elements (https://github.com/nuxeo/nuxeo-elements) as much as we can to try extracting a maximum number of custom Nuxeo new Polymer web-components.


We had previously done some work in https://jira.nuxeo.com/browse/NXP-16788 and as a result we came up with https://github.com/nuxeo/nuxeo-elements:


  • The creation of Polymer component nx-connection,nx-resource and nx-operation that will let us access the Nuxeo Platform through REST API (document and operation resources)

  • The creation of Polymer component nx-widget, nx-layout etc.


Then we applied this to the new rights screen replacement from Seam/JSF to Polymer technology: https://jira.nuxeo.com/browse/NXP-17016

All of these implementation and tests had been made with Polymer 0.5.x tools and libraries - https://github.com/nuxeo/nuxeo-elements/tree/upgrade-1.0. On May 14th, the new Polymer Beta 0.9 version was released and last week, the 1.0 stable library release for Google IO was announced. So a migration was definitely in the cards for us!

Polymer 0.5 Alpha to 1.0 Migration


Here is the migration guide provided by Google, clear and explicit: https://www.polymer-project.org/1.0/docs/migration.html

Following the guide was quick and easy!

Polymer 0.5.x vs 1.0

But there are a few tricky points:


  • If you want to evaluate an expression with the new 1.0 Polymer, place it into a dom element like span (placing it outside the element doesn’t work anymore).

  • ‘Granular’ observer can be used directly and bound to properties:

 properties: {
foo: {
type: String,
value: '',
observer: 'fooChanged'
}
}

We did notice a strange behavior (or we can say a bug) in this property - useless extra REST calls for each property observer set. But in all cases, general ‘observers’ feature does the job.

Properties are wrapped into ‘properties’ object with the following attributes: type, notify, observe, value and computed. Your properties should not be in lower case. The computed function should be named something other than your property name. Computed function should be signed with one parameter at least.

Finally, if you want to apply some business rules in your templates, such as,

<template is="dom-if" if="{{doc.contextParameters.acls[0].name=='local'}}">

you can’t do it with Polymer 1.0 because only boolean helper is allowed.

<template is="dom-if" if="{{hasLocalRights}}">

You should wrap this rule into a JavaScript part of an element like we have in nx-doc-resource, thanks to a Polymer property of our nx-doc-resource custom element (and its ‘computed’ function attribute):

 ...
haslocalrights: {
type: Boolean,
value: false,
notify: true,
computed: 'hasLocalRightsFunction(data)'
}
...
hasLocalRightsFunction: function (data) {
if (data) {
return data.contextParameters.acls[0].name == 'local';
}
}
...

This definitely makes it mandatory for developers to encapsulate their business logic within more and more custom components.

The Nuxeo Team is loving the web component architecture in general and of course the Polymer layer a lot! We are very excited about migrating to these new technologies and know you will like it too :-)