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 			
 83 			if (Object.isString(initializers.template)) {
 84 				component.template(initializers.template);
 85 			}
 86 			
 87 			(initializers.styles || []).each(function(styleName) {
 88 				component.style(styleName);
 89 			});
 90 			
 91 			rio.Component.extend(component, initializers.methods || {});
 92 		}
 93 		
 94 		return component;
 95 	},
 96 	
 97 	extend: function(component, extension) {
 98 		extension.__initialize = extension.initialize || Prototype.emptyFunction;
 99 		extension.initialize = function(options) {
100 			component.applyTemplate();
101 		
102 			(this.__initialize.bind(this))(options);
103 		};
104 
105 		rio.Attr.extend(component, extension);
106 	},
107 	
108 	toString: function() {
109 		return "Component";
110 	}
111 };
112 
113 
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130