com.phloc.css.tools.MediaQueryTools Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of phloc-css-jdk5 Show documentation
Show all versions of phloc-css-jdk5 Show documentation
phloc CSS parser an other components
The newest version!
/**
* Copyright (C) 2006-2014 phloc systems
* http://www.phloc.com
* office[at]phloc[dot]com
*
* 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 com.phloc.css.tools;
import java.nio.charset.Charset;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import com.phloc.commons.ValueEnforcer;
import com.phloc.commons.annotations.Nonempty;
import com.phloc.commons.annotations.PresentForCodeCoverage;
import com.phloc.commons.collections.ContainerHelper;
import com.phloc.commons.string.StringHelper;
import com.phloc.css.ECSSVersion;
import com.phloc.css.decl.CSSImportRule;
import com.phloc.css.decl.CSSMediaQuery;
import com.phloc.css.decl.CSSMediaRule;
import com.phloc.css.decl.CSSNamespaceRule;
import com.phloc.css.decl.CascadingStyleSheet;
import com.phloc.css.decl.ICSSTopLevelRule;
import com.phloc.css.reader.CSSReader;
/**
* A small utility class to wrap an existing {@link CascadingStyleSheet} within
* a specific media, if possible. {@link CascadingStyleSheet} can only be
* wrapped, if they don't contain a media rule themselves.
*
* @author Philip Helger
*/
@Immutable
public final class MediaQueryTools
{
@SuppressWarnings ("unused")
@PresentForCodeCoverage
private static final MediaQueryTools s_aInstance = new MediaQueryTools ();
private MediaQueryTools ()
{}
@Nullable
@Deprecated
public static List parseToMediaQuery (@Nullable final String sMediaQuery,
@Nonnull final Charset aCharset,
@Nonnull final ECSSVersion eVersion)
{
return parseToMediaQuery (sMediaQuery, eVersion);
}
@Nullable
public static List parseToMediaQuery (@Nullable final String sMediaQuery,
@Nonnull final ECSSVersion eVersion)
{
if (StringHelper.hasNoText (sMediaQuery))
return null;
final String sCSS = "@media " + sMediaQuery + " {}";
final CascadingStyleSheet aCSS = CSSReader.readFromString (sCSS, eVersion);
if (aCSS == null)
return null;
final CSSMediaRule aMediaRule = aCSS.getAllMediaRules ().get (0);
return aMediaRule.getAllMediaQueries ();
}
/**
* Check if the passed CSS can be wrapped in an external media rule. This
* method is now deprecated because nested media queries are now allowed.
*
* @param aCSS
* The CSS to be checked for wrapping. May be null
.
* @return true
if the CSS can be wrapped, false
if
* it can't be wrapped.
*/
@Deprecated
public static boolean canWrapInMediaQuery (@Nullable final CascadingStyleSheet aCSS)
{
// false was the previous handling
return canWrapInMediaQuery (aCSS, false);
}
/**
* Check if the passed CSS can be wrapped in an external media rule.
*
* @param aCSS
* The CSS to be checked for wrapping. May be null
.
* @param bAllowNestedMediaQueries
* if true
nested media queries are allowed,
* false
if they are prohibited.
* @return true
if the CSS can be wrapped, false
if
* it can't be wrapped.
*/
public static boolean canWrapInMediaQuery (@Nullable final CascadingStyleSheet aCSS,
final boolean bAllowNestedMediaQueries)
{
if (aCSS == null)
return false;
if (bAllowNestedMediaQueries)
return true;
// Nested media queries are not allowed, therefore wrapping can only take
// place if no other media queries are present
return !aCSS.hasMediaRules ();
}
/**
* Get the CSS wrapped in the specified media query. Note: all existing rule
* objects are reused, so modifying them also modifies the original CSS!
*
* @param aCSS
* The CSS to be wrapped. May not be null
.
* @param aMediaQuery
* The media query to use.
* @return null
if out CSS cannot be wrapped, the newly created
* {@link CascadingStyleSheet} object otherwise.
*/
@Nullable
@Deprecated
public static CascadingStyleSheet getWrappedInMediaQuery (@Nonnull final CascadingStyleSheet aCSS,
@Nonnull final CSSMediaQuery aMediaQuery)
{
// false was the old default value
return getWrappedInMediaQuery (aCSS, aMediaQuery, false);
}
/**
* Get the CSS wrapped in the specified media query. Note: all existing rule
* objects are reused, so modifying them also modifies the original CSS!
*
* @param aCSS
* The CSS to be wrapped. May not be null
.
* @param aMediaQuery
* The media query to use.
* @param bAllowNestedMediaQueries
* if true
nested media queries are allowed,
* false
if they are prohibited.
* @return null
if out CSS cannot be wrapped, the newly created
* {@link CascadingStyleSheet} object otherwise.
*/
@Nullable
public static CascadingStyleSheet getWrappedInMediaQuery (@Nonnull final CascadingStyleSheet aCSS,
@Nonnull final CSSMediaQuery aMediaQuery,
final boolean bAllowNestedMediaQueries)
{
return getWrappedInMediaQuery (aCSS, ContainerHelper.newList (aMediaQuery), bAllowNestedMediaQueries);
}
/**
* Get the CSS wrapped in the specified media query. Note: all existing rule
* objects are reused, so modifying them also modifies the original CSS!
*
* @param aCSS
* The CSS to be wrapped. May not be null
.
* @param aMediaQueries
* The media queries to use. May neither be null
nor empty
* nor may it contain null
elements.
* @return null
if out CSS cannot be wrapped, the newly created
* {@link CascadingStyleSheet} object otherwise.
*/
@Nullable
@Deprecated
public static CascadingStyleSheet getWrappedInMediaQuery (@Nonnull final CascadingStyleSheet aCSS,
@Nonnull @Nonempty final List aMediaQueries)
{
// false was the old default value
return getWrappedInMediaQuery (aCSS, aMediaQueries, false);
}
/**
* Get the CSS wrapped in the specified media query. Note: all existing rule
* objects are reused, so modifying them also modifies the original CSS!
*
* @param aCSS
* The CSS to be wrapped. May not be null
.
* @param aMediaQueries
* The media queries to use. May neither be null
nor empty
* nor may it contain null
elements.
* @param bAllowNestedMediaQueries
* if true
nested media queries are allowed,
* false
if they are prohibited.
* @return null
if out CSS cannot be wrapped, the newly created
* {@link CascadingStyleSheet} object otherwise.
*/
@Nullable
public static CascadingStyleSheet getWrappedInMediaQuery (@Nonnull final CascadingStyleSheet aCSS,
@Nonnull @Nonempty final Iterable extends CSSMediaQuery> aMediaQueries,
final boolean bAllowNestedMediaQueries)
{
ValueEnforcer.notNull (aCSS, "CSS");
ValueEnforcer.notEmpty (aMediaQueries, "MediaQueries");
if (!canWrapInMediaQuery (aCSS, bAllowNestedMediaQueries))
return null;
final CascadingStyleSheet ret = new CascadingStyleSheet ();
// Copy all import rules
for (final CSSImportRule aImportRule : aCSS.getAllImportRules ())
{
if (aImportRule.hasMediaQueries ())
{
// import rule already has a media query - do not alter
ret.addImportRule (aImportRule);
}
else
{
// Create a new rule and add the passed media queries
final CSSImportRule aNewImportRule = new CSSImportRule (aImportRule.getLocation ());
for (final CSSMediaQuery aMediaQuery : aMediaQueries)
aNewImportRule.addMediaQuery (aMediaQuery);
ret.addImportRule (aNewImportRule);
}
}
// Copy all namespace rules
for (final CSSNamespaceRule aNamespaceRule : aCSS.getAllNamespaceRules ())
ret.addNamespaceRule (aNamespaceRule);
// Create a single top-level media rule ...
// into this media rule
final CSSMediaRule aNewMediaRule = new CSSMediaRule ();
for (final CSSMediaQuery aMediaQuery : aMediaQueries)
aNewMediaRule.addMediaQuery (aMediaQuery);
// ... and add the existing top-level rules into this media rule
for (final ICSSTopLevelRule aRule : aCSS.getAllRules ())
aNewMediaRule.addRule (aRule);
// Finally add the resulting media rule into the new CSS
ret.addRule (aNewMediaRule);
return ret;
}
}