示例#1
0
        public static LayoutSettings LayoutFromJson(dynamic json)
        {
            var layout = new LayoutSettings();

            if (JsContext.@typeof(json) == "string")
            {
                layout.Mode = json;
            }
            else
            {
                if (json.mode)
                {
                    layout.Mode = json.mode;
                }
                if (json.additionalSettings)
                {
                    string[] keys = Std.JsonKeys(json.additionalSettings);
                    foreach (var key in keys)
                    {
                        layout.AdditionalSettings[key.ToLower()] = json.additionalSettings[key];
                    }
                }
            }
            return(layout);
        }
示例#2
0
        public static JsType GetType(object typeOrNameOrCtor, bool throwIfNotFound)
        {
            if (JsContext.@typeof(typeOrNameOrCtor) != "string")
            {
                if (JsContext.@typeof(typeOrNameOrCtor) == "function")
                {
                    return(typeOrNameOrCtor.As <JsCompilerFunction>()._type);
                }
                return(typeOrNameOrCtor.As <JsType>());
            }
            var name = typeOrNameOrCtor.As <JsString>();
            var gti  = name.As <JsString>().indexOf("`");

            if (gti != -1)
            {
                name = name.As <JsString>().substr(0, gti + 2).As <JsString>().replace("`", "$");
            }
            var type = JsCompiler.Types[name].As <JsType>();

            if (type == null)
            {
                if (throwIfNotFound)
                {
                    throw new JsError("JsType " + name + " was not found").As <Exception>();
                }
                return(null);
            }
            return(type);
        }
示例#3
0
        private static StaveSettings StavesFromJson(dynamic json)
        {
            StaveSettings staveSettings;

            if (JsContext.@typeof(json) == "string")
            {
                staveSettings = new StaveSettings(json);
            }
            else if (json.id)
            {
                staveSettings = new StaveSettings(json.id);
                if (json.additionalSettings)
                {
                    string[] keys2 = Std.JsonKeys(json.additionalSettings);
                    foreach (var key2 in keys2)
                    {
                        staveSettings.AdditionalSettings[key2.ToLower()] = json.additionalSettings[key2];
                    }
                }
            }
            else
            {
                return(new StaveSettings("score-tab"));
            }
            return(staveSettings);
        }
示例#4
0
        private static object Cast(object obj, string typeOrName)
        {
            if (obj == null)
            {
                return(obj);
            }
            var type = JsTypeHelper.GetType(typeOrName, true);

            if (Is(obj, type))
            {
                return(obj);
            }
            var converted = TryImplicitConvert(obj, type);

            if (converted != null)
            {
                return(converted);
            }
            var objTypeName = JsContext.@typeof(obj);

            if (JsContext.@typeof(obj.As <JsCompilerObject>().getTypeName) == "function")
            {
                objTypeName = obj.As <JsCompilerObject2>().getTypeName();
            }
            var msg = new JsArray("InvalidCastException: Cannot cast ", objTypeName, " to ", type.fullname, "Exception generated by JsRuntime").join("");

            throw new JsError(msg).As <Exception>();
        }
示例#5
0
        private static object TryConvert(object obj, string type)
        {
            var    objTypeName = JsContext.@typeof(obj);
            object oj;

            switch (objTypeName)
            {
            case "System.Int16":
                return(FromNumber(obj, type));

            case "System.Int32":
                return(FromNumber(obj, type));

            case "System.Int64":
                return(FromNumber(obj, type));

            case "System.Byte":
                return(FromNumber(obj, type));

            case "System.SByte":
                return(FromNumber(obj, type));

            case "System.UInt64":
                return(FromNumber(obj, type));

            case "System.UInt16":
                return(FromNumber(obj, type));

            case "System.UInt32":
                return(FromNumber(obj, type));

            default:
                return(null);
            }
        }
示例#6
0
        public bool TryGetValue(TKey key, out TValue value)
        {
            var hashKey = GetHashKey(key);
            var v       = this._table[hashKey];

            value = v.As <TValue>();
            return(JsContext.@typeof(v) != "undefined");
        }
示例#7
0
 static Extensions()
 {
     HtmlContext.window.setTimeout(() =>
     {
         var el = HtmlContext.document.createElement("a");
         HasInsertAdjacentElement = new JsNativeAction <JsString, SharpKit.Html4.HtmlElement>(el.As <SharpKit.Html4.HtmlElement>().insertAdjacentElement) != null;
         HasInnerText             = JsContext.@typeof(el.As <SharpKit.Html4.HtmlElement>().innerText) != "undefined";
     }, 0);
 }
示例#8
0
 private static JsImplType Typeof(object jsTypeOrName)
 {
     if (jsTypeOrName == null)
     {
         throw new JsError("Unknown type.").As <Exception>();
     }
     if (JsContext.@typeof(jsTypeOrName) == "string")
     {
         return(JsImplType.GetType(jsTypeOrName.As <string>(), true));
     }
     return(JsImplType._TypeOf(jsTypeOrName.As <JsType>()));
 }
示例#9
0
        public static JsType GetTypeIgnoreNamespace(string name, bool throwIfNotFound)
        {
            JsType type;
            var    cache = GetTypeIgnoreNamespaceCache;//arguments.callee.cache;

            if (cache != null)
            {
                type = cache[name].As <JsType>();
                if (JsContext.@typeof(type) != "undefined")
                {
                    if (throwIfNotFound && type == null)
                    {
                        throw new JsError("type " + name + " was not found with (with IgnoreNamespace).").As <Exception>();
                    }
                    return(type);
                }
            }
            if (name.As <JsString>().search(".") > -1)
            {
                var tokens = name.As <JsString>().split(".").As <JsArray>();
                name = tokens[tokens.length - 1].As <string>();
            }
            type = JsCompiler.Types[name].As <JsType>();
            var nameAfterNs = "." + name;

            if (type == null)
            {
                foreach (var p in JsCompiler.Types)
                {
                    if (p == name || p.As <JsString>().endsWith(nameAfterNs))
                    {
                        type = JsCompiler.Types[p].As <JsType>();
                        break;
                    }
                }
            }
            if (throwIfNotFound && type == null)
            {
                throw new JsError("type " + name + " was not found with (with IgnoreNamespace).").As <Exception>();
            }
            if (cache != null)
            {
                cache[name] = type ?? null;
            }
            return(type);
        }
示例#10
0
        public static JsFunction GetDelegate(object obj, JsFunction func)
        {
            var target = obj.As <JsCompilerObject>();

            if (target == null)
            {
                return(func);
            }
            if (JsContext.@typeof(func) == "string")
            {
                func = target.As <JsObject>()[func.As <JsString>()].As <JsFunction>();
            }
            var cache = target.__delegateCache;

            if (cache == null)
            {
                cache = new JsObject <JsDelegateFunction>();
                target.__delegateCache = cache;
            }
            var key = JsCompiler.GetHashKey(func);
            var del = cache[key];

            if (del == null)
            {
                del = new JsNativeFunc <object>(delegate()
                {
                    var del2 = JsContext.arguments.callee.As <JsDelegateFunction>();
                    return(del2.func.apply(del.target, JsContext.arguments.As <object[]>()));
                }).As <JsDelegateFunction>();
                del.func       = func;
                del.target     = target;
                del.isDelegate = true;
                cache[key]     = del;
            }
            return(del);
        }
示例#11
0
        private static JsType CompileType(JsType type)
        {
            var currentType = Types[type.fullname].As <JsType>() ?? type;

            if (currentType.ctors == null)
            {
                currentType.ctors = new JsObject();
            }
            if (!type.isCompiled)
            {
                var baseTypeResolved = false;
                if (currentType.baseType == null && currentType.baseTypeName != null)
                {
                    ResolveBaseType(type, currentType);
                    if (currentType.baseType != null)
                    {
                        baseTypeResolved = true;
                    }
                }
                ResolveInterfaces(type, currentType);
                foreach (var p in type.definition)
                {
                    if (p.As <JsString>().search("ctor") == 0) //isCtor
                    {
                        currentType.As <JsObject>()[p] = type.definition[p];
                        delete(type.definition[p]);
                        if (@typeof(currentType.commonPrototype) == "undefined")
                        {
                            currentType.commonPrototype = currentType.As <JsObject>()[p].As <JsFunction>().prototype.As <JsCompilerPrototype>();
                        }
                        else
                        {
                            currentType.As <JsObject>()[p].As <JsFunction>().prototype = currentType.commonPrototype;
                        }
                        currentType.ctors[p] = currentType.As <JsObject>()[p];
                    }
                    if (p == "cctor")
                    {
                        currentType.cctor = p.As <JsFunction>();
                    }
                }
                if (currentType.ctor == null)
                {
                    if (currentType.ns == null || currentType.ns == "")
                    {
                        var jsCtor = window.As <JsObject>()[currentType.name].As <JsFunction>();
                        if (JsTypeOf(jsCtor) == JavaScript.JsTypes.function || JsTypeOf(jsCtor) == JavaScript.JsTypes.@object)
                        {
                            currentType.ctor = jsCtor;
                        }
                    }
                    if (currentType.ctor == null && currentType.ctors != null)
                    {
                        //create default ctor anyway for generic argument passing, etc...
                        //var createCtor = true;
                        //foreach (var p in currentType.ctors)
                        //{
                        //    createCtor = false;
                        //    break;
                        //}
                        //if (createCtor)
                        //{
                        if (currentType.baseType != null)
                        {
                            currentType.ctor = CreateBaseCtor(currentType);
                        }
                        else
                        {
                            currentType.ctor = CreateEmptyCtor();
                        }
                        //}
                    }
                    if (currentType.ctor != null)
                    {
                        currentType.ctors["ctor"] = currentType.ctor;
                        if (@typeof(currentType.commonPrototype) == "undefined")
                        {
                            currentType.commonPrototype = currentType.ctor.prototype.As <JsCompilerPrototype>();
                        }
                        else
                        {
                            currentType.ctor.prototype = currentType.commonPrototype;
                        }
                    }
                }
                foreach (var p in currentType.ctors)
                {
                    var ctor = currentType.ctors[p].As <JsCompilerFunction>();
                    if (ctor._type == null)
                    {
                        ctor._type = currentType;
                    }
                }
                if (baseTypeResolved)
                {
                    _CopyObject(currentType.baseType.commonPrototype, currentType.commonPrototype);
                }
                foreach (var p in type.definition)
                {
                    var member = type.definition[p];
                    currentType.commonPrototype[p] = member;
                    if (JsContext.@typeof(member) == "function")
                    {
                        member.As <JsCompilerFunction>()._name = p;
                        member.As <JsCompilerFunction>()._type = currentType;
                    }
                }
                if (type.definition.As <JsCompilerPrototype>().toString != JsCompilerObject.prototype.toString)
                {
                    currentType.commonPrototype.toString = type.definition.As <JsCompilerPrototype>().toString;
                    //currentType.commonPrototype.toString.name = "toString"; //It's always readonly! (and forbidden in strict mode)
                    currentType.commonPrototype.toString._type = currentType;
                }
                foreach (var p in type.staticDefinition)
                {
                    var member = type.staticDefinition[p];
                    //TODO: if (@typeof(currentType.As<JsObject>()[p]) != "undefined")
                    //TODO:    throw new JsError("Reserved static member name " + p).As<Exception>();
                    currentType.As <JsObject>()[p] = member;
                    if (JsContext.@typeof(member) == "function")
                    {
                        member.As <JsCompilerFunction>()._name = p;
                        member.As <JsCompilerFunction>()._type = currentType;
                    }
                }
                type.isCompiled = true;
            }
            CompileEnum(currentType);
            if (currentType != type && type.customAttributes != null)
            {
                if (currentType.customAttributes != null)
                {
                    for (var i = 0; i < type.customAttributes.length; i++)
                    {
                        currentType.customAttributes.push(type.customAttributes[i]);
                    }
                }
                else
                {
                    currentType.customAttributes = type.customAttributes;
                }
            }

            return(currentType);
        }
示例#12
0
        private static JsType CompileType(JsType type)
        {
            var currentType = Types[type.fullname].As <JsType>() ?? type;

            if (currentType.ctors == null)
            {
                currentType.ctors = new JsObject();
            }
            if (!type.isCompiled)
            {
                var baseTypeResolved = false;
                if (currentType.baseType == null && currentType.baseTypeName != null)
                {
                    ResolveBaseType(type, currentType);
                    if (currentType.baseType != null)
                    {
                        baseTypeResolved = true;
                    }
                }
                ResolveInterfaces(type, currentType);
                foreach (var p in type.definition)
                {
                    if (p.As <JsString>().search("ctor") == 0) //isCtor
                    {
                        currentType.As <JsObject>()[p] = type.definition[p];
                        JsContext.delete(type.definition[p]);
                        if (JsContext.@typeof(currentType.commonPrototype) == "undefined")
                        {
                            currentType.commonPrototype = currentType.As <JsObject>()[p].As <JsFunction>().prototype.As <JsCompilerPrototype>();
                        }
                        else
                        {
                            currentType.As <JsObject>()[p].As <JsFunction>().prototype = currentType.commonPrototype;
                        }
                        currentType.ctors[p] = currentType.As <JsObject>()[p];
                    }
                    if (p == "cctor")
                    {
                        currentType.cctor = p.As <JsFunction>();
                    }
                }
                //		if(currentType.ctor==null)
                //		{
                //			currentType.ctor = window[type.get_FullName()];
                //		}
                if (currentType.ctor == null)
                {
                    if (currentType.ns == null || currentType.ns == "")
                    {
                        var jsCtor = window.As <JsObject>()[currentType.name].As <JsFunction>();
                        currentType.ctor = jsCtor;
                    }
                    //			currentType.ctor = type.definition[type.name];
                    //			if(type.definition[type.name]!=null)
                    //				delete type.definition[type.name];
                    //			else
                    if (currentType.ctor == null && currentType.ctors != null)
                    {
                        var createCtor = true;
                        foreach (var p in currentType.ctors)
                        {
                            createCtor = false;
                            break;
                        }
                        if (createCtor)
                        {
                            if (currentType.baseType != null)
                            {
                                currentType.ctor = CreateBaseCtor();
                            }
                            else
                            {
                                currentType.ctor = CreateEmptyCtor();
                            }
                        }
                    }
                    if (currentType.ctor != null)
                    {
                        currentType.ctors["ctor"] = currentType.ctor;
                        if (JsContext.@typeof(currentType.commonPrototype) == "undefined")
                        {
                            currentType.commonPrototype = currentType.ctor.prototype.As <JsCompilerPrototype>();
                        }
                        else
                        {
                            currentType.ctor.prototype = currentType.commonPrototype;
                        }
                    }
                }
                foreach (var p in currentType.ctors)
                {
                    var ctor = currentType.ctors[p].As <JsCompilerFunction>();
                    if (ctor._type == null)
                    {
                        ctor._type = currentType;
                    }
                }
                //		if(currentType.ctor._type==null)
                //			currentType.ctor._type = currentType;
                if (baseTypeResolved)
                {
                    _CopyObject(currentType.baseType.commonPrototype, currentType.commonPrototype);
                }
                foreach (var p in type.definition)
                {
                    var member = type.definition[p];
                    currentType.commonPrototype[p] = member;
                    if (JsContext.@typeof(member) == "function")
                    {
                        member.As <JsCompilerFunction>()._name = p;
                        member.As <JsCompilerFunction>()._type = currentType;
                    }
                }
                if (type.definition.As <JsCompilerPrototype>().toString != JsCompilerObject.prototype.toString)
                {
                    currentType.commonPrototype.toString       = type.definition.As <JsCompilerPrototype>().toString;
                    currentType.commonPrototype.toString.name  = "toString";
                    currentType.commonPrototype.toString._type = currentType;
                }
                foreach (var p in type.staticDefinition)
                {
                    var member = type.staticDefinition[p];
                    //TODO: if (JsContext.@typeof(currentType.As<JsObject>()[p]) != "undefined")
                    //TODO:    throw new JsError("Reserved static member name " + p).As<Exception>();
                    currentType.As <JsObject>()[p] = member;
                    if (JsContext.@typeof(member) == "function")
                    {
                        member.As <JsCompilerFunction>()._name = p;
                        member.As <JsCompilerFunction>()._type = currentType;
                    }
                }
                type.isCompiled = true;
            }
            CompileEnum(currentType);
            if (currentType != type && type.customAttributes != null)
            {
                if (currentType.customAttributes != null)
                {
                    for (var i = 0; i < type.customAttributes.length; i++)
                    {
                        currentType.customAttributes.push(type.customAttributes[i]);
                    }
                }
                else
                {
                    currentType.customAttributes = type.customAttributes;
                }
            }

            return(currentType);
        }
示例#13
0
        public static void FillFromJson(Settings settings, dynamic json)
        {
            if (!json)
            {
                return;
            }
            if (Std.JsonExists(json, "scale"))
            {
                settings.Scale = json.scale;
            }
            if (Std.JsonExists(json, "width"))
            {
                settings.Width = json.width;
            }
            if (Std.JsonExists(json, "height"))
            {
                settings.Height = json.height;
            }
            if (Std.JsonExists(json, "engine"))
            {
                settings.Engine = json.engine;
            }
            if (Std.JsonExists(json, "stretchForce"))
            {
                settings.StretchForce = json.stretchForce;
            }
            if (Std.JsonExists(json, "forcePianoFingering"))
            {
                settings.ForcePianoFingering = json.forcePianoFingering;
            }

            if (Std.JsonExists(json, "layout"))
            {
                if (JsContext.@typeof(json.layout) == "string")
                {
                    settings.Layout.Mode = json.layout;
                }
                else
                {
                    if (json.layout.mode)
                    {
                        settings.Layout.Mode = json.layout.mode;
                    }
                    if (json.layout.additionalSettings)
                    {
                        string[] keys = Std.JsonKeys(json.layout.additionalSettings);
                        foreach (var key in keys)
                        {
                            settings.Layout.AdditionalSettings[key] = json.layout.additionalSettings[key];
                        }
                    }
                }
            }

            if (Std.JsonExists(json, "staves"))
            {
                settings.Staves = new FastList <StaveSettings>();
                string[] keys = Std.JsonKeys(json.staves);
                foreach (var key in keys)
                {
                    var val = json.staves[key];
                    if (JsContext.@typeof(val) == "string")
                    {
                        settings.Staves.Add(new StaveSettings(val));
                    }
                    else
                    {
                        if (val.id)
                        {
                            var staveSettings = new StaveSettings(val.id);
                            if (val.additionalSettings)
                            {
                                string[] keys2 = Std.JsonKeys(val.additionalSettings);
                                foreach (var key2 in keys2)
                                {
                                    staveSettings.AdditionalSettings[key2] = val.additionalSettings[key2];
                                }
                            }
                            settings.Staves.Add(staveSettings);
                        }
                    }
                }
            }
        }
示例#14
0
        public static Settings FromJson(dynamic json)
        {
            if (Std.InstanceOf <Settings>(json))
            {
                return((Settings)json);
            }

            var settings = Defaults;

            if (!json)
            {
                return(settings);
            }
            if (JsonExists(json, "scale"))
            {
                settings.Scale = json.scale;
            }
            if (JsonExists(json, "width"))
            {
                settings.Width = json.width;
            }
            if (JsonExists(json, "height"))
            {
                settings.Height = json.height;
            }
            if (JsonExists(json, "engine"))
            {
                settings.Engine = json.engine;
            }

            if (JsonExists(json, "layout"))
            {
                if (JsContext.@typeof(json.layout) == "string")
                {
                    settings.Layout.Mode = json.layout;
                }
                else
                {
                    if (json.layout.mode)
                    {
                        settings.Layout.Mode = json.layout.mode;
                    }
                    if (json.layout.additionalSettings)
                    {
                        string[] keys = JsonKeys(json.layout.additionalSettings);
                        foreach (var key in keys)
                        {
                            settings.Layout.AdditionalSettings[key] = json.layout.additionalSettings[key];
                        }
                    }
                }
            }

            if (JsonExists(json, "staves"))
            {
                settings.Staves = new FastList <StaveSettings>();
                string[] keys = JsonKeys(json.staves);
                foreach (var key in keys)
                {
                    var val = json.staves[key];
                    if (JsContext.@typeof(val) == "string")
                    {
                        settings.Staves.Add(new StaveSettings(val));
                    }
                    else
                    {
                        if (val.id)
                        {
                            var staveSettings = new StaveSettings(val.id);
                            if (val.additionalSettings)
                            {
                                string[] keys2 = JsonKeys(val.additionalSettings);
                                foreach (var key2 in keys2)
                                {
                                    staveSettings.AdditionalSettings[key2] = val.additionalSettings[key2];
                                }
                            }
                            settings.Staves.Add(staveSettings);
                        }
                    }
                }
            }

            return(settings);
        }
示例#15
0
        public static void FillFromJson(Settings settings, dynamic json)
        {
            if (!json)
            {
                return;
            }
            if (Std.JsonExists(json, "scale"))
            {
                settings.Scale = json.scale;
            }
            if (Std.JsonExists(json, "width"))
            {
                settings.Width = json.width;
            }
            if (Std.JsonExists(json, "height"))
            {
                settings.Height = json.height;
            }
            if (Std.JsonExists(json, "engine"))
            {
                settings.Engine = json.engine;
            }
            if (Std.JsonExists(json, "stretchForce"))
            {
                settings.StretchForce = json.stretchForce;
            }
            if (Std.JsonExists(json, "forcePianoFingering"))
            {
                settings.ForcePianoFingering = json.forcePianoFingering;
            }

            if (Std.JsonExists(json, "scriptFile"))
            {
                settings.ScriptFile = EnsureFullUrl(settings.ScriptFile);
                settings.ScriptFile = AppendScriptName(json.scriptFile);
            }
            else if (HtmlContext.self.document.As <bool>() && HtmlContext.self.window.Member("ALPHATAB_ROOT").As <bool>())
            {
                settings.ScriptFile = HtmlContext.self.window.Member("ALPHATAB_ROOT").As <string>();
                settings.ScriptFile = EnsureFullUrl(settings.ScriptFile);
                settings.ScriptFile = AppendScriptName(settings.ScriptFile);
            }
            else
            {
                settings.ScriptFile = Environment.ScriptFile;
            }

            if (Std.JsonExists(json, "fontDirectory"))
            {
                settings.FontDirectory = EnsureFullUrl(json.fontDirectory);
            }
            else if (HtmlContext.self.document.As <bool>() && HtmlContext.self.window.Member("ALPHATAB_FONT").As <bool>())
            {
                settings.FontDirectory = HtmlContext.self.window.Member("ALPHATAB_FONT").As <string>();
                settings.FontDirectory = EnsureFullUrl(settings.FontDirectory);
            }
            else
            {
                settings.FontDirectory = settings.ScriptFile;
                if (!string.IsNullOrEmpty(settings.FontDirectory))
                {
                    var lastSlash = settings.FontDirectory.LastIndexOf('/');
                    if (lastSlash >= 0)
                    {
                        settings.FontDirectory = settings.FontDirectory.Substring(0, lastSlash) + "/Font/";
                    }
                }
            }

            if (Std.JsonExists(json, "layout"))
            {
                if (JsContext.@typeof(json.layout) == "string")
                {
                    settings.Layout.Mode = json.layout;
                }
                else
                {
                    if (json.layout.mode)
                    {
                        settings.Layout.Mode = json.layout.mode;
                    }
                    if (json.layout.additionalSettings)
                    {
                        string[] keys = Std.JsonKeys(json.layout.additionalSettings);
                        foreach (var key in keys)
                        {
                            settings.Layout.AdditionalSettings[key] = json.layout.additionalSettings[key];
                        }
                    }
                }
            }

            if (Std.JsonExists(json, "staves"))
            {
                var val = json.staves;
                if (JsContext.@typeof(val) == "string")
                {
                    settings.Staves = new StaveSettings(val);
                }
                else
                {
                    if (val.id)
                    {
                        var staveSettings = new StaveSettings(val.id);
                        if (val.additionalSettings)
                        {
                            string[] keys2 = Std.JsonKeys(val.additionalSettings);
                            foreach (var key2 in keys2)
                            {
                                staveSettings.AdditionalSettings[key2] = val.additionalSettings[key2];
                            }
                        }
                        settings.Staves = staveSettings;
                    }
                }
            }
        }
示例#16
0
        public bool ContainsKey(TKey key)
        {
            var hashKey = GetHashKey(key);

            return(JsContext.@typeof(this._table[hashKey]) != "undefined");
        }
示例#17
0
        public static void FillFromJson(Settings settings, dynamic json)
        {
            if (!json)
            {
                return;
            }
            if (Std.JsonExists(json, "scale"))
            {
                settings.Scale = json.scale;
            }
            if (Std.JsonExists(json, "width"))
            {
                settings.Width = json.width;
            }
            if (Std.JsonExists(json, "height"))
            {
                settings.Height = json.height;
            }
            if (Std.JsonExists(json, "engine"))
            {
                settings.Engine = json.engine;
            }
            if (Std.JsonExists(json, "stretchForce"))
            {
                settings.StretchForce = json.stretchForce;
            }
            if (Std.JsonExists(json, "forcePianoFingering"))
            {
                settings.ForcePianoFingering = json.forcePianoFingering;
            }

            if (Std.JsonExists(json, "atRoot"))
            {
                settings.ScriptFile = json.atRoot;
                // append script name
                if (!settings.ScriptFile.EndsWith(".js"))
                {
                    if (!settings.ScriptFile.EndsWith("/"))
                    {
                        settings.ScriptFile += "/";
                    }
                    settings.ScriptFile += "AlphaTab.js";
                }
                if (!settings.ScriptFile.StartsWith("http") && !settings.ScriptFile.StartsWith("https"))
                {
                    var root = new StringBuilder();
                    root.Append(HtmlContext.window.location.protocol);
                    root.Append("//");
                    root.Append(HtmlContext.window.location.hostname);
                    if (HtmlContext.window.location.port.As <bool>())
                    {
                        root.Append(":");
                        root.Append(HtmlContext.window.location.port);
                    }
                    root.Append(settings.ScriptFile);
                    settings.ScriptFile = root.ToString();
                }
            }
            else
            {
                settings.ScriptFile = Environment.ScriptFile;
            }

            if (Std.JsonExists(json, "layout"))
            {
                if (JsContext.@typeof(json.layout) == "string")
                {
                    settings.Layout.Mode = json.layout;
                }
                else
                {
                    if (json.layout.mode)
                    {
                        settings.Layout.Mode = json.layout.mode;
                    }
                    if (json.layout.additionalSettings)
                    {
                        string[] keys = Std.JsonKeys(json.layout.additionalSettings);
                        foreach (var key in keys)
                        {
                            settings.Layout.AdditionalSettings[key] = json.layout.additionalSettings[key];
                        }
                    }
                }
            }

            if (Std.JsonExists(json, "staves"))
            {
                settings.Staves = new FastList <StaveSettings>();
                string[] keys = Std.JsonKeys(json.staves);
                foreach (var key in keys)
                {
                    var val = json.staves[key];
                    if (JsContext.@typeof(val) == "string")
                    {
                        settings.Staves.Add(new StaveSettings(val));
                    }
                    else
                    {
                        if (val.id)
                        {
                            var staveSettings = new StaveSettings(val.id);
                            if (val.additionalSettings)
                            {
                                string[] keys2 = Std.JsonKeys(val.additionalSettings);
                                foreach (var key2 in keys2)
                                {
                                    staveSettings.AdditionalSettings[key2] = val.additionalSettings[key2];
                                }
                            }
                            settings.Staves.Add(staveSettings);
                        }
                    }
                }
            }
        }