blob: 685c56fca58214443836c560c000e1253ec4e8b8 [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* 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.google.gwt.resources.css.ast;
import com.google.gwt.resources.css.ast.CssProperty.DotPathValue;
import com.google.gwt.resources.css.ast.CssProperty.ListValue;
import com.google.gwt.resources.css.ast.CssProperty.StringValue;
import com.google.gwt.resources.css.ast.CssProperty.Value;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* Represents a sprited image. This is basically a normal CssRule, except for
* one well-known property {@value CssSprite#IMAGE_PROPERTY_NAME}, which
* specifies the name of an ImageResource accessor.
*/
public class CssSprite extends CssRule {
public static final String IMAGE_PROPERTY_NAME = "gwt-image";
/**
* A facade for the underlying CssProperty list maintained by CssRule. We
* override the add and set methods to intercept the
* {@value CssSprite#IMAGE_PROPERTY_NAME} property.
*/
private class SpritePropertyList implements List<CssProperty> {
private final List<CssProperty> source;
public SpritePropertyList(List<CssProperty> source) {
this.source = source;
}
public boolean add(CssProperty o) {
if (!processProperty(o)) {
return source.add(o);
} else {
return false;
}
}
public void add(int index, CssProperty element) {
if (!processProperty(element)) {
source.add(index, element);
}
}
public boolean addAll(Collection<? extends CssProperty> c) {
return source.addAll(c);
}
public boolean addAll(int index, Collection<? extends CssProperty> c) {
return source.addAll(index, c);
}
public void clear() {
source.clear();
}
public boolean contains(Object o) {
return source.contains(o);
}
public boolean containsAll(Collection<?> c) {
return source.containsAll(c);
}
@Override
public boolean equals(Object o) {
return source.equals(o);
}
public CssProperty get(int index) {
return source.get(index);
}
@Override
public int hashCode() {
return source.hashCode();
}
public int indexOf(Object o) {
return source.indexOf(o);
}
public boolean isEmpty() {
return source.isEmpty();
}
public Iterator<CssProperty> iterator() {
return source.iterator();
}
public int lastIndexOf(Object o) {
return source.lastIndexOf(o);
}
public ListIterator<CssProperty> listIterator() {
return source.listIterator();
}
public ListIterator<CssProperty> listIterator(int index) {
return source.listIterator(index);
}
public CssProperty remove(int index) {
return source.remove(index);
}
public boolean remove(Object o) {
return source.remove(o);
}
public boolean removeAll(Collection<?> c) {
return source.removeAll(c);
}
public boolean retainAll(Collection<?> c) {
return source.retainAll(c);
}
public CssProperty set(int index, CssProperty element) {
if (!processProperty(element)) {
return source.set(index, element);
} else {
return source.remove(index);
}
}
public int size() {
return source.size();
}
public List<CssProperty> subList(int fromIndex, int toIndex) {
return source.subList(fromIndex, toIndex);
}
public Object[] toArray() {
return source.toArray();
}
public <T> T[] toArray(T[] a) {
return source.toArray(a);
}
}
private DotPathValue resourceFunction;
@Override
public List<CssProperty> getProperties() {
return new SpritePropertyList(super.getProperties());
}
public DotPathValue getResourceFunction() {
return resourceFunction;
}
public void setResourceFunction(DotPathValue resourceFunction) {
this.resourceFunction = resourceFunction;
}
@Override
public void traverse(CssVisitor visitor, Context context) {
if (visitor.visit(this, context)) {
visitor.acceptWithInsertRemove(selectors);
visitor.acceptWithInsertRemove(getProperties());
}
visitor.endVisit(this, context);
}
private boolean processProperty(CssProperty property) {
if (IMAGE_PROPERTY_NAME.equals(property.getName())) {
setImageProperty(property.getValues());
return true;
}
return false;
}
private void setImageProperty(Value value) {
StringValue stringValue;
ListValue listValue;
if ((stringValue = value.isStringValue()) != null) {
String s = stringValue.getValue();
// Allow the user to use both raw idents and quoted strings
if (s.startsWith("\"")) {
s = s.substring(1, s.length() - 1);
}
resourceFunction = new DotPathValue(s);
} else if ((listValue = value.isListValue()) != null) {
List<Value> values = listValue.getValues();
if (values.size() == 1) {
setImageProperty(values.get(0));
}
} else {
throw new IllegalArgumentException("The " + IMAGE_PROPERTY_NAME
+ " property of @sprite must have exactly one value");
}
}
}