orbeon / orbeon-forms

Orbeon Forms is an open source web forms solution. It includes an XForms engine, the Form Builder web-based form editor, and the Form Runner runtime.
http://www.orbeon.com/
GNU Lesser General Public License v2.1
514 stars 221 forks source link

Embedded XForms Server for mobile and offline clients #1221

Open ebruchez opened 11 years ago

ebruchez commented 11 years ago

Status

The purpose of this RFE is to gather ideas and track progress of an Orbeon Labs investigation project. The purpose of the project is to make the Orbeon Forms forms engine available on clients, including online and offline web browsers and mobile applications.

As of October 2016, there has been some progress on this project, including:

We expect to continue progress on this project incrementally.

Subprojects, dependencies, and related projects

These are related subprojects

Historical note

With Orbeon Forms 3.7 (back in 2009!), we had an implementation which wasn't bad in concept, but was too limited and based on Google Gears (the precursor to HTML5 local storage among other things). Due to those limitations, Google abandoning Gears and lack of interest from customers at that time, we decided not to maintain it anymore starting Orbeon Forms 3.8. See:

The idea is to bring our forms engine to Web apps and "native" mobile apps. This would serve multiple purposes:

  1. supporting offline form management and data entry with a Web app
  2. supporting offline form management and data entry from with a native phone/tablet app
  3. generally having more of the form processing handled on the client, as client capabilities improve

The general idea is to make the code which currently runs on the server run on the client, whether within a Web browser directly or as a native application on a mobile device.

We need to abstract and modularize the XForms engine to make it as small as possible and as independent as possible from other things including the servlet API.

The user-interface part would remain browser technology-based. We don't want to change this at all at first and we wants to leverage either an actual Web browser or a Web view within a native app.

One components that we need to have is some kind of abstraction for the client/server communication. Right now that communication is handled via Ajax in the JavaScript code and we have the XForms server on the server. What we would like to do here is allowing the option to have something local like at simple queue. That doesn't seem to be extremely hard to do.

Platforms

General considerations

For a web application we have to compile our code to JavaScript. For offline support we can use modern browser APIs.

Native iOS app

The current plan is to use JavaScript as well. In the future, and if it matures and gains the appropriate bindings, Scala Native could become an option as well.

HIstorical considerations

We also considered these options, but have opted not to use them:

  1. Scala -> scalac -> IKVM -> Xamarin.iOS -> ARM x86 assembly
    • iKVM is stable
    • MonoTouch is stable (?)
    • uses optimizing compiler (I think)
    • drawback: painful toolchain
    • benefit: might be the best performance possible as of 2013
    • opens the door of Microsoft phones/tablets as well
  2. Avian VM
    • promising (2013-08-30 update: Scala runs fully)
    • JIT/AOT compilers and GC performance still poor

Abandoned projects, for reference:

  1. RoboVM compiles Java bytecode to native code (project/product is dead)
  2. ScalaGWT
    • run in WebView
    • no JIT in WebView probably
  3. LLVM backend
  4. J2ObjC from Google
    • compiles Java source to Objective-C
    • see also Going under the hood of Inbox
    • would not work for us almost half of our server-side code is in Scala

      Native Android application

Android already supports Java bytecode. This means we have two options:

  1. Compile our Java/Scala code to Android.
  2. Compile our Scala code to JavaScript as in the case of the browser and iOS.

We would need to use a WebView probably and then we would need to interact between the application and the WebView. On Android the JavaScript side of a WebView is able to call a Java object that has been exposed.

Modularization effort

The Orbeon code needs to be modularized and abstracted. In particular:

Once a prototype is developed, we needs to think about the general architecture of the mobile application, including lifecycle, how to load forms and so on. Form Runner needs to be included, and local storage at least needs to be used.

ebruchez commented 9 years ago

Steps for a prototype

Strategy

As of 2015-01-13, the plan to use Scala.js. This way a single compilation can be used:

This also allows us to master Scala.js, which we want to use more for Form Builder (and later Form Runner).

First goals

We are trying to define reasonable chunks of work which lead us somewhere. First goals:

  1. run some of our code in the browser
  2. run an XForms hello world prototype in the browser

It is ok to hack to get to these goals. The purpose is to get familiar with the tool chain, potential issues, and learn more about what remaining work will be needed.

Known challenges

Things the client must not need

General architecture

Q&A

ebruchez commented 9 years ago

form-runner

ebruchez commented 8 years ago

+1 from customer

ebruchez commented 8 years ago

+1 from evaluator

ebruchez commented 7 years ago

Immediate concrete next steps:

ebruchez commented 7 years ago

+1 from evaluator, with a preference for a web app using browser storage, as native apps can be more challenging to deploy.

ebruchez commented 7 years ago

+1 from customer

ebruchez commented 7 years ago

+1 from evaluator

ebruchez commented 6 years ago

+1 from user

siebertm commented 5 years ago

We as a customer would also +1 that. Just the form runner, right?

avernet commented 5 years ago

@siebertm Correct: this feature is specifically for forms created with Form Builder and running in Form Runner.

ebruchez commented 5 years ago

+1 from user on StackOverflow

ebruchez commented 4 years ago

This feature will also help us write more responsive UI for Form Builder. We'd like, for example, Form Builder dialogs showing and navigating faster and reducing the number of roundtrips to the server.

ebruchez commented 4 years ago

The proxy portlet preferences could also benefit.

antoinesamaha commented 4 years ago

Hello, Is there any news regarding offline form runner? It is really a requirement from our business people. On the other side how does the Form builder store the form layout. Is it a JSON or XML file? And is the response also an XML JSON file? In which case one would imagine coding a new renderer for mobiles and Flutter can be an option for cross platform compatibility.

avernet commented 4 years ago

@FOC-framework Offline support is still something we'd like to do, but just not actively working at this point in time. Form definitions are stored in an XML format, which essentially looks like HTML + XForms + some Orbeon Forms specific elements and attributes. You can see what it looks like by going, in Form Builder, to Advanced / Edit Source. For services called by the forms, Orbeon Forms supports both XML and JSON.

ebruchez commented 4 years ago

Moving and reworking the steps into this separate comment:

Proposal for next steps

1. Initial XForms engine extraction

Goals:

Non-goals:

Steps:

2. First compilation with Scala.js

Goals:

Non-goals:

Steps:

3. Simple client-side Hello World

Goals:

Non-goals:

Steps:

4. Full XForms support

Goals:

Steps:

5. Initial Form Runner support

Goals:

Steps:

6. Full Form Runner support

Goals:

7. Option: demo iOS app

Goal:

Steps:

siebertm commented 4 years ago

@ebruchez that's a large chunk of work and i know this is rather far out but if you're at the point you've got an MVP or so to test out, ping me! I really want to try this in our real use cases!

ebruchez commented 4 years ago

The initial refactoring requires separating the following:

ebruchez commented 4 years ago
ebruchez commented 4 years ago

We will need the handlers offline to support instantiating new forms offline. Right now, this works as follows:

So we need a way to do this when offline as well. We probably need to have SAXStore and some of the SAX API for this.

ebruchez commented 4 years ago

Splitting this into modules/projects is not that trivial. We not only have the runtime/compile-time axis, but the "thin client" (what we have now)/full client axis, and the JVM/JS/shared axis.

For example we don't want the "thin client" to pull down the full client. Scala.js prunes the call tree but it's not perfect at doing that, probably, so it's better if we have a clean separation of the "full client" module, which would contain mainly the XForms runtime.

ebruchez commented 4 years ago

How static state construction works:

ebruchez commented 4 years ago

Client-server communication abstraction:

ebruchez commented 4 years ago

So for the client-server, we now have:

For XFormsModelSubmission:

So probably that we don't need to modify much XFormsModelSubmission. One approach:

Another approach is to make Submissions pluggable, and on JavaScript:

The second approach might be easier as it's not pulling in Connection.

siebertm commented 4 years ago

My 2 cents on this:

when fully offline, we should have an OfflineHttpClient, configurable to call back JavaScript functions

Why not normal fetch/XHR which are then caught in a ServiceWorker? This generates less special cases.

Depending whether this must support IE, of course. But, even we (working with german hospitals) are phasing out IE support...

ebruchez commented 4 years ago

@siebertm Thanks for the feedback.

Why not normal fetch/XHR which are then caught in a ServiceWorker? This generates less special cases.

The main reason for a JavaScript callback API is embedding in native mobile applications which can then provide their own persistence and service support. It's also very easy to implement on both sides.

For regular online/offline mode in a browser then yes, Fetch support is needed.

Depending whether this must support IE, of course. But, even we (working with german hospitals) are phasing out IE support...

Agreed, and IE support is not a requirement at this point.

ebruchez commented 4 years ago

For the record, we have now made Connection implement ConnectionTrait, with two implementations (JVM/JS). The JS implementation is not done yet.

More work:

ebruchez commented 4 years ago

Which parts of the static analysis must not be present in the ElementAnalysis tree?

So we should probably separate the "builders": ChildrenBuilderTrait, ShadowChildrenBuilder, etc.

ebruchez commented 4 years ago

So now we are refactoring out all the building of the tree. This will take care of XBLBindingBuilder and others.

However we need to solve the question of how to pass in the XPath analysis information. We do this after we have built the tree:

For deserialization, the information should be passed to the constructor. So maybe the constructor of the classes should have the XPath analysis information as vars set to None, but then the vars are updated before serialization. Upon deserialization, the proper information can be passed.

ebruchez commented 4 years ago

Next step is to move towards serialization/deserialization. This includes:

We can use case classes with vars, or semi-automatic, or manual serialization.

ebruchez commented 3 years ago

Remaining tasks before we can rebase on the pe branch:

On master (CE) branch:

P2:

ebruchez commented 3 years ago

For 2021.1 this is not a full-fledged feature. Our plan is to enable, possibly optionally, the "Test Offline" feature from Form Builder. This feature allows running a form in test mode using the JavaScript form runtime.

ebruchez commented 2 years ago