<!--
/***************************************************************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 ***************************************************************************************************************************/
 -->

Stylesheets

<p>
	The sample root page renders in the default "devops" look-and-feel:
</p>
<p class='bpcode w800'>
	http://localhost:10000
</p>
<img class='bordered w800' src='doc-files/juneau-rest-server.Stylesheets.0.png'>
<p>
	The sample root page provides a dropdown widget to try out the other default look-and-feels:
</p>
<img class='bordered' src='doc-files/juneau-rest-server.Stylesheets.1.png'/>
<p>
	For example, the "light" look-and-feel:
</p>
<p class='bpcode w800'>
	http://localhost:10000/?stylesheet=styles%2Flight.css
</p>
<img class='bordered w800' src='doc-files/juneau-rest-server.Stylesheets.2.png'>
<p>
	And the "dark" look-and-feel:
</p>
<p class='bpcode w800'>
	http://localhost:10000/?stylesheet=styles%2Fdark.css
</p>
<img class='bordered w800' src='doc-files/juneau-rest-server.Stylesheets.3.png'>
<p>
	The stylesheet URL is controlled by the {@link oaj.html.annotation.HtmlDocConfig#stylesheet() @HtmlDocConfig(stylesheet)} annotation.
	The {@link oajr.BasicRestServlet} class defines the stylesheet served up as a static file:
<p class='bpcode w800'>
	<ja>@Rest</ja>(
		htmldoc=<ja>@HtmlDoc</ja>(
			stylesheet=<js>"$C{REST/stylesheet,servlet:/styles/devops.css}"</js>,
		),
	
		staticFiles={<js>"styles:styles"</js>}
	)
	<jk>public abstract class</jk> BasicRestServlet <jk>extends</jk> RestServlet {...}
</p>		
<p>
	The <js>"$C{REST/stylesheet,servlet:/styles/devops.css}"</js> variable says to use the URI defined
	in your servlet's config file, if there is one, and to default to serving up the file
	<c>org/apache/juneau/rest/styles/devops.css</c>.
</p>
<p>
	To provide your own stylesheet, simply override the stylesheet attribute and point to a different
	file:	
</p>
<p class='bpcode w800'>
	<ja>@Rest</ja>(
		htmldoc=<ja>@HtmlDoc</ja>(
			stylesheet=<js>"servlet:/my-styles/my-style.css}"</js>,
		),
		staticFiles={<js>"my-styles:my-styles"</js>}
	)
	<jk>public class</jk> MyResourceBaseClass <jk>extends</jk> BasicRestServlet {...}
</p>
<p>
	You can try out different stylesheets by passing in a <c>stylesheet</c> attribute in the request
	URL.
	The example above show this in use.
</p>
<p>
	In case you're curious about how the menu item works, it's defined via a widget:
</p>
<p class='bpcode w800'>
	<ja>@Rest</ja>(
		htmldoc=<ja>@HtmlDoc</ja>(
			widgets={
				PoweredByApache.<jk>class</jk>,
				ContentTypeMenuItem.<jk>class</jk>,
				StyleMenuItem.<jk>class</jk>
			},
			navlinks={
				<js>"options: ?method=OPTIONS"</js>,
				<js>"$W{ContentTypeMenuItem}"</js>,
				<js>"$W{StyleMenuItem}"</js>,
				<js>"source: $C{Source/gitHub}/org/apache/juneau/examples/rest/$R{servletClassSimple}.java"</js>
			},
	)
	<jk>public class</jk> RootResources <jk>extends</jk> BasicRestServletJenaGroup {...}
</p>
<p>
	The <l>StyleMenuItem</l> is a widget that extends from {@link oajr.widget.MenuItemWidget}, a
	specialized widget for creating pop-up menus.
	In the case of <l>StyleMenuItem</l>, it's simply returning a list of links wrapped in a div tag:
</p>
<p class='bpcode w800'>
	<jk>import static</jk> org.apache.juneau.dto.html5.HtmlBuilder.*;

	<jk>public class</jk> StyleMenuItem <jk>extends</jk> MenuItemWidget {
	
		<jk>private static final</jk> String[] <jsf>BUILT_IN_STYLES</jsf> = {<js>"devops"</js>, <js>"light"</js>, <js>"original"</js>, <js>"dark"</js>};
	
		<ja>@Override</ja> <jc>/* Widget */</jc>
		<jk>public</jk> String getLabel(RestRequest req) {
			<jk>return</jk> <js>"styles"</js>;
		}

		<ja>@Override</ja> <jc>/* MenuItemWidget */</jc>
		<jk>public</jk> Div getContent(RestRequest req) <jk>throws</jk> Exception {
			Div div = <jsm>div</jsm>();
			<jk>for</jk> (String s : <jsf>BUILT_IN_STYLES</jsf>) {
				java.net.URI uri = req.getUri(<jk>true</jk>, <jk>new</jk> AMap&lt;String,String&gt;().append(<js>"stylesheet"</js>, <js>"styles/"</js>+s+<js>".css"</js>));
				div.children(<jsm>a</jsm>(uri, s), <jsm>br</jsm>());
			}
			<jk>return</jk> div;
		}
	}
</p>
