001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.markup.head;
018
019import java.util.Objects;
020
021import org.apache.wicket.request.mapper.parameter.PageParameters;
022import org.apache.wicket.request.resource.ResourceReference;
023
024/**
025 * Base class for all {@link HeaderItem}s that represent stylesheets. This class mainly contains
026 * factory methods.
027 * 
028 * @author papegaaij
029 */
030public abstract class CssHeaderItem extends AbstractCspHeaderItem
031{
032        private static final long serialVersionUID = 1L;
033
034        private String markupId;
035
036        /**
037         * @return an optional markup id for the <link> HTML element that will be rendered
038         * for this header item
039         */
040        public String getId()
041        {
042                return markupId;
043        }
044
045        /**
046         * @param markupId
047         *          an optional markup id for this header item
048         * @return {@code this} object, for method chaining
049         */
050        public CssHeaderItem setId(String markupId)
051        {
052                this.markupId = markupId;
053                return this;
054        }
055
056        /**
057         * Creates a {@link CssReferenceHeaderItem} for the given reference.
058         * 
059         * @param reference
060         *            a reference to a CSS resource
061         * @return A newly created {@link CssReferenceHeaderItem} for the given reference.
062         */
063        public static CssReferenceHeaderItem forReference(ResourceReference reference)
064        {
065                return forReference(reference, null);
066        }
067
068        /**
069         * Creates a {@link CssReferenceHeaderItem} for the given reference.
070         * 
071         * @param reference
072         *            a reference to a CSS resource
073         * @param media
074         *            the media type for this CSS ("print", "screen", etc.)
075         * @return A newly created {@link CssReferenceHeaderItem} for the given reference.
076         */
077        public static CssReferenceHeaderItem forReference(ResourceReference reference, String media)
078        {
079                return forReference(reference, null, media);
080        }
081
082        /**
083         * Creates a {@link CssReferenceHeaderItem} for the given reference.
084         * 
085         * @param reference
086         *            a reference to a CSS resource
087         * @param pageParameters
088         *            the parameters for this CSS resource reference
089         * @param media
090         *            the media type for this CSS ("print", "screen", etc.)
091         * @return A newly created {@link CssReferenceHeaderItem} for the given reference.
092         */
093        public static CssReferenceHeaderItem forReference(ResourceReference reference,
094                PageParameters pageParameters, String media)
095        {
096                return new CssReferenceHeaderItem(reference, pageParameters, media);
097        }
098
099        /**
100         * Creates a {@link CssReferenceHeaderItem} for the given reference.
101         *
102         * <strong>Warning</strong>: the conditional comments don't work when injected dynamically with
103         * JavaScript (i.e. in Ajax response). An alternative solution is to use user agent sniffing at
104         * the server side: <code><pre>
105         * public void renderHead(IHeaderResponse response) {
106         *   WebClientInfo clientInfo = (WebClientInfo) getSession().getClientInfo();
107         *   ClientProperties properties = clientInfo.getProperties();
108         *   if (properties.isBrowserInternetExplorer() &amp;&amp; properties.getBrowserVersionMajor() &gt;= 8) {
109         *     response.renderCSSReference(new PackageResourceReference(MyPage.class, "my-conditional.css" ));
110         *   }
111         * }
112         * </pre></code>
113         *
114         * @param reference
115         *            a reference to a CSS resource
116         * @param pageParameters
117         *            the parameters for this CSS resource reference
118         * @param media
119         *            the media type for this CSS ("print", "screen", etc.)
120         * @param rel
121         *            the rel attribute content
122         * @return A newly created {@link CssReferenceHeaderItem} for the given reference.
123         */
124        public static CssReferenceHeaderItem forReference(ResourceReference reference,
125                PageParameters pageParameters, String media, String rel)
126        {
127                return new CssReferenceHeaderItem(reference, pageParameters, media, rel);
128        }
129
130        /**
131         * Creates a {@link CssContentHeaderItem} for the given content.
132         * 
133         * @param css
134         *            css content to be rendered.
135         * @param id
136         *            unique id for the &lt;style&gt; element. This can be <code>null</code>, however in
137         *            that case the ajax header contribution can't detect duplicate CSS fragments.
138         * @return A newly created {@link CssContentHeaderItem} for the given content.
139         */
140        public static CssContentHeaderItem forCSS(CharSequence css, String id)
141        {
142                return new CssContentHeaderItem(css, id);
143        }
144        
145        /**
146         * Creates a {@link CssUrlReferenceHeaderItem} for the given url.
147         * 
148         * @param url
149         *            context-relative url of the CSS resource
150         * @return A newly created {@link CssUrlReferenceHeaderItem} for the given url.
151         */
152        public static CssUrlReferenceHeaderItem forUrl(String url)
153        {
154                return forUrl(url, null);
155        }
156
157        /**
158         * Creates a {@link CssUrlReferenceHeaderItem} for the given url.
159         * 
160         * @param url
161         *            context-relative url of the CSS resource
162         * @param media
163         *            the media type for this CSS ("print", "screen", etc.)
164         * @return A newly created {@link CssUrlReferenceHeaderItem} for the given url.
165         */
166        public static CssUrlReferenceHeaderItem forUrl(String url, String media)
167        {
168                return new CssUrlReferenceHeaderItem(url, media);
169        }
170
171        /**
172         * Creates a {@link CssUrlReferenceHeaderItem} for the given url.
173         *
174         * <strong>Warning</strong>: the conditional comments don't work when injected dynamically with
175         * JavaScript (i.e. in Ajax response). An alternative solution is to use user agent sniffing at
176         * the server side: <code><pre>
177         * public void renderHead(IHeaderResponse response) {
178         *   WebClientInfo clientInfo = (WebClientInfo) getSession().getClientInfo();
179         *   ClientProperties properties = clientInfo.getProperties();
180         *   if (properties.isBrowserInternetExplorer() &amp;&amp; properties.getBrowserVersionMajor() &gt;= 8) {
181         *     response.renderCSSReference(new PackageResourceReference(MyPage.class, "my-conditional.css" ));
182         *   }
183         * }
184         * </pre></code>
185         *
186         * @param url
187         *            context-relative url of the CSS resource
188         * @param media
189         *            the media type for this CSS ("print", "screen", etc.)
190         * @param rel
191         *            the rel attribute content
192         * @return A newly created {@link CssUrlReferenceHeaderItem} for the given url.
193         */
194        public static CssUrlReferenceHeaderItem forUrl(String url, String media, String rel)
195        {
196                return new CssUrlReferenceHeaderItem(url, media, rel);
197        }
198
199        @Override
200        public boolean equals(Object o)
201        {
202                if (this == o) return true;
203                if (o == null || getClass() != o.getClass()) return false;
204                CssHeaderItem that = (CssHeaderItem) o;
205                return Objects.equals(markupId, that.markupId);
206        }
207
208        @Override
209        public int hashCode()
210        {
211                return Objects.hash(markupId);
212        }
213}