From 3e20cadca1be33252adfa1bec921fee997b2266e Mon Sep 17 00:00:00 2001 From: hns Date: Fri, 23 Mar 2007 11:16:06 +0000 Subject: [PATCH] * Allow subskins of the currently rendered skin to be rendered using relative skin names ("#subskinName") * Fix minor bug in subskin parsing. --- src/helma/framework/ResponseTrans.java | 22 ++++++++++++++++++++++ src/helma/framework/core/Skin.java | 3 +++ src/helma/scripting/rhino/RhinoEngine.java | 11 +++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/helma/framework/ResponseTrans.java b/src/helma/framework/ResponseTrans.java index ef3ef1c7..cd386d37 100644 --- a/src/helma/framework/ResponseTrans.java +++ b/src/helma/framework/ResponseTrans.java @@ -113,6 +113,9 @@ public final class ResponseTrans extends Writer implements Serializable { // the message digest used to generate composed digests for ETag headers private transient MessageDigest digest; + // the skin current or last rendered skin + private transient volatile Skin activeSkin; + // the application Application app; @@ -823,6 +826,25 @@ public final class ResponseTrans extends Writer implements Serializable { skincache.put(id, skin); } + /** + * Set the skin currently being rendered, returning the previously active skin. + * @param skin the new active skin + * @return the previously active skin + */ + public Skin switchActiveSkin(Skin skin) { + Skin previousSkin = activeSkin; + activeSkin = skin; + return previousSkin; + } + + /** + * Return the skin currently being rendered, or none. + * @return the currently active skin + */ + public Skin getActiveSkin() { + return activeSkin; + } + /** * Set a cookie. * diff --git a/src/helma/framework/core/Skin.java b/src/helma/framework/core/Skin.java index a0f01cf2..131c9f86 100644 --- a/src/helma/framework/core/Skin.java +++ b/src/helma/framework/core/Skin.java @@ -256,6 +256,7 @@ public final class Skin { // register param object, remember previous one to reset afterwards Map handlers = res.getMacroHandlers(); Object previousParam = handlers.put("param", paramObject); + Skin previousSkin = res.switchActiveSkin(parentSkin); try { int written = offset; @@ -279,6 +280,7 @@ public final class Skin { } } finally { reval.skinDepth--; + res.switchActiveSkin(previousSkin); if (previousParam == null) { handlers.remove("param"); } else { @@ -422,6 +424,7 @@ public final class Skin { } b.append(source[i]); escape = false; + break; case '|': diff --git a/src/helma/scripting/rhino/RhinoEngine.java b/src/helma/scripting/rhino/RhinoEngine.java index 615188cf..ca074aab 100644 --- a/src/helma/scripting/rhino/RhinoEngine.java +++ b/src/helma/scripting/rhino/RhinoEngine.java @@ -596,10 +596,17 @@ public class RhinoEngine implements ScriptingEngine { * caching. */ public Skin getSkin(String protoName, String skinName) throws IOException { - SkinKey key = new SkinKey(protoName, skinName); + Skin skin; ResponseTrans res = getResponse(); + if (skinName.startsWith("#")) { + // evaluate relative subskin name against currently rendering skin + skin = res.getActiveSkin(); + return skin == null ? + null : skin.getSubskin(skinName.substring(1)); + } - Skin skin = res.getCachedSkin(key); + SkinKey key = new SkinKey(protoName, skinName); + skin = res.getCachedSkin(key); if (skin == null) { // retrieve res.skinpath, an array of objects that tell us where to look for skins