Javascript Translation

Dec 28, 2010 at 12:48 AM

Just a little class I whipped up to translate between .NET and JSValue and back again.  Figured it might be useful to either include in the wrapper OR just for folks reading this?  :-)  

I've not had chance to test it since JS communication seems broken in RC2.. but it's simple enough.. watch this space!

 

    /// <summary>
    /// Defines the functionality required to translate to and from Awesomium Javascript values and C# types.
    /// </summary>
    /// <author>John Hardy</author>
    /// <date>25th September 2010</date>
    public abstract class JSTranslator
    {
        #region To Javascript
        /// <summary>
        /// Copy a null value into a JSValue.
        /// </summary>
        /// <returns>A JSValue which contains a null value.</returns>
        public static JSValue copy()
        {
            return new JSValue();
        }

        /// <summary>
        /// Copy a String value into a JSValue.
        /// </summary>
        /// <param name="sValue">The value we want to convert.</param>
        /// <returns>A JSValue which contains our value.</returns>
        public static JSValue copy(String sValue)
        {
            return new JSValue(sValue);
        }

        /// <summary>
        /// Copy an Integer value into a JSValue.
        /// </summary>
        /// <param name="iValue">The value we want to convert.</param>
        /// <returns>A JSValue which contains our value.</returns>
        public static JSValue copy(int iValue)
        {
            return new JSValue(iValue);
        }

        /// <summary>
        /// Copy an Double value into a JSValue.
        /// </summary>
        /// <param name="fValue">The value we want to convert.</param>
        /// <returns>A JSValue which contains our value.</returns>
        public static JSValue copy(double fValue)
        {
            return new JSValue(fValue);
        }

        /// <summary>
        /// Copy an Float value into a JSValue (as a double).
        /// </summary>
        /// <param name="fValue">The value we want to convert.</param>
        /// <returns>A JSValue which contains our value.</returns>
        public static JSValue copy(float fValue)
        {
            return new JSValue((double)fValue);
        }

        /// <summary>
        /// Copy a Boolean value into a JSValue.
        /// </summary>
        /// <param name="bValue">The value we want to convert.</param>
        /// <returns>A JSValue which contains our value.</returns>
        public static JSValue copy(bool bValue)
        {
            return new JSValue(bValue);
        }

        /// <summary>
        /// Copy a Dictionary value (and any children, recursively) into a JSValue.
        /// </summary>
        /// <remarks>Note, this clones the dictionary.</remarks>
        /// <param name="dTable">The value we want to convert.</param>
        /// <returns>A JSValue which contains our value.</returns>
        public static JSValue copy(IDictionary dTable)
        {
            // Check to see if we have a String key.
            Type[] tTypes = dTable.GetType().GetGenericArguments();
            if (tTypes.Length != 2)
                throw new ArgumentException("Cannot convert '"+dTable.ToString()+"' because it has '"+tTypes.Length+"' generic types rather than 2.");
            if (tTypes[0] != typeof(String))
                throw new ArgumentException("Cannot convert '"+dTable.ToString()+"' because it contains key values which are not of type String.");
            
            // For each key, value pair - copy it into another table of JSValues.
            Dictionary<String, JSValue> dClone = new Dictionary<string,JSValue>(dTable.Count);
            foreach (DictionaryEntry tEntry in dTable)
            {
                // Get the string representation of each item and then clone the value.
                dClone[tEntry.Key as String] = copy(tEntry.Value);
            }

            // Return the JSValue.
            return new JSValue(dClone);
        }

        /// <summary>
        /// Copy a List value (and any children, recursively) into a JSValue.
        /// </summary>
        /// <remarks>Note, this clones the list.</remarks>
        /// <param name="lCollection">The value we want to convert.</param>
        /// <returns>A JSValue which contains our value.</returns>
        public static JSValue copy(ICollection lCollection)
        {
            // For each item - copy it into another list of JSValues.
            Collection<JSValue> lClone = new Collection<JSValue>();
            foreach (object kElement in lCollection)
            {
                lClone.Add(copy(kElement));
            }

            // Return the JSValue.
            return new JSValue(lClone);
        }

        /// <summary>
        /// Copy an object into a JSValue.  This can translate the following types: Strings, integers, doubles, floats, booleans, characters, doubles, floats, booleans, dictionarys and collections.
        /// </summary>
        /// <param name="kData">The value we want to convert.</param>
        /// <returns>A JSValue which contains our value.</returns>
        public static JSValue copy(object kData)
        {
            // Cast it to the most appropriate type.
            if (kData is String)        return copy(kData as String);
            if (kData is char)          return copy("" + kData);
            if (kData is int)           return copy((int)kData);
            if (kData is double)        return copy((double)kData);
            if (kData is float)         return copy((float)kData);
            if (kData is bool)          return copy((bool)kData);
            if (kData is IDictionary)   return copy(kData as IDictionary);
            if (kData is ICollection)   return copy(kData as ICollection);
            if (kData == null)          return copy();

            // Use reflection to get at the fields of classes and structs?

            // Cannot convert this value.
            return null;
        }
        #endregion

        #region From Javascript
        /// <summary>
        /// Copy a JSValue into the appropriate .NET objects.
        /// </summary>
        /// <param name="pValue">The value we want to convert.</param>
        /// <returns>An object which contains our value.</returns>
        public static object copy(JSValue pValue)
        {
            // Parse out the primitive (ish) types.
            if (pValue.IsString)    return pValue.ToString();
            if (pValue.IsBoolean)   return pValue.ToBoolean();
            if (pValue.IsDouble)    return pValue.ToDouble();
            if (pValue.IsInteger)   return pValue.ToInteger();
            if (pValue.IsNull)      return null;

            // Tables.
            if (pValue.IsObject)
            {
                Dictionary<String, object> dClone = new Dictionary<String, object>();
                foreach (KeyValuePair<String, JSValue> pPair in pValue.GetObject())
                {
                    dClone[pPair.Key] = copy(pPair.Value);
                }
                return dClone;
            }

            // Collections.
            if (pValue.IsArray)
            {
                IEnumerable<JSValue> lSource = pValue.GetArray();
                List<object> lClone = new List<object>();
                foreach (JSValue pItem in lSource)
                {
                    lClone.Add(pItem);
                }
                return lClone;
            }

            // Cannot convert this value.
            throw new ArgumentException();
        }
        #endregion