1 rio.Theme = { 2 3 isThemeBindingOn: function() { 4 return rio.environment.themeBindability; 5 }, 6 7 scrubStyleName: function(styleName) { 8 return styleName.gsub(/\./, "_"); 9 }, 10 11 create: function(name, attributes) { 12 var theme; 13 14 var compute = function(component, name) { 15 var themeletTheme = "." + (component.getThemelet() || "") + "." + name; 16 var buildComponentThemes = function(component) { 17 var componentTheme = component + "." + name; 18 if (component.superclass) { 19 return [componentTheme, buildComponentThemes(component.superclass)].flatten(); 20 } else { 21 return [componentTheme]; 22 } 23 }; 24 25 var componentTheme = buildComponentThemes(component.constructor).detect(function(componentTheme) { 26 return this.names().include(componentTheme); 27 }.bind(this)); 28 if (this.names().include(themeletTheme)) { 29 return this.get(themeletTheme); 30 } else if (componentTheme != undefined) { 31 return this.get(componentTheme); 32 } else { 33 return this.get(name); 34 } 35 }; 36 if (this.isThemeBindingOn()) { 37 theme = rio.Attr.create(); 38 Object.keys(attributes).each(function(styleName) { 39 theme.attrAccessor(rio.Theme.scrubStyleName(styleName), attributes[styleName]); 40 }); 41 42 rio.Attr.extend(theme, { 43 get: function(name) { 44 return this[rio.Theme.scrubStyleName(name)]; 45 }, 46 names: function() { 47 return Object.keys(attributes); 48 }, 49 compute: compute 50 }); 51 return new theme(); 52 } else { 53 theme = {}; 54 55 theme._names = Object.keys(attributes); 56 theme.attributes = theme._names.inject({}, function(acc, name) { 57 acc[rio.Theme.scrubStyleName(name)] = attributes[name]; 58 return acc; 59 }); 60 61 theme.get = function(name) { 62 var scrubbedName = rio.Theme.scrubStyleName(name); 63 var value = this.attributes[scrubbedName]; 64 if (value && value.ATTR_ALIAS) { 65 return this.get(value.name); 66 } else { 67 return value; 68 } 69 }.bind(theme); 70 theme.names = function() { 71 return this._names; 72 }.bind(theme); 73 74 theme.compute = compute.bind(theme); 75 76 return theme; 77 } 78 }, 79 80 alias: function(name) { 81 return rio.Attr.alias(rio.Theme.scrubStyleName(name)); 82 }, 83 84 toString: function() { return "Theme"; } 85 }; 86 87 rio.theme = function(name) { 88 if (rio.app && rio.app.themeLoaded()) { 89 return rio.app.theme(name); 90 } else { 91 var themeResolver = function() { 92 return rio.app.theme(name); 93 }; 94 95 themeResolver.DELEGATE_GET = true; 96 return themeResolver; 97 } 98 };