IDEMPIERE-4421 Html asset versioning should allow fluent deployment (#420)

* IDEMPIERE-4421 Html asset versioning should allow fluent deployment

use classpath loading and lang-addon versioning for theme resources

* IDEMPIERE-4421 Html asset versioning should allow fluent deployment

Incorporate backward compatibility patch from Carlos.
This commit is contained in:
hengsin 2020-11-30 22:33:23 +08:00 committed by GitHub
parent 60e584655c
commit 5d236de30c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
281 changed files with 93 additions and 54 deletions

View File

@ -51,4 +51,8 @@ Copyright (C) 2007 Ashley G Ramdass (ADempiere WebUI).
<javascript-module name="org.idempiere.commons" version="202011230530"/>
<javascript-module name="jquery.maskedinput" version="1.4.1" />
<javascript-module name="photobooth" version="0.7-rsd3" />
<!-- this js module doesn't actually exists and it is here for default theme version -->
<!-- since loading of js module is on demand, it doesn't cause any error as long as you don't try to load it -->
<javascript-module name="idempiere.theme.default" version="202011282132" />
</language>

View File

@ -22,7 +22,6 @@ import org.adempiere.webui.adwindow.ADWindow;
import org.adempiere.webui.desktop.FavouriteController;
import org.adempiere.webui.exception.ApplicationException;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.theme.ITheme;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.window.FDialog;
import org.compiere.model.MMenu;
@ -175,7 +174,7 @@ public class DPFavourites extends DashboardPanel implements EventListener<Event>
btnFavItem.setTooltiptext(description);
if (ThemeManager.isUseFontIconForImage())
btnFavItem.setIconSclass(imageSrc);
else if (imageSrc.startsWith(ITheme.THEME_PATH_PREFIX))
else if (imageSrc.startsWith(ThemeManager.THEME_PATH_PREFIX))
btnFavItem.setImage(imageSrc);
else
btnFavItem.setImage(ThemeManager.getThemeResource(imageSrc));

View File

@ -21,8 +21,9 @@ package org.adempiere.webui.theme;
public interface ITheme {
//default theme
public static final String ZK_THEME_DEFAULT = "default";
//theme resource url prefix
public static final String THEME_PATH_PREFIX = "/theme/";
//theme resource url prefix. ~./ is the zk url prefix for resources loaded from classpath (typically at src/web folder)
public static final String THEME_PATH_PREFIX_V8 = "~./theme/";
public static final String THEME_PATH_PREFIX_V7 = "/theme/"; // for backward compatibility
//css for login window and box
public static final String LOGIN_WINDOW_CLASS = "login-window";

View File

@ -32,18 +32,26 @@ import org.zkoss.image.AImage;
*/
public final class ThemeManager {
//zk predefined starting path for classpath resources (src/web)
public static final String ZK_PREFIX_FOR_CLASSPATH_RESOURCE = "/web";
//zk predefined url prefix for resources loaded from classpath
public static final String ZK_URL_PREFIX_FOR_CLASSPATH_RESOURCE = "~./";
/** Logger */
private static CLogger log = CLogger.getCLogger(ThemeManager.class);
private static String m_theme = null;
private static String m_theme = ITheme.ZK_THEME_DEFAULT;
private static String m_brokenTheme = null;
public static String THEME_PATH_PREFIX = ITheme.THEME_PATH_PREFIX_V8;
/**
* @return url for large logo
*/
public static String getLargeLogo() {
String theme = getTheme();
String def = ITheme.THEME_PATH_PREFIX+theme+ITheme.LOGIN_LOGO_IMAGE;
String def = THEME_PATH_PREFIX+theme+ITheme.LOGIN_LOGO_IMAGE;
return MSysConfig.getValue(MSysConfig.ZK_LOGO_LARGE, def);
}
@ -52,7 +60,7 @@ public final class ThemeManager {
*/
public static String getSmallLogo() {
String theme = getTheme();
String def = ITheme.THEME_PATH_PREFIX+theme+ITheme.HEADER_LOGO_IMAGE;
String def = THEME_PATH_PREFIX+theme+ITheme.HEADER_LOGO_IMAGE;
String url = MSysConfig.getValue(MSysConfig.ZK_LOGO_SMALL, null);
if (url == null)
url = MSysConfig.getValue(MSysConfig.WEBUI_LOGOURL, def);
@ -72,11 +80,21 @@ public final class ThemeManager {
if (! theme.equals(m_theme)) {
if (! ITheme.ZK_THEME_DEFAULT.equals(theme)) {
// Verify the theme.css.dsp exists in the theme folder
if (ThemeManager.class.getResource(ITheme.THEME_PATH_PREFIX + theme + ITheme.THEME_STYLESHEET) == null) {
log.warning("The theme " + theme + " does not exist or is not properly configured, falling back to default");
m_brokenTheme = theme;
theme = ITheme.ZK_THEME_DEFAULT;
String themeCSSURL = THEME_PATH_PREFIX + theme + ITheme.THEME_STYLESHEET;
if (ThemeManager.class.getResource(toClassPathResourcePath(themeCSSURL)) == null) {
// verify if is a v7 theme
themeCSSURL = ITheme.THEME_PATH_PREFIX_V7 + theme + ITheme.THEME_STYLESHEET;
if (ThemeManager.class.getResource(toClassPathResourcePath(themeCSSURL)) != null) {
THEME_PATH_PREFIX = ITheme.THEME_PATH_PREFIX_V7;
} else {
log.warning("The theme " + theme + " does not exist or is not properly configured, falling back to default");
m_brokenTheme = theme;
THEME_PATH_PREFIX = ITheme.THEME_PATH_PREFIX_V8;
theme = ITheme.ZK_THEME_DEFAULT;
}
}
} else {
THEME_PATH_PREFIX = ITheme.THEME_PATH_PREFIX_V8;
}
m_theme = theme;
}
@ -88,21 +106,21 @@ public final class ThemeManager {
* @return url of theme stylesheet
*/
public static String getStyleSheet() {
return ITheme.THEME_PATH_PREFIX + getTheme() + ITheme.THEME_STYLESHEET;
return THEME_PATH_PREFIX + getTheme() + ITheme.THEME_STYLESHEET;
}
/**
* @return url of theme stylesheet by browser
*/
public static String getStyleSheetByBrowser() {
return ITheme.THEME_PATH_PREFIX + getTheme() + ITheme.THEME_STYLESHEET_BY_BROWSER;
return THEME_PATH_PREFIX + getTheme() + ITheme.THEME_STYLESHEET_BY_BROWSER;
}
/**
* @return url of theme preference page
*/
public static String getPreference() {
return ITheme.THEME_PATH_PREFIX + getTheme() + ITheme.THEME_PREFERENCE;
return THEME_PATH_PREFIX + getTheme() + ITheme.THEME_PREFERENCE;
}
/**
@ -117,7 +135,7 @@ public final class ThemeManager {
*/
public static String getBrowserIcon() {
String theme = getTheme();
String def = ITheme.THEME_PATH_PREFIX + theme + ITheme.BROWSER_ICON_IMAGE;
String def = THEME_PATH_PREFIX + theme + ITheme.BROWSER_ICON_IMAGE;
return MSysConfig.getValue(MSysConfig.ZK_BROWSER_ICON, def);
}
@ -127,7 +145,7 @@ public final class ThemeManager {
* @return full resource url
*/
public static String getThemeResource(String name) {
StringBuilder builder = new StringBuilder(ITheme.THEME_PATH_PREFIX);
StringBuilder builder = new StringBuilder(THEME_PATH_PREFIX);
builder.append(getTheme());
builder.append("/").append(name);
String url = builder.toString().intern();
@ -173,7 +191,7 @@ public final class ThemeManager {
}
private static final CCache<String, Boolean> s_themeHasCustomCSSCache = new CCache<String, Boolean>(null, "ThemeHasCustomCSSCache", 2, -1, false);
/**
* @return true if custom css exists
*/
@ -182,7 +200,8 @@ public final class ThemeManager {
Boolean flag = s_themeHasCustomCSSCache.get(theme);
if (flag != null)
return flag;
if (ThemeManager.class.getResource(ITheme.THEME_PATH_PREFIX + theme + "/css/fragment/custom.css.dsp") == null) {
String customCSSURL = THEME_PATH_PREFIX + theme + "/css/fragment/custom.css.dsp";
if (ThemeManager.class.getResource(toClassPathResourcePath(customCSSURL)) == null) {
flag = Boolean.FALSE;
} else {
flag = Boolean.TRUE;
@ -197,5 +216,19 @@ public final class ThemeManager {
public static boolean isUseFontIconForImage() {
return "Y".equals(Env.getContext(Env.getCtx(), ITheme.USE_FONT_ICON_FOR_IMAGE));
}
}
/**
* @param zkResourceURL zk resource url for classpath resources (url start with ~./)
* @return Resource path for lookup/loading through class loader (absolute path start with /web)
*/
public static String toClassPathResourcePath(String zkResourceURL) {
if (zkResourceURL == null)
return zkResourceURL;
if (!zkResourceURL.startsWith(ZK_URL_PREFIX_FOR_CLASSPATH_RESOURCE))
return zkResourceURL;
return ZK_PREFIX_FOR_CLASSPATH_RESOURCE+zkResourceURL.substring(2);
}
}

View File

@ -74,13 +74,21 @@ public class WebUIResourceFinder implements IResourceFinder {
}
} else if (url == null && name.startsWith("images/")) {
String t = ThemeManager.getThemeResource(name);
e = find(t);
url = e != null && e.hasMoreElements() ? e.nextElement() : null;
if (url == null && t.endsWith(".gif")) {
t = t.replace(".gif", ".png");
if (t.startsWith(ThemeManager.ZK_URL_PREFIX_FOR_CLASSPATH_RESOURCE)) {
url = ThemeManager.class.getResource(ThemeManager.toClassPathResourcePath(t));
} else {
e = find(t);
url = e != null && e.hasMoreElements() ? e.nextElement() : null;
}
if (url == null && t.endsWith(".gif")) {
t = t.replace(".gif", ".png");
if (t.startsWith(ThemeManager.ZK_URL_PREFIX_FOR_CLASSPATH_RESOURCE)) {
url = ThemeManager.class.getResource(ThemeManager.toClassPathResourcePath(t));
} else {
e = find(t);
url = e != null && e.hasMoreElements() ? e.nextElement() : null;
}
}
} else if (url == null && name.endsWith(".gif")) {
String t = name.replace(".gif", ".png");
e = find(t);

View File

@ -7,7 +7,7 @@
.z-grid tbody tr.grid-inactive-row td.row-indicator-selected {
background-color: #DCDAD4 !important;
background-image: url(${c:encodeURL('/theme/default/images/EditRecord16.png')}) !important;
background-image: url(${c:encodeURL('~./theme/default/images/EditRecord16.png')}) !important;
background-position: center;
background-repeat: no-repeat;
background-size: 16px 16px;
@ -27,7 +27,7 @@
.z-grid tbody tr.highlight td.row-indicator-selected {
background-color: #FFFFCC !important;
background-image: url(${c:encodeURL('/theme/default/images/EditRecord16.png')}) !important;
background-image: url(${c:encodeURL('~./theme/default/images/EditRecord16.png')}) !important;
background-position: center;
background-repeat: no-repeat;
background-size: 16px 16px;

View File

Before

Width:  |  Height:  |  Size: 588 B

After

Width:  |  Height:  |  Size: 588 B

View File

Before

Width:  |  Height:  |  Size: 933 B

After

Width:  |  Height:  |  Size: 933 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 503 B

After

Width:  |  Height:  |  Size: 503 B

View File

Before

Width:  |  Height:  |  Size: 645 B

After

Width:  |  Height:  |  Size: 645 B

View File

Before

Width:  |  Height:  |  Size: 466 B

After

Width:  |  Height:  |  Size: 466 B

View File

Before

Width:  |  Height:  |  Size: 636 B

After

Width:  |  Height:  |  Size: 636 B

View File

Before

Width:  |  Height:  |  Size: 622 B

After

Width:  |  Height:  |  Size: 622 B

View File

Before

Width:  |  Height:  |  Size: 639 B

After

Width:  |  Height:  |  Size: 639 B

View File

Before

Width:  |  Height:  |  Size: 808 B

After

Width:  |  Height:  |  Size: 808 B

View File

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 592 B

View File

Before

Width:  |  Height:  |  Size: 916 B

After

Width:  |  Height:  |  Size: 916 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 464 B

After

Width:  |  Height:  |  Size: 464 B

View File

Before

Width:  |  Height:  |  Size: 678 B

After

Width:  |  Height:  |  Size: 678 B

View File

Before

Width:  |  Height:  |  Size: 616 B

After

Width:  |  Height:  |  Size: 616 B

View File

Before

Width:  |  Height:  |  Size: 815 B

After

Width:  |  Height:  |  Size: 815 B

View File

Before

Width:  |  Height:  |  Size: 961 B

After

Width:  |  Height:  |  Size: 961 B

View File

Before

Width:  |  Height:  |  Size: 551 B

After

Width:  |  Height:  |  Size: 551 B

View File

Before

Width:  |  Height:  |  Size: 719 B

After

Width:  |  Height:  |  Size: 719 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 589 B

After

Width:  |  Height:  |  Size: 589 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 559 B

After

Width:  |  Height:  |  Size: 559 B

View File

Before

Width:  |  Height:  |  Size: 546 B

After

Width:  |  Height:  |  Size: 546 B

View File

Before

Width:  |  Height:  |  Size: 656 B

After

Width:  |  Height:  |  Size: 656 B

View File

Before

Width:  |  Height:  |  Size: 619 B

After

Width:  |  Height:  |  Size: 619 B

View File

Before

Width:  |  Height:  |  Size: 843 B

After

Width:  |  Height:  |  Size: 843 B

View File

Before

Width:  |  Height:  |  Size: 603 B

After

Width:  |  Height:  |  Size: 603 B

View File

Before

Width:  |  Height:  |  Size: 678 B

After

Width:  |  Height:  |  Size: 678 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 773 B

After

Width:  |  Height:  |  Size: 773 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 844 B

After

Width:  |  Height:  |  Size: 844 B

View File

Before

Width:  |  Height:  |  Size: 310 B

After

Width:  |  Height:  |  Size: 310 B

View File

Before

Width:  |  Height:  |  Size: 737 B

After

Width:  |  Height:  |  Size: 737 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 603 B

After

Width:  |  Height:  |  Size: 603 B

View File

Before

Width:  |  Height:  |  Size: 691 B

After

Width:  |  Height:  |  Size: 691 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 974 B

After

Width:  |  Height:  |  Size: 974 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 803 B

After

Width:  |  Height:  |  Size: 803 B

View File

Before

Width:  |  Height:  |  Size: 267 B

After

Width:  |  Height:  |  Size: 267 B

View File

Before

Width:  |  Height:  |  Size: 619 B

After

Width:  |  Height:  |  Size: 619 B

View File

Before

Width:  |  Height:  |  Size: 920 B

After

Width:  |  Height:  |  Size: 920 B

View File

Before

Width:  |  Height:  |  Size: 793 B

After

Width:  |  Height:  |  Size: 793 B

View File

Before

Width:  |  Height:  |  Size: 913 B

After

Width:  |  Height:  |  Size: 913 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Some files were not shown because too many files have changed in this diff Show More