From 4d136c8275b6e0d3d8badad269c5fe02cd2a1aef Mon Sep 17 00:00:00 2001
From: Simon Levermann
Date: Fri, 8 Apr 2022 18:58:17 +0200
Subject: [PATCH] WIP defer and async loading of JS in themes and templates
---
.../forms/login/LoginFormsProvider.java | 4 ++
.../FreeMarkerLoginFormsProvider.java | 12 ++++--
.../login/freemarker/model/ScriptBean.java | 37 +++++++++++++++++++
.../resources/theme/base/login/template.ftl | 12 +++++-
4 files changed, 61 insertions(+), 4 deletions(-)
create mode 100644 services/src/main/java/org/keycloak/forms/login/freemarker/model/ScriptBean.java
diff --git a/server-spi-private/src/main/java/org/keycloak/forms/login/LoginFormsProvider.java b/server-spi-private/src/main/java/org/keycloak/forms/login/LoginFormsProvider.java
index 9a2487ee0061..3347cc46994b 100755
--- a/server-spi-private/src/main/java/org/keycloak/forms/login/LoginFormsProvider.java
+++ b/server-spi-private/src/main/java/org/keycloak/forms/login/LoginFormsProvider.java
@@ -50,6 +50,10 @@ public interface LoginFormsProvider extends Provider {
*/
void addScript(String scriptUrl);
+ default void addScript(String scriptUrl, boolean async, boolean defer) {
+ addScript(scriptUrl);
+ }
+
Response createResponse(UserModel.RequiredAction action);
Response createForm(String form);
diff --git a/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java b/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java
index ad2ec949ec1a..ff6337c4dc09 100755
--- a/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java
+++ b/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java
@@ -43,6 +43,7 @@
import org.keycloak.forms.login.freemarker.model.RegisterBean;
import org.keycloak.forms.login.freemarker.model.RequiredActionUrlFormatterMethod;
import org.keycloak.forms.login.freemarker.model.SAMLPostFormBean;
+import org.keycloak.forms.login.freemarker.model.ScriptBean;
import org.keycloak.forms.login.freemarker.model.TotpBean;
import org.keycloak.forms.login.freemarker.model.TotpLoginBean;
import org.keycloak.forms.login.freemarker.model.UrlBean;
@@ -136,11 +137,16 @@ public FreeMarkerLoginFormsProvider(KeycloakSession session, FreeMarkerUtil free
this.uriInfo = session.getContext().getUri();
}
- @SuppressWarnings("unchecked")
@Override
public void addScript(String scriptUrl) {
- List scripts = (List) this.attributes.get("scripts");
- scripts.add(scriptUrl);
+ addScript(scriptUrl, false, false);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addScript(final String scriptUrl, final boolean async, final boolean defer) {
+ List scripts = (List) this.attributes.get("scripts");
+ scripts.add(new ScriptBean(scriptUrl, async, defer));
}
@Override
diff --git a/services/src/main/java/org/keycloak/forms/login/freemarker/model/ScriptBean.java b/services/src/main/java/org/keycloak/forms/login/freemarker/model/ScriptBean.java
new file mode 100644
index 000000000000..1f6e623a41c2
--- /dev/null
+++ b/services/src/main/java/org/keycloak/forms/login/freemarker/model/ScriptBean.java
@@ -0,0 +1,37 @@
+package org.keycloak.forms.login.freemarker.model;
+
+public class ScriptBean {
+
+ private final String url;
+ private final boolean async;
+ private final boolean defer;
+
+ public ScriptBean(String url, boolean async, boolean defer) {
+ this.url = url;
+ this.async = async;
+ this.defer = defer;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public boolean isAsync() {
+ return async;
+ }
+
+ public boolean isDefer() {
+ return defer;
+ }
+
+ /*
+ * This is a workaround: When an old theme template copies the mechanism of loading these scripts:
+ *
+ * They assume the "script" is the URL. By returning URL in toString, Freemarker will call toString on the object and
+ * return the url. This way, we don't break backwards compatibility
+ */
+ @Override
+ public String toString() {
+ return url;
+ }
+}
diff --git a/themes/src/main/resources/theme/base/login/template.ftl b/themes/src/main/resources/theme/base/login/template.ftl
index f21e6cb3f58e..7c628a67cf18 100644
--- a/themes/src/main/resources/theme/base/login/template.ftl
+++ b/themes/src/main/resources/theme/base/login/template.ftl
@@ -29,9 +29,19 @@
#list>
#if>
+ <#if properties.asyncScripts?has_content>
+ <#list properties.asyncScripts?split(' ') as script>
+
+ #list>
+ #if>
+ <#if properties.deferScripts?has_content>
+ <#list properties.deferScripts?split(' ') as script>
+
+ #list>
+ #if>
<#if scripts??>
<#list scripts as script>
-
+
#list>
#if>