Index: src/main/java/com/xpn/xwiki/plugin/skinx/AbstractDocumentSkinExtensionPlugin.java =================================================================== --- src/main/java/com/xpn/xwiki/plugin/skinx/AbstractDocumentSkinExtensionPlugin.java (revision 26058) +++ src/main/java/com/xpn/xwiki/plugin/skinx/AbstractDocumentSkinExtensionPlugin.java (working copy) @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.Collection; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; @@ -38,6 +39,7 @@ import com.xpn.xwiki.notify.XWikiDocChangeNotificationInterface; import com.xpn.xwiki.notify.XWikiNotificationRule; import com.xpn.xwiki.objects.classes.BaseClass; +import com.xpn.xwiki.objects.BaseObject; /** * Abstract SX plugin for wiki-document-based extensions (Extensions written as object of a XWiki Extension class). @@ -174,6 +176,26 @@ /** * {@inheritDoc} + * + * @see com.xpn.xwiki.plugin.skinx.AbstractSkinExtensionPlugin#hasPageExtensions(com.xpn.xwiki.XWikiContext) + */ + @Override + public boolean hasPageExtensions(XWikiContext context) + { + XWikiDocument doc = context.getDoc(); + Collection objects = doc.getObjects(getExtensionClassName()); + if (objects != null) { + for (BaseObject obj : objects) { + if (obj.getStringValue(USE_FIELDNAME).equals("currentPage")) { + return true; + } + } + } + return false; + } + + /** + * {@inheritDoc} *

* We must override this method since the plugin manager only calls it for classes that provide their own * implementation, and not an inherited one. @@ -199,6 +221,7 @@ try { XWikiDocument doc = context.getWiki().getDocument(getExtensionClassName(), context); boolean needsUpdate = false; + String useOptions = "onDemand=On demand|always=Always on this wiki|currentPage=Always on this page"; BaseClass bclass = doc.getxWikiClass(); if (context.get("initdone") != null) { @@ -210,7 +233,7 @@ needsUpdate |= bclass.addTextField("name", "Name", 30); needsUpdate |= bclass.addTextAreaField("code", "Code", 50, 20); needsUpdate |= - bclass.addStaticListField(USE_FIELDNAME, "Use this extension", "onDemand=On demand|always=Always"); + bclass.addStaticListField(USE_FIELDNAME, "Use this extension", useOptions); needsUpdate |= bclass.addBooleanField("parse", "Parse content", "yesno"); needsUpdate |= bclass.addStaticListField("cache", "Caching policy", "long|short|default|forbid"); Index: src/main/java/com/xpn/xwiki/plugin/skinx/AbstractResourceSkinExtensionPlugin.java =================================================================== --- src/main/java/com/xpn/xwiki/plugin/skinx/AbstractResourceSkinExtensionPlugin.java (revision 26058) +++ src/main/java/com/xpn/xwiki/plugin/skinx/AbstractResourceSkinExtensionPlugin.java (working copy) @@ -100,4 +100,19 @@ // extensions. return Collections.emptySet(); } + + /** + * {@inheritDoc} + * + * @see com.xpn.xwiki.plugin.skinx.AbstractSkinExtensionPlugin#hasPageExtensions(com.xpn.xwiki.XWikiContext) + * + *

+ * Not supported for resource extensions. + *

+ */ + @Override + public boolean hasPageExtensions(XWikiContext context) + { + return false; + } } Index: src/main/java/com/xpn/xwiki/plugin/skinx/AbstractSkinExtensionPlugin.java =================================================================== --- src/main/java/com/xpn/xwiki/plugin/skinx/AbstractSkinExtensionPlugin.java (revision 26058) +++ src/main/java/com/xpn/xwiki/plugin/skinx/AbstractSkinExtensionPlugin.java (working copy) @@ -103,6 +103,14 @@ public abstract Set getAlwaysUsedExtensions(XWikiContext context); /** + * Specifies if the requested document contains on page skin extension objects of this type. StyleSheet extensions + * that are searched have a use property which can have the value currentPage. + * @param context the current request context. + * @return A boolean specifying if the requested document contains on page skin extensions. + */ + public abstract boolean hasPageExtensions(XWikiContext context); + + /** * {@inheritDoc} * * @see com.xpn.xwiki.plugin.XWikiDefaultPlugin#getPluginApi @@ -210,18 +218,22 @@ public String getImportString(XWikiContext context) { StringBuilder result = new StringBuilder(); + //Using LinkedHashSet to preserve the extensions order. + Set extensions = new LinkedHashSet(); // First, we add to the import string the extensions that should always be used. // TODO Global extensions should be able to select a set of actions for which they are enabled. - for (String docName : getAlwaysUsedExtensions(context)) { - result.append(getLink(docName, context)); + extensions.addAll(getAlwaysUsedExtensions(context)); + + // Then, we add On-Demand extensions for this request. + extensions.addAll(getPulledResources(context)); + + //Add On-Page extensions + if (hasPageExtensions(context)) { + extensions.add(context.getDoc().getFullName()); } - // Then, we add On-Demand extensions for this request, from which we remove the - // extensions that were already in the "always use". - Set requestList = getPulledResources(context); - // Remove all extensions already requested through "use always". - requestList.removeAll(getAlwaysUsedExtensions(context)); - for (String docName : requestList) { - result.append(getLink(docName, context)); + + for (String documentName : extensions) { + result.append(getLink(documentName, context)); } return result.toString(); } Index: src/main/java/com/xpn/xwiki/plugin/skinx/CssSkinFileExtensionPlugin.java =================================================================== --- src/main/java/com/xpn/xwiki/plugin/skinx/CssSkinFileExtensionPlugin.java (revision 26058) +++ src/main/java/com/xpn/xwiki/plugin/skinx/CssSkinFileExtensionPlugin.java (working copy) @@ -81,7 +81,7 @@ /** * {@inheritDoc} * - * @see SkinExtensionPlugin#getLink(String, XWikiContext) + * @see AbstractSkinExtensionPlugin#getLink(String, XWikiContext) */ @Override public String getLink(String filename, XWikiContext context) @@ -127,4 +127,19 @@ { return Collections.emptySet(); } + + /** + * {@inheritDoc} + * + * @see com.xpn.xwiki.plugin.skinx.AbstractSkinExtensionPlugin#hasPageExtensions(com.xpn.xwiki.XWikiContext) + * + *

+ * Not supported for skinfile-based extensions. + *

+ */ + @Override + public boolean hasPageExtensions(XWikiContext context) + { + return false; + } } Index: src/main/java/com/xpn/xwiki/plugin/skinx/JsSkinFileExtensionPlugin.java =================================================================== --- src/main/java/com/xpn/xwiki/plugin/skinx/JsSkinFileExtensionPlugin.java (revision 26058) +++ src/main/java/com/xpn/xwiki/plugin/skinx/JsSkinFileExtensionPlugin.java (working copy) @@ -127,4 +127,19 @@ { return Collections.emptySet(); } + + /** + * {@inheritDoc} + * + * @see com.xpn.xwiki.plugin.skinx.AbstractSkinExtensionPlugin#hasPageExtensions(com.xpn.xwiki.XWikiContext) + * + *

+ * Not supported for skinfile-based extensions. + *

+ */ + @Override + public boolean hasPageExtensions(XWikiContext context) + { + return false; + } } Index: src/main/java/com/xpn/xwiki/plugin/skinx/LinkExtensionPlugin.java =================================================================== --- src/main/java/com/xpn/xwiki/plugin/skinx/LinkExtensionPlugin.java (revision 26058) +++ src/main/java/com/xpn/xwiki/plugin/skinx/LinkExtensionPlugin.java (working copy) @@ -71,7 +71,21 @@ /** * {@inheritDoc} + * + * @see com.xpn.xwiki.plugin.skinx.AbstractSkinExtensionPlugin#hasPageExtensions(com.xpn.xwiki.XWikiContext) *

+ * Not supported for link extensions. + *

+ */ + @Override + public boolean hasPageExtensions(XWikiContext context) + { + return false; + } + + /** + * {@inheritDoc} + *

* We must override this method since the plugin manager only calls it for classes that provide their own * implementation, and not an inherited one. *