Uploaded image for project: 'Nuxeo Platform'
  1. Nuxeo Platform
  2. NXP-16788

Experiment with webcomponents

    XMLWordPrintable

    Details

      Description

      Setup explanations

      Server side

      Client side:

      Startup

      Start the Nuxeo server, and run the client side app nuxeo-elements-samples by running "grunt" inside it.

      Experiments

      Server side generation of polymer elements

      See Nelson's report.

      Notes:

      • explain how polymer elements are packaged and served by the Nuxeo server
      • explain how polymer elements are generated (naming issues, conversion issues)
      • explain how generated elements can be used by third party applications // by the designer

      Client side implementation of polymer elements

      Approach

      Approach similar to the first experiment made by Nelson, here is a summary:

      • define polymer elements that will process layout/widget definitions on the client side
      • define a registry to route a given widget type rendering to a given polymer element (nx-text-widget, etc...)
      • retrieve a document and a layout definition using elements nx-connection and nx-resource, and apply the layout-related elements to them

      Slight difference in the approach: this time, make the client manipulate layout and widget instances instead of their definitions, because:

      • instances are easier to manage for display (the widget instance will only hold the edit properties, for instance, not all potential properties for all supported modes)
      • the layout service (turning the definition into an instance) can hold logics server side to hide some widgets for instance (maybe also perform some conversions to handle translations, or make directory items available to the client)
      • this is similar to what JSF layout and widget tags are currently manipulating (e.g. instances, not definitions)
      Test pages

      This page displays the "dublincore" layout on the /default-domain/workspaces document (only the text widget is currently implemented), retrieving the doc thanks to nx-connection and nx-resource elements.

      Excerpt:

        <nx-connection id="nx_connection"
          url="http://localhost:8080/nuxeo"
          username="Administrator"
          password="Administrator">
        </nx-connection>
        <nx-resource auto id="doc" path="/path/default-domain/workspaces" data="{{doc}}"></nx-resource>
        <nx-form-layout name="dublincore" mode="edit" value="{{doc}}"></nx-form-layout>
      
      Result
      • automatic registration of client-side polymer elements (mapping Nuxeo widget types names) is relying on "modularize" and "using" mechanisms offered by Polymer
      • additional polymer elements like nx-form-layout are in charge of rendering/placing the widgets on the page
      • the nx-widget-instance element dispatches the widget rendering to the right polymer element
      • a base element, nx-base-widget-type handles the widget types registration, and exposes the field variables to widget types that extend it (similarly to variables exposed by JSF layout/widget tags, for instance in widgets of type "template")
      • only one widget type is implemented for now (nx-text)
      • these tags could also be packaged and made available to users thanks to the "Server side generation of polymer elements" approach, depending on was "tags API" Nuxeo should provide to users/devs
      Issues and things to discuss
      • the endpoint to retrieve the layout instance as json is not using nx-connection because the automation client lib does not have that kind of API
      • every time the mode will change, a new ajax call to the server, to retrieve the corresponding json, will have to be made: mode is resolved server side, to allow hiding some widgets depending on custom criteria (some of these criteria could rely on request parameters or nx-form-layout element attributes)
      • the field variable is resolved from the bound value using the following js code:
            _resolveField: function() {
              if (this.value && this.widget.fields) {
                this.field = this.value.properties[this.widget.fields[0].propertyName];
              }
            },
      

      This should ideally be extended and made pluggable (similarly to EL resolvers mechanism) or could be implemented differently, following the Polymer "binding" mechanism (to check).

      JSF integration of webcomponents

      Approach(es)

      First nave approach, since JSF is producing a HTML page in the end, is to integrate these tags to an XHTML page

      Second approach is similar, but trying to rely on the we resources endpoint, adding specific tags to handle imports

      Third approach is a bit different: it tries to reuse the html resources (packaged as polymer elements) to keep these resources unchanged (and usable on a client application): the original resource, the tag using it.

      Result

      First approach add some constraints due to the fact that JSF still parses the page, and integration with JSF context is very naive:

        <nx-resource auto="auto" id="doc" path="/path#{currentDocument.pathAsString}" data="{{doc}}"></nx-resource>
      

      But it works!

      Second approach is not that related to JSF integration, but gives an idea of needs around resources management in different use cases.

      Third approach is better, but not working as is (did not try to fix it for now):

        <nxwebr:import src="/components/test_bare.html" />
        <nx-test-bare docpath="#{currentDocument.pathAsString}"></nx-test-bare>
      

      This fails with the following error in console (inside polymer.js code, l.6850)

      Uncaught Error: Template must be cleared before a new bindingDelegate can be assigned
      
      Issues and things to discuss
      1. It could be interesting to try again another approach, defining a JSF tag that would produce the accurate HTML using the Polymer element, as well as injecting variables to the Polymer context. Usually this is done via tag attributes, but tag attributes also accept variables, so "complex types" (e.g attributes that are not simple types like String or Integer) would need to be serialized to json by JSF and made available to the Polymer JS context (pluggability still to investigate)
      2. Approaches tried to pass JSF contextual information from JSF to web components. In some cases, "actions" triggered inside the web component (e.g calls to rest api) would need to notify the JSF layers that some changes have been done (to trigger a context refresh on JSF side too)

        Attachments

          Issue Links

            Activity

              People

              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: