jakartaee / faces

Jakarta Faces
Other
109 stars 55 forks source link

Improve JSF javascript #1598

Open hantsy opened 2 years ago

hantsy commented 2 years ago

Today in the frontend web client, Typescript is preferred, if consider to rewrite the jsf.js(faces.js in Faces 4.0) in TypeScript or add a @types/jsfjs to the existing work, make it more interchangeable with the modern front-end technologies today.

BWT, if possible to write the facelet template with the popular frameworks directly, such as React components, and make the Faces managed beans/components(CDI beans) in the background worked as React server renderers.

melloware commented 2 years ago

Adding @blutorange as our TypeScript expert.

blutorange commented 2 years ago

I guess the decision which technology to use is up to somebody else, but I'd gladly help with the TypeScript part.

If we are talking about https://docs.oracle.com/javaee/7/javaserver-faces-2-2/jsdocs/symbols/jsf.html (?), I already created a type declaration file for that here: https://github.com/primefaces/primefaces/blob/master/primefaces/src/main/type-definitions/core-jsf.d.ts (might need some updates for the recent release)

arjantijms commented 2 years ago

I'm absolutely not the person to be able to help out with rewriting jsf.js (now faces.js indeed), but I did notice it's written in a quite horrible style. There's also an endless amount of warnings and even errors reported from it, that overal don't give a good impression.

tandraschko commented 2 years ago

there is a implementation in TypeScript from a MyFaces member i'm sure he would share it ;D

tandraschko commented 2 years ago

https://github.com/werpu/jsfs_js_ts

nimo23 commented 2 years ago

BWT, if possible to write the facelet template with the popular frameworks directly, such as React components, and make the Faces managed beans/components(CDI beans) in the background worked as React server renderers.

@hantsy Do you mean to introduce 3rd party client side technologies into JSF? I don't like the idea to bind 3rd party client side technologies into the JSF-implementation. JSF should remain (client-side) framework independent.

I think, it would be good to extend faces.js with more capabilities to make client side binding more flexible. For example, a response where the model data is decoupled from component tree. With this, the model data can be used on the client side to refresh its components: the model data can be provided as a json response which can be consumed by "jsf components" and by any client side javascript.

pizzi80 commented 2 years ago

Some time ago I've modernized jsf.js (faces.js) and removed the old FrameTransport but due to specs limit I didn't share it with a public PR ... I'm not an "expert" of JS or TypeScript but, at that time I made some tests in production and the chrome profiler shown less memory used and less function calls...

Again I'm not an expert in profiling JS so If someone could help or improve my version is welcome

I'm not sure if with Faces 4 is finally possible to use ES6 JS or not but If it's ok I could provide a PR

pizzi80 commented 2 years ago

I've spent some time to investigate the overall deprecation of old software...

Actually Safari 10 - 11 - 12 - 13 - 14 are not supported anymore by Apple

Even a 10 years old Macbook can upgrade to "Big Sur", which include Safari version 15.5

https://discussions.apple.com/thread/253968805

IOS 11 with Safari 11 is availble since September 2017 ( 5 years ago ) and it's available for upgrade even of iPhone 5S (which is a 2013 phone)

https://www.wired.co.uk/article/ios-11-features-update-download-release-date-uk#:~:text=Which%20devices%20support%20iOS%2011,2%20and%205th-gen%20iPad

IE11 is official in EOL from Microsoft

https://docs.microsoft.com/en-us/lifecycle/announcements/internet-explorer-11-end-of-support

Even more If you think that at the moment:

1) the are no Official Application Servers supporting Jakarta EE 10 2) there will be no Official Application Servers supporting Jakarta EE 10.1 before March 2023 (when Faces 4.1 will probably be released)

So it is more than safe to updagrade at least to full ES6 support

tandraschko commented 1 year ago

JFYI MyFaces impl uses typescript now

arjantijms commented 1 year ago

In the current version of "faces.js" in the master of Mojarra, some things don't work correctly atm.

For example consider the following page:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head id="j_idt3">
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Ajax</title>
    <script src="/test-faces22-ajax/jakarta.faces.resource/faces.js.xhtml?ln=jakarta.faces"></script>
    </head>
<body>
    <form id="form1" name="form1" method="post" action="/test-faces22-ajax/updateBody.xhtml" enctype="application/x-www-form-urlencoded">
    <input type="hidden" name="form1" value="form1" />
    <input id="form1:bodytag" type="submit" name="form1:bodytag" value="BodyTag" onclick="mojarra.ab(this,event,'action','@this','@none');return false" />
    <input type="hidden" name="jakarta.faces.ViewState" id="j_id1:jakarta.faces.ViewState:0" value="5704712853588420397:-194852515398040622" autocomplete="off" />
    </form>
</body>
</html>

Also consider the following AJAX response:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
    <changes>
        <update id="jakarta.faces.ViewBody">
              <![CDATA[
               <body class="foo" title="fooTitle" lang="fooLang">
                    <span id="status"></span>
               </body>]]>
        </update>

        <eval>
            <![CDATA[
            var body = document.getElementsByTagName('body')[0];
            document.getElementById('status').innerHTML=
             'BODY CLASS:'+body.className+
             ' BODY TITLE:'+body.title+
             ' BODY LANG:'+body.lang]]>
        </eval>
    </changes>
</partial-response>

In the above example, the attributes on the body class are not being set. Switching the faces.js file to the old version again, and they are set.

See test Issue2381IT.testBodyAttributesAfterUpdate:58.

cc @BalusC @tandraschko

BalusC commented 1 year ago

@pizzi80 can you fix this?

pizzi80 commented 1 year ago

Fixed https://github.com/eclipse-ee4j/mojarra/pull/5225

How to run Faces TCK tests with the current master snapshot?

I read the docs and tried the following test run:

mvn clean install -pl :ajax -Dfaces.version=4.1.0-SNAPSHOT

but it doesn't compile

[ERROR] Failed to execute goal on project ajax: Could not resolve dependencies for project 
org.eclipse.ee4j.tck.faces.faces22:ajax:war:4.0.2-SNAPSHOT: The following artifacts could not be resolved: 
org.eclipse.ee4j.tck.faces.test:util:jar:4.0.2-SNAPSHOT, jakarta.faces:jakarta.faces-api:jar:4.1.0-SNAPSHOT: 
org.eclipse.ee4j.tck.faces.test:util:jar:4.0.2-SNAPSHOT was not found in 
https://jakarta.oss.sonatype.org/content/repositories/staging during a previous attempt. This failure was cached in the 
local repository and resolution is not reattempted until the update interval of jakarta-staging has elapsed or updates 
are forced 
arjantijms commented 1 year ago

@pizzi80 the faces.version option sets the API, for which there is no 4.1.0-SNAPSHOT artefact.

You'd probably wanted to set the Mojarra version. If the docs say otherwise we should update them I guess.

Can you try something like the following, assuming you have compiled Mojarra master locally:

mvn clean install -pl :ajax -Dglassfish.version=7.0.3 -Dmojarra.version=4.1.0-SNAPSHOT -Dtest.selenium=true

The last option is important too, since default is using httpunit/rhino, which totally dislikes the new faces.js.

arjantijms commented 1 year ago

@pizzi80 https://github.com/eclipse-ee4j/mojarra/pull/5225 didn't quite fix the Ajax problems. There's still many failures.

[ERROR] Failures: 
[ERROR]   Issue2162IT.testIssue2162:52
[ERROR]   Issue3097IT.testViewExpired1:48
[ERROR]   Issue3171IT.testExceptionDuringRenderOk:56
[ERROR]   Issue3344IT.testXmlPreambleOnRedirect:43
[ERROR]   Issue3473IT.testButtonOnlySubmitsOne:42
[ERROR] Errors: 
[ERROR]   Issue4345IT.testAjaxResourceNotDoubleHTMLEscaped:45 » NoSuchElement no such el...
[INFO] 
[ERROR] Tests run: 126, Failures: 5, Errors: 1, Skipped: 63
pizzi80 commented 1 year ago

I did the PR before i know how to run this new Faces test suite...

fixed with https://github.com/eclipse-ee4j/mojarra/pull/5231

werpu commented 1 year ago

Hi sorry to chime in here so late:

The Github project above mentioned and MyFaces basically are the same implementation and done by me. I started the project outside of MyFaces a few years ago, because we had the same growing pains Mojarra has faced/is facing in this issue. The project was stalled in a working condition, but with no TCK testing for a while, due to Covid and projects for quite a while but I had time end of 2022 to wrap things up just in time for the MyFaces release (hence also my request and work to move the Ajax tests away from HTMLUnit). However this has been resolved in the last few months of 22, the TCK tests now pass, and also a ton of additional fixes went in (with additional unit tests)

Atm the Github version usually a litte bit ahead of MyFaces (currently, 1 bugfix of a rare corner case, raised by Tobago, which I will merge the next 2-3 days).

Either way the code was written for modern browsers and more importantly readability and only has one real source dependency to another library which I have written (not necessarily needed, but makes the code way more readable) the rest of the dependencies either are build or test dependencies. It is covered by roughly 180 unit tests atm!

It does 2 target builds one for JSF 2.x (javax namespace used by Tobago) and JSF 4.x (jakarta namespace used by Tobgao and MyFaces)

So yes the new code is way more advanced, feel free to rip out anything you need (it is ASL licensed so taking code from there into Jakarta should be a non issue, if you want I can relicense the entire code as ASL2/EPL dual license to make things easier for you guys. (I just have to ask a small number of people from the Tobago Team which have provided several unit tests as pull requests for permission)

Just ping me or comment, if you need help or want to have a dual ASL2/EPL relicense of the code!

werpu commented 1 year ago

I'm not sure if with Faces 4 is finally possible to use ES6 JS or not but If it's ok I could provide a PR

MyFaces already has moved to ES6 level we cut old ropes with 4.0, but stepping back from a language pov it would be easy, since we are in TypeScript (but given the we also cut out old browsers on dom level as well this is theoretical es5 and modern dom level does not make sense)!

There is nothing in the spec I am aware of which would prevent to go with ES6. It really depends where you want to make the cutoff point regarding browser support! ES6 by now is pretty old (ES2015) and literally all browsers not supporting it have been phased out, but if you use HTMLUnit you will run into issues, you will have to move to Selenium!