| /* |
| * 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. |
| */ |
| |
| package org.apache.royale.compiler.internal.css; |
| |
| import org.antlr.runtime.TokenStream; |
| import org.antlr.runtime.tree.CommonTree; |
| |
| import org.apache.royale.compiler.css.ICSSProperty; |
| import org.apache.royale.compiler.css.ICSSPropertyValue; |
| |
| import com.google.common.base.Joiner; |
| import com.google.common.base.Strings; |
| |
| /** |
| * Implementation for a CSS property. |
| */ |
| public class CSSProperty extends CSSNodeBase implements ICSSProperty |
| { |
| protected CSSProperty(final String name, final CSSPropertyValue value, final CommonTree tree, final TokenStream tokenStream) |
| { |
| super(tree, tokenStream, CSSModelTreeType.PROPERTY); |
| assert !Strings.isNullOrEmpty(name) : "CSS property name can't be empty."; |
| assert value != null : "CSS property name can't be null."; |
| this.rawName = name; |
| this.normalizedName = normalize(name); |
| this.value = value; |
| } |
| |
| private final String normalizedName; |
| private final String rawName; |
| private final CSSPropertyValue value; |
| |
| @Override |
| public String getName() |
| { |
| return normalizedName; |
| } |
| |
| @Override |
| public ICSSPropertyValue getValue() |
| { |
| return value; |
| } |
| |
| @Override |
| public String toString() |
| { |
| if (rawName.equalsIgnoreCase("border") && value instanceof CSSArrayPropertyValue) |
| { |
| CSSArrayPropertyValue borderValues = (CSSArrayPropertyValue)value; |
| return String.format("%s: %s;", rawName, Joiner.on(" ").join(borderValues.getElements())); |
| } |
| return String.format("%s: %s;", rawName, value.toString()); |
| } |
| |
| public String toCSSString() |
| { |
| String cssName = rawName; |
| if (!rawName.equals(rawName.toLowerCase())) |
| { |
| cssName = cssName.replaceAll("[A-Z]", "-$0").toLowerCase(); |
| } |
| if (cssName.equals("content") && value instanceof CSSStringPropertyValue) |
| { |
| return String.format("%s: \"%s\";", cssName, escape(((CSSStringPropertyValue)value).getValue())); |
| } |
| if (value instanceof CSSStringPropertyValue) |
| { |
| return String.format("%s: %s;", cssName, ((CSSStringPropertyValue)value).getValue()); |
| } |
| if (value instanceof CSSFunctionCallPropertyValue) |
| { |
| return String.format("%s: %s;", cssName, ((CSSFunctionCallPropertyValue)value).toString()); |
| } |
| return String.format("%s: %s;", cssName, value.toString()); |
| } |
| |
| |
| /** |
| * Normalize CSS property names to camel-case style names. Names alread in |
| * camel-cases will be returned as-is. |
| * <p> |
| * For example:<br> |
| * {@code normalize("font-family")} returns {@code "fontFamily"}.<br> |
| * {@code normalize("fontFamily")} returns {@code "fontFamily"}. |
| * |
| * @param name CSS property name |
| * @return Camel-case style name. |
| */ |
| protected static String normalize(final String name) |
| { |
| if (name == null) |
| return null; |
| |
| final StringBuilder result = new StringBuilder(); |
| |
| boolean lastCharIsHyphen = false; |
| boolean isFirstChar = true; |
| for (int i = 0; i < name.length(); i++) |
| { |
| final char c = name.charAt(i); |
| if ('-' == c) |
| { |
| lastCharIsHyphen = true; |
| } |
| else if (lastCharIsHyphen) |
| { |
| result.append(Character.toUpperCase(c)); |
| lastCharIsHyphen = false; |
| } |
| else if (isFirstChar) |
| { |
| result.append(Character.toLowerCase(c)); |
| isFirstChar = false; |
| } |
| else |
| { |
| result.append(c); |
| } |
| } |
| |
| return result.toString(); |
| } |
| |
| private String escape(String content) |
| { |
| if (content.length() == 1 && content.codePointAt(0) > 255) |
| { |
| int code = content.codePointAt(0); |
| content = Integer.toHexString(code); |
| return "\\" + content; |
| } |
| return content; |
| } |
| } |