package com.intellij.flex.uiDesigner.mxml; import com.intellij.flex.uiDesigner.InvalidPropertyException; import com.intellij.flex.uiDesigner.css.CssPropertyType; import com.intellij.flex.uiDesigner.io.Amf3Types; import com.intellij.flex.uiDesigner.io.PrimitiveAmfOutputStream; import com.intellij.flex.uiDesigner.io.StringRegistry; import com.intellij.javascript.flex.css.FlexCssPropertyDescriptor; import com.intellij.lang.javascript.flex.AnnotationBackedDescriptor; import com.intellij.lang.javascript.psi.JSCommonTypeNames; import com.intellij.psi.xml.XmlElement; import com.intellij.xml.util.ColorMap; import org.jetbrains.annotations.Nullable; import java.util.Locale; public class PrimitiveWriter { protected final StringRegistry.StringWriter stringWriter; protected final PrimitiveAmfOutputStream out; public PrimitiveWriter(PrimitiveAmfOutputStream out, StringRegistry.StringWriter stringWriter) { this.out = out; this.stringWriter = stringWriter; stringWriter.startChange(); } public void stringReference(int reference) { out.write(AmfExtendedTypes.STRING_REFERENCE); out.writeUInt29(reference); } public void stringReference(String reference) { out.write(AmfExtendedTypes.STRING_REFERENCE); stringWriter.write(reference, out); } public void string(CharSequence value) { out.write(Amf3Types.STRING); out.writeAmfUtf(value, false); } public void color(XmlElement element, String value, boolean isPrimitiveStyle) throws InvalidPropertyException { out.write(AmfExtendedTypes.COLOR_STYLE); if (value.charAt(0) == '#') { if (isPrimitiveStyle) { out.write(CssPropertyType.COLOR_INT); } value = value.substring(1); } else if (value.charAt(0) == '0' && value.length() > 2 && value.charAt(1) == 'x') { if (isPrimitiveStyle) { out.write(CssPropertyType.COLOR_INT); } value = value.substring(2); } else { final String colorName = value.toLowerCase(Locale.ENGLISH); String hexCodeForColorName = ColorMap.getHexCodeForColorName(colorName); if (hexCodeForColorName == null) { try { long v = Long.parseLong(colorName); if (isPrimitiveStyle) { out.write(CssPropertyType.COLOR_INT); } out.writeAmfUInt(v); return; } catch (NumberFormatException ignored) { // Why themeColor for theme halo valid for any other theme? But it is compiler behavior, see // example http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/components/Form.html // or our test EmbedSwfAndImageFromCss if (colorName.equalsIgnoreCase("halogreen")) { hexCodeForColorName = "#80FF4D"; } else if (colorName.equalsIgnoreCase("haloblue")) { hexCodeForColorName = "#009DFF"; } else if (colorName.equalsIgnoreCase("haloorange")) { hexCodeForColorName = "#FFB600"; } else if (colorName.equalsIgnoreCase("halosilver")) { hexCodeForColorName = "#AECAD9"; } else { throw new InvalidPropertyException(element, "invalid.color.name", colorName); } } } if (isPrimitiveStyle) { out.write(CssPropertyType.COLOR_STRING); stringWriter.writeNullable(colorName, out); } value = hexCodeForColorName.substring(1); } if (value.length() > 6) { out.writeAmfUInt(Long.parseLong(value, 16)); } else { out.writeAmfUInt(Integer.parseInt(value, 16)); } } public boolean writeIfApplicable(XmlElementValueProvider valueProvider, PrimitiveAmfOutputStream out, AnnotationBackedDescriptor descriptor) throws InvalidPropertyException { return writeIfApplicable(valueProvider, descriptor.getType(), out, descriptor, false, false); } public boolean writeIfApplicable(XmlElementValueProvider valueProvider, String type, PrimitiveAmfOutputStream out, @Nullable AnnotationBackedDescriptor descriptor, boolean isStyle, boolean emptyNumericAs0) throws InvalidPropertyException { if (type.equals(JSCommonTypeNames.STRING_CLASS_NAME)) { writeString(valueProvider, descriptor); } else if (type.equals(JSCommonTypeNames.NUMBER_CLASS_NAME) || type.equals(JSCommonTypeNames.INT_TYPE_NAME) || type.equals(JSCommonTypeNames.UINT_TYPE_NAME)) { final String trimmed = valueProvider.getTrimmed(); if (trimmed.isEmpty()) { if (emptyNumericAs0) { out.writeAmfInt(0); return true; } else { throw new InvalidPropertyException(valueProvider.getElement(), "invalid.numeric.value"); } } if (type.equals(JSCommonTypeNames.NUMBER_CLASS_NAME)) { out.writeAmfDouble(trimmed); } else if (descriptor != null && FlexCssPropertyDescriptor.COLOR_FORMAT.equals(descriptor.getFormat())) { color(valueProvider.getElement(), trimmed, isStyle); } else { out.writeAmfInt(trimmed); } } else if (type.equals(JSCommonTypeNames.BOOLEAN_CLASS_NAME)) { out.writeAmfBoolean(valueProvider.getTrimmed()); } else { return false; } return true; } void writeString(XmlElementValueProvider valueProvider, @Nullable AnnotationBackedDescriptor descriptor) { if (descriptor != null && descriptor.isEnumerated()) { stringReference(valueProvider.getTrimmed()); } else { CharSequence v = writeIfEmpty(valueProvider); if (v != null) { string(v); } } } @Nullable CharSequence writeIfEmpty(XmlElementValueProvider valueProvider) { CharSequence v = valueProvider.getSubstituted(); if (v == XmlElementValueProvider.EMPTY) { stringReference(XmlElementValueProvider.EMPTY); return null; } else { return v; } } }