TAP5-2612: Allow the usage of Tapestry without Bootstrap (CSS framework)
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java b/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
index b11a3cd..899d6b8 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
@@ -17,9 +17,11 @@
import org.apache.tapestry5.corelib.components.BeanEditor;
import org.apache.tapestry5.corelib.mixins.FormGroup;
import org.apache.tapestry5.internal.services.AssetDispatcher;
+import org.apache.tapestry5.modules.NoBootstrapModule;
import org.apache.tapestry5.services.Html5Support;
import org.apache.tapestry5.services.assets.AssetPathConstructor;
import org.apache.tapestry5.services.assets.ResourceMinimizer;
+import org.apache.tapestry5.services.compatibility.Trait;
import org.apache.tapestry5.services.javascript.JavaScriptStack;
/**
@@ -209,10 +211,15 @@
public static final String START_PAGE_NAME = "tapestry.start-page-name";
/**
- * The default stylesheet automatically inserted into every rendered HTML page.
+ * The default stylesheet automatically inserted into every rendered HTML page when
+ * no Bootstrap version is enabled (i.e both {@link Trait#BOOTSTRAP_3} and {@link Trait#BOOTSTRAP_4}
+ * traits are disabled, something done by {@linkplain NoBootstrapModule}).
+ *
+ * It was deprecated in 5.4 with no replacement (the stylesheet is now associated with the core {@link JavaScriptStack}.),
+ * but undeprecated in 5.5.0 with the caveat described above.
*
+ * @see NoBootstrapModule
* @since 5.2.0
- * @deprecated Deprecated in 5.4 with no replacement; the stylesheet is now associated with the core {@link JavaScriptStack}.
*/
public static final String DEFAULT_STYLESHEET = "tapestry.default-stylesheet";
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java
index 19081fe..4f267d8 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/JavaScriptModule.java
@@ -164,6 +164,11 @@
addCoreStylesheets(configuration, "${" + SymbolConstants.BOOTSTRAP_ROOT + "}/css/bootstrap.css");
addCoreStylesheets(configuration, "${" + SymbolConstants.BOOTSTRAP_ROOT + "}/css/bootstrap-grid.css");
}
+
+ if (!compatibility.enabled(Trait.BOOTSTRAP_3) && !compatibility.enabled(Trait.BOOTSTRAP_4))
+ {
+ configuration.add("defaultcss", StackExtension.stylesheet("${" + SymbolConstants.DEFAULT_STYLESHEET + "}"));
+ }
for (String name : bundledModules)
{
@@ -393,15 +398,9 @@
if (compatibility.enabled(Trait.BOOTSTRAP_3))
{
- configuration.add("bootstrap/transition", new AMDWrapper(transition).require("jquery", "$").asJavaScriptModuleConfiguration());
-
- for (String name : new String[]{"affix", "alert", "button", "carousel", "collapse", "dropdown", "modal",
- "scrollspy", "tab", "tooltip"})
- {
- Resource lib = transition.forFile(name + ".js");
-
- configuration.add("bootstrap/" + name, new AMDWrapper(lib).require("bootstrap/transition").asJavaScriptModuleConfiguration());
- }
+ final String[] modules = new String[]{"affix", "alert", "button", "carousel", "collapse", "dropdown", "modal",
+ "scrollspy", "tab", "tooltip"};
+ addBootstrap3Modules(configuration, transition, modules);
Resource popover = transition.forFile("popover.js");
@@ -428,12 +427,31 @@
}
}
+ // Just the minimum to have alerts and AJAX validation working when Bootstrap
+ // is completely disabled
+ if (!compatibility.enabled(Trait.BOOTSTRAP_3) && !compatibility.enabled(Trait.BOOTSTRAP_4))
+ {
+ final String[] modules = new String[]{"alert", "dropdown", "collapse"};
+ addBootstrap3Modules(configuration, transition, modules);
+ }
+
configuration.add("t5/core/typeahead", new JavaScriptModuleConfiguration(typeahead).dependsOn("jquery"));
configuration.add("moment", new JavaScriptModuleConfiguration(moment));
}
+ private static void addBootstrap3Modules(MappedConfiguration<String, Object> configuration, Resource transition, final String[] modules) {
+ configuration.add("bootstrap/transition", new AMDWrapper(transition).require("jquery", "$").asJavaScriptModuleConfiguration());
+
+ for (String name : modules)
+ {
+ Resource lib = transition.forFile(name + ".js");
+
+ configuration.add("bootstrap/" + name, new AMDWrapper(lib).require("bootstrap/transition").asJavaScriptModuleConfiguration());
+ }
+ }
+
@Contribute(SymbolProvider.class)
@FactoryDefaults
public static void setupFactoryDefaults(MappedConfiguration<String, Object> configuration)
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/NoBootstrapModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/NoBootstrapModule.java
new file mode 100644
index 0000000..bb894df
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/NoBootstrapModule.java
@@ -0,0 +1,37 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.modules;
+
+import org.apache.tapestry5.SymbolConstants;
+import org.apache.tapestry5.ioc.MappedConfiguration;
+import org.apache.tapestry5.ioc.annotations.Contribute;
+import org.apache.tapestry5.services.compatibility.Compatibility;
+import org.apache.tapestry5.services.compatibility.Trait;
+
+/**
+ * Module which defines the options needed to run Tapestry without Bootstrap. You'll need
+ * to define the CSS file to be included in all pages by setting the
+ * <code>tapestry.default-stylesheet</code> configuration symbol
+ * ({@link SymbolConstants#DEFAULT_STYLESHEET}). Notice Tapestry will not provide any
+ * CSS, so you're on your own regarding stylesheets.
+ *
+ * @since 5.5
+ */
+public class NoBootstrapModule
+{
+ @Contribute(Compatibility.class)
+ public static void setupCompatibilityDefaults(MappedConfiguration<Trait, Boolean> configuration)
+ {
+ configuration.add(Trait.BOOTSTRAP_3, false);
+ }
+}
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
index ad96765..9ecddaa 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/modules/TapestryModule.java
@@ -2023,8 +2023,6 @@
configuration.add(SymbolConstants.START_PAGE_NAME, "start");
- configuration.add(SymbolConstants.DEFAULT_STYLESHEET, "${" + SymbolConstants.BOOTSTRAP_ROOT + "}/css/bootstrap.css");
-
configuration.add(SymbolConstants.PRODUCTION_MODE, true);
configuration.add(SymbolConstants.CLUSTERED_SESSIONS, true);
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
index 89300a2..c47e7b9 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
@@ -42,6 +42,7 @@
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.services.ServiceOverride;
import org.apache.tapestry5.modules.Bootstrap4Module;
+import org.apache.tapestry5.modules.NoBootstrapModule;
import org.apache.tapestry5.services.BaseURLSource;
import org.apache.tapestry5.services.BeanBlockContribution;
import org.apache.tapestry5.services.BeanBlockSource;
@@ -55,6 +56,8 @@
import org.apache.tapestry5.services.Response;
import org.apache.tapestry5.services.ValueEncoderFactory;
import org.apache.tapestry5.services.ValueLabelProvider;
+import org.apache.tapestry5.services.compatibility.Compatibility;
+import org.apache.tapestry5.services.compatibility.Trait;
import org.apache.tapestry5.services.pageload.PagePreloader;
import org.apache.tapestry5.services.pageload.PreloaderMode;
import org.apache.tapestry5.services.security.ClientWhitelist;
@@ -66,6 +69,7 @@
* I was just dying to see how fast requests are!
*/
//@ImportModule(Bootstrap4Module.class)
+//@ImportModule(NoBootstrapModule.class)
public class AppModule
{
@@ -177,6 +181,7 @@
configuration.add(D3_URL_SYMBOL, "cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.js");
configuration.add(SymbolConstants.PRELOADER_MODE, PreloaderMode.ALWAYS);
// configuration.add(SymbolConstants.ERROR_CSS_CLASS, "yyyy");
+// configuration.add(SymbolConstants.DEFAULT_STYLESHEET, "classpath:/org/apache/tapestry5/integration/app1/app1.css");
}
public static void contributeIgnoredPathsFilter(Configuration<String> configuration)
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/app1.css b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/app1.css
new file mode 100644
index 0000000..3f0e07d
--- /dev/null
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/app1.css
@@ -0,0 +1,3 @@
+.well {
+ background-color: grey;
+}
\ No newline at end of file