1 /**
  2 	@class
  3 	
  4 	Component is the root of all rio components.  It provides basic html and rendering support as 
  5 	well as css dependency management.
  6 	
  7 	@extends rio.Attr
  8 */
  9 rio.Component = {
 10 	create: function() {
 11 		var args = $A(arguments);
 12 		if (args.length > 0 && args.last() != undefined && !args.last().ATTR) {
 13 			args[args.size() - 1] = Object.extend({ noExtend: true }, args.last());
 14 		}
 15 		var component = rio.Attr.create.apply(this, args);
 16 		
 17 		var methods = {
 18 			rerender: function() {
 19 				if (!this._html) { return; }
 20 				var oldHtml = this._html;
 21 				this._html = null;
 22 				component._htmls.each(function(fieldName) {
 23 					this[fieldName].remove();
 24 					this[fieldName] = null;
 25 				}.bind(this));
 26 				oldHtml.replace(this.html());
 27 				rio.app.getCurrentPage().__lm.resize();
 28 			},
 29 
 30 			toString: function() {
 31 				return "[rio.components.*]";
 32 			}
 33 		};
 34 		if (!component.prototype.html) {
 35 			methods.html = function() {
 36 				if (!this._html) { this._html = this.buildHtml(); }
 37 				return this._html;
 38 			};
 39 		}
 40 		component.addMethods(methods);
 41 
 42 		Object.extend(component, {
 43 			requireCss: function(name) {
 44 				rio.Application.includeCss("components/" + name);
 45 			},
 46 			
 47 			template: function(name) {
 48 				rio.boot.loadedTemplates.push(rio.boot.appRoot + "components/" + name);
 49 				
 50 				this._templateName = name;
 51 			},
 52 			
 53 			applyTemplate: function() {
 54 				if (this._templateName && !this._templateApplied) {
 55 					var template = rio.JsTemplate.build("components/" + this._templateName);
 56 					var mixinMethods = template.mixinMethods();
 57 					if (component.prototype.render == undefined) {
 58 						mixinMethods.render = function() {};
 59 					}
 60 					mixinMethods.buildHtml = mixinMethods.buildHtml.wrap(function(proceed) {
 61 						var ret = proceed();
 62 						this._html = ret;
 63 						this.render();
 64 						return ret;
 65 					});
 66 					component.addMethods(mixinMethods);
 67 
 68 					this._templateApplied = true;
 69 				}
 70 			},
 71 			
 72 			style: function(name) {
 73 				component.attrAccessor(name);
 74 			}
 75 		});
 76 		
 77 		if (args.length > 0 && args.last() != undefined && !args.last().ATTR) {
 78 			var initializers = args.last();
 79 			if (Object.isString(initializers.requireCss)) {
 80 				component.requireCss(initializers.requireCss);
 81 			}
 82 			if (Object.isArray(initializers.requireCss)) {
 83 				initializers.requireCss.each(function(css) {
 84 					component.requireCss(css);
 85 				});
 86 			}
 87 			
 88 			if (Object.isString(initializers.template)) {
 89 				component.template(initializers.template);
 90 			}
 91 			
 92 			(initializers.styles || []).each(function(styleName) {
 93 				component.style(styleName);
 94 			});
 95 			
 96 			rio.Component.extend(component, initializers.methods || {});
 97 		}
 98 		
 99 		return component;
100 	},
101 	
102 	extend: function(component, extension) {
103 		extension.__initialize = extension.initialize || Prototype.emptyFunction;
104 		extension.initialize = function(options) {
105 			component.applyTemplate();
106 		
107 			(this.__initialize.bind(this))(options);
108 		};
109 
110 		rio.Attr.extend(component, extension);
111 	},
112 	
113 	toString: function() {
114 		return "Component";
115 	}
116 };
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135