com.projetloki.genesis.BackgroundPosition Maven / Gradle / Ivy
The newest version!
package com.projetloki.genesis;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.List;
import com.google.common.base.Ascii;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;
/**
* A background-position.
* See
* www.w3.org.
*
* @author Clément Roux
*/
final class BackgroundPosition extends SimpleStringWrapper {
private static final Joiner SPACE_JOINER = Joiner.on(' ');
// See http://www.w3.org/TR/css3-background/#ltpositiongt
static BackgroundPosition from(String css) {
css = Ascii.toLowerCase(css);
List terms = ImmutableList.copyOf(
Splitter.on(Util.WHITESPACE).omitEmptyStrings().split(css));
checkArgument(!terms.isEmpty(), "empty");
if (3 <= terms.size()) {
return fromMoreTerms(terms);
}
String first = terms.get(0);
boolean firstHKeyword = isHorizontalKeyword(first);
boolean firstVKeyword = isVerticalKeyword(first);
boolean keyword = firstHKeyword || firstVKeyword;
checkArgument(Util.isDimensionOrPercentage(first) || keyword,
"unexpected term: %s", first);
if (terms.size() == 1) {
// According to the CSS specification "3px" is equivalent to "3px center"
// We find that very confusing, so we make it illegal
checkArgument(firstHKeyword || firstVKeyword,
"term expected after %s", first);
return new BackgroundPosition(first);
}
String second = terms.get(1);
if (firstVKeyword && !firstHKeyword) {
// From the CSS specification:
// Note that a pair of keywords can be reordered while a combination of
// keyword and length or percentage cannot. So 'center left' is valid
// while '50% left' is not.
checkArgument(isHorizontalKeyword(second),
"unexpected term: %s", second);
String temp = first;
first = second;
second = temp;
} else {
checkArgument(
Util.isDimensionOrPercentage(second) || isVerticalKeyword(second),
"unexpected term: %s", second);
}
return create(first, second);
}
// From the CSS specification
// If three or four values are given, then each or
// represents an offset and must be preceded by a keyword, which specifies
// from which edge the offset is given. For example,
// ‘background-position: bottom 10px right 20px’ represents a ‘10px’ vertical
// offset up from the bottom edge and a ‘20px’ horizontal offset leftward
// from the right edge. If three values are given, the missing offset is
// assumed to be zero.
private static BackgroundPosition fromMoreTerms(List terms) {
PeekingIterator iterator =
Iterators.peekingIterator(terms.iterator());
String first = iterator.next();
boolean firstHKeyword = isHorizontalKeyword(first);
boolean firstVertical = isVerticalKeyword(first);
boolean firstCenter = firstHKeyword && firstVertical;
checkArgument(firstHKeyword || firstVertical,
"unexpected term: %s", first);
// horizontalKeyword && verticalKeyword means center
if (!firstCenter) {
String dim = iterator.peek();
if (Util.isDimensionOrPercentage(dim)) {
iterator.next();
}
}
String second = iterator.next();
boolean secondHKeyword = isHorizontalKeyword(second);
boolean secondVKeyword = isVerticalKeyword(second);
boolean secondCenter = secondHKeyword && secondVKeyword;
checkArgument(secondHKeyword || secondVKeyword,
"unexpected term: %s", second);
if (iterator.hasNext() && !secondCenter) {
String dim = iterator.next();
checkArgument(Util.isDimensionOrPercentage(dim),
"unexpected term: %s", dim);
}
if (iterator.hasNext()) {
String next = iterator.next();
throw new IllegalArgumentException("unexpected term: " + next);
}
checkArgument(
firstCenter || secondCenter || firstHKeyword == secondVKeyword,
"unexpected term: %s", second);
return new BackgroundPosition(SPACE_JOINER.join(terms));
}
private static final ImmutableSet HORIZONTAL_KEYWORDS =
ImmutableSet.of("left", "center", "right");
private static final ImmutableSet VERTICAL_KEYWORDS =
ImmutableSet.of("top", "center", "bottom");
private static boolean isHorizontalKeyword(String input) {
return HORIZONTAL_KEYWORDS.contains(input);
}
private static boolean isVerticalKeyword(String input) {
return VERTICAL_KEYWORDS.contains(input);
}
// We choose the shortest representation,
// e.g. "right".length() < "100% 0".length()
static final BackgroundPosition LEFT_TOP =
new BackgroundPosition("0 0");
static final BackgroundPosition LEFT = new BackgroundPosition("left");
static final BackgroundPosition LEFT_BOTTOM =
new BackgroundPosition("0 100%");
static final BackgroundPosition TOP = new BackgroundPosition("top");
static final BackgroundPosition CENTER =
new BackgroundPosition("center");
static final BackgroundPosition BOTTOM =
new BackgroundPosition("bottom");
static final BackgroundPosition RIGHT_TOP =
new BackgroundPosition("100% 0");
static final BackgroundPosition RIGHT =
new BackgroundPosition("right");
static final BackgroundPosition RIGHT_BOTTOM =
new BackgroundPosition("100% 100%");
static BackgroundPosition px(int left, int top) {
return create(LengthUnit.PX.format(left), LengthUnit.PX.format(top));
}
static BackgroundPosition pxPct(int left, double top) {
return create(LengthUnit.PX.format(left), Format.percentageOrZero(top));
}
static BackgroundPosition pctPx(double left, int top) {
return create(Format.percentageOrZero(left), LengthUnit.PX.format(top));
}
static BackgroundPosition pct(double left, double top) {
return create(Format.percentageOrZero(left), Format.percentageOrZero(top));
}
private static BackgroundPosition create(String left, String top) {
return new BackgroundPosition(left + " " + top);
}
private BackgroundPosition(String css) {
super(css);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy