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 @@ + <#if properties.asyncScripts?has_content> + <#list properties.asyncScripts?split(' ') as script> + + + + <#if properties.deferScripts?has_content> + <#list properties.deferScripts?split(' ') as script> + + + <#if scripts??> <#list scripts as script> - +