isWindows = (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1),
isMac = (ua.indexOf("macintosh") != -1 || ua.indexOf("mac os x") != -1),
isLinux = (ua.indexOf("linux") != -1),
- isSecure = window.location.href.toLowerCase().indexOf("https") === 0;
-
+ isSecure = window.location.href.toLowerCase().indexOf("https") === 0,
+ isTouch = 'ontouchstart' in window || window.DocumentTouch && document instanceof DocumentTouch;
// remove css image flicker
if(isIE && !isIE7){
try{
isLinux : isLinux,
/** @type Boolean */
isMac : isMac,
+ /** @type Boolean */
+ isTouch : isTouch,
/**
* By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
})();
Roo.namespace("Roo", "Roo.util", "Roo.grid", "Roo.dd", "Roo.tree", "Roo.data",
- "Roo.form", "Roo.menu", "Roo.state", "Roo.lib", "Roo.layout", "Roo.app", "Roo.ux");
+ "Roo.form", "Roo.menu", "Roo.state", "Roo.lib", "Roo.layout",
+ "Roo.app", "Roo.ux",
+ "Roo.bootstrap",
+ "Roo.bootstrap.dash");
/*
* Based on:
* Ext JS Library 1.1.1
getTarget: function(ev, resolveTextNode) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
var t = ev.target || ev.srcElement;
return this.resolveTextNode(t);
},
getPageX: function(ev) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
var x = ev.pageX;
if (!x && 0 !== x) {
x = ev.clientX || 0;
getPageY: function(ev) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
var y = ev.pageY;
if (!y && 0 !== y) {
y = ev.clientY || 0;
getXY: function(ev) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
return [this.getPageX(ev), this.getPageY(ev)];
},
getRelatedTarget: function(ev) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
var t = ev.relatedTarget;
if (!t) {
if (ev.type == "mouseout") {
getTime: function(ev) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
if (!ev.time) {
var t = new Date().getTime();
try {
Roo.lib.AnimMgr = new function() {
- var thread = null;
+ var thread = null;
- var queue = [];
+ var queue = [];
- var tweenCount = 0;
+ var tweenCount = 0;
- this.fps = 1000;
+ this.fps = 1000;
- this.delay = 1;
+ this.delay = 1;
- this.registerElement = function(tween) {
- queue[queue.length] = tween;
- tweenCount += 1;
- tween._onStart.fire();
- this.start();
- };
+ this.registerElement = function(tween) {
+ queue[queue.length] = tween;
+ tweenCount += 1;
+ tween._onStart.fire();
+ this.start();
+ };
- this.unRegister = function(tween, index) {
- tween._onComplete.fire();
- index = index || getIndex(tween);
- if (index != -1) {
- queue.splice(index, 1);
- }
+ this.unRegister = function(tween, index) {
+ tween._onComplete.fire();
+ index = index || getIndex(tween);
+ if (index != -1) {
+ queue.splice(index, 1);
+ }
- tweenCount -= 1;
- if (tweenCount <= 0) {
- this.stop();
- }
- };
+ tweenCount -= 1;
+ if (tweenCount <= 0) {
+ this.stop();
+ }
+ };
- this.start = function() {
- if (thread === null) {
- thread = setInterval(this.run, this.delay);
- }
- };
+ this.start = function() {
+ if (thread === null) {
+ thread = setInterval(this.run, this.delay);
+ }
+ };
- this.stop = function(tween) {
- if (!tween) {
- clearInterval(thread);
+ this.stop = function(tween) {
+ if (!tween) {
+ clearInterval(thread);
- for (var i = 0, len = queue.length; i < len; ++i) {
- if (queue[0].isAnimated()) {
- this.unRegister(queue[0], 0);
- }
+ for (var i = 0, len = queue.length; i < len; ++i) {
+ if (queue[0].isAnimated()) {
+ this.unRegister(queue[0], 0);
}
-
- queue = [];
- thread = null;
- tweenCount = 0;
- }
- else {
- this.unRegister(tween);
}
- };
+ queue = [];
+ thread = null;
+ tweenCount = 0;
+ }
+ else {
+ this.unRegister(tween);
+ }
+ };
- this.run = function() {
- for (var i = 0, len = queue.length; i < len; ++i) {
- var tween = queue[i];
- if (!tween || !tween.isAnimated()) {
- continue;
- }
- if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
- {
- tween.currentFrame += 1;
+ this.run = function() {
+ for (var i = 0, len = queue.length; i < len; ++i) {
+ var tween = queue[i];
+ if (!tween || !tween.isAnimated()) {
+ continue;
+ }
- if (tween.useSeconds) {
- correctFrame(tween);
- }
- tween._onTween.fire();
- }
- else {
- Roo.lib.AnimMgr.stop(tween, i);
+ if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
+ {
+ tween.currentFrame += 1;
+
+ if (tween.useSeconds) {
+ correctFrame(tween);
}
+ tween._onTween.fire();
}
- };
+ else {
+ Roo.lib.AnimMgr.stop(tween, i);
+ }
+ }
+ };
- var getIndex = function(anim) {
- for (var i = 0, len = queue.length; i < len; ++i) {
- if (queue[i] == anim) {
- return i;
- }
+ var getIndex = function(anim) {
+ for (var i = 0, len = queue.length; i < len; ++i) {
+ if (queue[i] == anim) {
+ return i;
}
- return -1;
- };
+ }
+ return -1;
+ };
- var correctFrame = function(tween) {
- var frames = tween.totalFrames;
- var frame = tween.currentFrame;
- var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
- var elapsed = (new Date() - tween.getStartTime());
- var tweak = 0;
+ var correctFrame = function(tween) {
+ var frames = tween.totalFrames;
+ var frame = tween.currentFrame;
+ var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
+ var elapsed = (new Date() - tween.getStartTime());
+ var tweak = 0;
- if (elapsed < tween.duration * 1000) {
- tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
- } else {
+ if (elapsed < tween.duration * 1000) {
+ tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
+ } else {
+ tweak = frames - (frame + 1);
+ }
+ if (tweak > 0 && isFinite(tweak)) {
+ if (tween.currentFrame + tweak >= frames) {
tweak = frames - (frame + 1);
}
- if (tweak > 0 && isFinite(tweak)) {
- if (tween.currentFrame + tweak >= frames) {
- tweak = frames - (frame + 1);
- }
- tween.currentFrame += tweak;
- }
- };
- };/*
+ tween.currentFrame += tweak;
+ }
+ };
+};
+
+ /*
* Portions of this file are based on pieces of Yahoo User Interface Library
* Copyright (c) 2007, Yahoo! Inc. All rights reserved.
* YUI licensed under the BSD License:
var E = Roo.lib.Event;
var D = Roo.lib.Dom;
+
+
var fireDocReady = function(){
if(!docReadyState){
}, o.delay || 10);
};
};
+ var transitionEndVal = false;
+
+ var transitionEnd = function()
+ {
+ if (transitionEndVal) {
+ return transitionEndVal;
+ }
+ var el = document.createElement('div');
+
+ var transEndEventNames = {
+ WebkitTransition : 'webkitTransitionEnd',
+ MozTransition : 'transitionend',
+ OTransition : 'oTransitionEnd otransitionend',
+ transition : 'transitionend'
+ };
+
+ for (var name in transEndEventNames) {
+ if (el.style[name] !== undefined) {
+ transitionEndVal = transEndEventNames[name];
+ return transitionEndVal ;
+ }
+ }
+ }
+
var listen = function(element, ename, opt, fn, scope){
var o = (!opt || typeof opt == "boolean") ? {} : opt;
fn = fn || o.fn; scope = scope || o.scope;
var el = Roo.getDom(element);
+
+
if(!el){
throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
}
+
+ if (ename == 'transitionend') {
+ ename = transitionEnd();
+ }
var h = function(e){
e = Roo.EventObject.setEvent(e);
var t;
h = createBuffered(h, o);
}
fn._handlers = fn._handlers || [];
+
+
fn._handlers.push([Roo.id(el), ename, h]);
-
+
+
+
E.on(el, ename, h);
if(ename == "mousewheel" && el.addEventListener){ // workaround for jQuery
el.addEventListener("DOMMouseScroll", h, false);
*/
mask : function(msg, msgCls)
{
- if(this.getStyle("position") == "static"){
+ if(this.getStyle("position") == "static" && this.dom.tagName !== 'BODY'){
this.setStyle("position", "relative");
}
if(!this._mask){
/**
* Sets or Returns the value the dom attribute value
- * @param {String} name The attribute name
+ * @param {String|Object} name The attribute name (or object to set multiple attributes)
* @param {String} value (optional) The value to set the attribute to
* @return {String} The attribute value
*/
this.dom.setAttribute(name, arguments[1]);
return arguments[1];
}
+ if (typeof(name) == 'object') {
+ for(var i in name) {
+ this.attr(i, name[i]);
+ }
+ return name;
+ }
+
+
if (!this.dom.hasAttribute(name)) {
return undefined;
}
/**
* Filters this composite to only elements that match the passed selector.
* @param {String} selector A string CSS selector
+ * @param {Boolean} inverse return inverse filter (not matches)
* @return {CompositeElement} this
*/
- filter : function(selector){
+ filter : function(selector, inverse){
var els = [];
+ inverse = inverse || false;
this.each(function(el){
- if(el.is(selector)){
+ var match = inverse ? !el.is(selector) : el.is(selector);
+ if(match){
els[els.length] = el.dom;
}
});
if(!(v instanceof Date)){
v = new Date(Date.parse(v));
}
- return v.dateFormat(format || "m/d/Y");
+ return v.dateFormat(format || Roo.util.Format.defaults.date);
},
/**
return !v ? v : String(v).replace(this.stripTagsRE, "");
}
};
-}();/*
+}();
+Roo.util.Format.defaults = {
+ date : 'd/M/Y'
+};/*
* Based on:
* Ext JS Library 1.1.1
* Copyright(c) 2006-2007, Ext JS, LLC.
((this.domain == null) ? "" : ("; domain=" + this.domain)) +
((this.secure == true) ? "; secure" : "");
}
-});
\ No newline at end of file
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+
+/**
+ * @class Roo.ComponentMgr
+ * Provides a common registry of all components on a page so that they can be easily accessed by component id (see {@link Roo.getCmp}).
+ * @singleton
+ */
+Roo.ComponentMgr = function(){
+ var all = new Roo.util.MixedCollection();
+
+ return {
+ /**
+ * Registers a component.
+ * @param {Roo.Component} c The component
+ */
+ register : function(c){
+ all.add(c);
+ },
+
+ /**
+ * Unregisters a component.
+ * @param {Roo.Component} c The component
+ */
+ unregister : function(c){
+ all.remove(c);
+ },
+
+ /**
+ * Returns a component by id
+ * @param {String} id The component id
+ */
+ get : function(id){
+ return all.get(id);
+ },
+
+ /**
+ * Registers a function that will be called when a specified component is added to ComponentMgr
+ * @param {String} id The component id
+ * @param {Funtction} fn The callback function
+ * @param {Object} scope The scope of the callback
+ */
+ onAvailable : function(id, fn, scope){
+ all.on("add", function(index, o){
+ if(o.id == id){
+ fn.call(scope || o, o);
+ all.un("add", fn, scope);
+ }
+ });
+ }
+ };
+}();/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.Component
+ * @extends Roo.util.Observable
+ * Base class for all major Roo components. All subclasses of Component can automatically participate in the standard
+ * Roo component lifecycle of creation, rendering and destruction. They also have automatic support for basic hide/show
+ * and enable/disable behavior. Component allows any subclass to be lazy-rendered into any {@link Roo.Container} and
+ * to be automatically registered with the {@link Roo.ComponentMgr} so that it can be referenced at any time via {@link Roo.getCmp}.
+ * All visual components (widgets) that require rendering into a layout should subclass Component.
+ * @constructor
+ * @param {Roo.Element/String/Object} config The configuration options. If an element is passed, it is set as the internal
+ * element and its id used as the component id. If a string is passed, it is assumed to be the id of an existing element
+ * and is used as the component id. Otherwise, it is assumed to be a standard config object and is applied to the component.
+ */
+Roo.Component = function(config){
+ config = config || {};
+ if(config.tagName || config.dom || typeof config == "string"){ // element object
+ config = {el: config, id: config.id || config};
+ }
+ this.initialConfig = config;
+
+ Roo.apply(this, config);
+ this.addEvents({
+ /**
+ * @event disable
+ * Fires after the component is disabled.
+ * @param {Roo.Component} this
+ */
+ disable : true,
+ /**
+ * @event enable
+ * Fires after the component is enabled.
+ * @param {Roo.Component} this
+ */
+ enable : true,
+ /**
+ * @event beforeshow
+ * Fires before the component is shown. Return false to stop the show.
+ * @param {Roo.Component} this
+ */
+ beforeshow : true,
+ /**
+ * @event show
+ * Fires after the component is shown.
+ * @param {Roo.Component} this
+ */
+ show : true,
+ /**
+ * @event beforehide
+ * Fires before the component is hidden. Return false to stop the hide.
+ * @param {Roo.Component} this
+ */
+ beforehide : true,
+ /**
+ * @event hide
+ * Fires after the component is hidden.
+ * @param {Roo.Component} this
+ */
+ hide : true,
+ /**
+ * @event beforerender
+ * Fires before the component is rendered. Return false to stop the render.
+ * @param {Roo.Component} this
+ */
+ beforerender : true,
+ /**
+ * @event render
+ * Fires after the component is rendered.
+ * @param {Roo.Component} this
+ */
+ render : true,
+ /**
+ * @event beforedestroy
+ * Fires before the component is destroyed. Return false to stop the destroy.
+ * @param {Roo.Component} this
+ */
+ beforedestroy : true,
+ /**
+ * @event destroy
+ * Fires after the component is destroyed.
+ * @param {Roo.Component} this
+ */
+ destroy : true
+ });
+ if(!this.id){
+ this.id = "ext-comp-" + (++Roo.Component.AUTO_ID);
+ }
+ Roo.ComponentMgr.register(this);
+ Roo.Component.superclass.constructor.call(this);
+ this.initComponent();
+ if(this.renderTo){ // not supported by all components yet. use at your own risk!
+ this.render(this.renderTo);
+ delete this.renderTo;
+ }
+};
+
+/** @private */
+Roo.Component.AUTO_ID = 1000;
+
+Roo.extend(Roo.Component, Roo.util.Observable, {
+ /**
+ * @scope Roo.Component.prototype
+ * @type {Boolean}
+ * true if this component is hidden. Read-only.
+ */
+ hidden : false,
+ /**
+ * @type {Boolean}
+ * true if this component is disabled. Read-only.
+ */
+ disabled : false,
+ /**
+ * @type {Boolean}
+ * true if this component has been rendered. Read-only.
+ */
+ rendered : false,
+
+ /** @cfg {String} disableClass
+ * CSS class added to the component when it is disabled (defaults to "x-item-disabled").
+ */
+ disabledClass : "x-item-disabled",
+ /** @cfg {Boolean} allowDomMove
+ * Whether the component can move the Dom node when rendering (defaults to true).
+ */
+ allowDomMove : true,
+ /** @cfg {String} hideMode
+ * How this component should hidden. Supported values are
+ * "visibility" (css visibility), "offsets" (negative offset position) and
+ * "display" (css display) - defaults to "display".
+ */
+ hideMode: 'display',
+
+ /** @private */
+ ctype : "Roo.Component",
+
+ /**
+ * @cfg {String} actionMode
+ * which property holds the element that used for hide() / show() / disable() / enable()
+ * default is 'el'
+ */
+ actionMode : "el",
+
+ /** @private */
+ getActionEl : function(){
+ return this[this.actionMode];
+ },
+
+ initComponent : Roo.emptyFn,
+ /**
+ * If this is a lazy rendering component, render it to its container element.
+ * @param {String/HTMLElement/Element} container (optional) The element this component should be rendered into. If it is being applied to existing markup, this should be left off.
+ */
+ render : function(container, position){
+ if(!this.rendered && this.fireEvent("beforerender", this) !== false){
+ if(!container && this.el){
+ this.el = Roo.get(this.el);
+ container = this.el.dom.parentNode;
+ this.allowDomMove = false;
+ }
+ this.container = Roo.get(container);
+ this.rendered = true;
+ if(position !== undefined){
+ if(typeof position == 'number'){
+ position = this.container.dom.childNodes[position];
+ }else{
+ position = Roo.getDom(position);
+ }
+ }
+ this.onRender(this.container, position || null);
+ if(this.cls){
+ this.el.addClass(this.cls);
+ delete this.cls;
+ }
+ if(this.style){
+ this.el.applyStyles(this.style);
+ delete this.style;
+ }
+ this.fireEvent("render", this);
+ this.afterRender(this.container);
+ if(this.hidden){
+ this.hide();
+ }
+ if(this.disabled){
+ this.disable();
+ }
+ }
+ return this;
+ },
+
+ /** @private */
+ // default function is not really useful
+ onRender : function(ct, position){
+ if(this.el){
+ this.el = Roo.get(this.el);
+ if(this.allowDomMove !== false){
+ ct.dom.insertBefore(this.el.dom, position);
+ }
+ }
+ },
+
+ /** @private */
+ getAutoCreate : function(){
+ var cfg = typeof this.autoCreate == "object" ?
+ this.autoCreate : Roo.apply({}, this.defaultAutoCreate);
+ if(this.id && !cfg.id){
+ cfg.id = this.id;
+ }
+ return cfg;
+ },
+
+ /** @private */
+ afterRender : Roo.emptyFn,
+
+ /**
+ * Destroys this component by purging any event listeners, removing the component's element from the DOM,
+ * removing the component from its {@link Roo.Container} (if applicable) and unregistering it from {@link Roo.ComponentMgr}.
+ */
+ destroy : function(){
+ if(this.fireEvent("beforedestroy", this) !== false){
+ this.purgeListeners();
+ this.beforeDestroy();
+ if(this.rendered){
+ this.el.removeAllListeners();
+ this.el.remove();
+ if(this.actionMode == "container"){
+ this.container.remove();
+ }
+ }
+ this.onDestroy();
+ Roo.ComponentMgr.unregister(this);
+ this.fireEvent("destroy", this);
+ }
+ },
+
+ /** @private */
+ beforeDestroy : function(){
+
+ },
+
+ /** @private */
+ onDestroy : function(){
+
+ },
+
+ /**
+ * Returns the underlying {@link Roo.Element}.
+ * @return {Roo.Element} The element
+ */
+ getEl : function(){
+ return this.el;
+ },
+
+ /**
+ * Returns the id of this component.
+ * @return {String}
+ */
+ getId : function(){
+ return this.id;
+ },
+
+ /**
+ * Try to focus this component.
+ * @param {Boolean} selectText True to also select the text in this component (if applicable)
+ * @return {Roo.Component} this
+ */
+ focus : function(selectText){
+ if(this.rendered){
+ this.el.focus();
+ if(selectText === true){
+ this.el.dom.select();
+ }
+ }
+ return this;
+ },
+
+ /** @private */
+ blur : function(){
+ if(this.rendered){
+ this.el.blur();
+ }
+ return this;
+ },
+
+ /**
+ * Disable this component.
+ * @return {Roo.Component} this
+ */
+ disable : function(){
+ if(this.rendered){
+ this.onDisable();
+ }
+ this.disabled = true;
+ this.fireEvent("disable", this);
+ return this;
+ },
+
+ // private
+ onDisable : function(){
+ this.getActionEl().addClass(this.disabledClass);
+ this.el.dom.disabled = true;
+ },
+
+ /**
+ * Enable this component.
+ * @return {Roo.Component} this
+ */
+ enable : function(){
+ if(this.rendered){
+ this.onEnable();
+ }
+ this.disabled = false;
+ this.fireEvent("enable", this);
+ return this;
+ },
+
+ // private
+ onEnable : function(){
+ this.getActionEl().removeClass(this.disabledClass);
+ this.el.dom.disabled = false;
+ },
+
+ /**
+ * Convenience function for setting disabled/enabled by boolean.
+ * @param {Boolean} disabled
+ */
+ setDisabled : function(disabled){
+ this[disabled ? "disable" : "enable"]();
+ },
+
+ /**
+ * Show this component.
+ * @return {Roo.Component} this
+ */
+ show: function(){
+ if(this.fireEvent("beforeshow", this) !== false){
+ this.hidden = false;
+ if(this.rendered){
+ this.onShow();
+ }
+ this.fireEvent("show", this);
+ }
+ return this;
+ },
+
+ // private
+ onShow : function(){
+ var ae = this.getActionEl();
+ if(this.hideMode == 'visibility'){
+ ae.dom.style.visibility = "visible";
+ }else if(this.hideMode == 'offsets'){
+ ae.removeClass('x-hidden');
+ }else{
+ ae.dom.style.display = "";
+ }
+ },
+
+ /**
+ * Hide this component.
+ * @return {Roo.Component} this
+ */
+ hide: function(){
+ if(this.fireEvent("beforehide", this) !== false){
+ this.hidden = true;
+ if(this.rendered){
+ this.onHide();
+ }
+ this.fireEvent("hide", this);
+ }
+ return this;
+ },
+
+ // private
+ onHide : function(){
+ var ae = this.getActionEl();
+ if(this.hideMode == 'visibility'){
+ ae.dom.style.visibility = "hidden";
+ }else if(this.hideMode == 'offsets'){
+ ae.addClass('x-hidden');
+ }else{
+ ae.dom.style.display = "none";
+ }
+ },
+
+ /**
+ * Convenience function to hide or show this component by boolean.
+ * @param {Boolean} visible True to show, false to hide
+ * @return {Roo.Component} this
+ */
+ setVisible: function(visible){
+ if(visible) {
+ this.show();
+ }else{
+ this.hide();
+ }
+ return this;
+ },
+
+ /**
+ * Returns true if this component is visible.
+ */
+ isVisible : function(){
+ return this.getActionEl().isVisible();
+ },
+
+ cloneConfig : function(overrides){
+ overrides = overrides || {};
+ var id = overrides.id || Roo.id();
+ var cfg = Roo.applyIf(overrides, this.initialConfig);
+ cfg.id = id; // prevent dup id
+ return new this.constructor(cfg);
+ }
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.BoxComponent
+ * @extends Roo.Component
+ * Base class for any visual {@link Roo.Component} that uses a box container. BoxComponent provides automatic box
+ * model adjustments for sizing and positioning and will work correctly withnin the Component rendering model. All
+ * container classes should subclass BoxComponent so that they will work consistently when nested within other Ext
+ * layout containers.
+ * @constructor
+ * @param {Roo.Element/String/Object} config The configuration options.
+ */
+Roo.BoxComponent = function(config){
+ Roo.Component.call(this, config);
+ this.addEvents({
+ /**
+ * @event resize
+ * Fires after the component is resized.
+ * @param {Roo.Component} this
+ * @param {Number} adjWidth The box-adjusted width that was set
+ * @param {Number} adjHeight The box-adjusted height that was set
+ * @param {Number} rawWidth The width that was originally specified
+ * @param {Number} rawHeight The height that was originally specified
+ */
+ resize : true,
+ /**
+ * @event move
+ * Fires after the component is moved.
+ * @param {Roo.Component} this
+ * @param {Number} x The new x position
+ * @param {Number} y The new y position
+ */
+ move : true
+ });
+};
+
+Roo.extend(Roo.BoxComponent, Roo.Component, {
+ // private, set in afterRender to signify that the component has been rendered
+ boxReady : false,
+ // private, used to defer height settings to subclasses
+ deferHeight: false,
+ /** @cfg {Number} width
+ * width (optional) size of component
+ */
+ /** @cfg {Number} height
+ * height (optional) size of component
+ */
+
+ /**
+ * Sets the width and height of the component. This method fires the resize event. This method can accept
+ * either width and height as separate numeric arguments, or you can pass a size object like {width:10, height:20}.
+ * @param {Number/Object} width The new width to set, or a size object in the format {width, height}
+ * @param {Number} height The new height to set (not required if a size object is passed as the first arg)
+ * @return {Roo.BoxComponent} this
+ */
+ setSize : function(w, h){
+ // support for standard size objects
+ if(typeof w == 'object'){
+ h = w.height;
+ w = w.width;
+ }
+ // not rendered
+ if(!this.boxReady){
+ this.width = w;
+ this.height = h;
+ return this;
+ }
+
+ // prevent recalcs when not needed
+ if(this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
+ return this;
+ }
+ this.lastSize = {width: w, height: h};
+
+ var adj = this.adjustSize(w, h);
+ var aw = adj.width, ah = adj.height;
+ if(aw !== undefined || ah !== undefined){ // this code is nasty but performs better with floaters
+ var rz = this.getResizeEl();
+ if(!this.deferHeight && aw !== undefined && ah !== undefined){
+ rz.setSize(aw, ah);
+ }else if(!this.deferHeight && ah !== undefined){
+ rz.setHeight(ah);
+ }else if(aw !== undefined){
+ rz.setWidth(aw);
+ }
+ this.onResize(aw, ah, w, h);
+ this.fireEvent('resize', this, aw, ah, w, h);
+ }
+ return this;
+ },
+
+ /**
+ * Gets the current size of the component's underlying element.
+ * @return {Object} An object containing the element's size {width: (element width), height: (element height)}
+ */
+ getSize : function(){
+ return this.el.getSize();
+ },
+
+ /**
+ * Gets the current XY position of the component's underlying element.
+ * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)
+ * @return {Array} The XY position of the element (e.g., [100, 200])
+ */
+ getPosition : function(local){
+ if(local === true){
+ return [this.el.getLeft(true), this.el.getTop(true)];
+ }
+ return this.xy || this.el.getXY();
+ },
+
+ /**
+ * Gets the current box measurements of the component's underlying element.
+ * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)
+ * @returns {Object} box An object in the format {x, y, width, height}
+ */
+ getBox : function(local){
+ var s = this.el.getSize();
+ if(local){
+ s.x = this.el.getLeft(true);
+ s.y = this.el.getTop(true);
+ }else{
+ var xy = this.xy || this.el.getXY();
+ s.x = xy[0];
+ s.y = xy[1];
+ }
+ return s;
+ },
+
+ /**
+ * Sets the current box measurements of the component's underlying element.
+ * @param {Object} box An object in the format {x, y, width, height}
+ * @returns {Roo.BoxComponent} this
+ */
+ updateBox : function(box){
+ this.setSize(box.width, box.height);
+ this.setPagePosition(box.x, box.y);
+ return this;
+ },
+
+ // protected
+ getResizeEl : function(){
+ return this.resizeEl || this.el;
+ },
+
+ // protected
+ getPositionEl : function(){
+ return this.positionEl || this.el;
+ },
+
+ /**
+ * Sets the left and top of the component. To set the page XY position instead, use {@link #setPagePosition}.
+ * This method fires the move event.
+ * @param {Number} left The new left
+ * @param {Number} top The new top
+ * @returns {Roo.BoxComponent} this
+ */
+ setPosition : function(x, y){
+ this.x = x;
+ this.y = y;
+ if(!this.boxReady){
+ return this;
+ }
+ var adj = this.adjustPosition(x, y);
+ var ax = adj.x, ay = adj.y;
+
+ var el = this.getPositionEl();
+ if(ax !== undefined || ay !== undefined){
+ if(ax !== undefined && ay !== undefined){
+ el.setLeftTop(ax, ay);
+ }else if(ax !== undefined){
+ el.setLeft(ax);
+ }else if(ay !== undefined){
+ el.setTop(ay);
+ }
+ this.onPosition(ax, ay);
+ this.fireEvent('move', this, ax, ay);
+ }
+ return this;
+ },
+
+ /**
+ * Sets the page XY position of the component. To set the left and top instead, use {@link #setPosition}.
+ * This method fires the move event.
+ * @param {Number} x The new x position
+ * @param {Number} y The new y position
+ * @returns {Roo.BoxComponent} this
+ */
+ setPagePosition : function(x, y){
+ this.pageX = x;
+ this.pageY = y;
+ if(!this.boxReady){
+ return;
+ }
+ if(x === undefined || y === undefined){ // cannot translate undefined points
+ return;
+ }
+ var p = this.el.translatePoints(x, y);
+ this.setPosition(p.left, p.top);
+ return this;
+ },
+
+ // private
+ onRender : function(ct, position){
+ Roo.BoxComponent.superclass.onRender.call(this, ct, position);
+ if(this.resizeEl){
+ this.resizeEl = Roo.get(this.resizeEl);
+ }
+ if(this.positionEl){
+ this.positionEl = Roo.get(this.positionEl);
+ }
+ },
+
+ // private
+ afterRender : function(){
+ Roo.BoxComponent.superclass.afterRender.call(this);
+ this.boxReady = true;
+ this.setSize(this.width, this.height);
+ if(this.x || this.y){
+ this.setPosition(this.x, this.y);
+ }
+ if(this.pageX || this.pageY){
+ this.setPagePosition(this.pageX, this.pageY);
+ }
+ },
+
+ /**
+ * Force the component's size to recalculate based on the underlying element's current height and width.
+ * @returns {Roo.BoxComponent} this
+ */
+ syncSize : function(){
+ delete this.lastSize;
+ this.setSize(this.el.getWidth(), this.el.getHeight());
+ return this;
+ },
+
+ /**
+ * Called after the component is resized, this method is empty by default but can be implemented by any
+ * subclass that needs to perform custom logic after a resize occurs.
+ * @param {Number} adjWidth The box-adjusted width that was set
+ * @param {Number} adjHeight The box-adjusted height that was set
+ * @param {Number} rawWidth The width that was originally specified
+ * @param {Number} rawHeight The height that was originally specified
+ */
+ onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
+
+ },
+
+ /**
+ * Called after the component is moved, this method is empty by default but can be implemented by any
+ * subclass that needs to perform custom logic after a move occurs.
+ * @param {Number} x The new x position
+ * @param {Number} y The new y position
+ */
+ onPosition : function(x, y){
+
+ },
+
+ // private
+ adjustSize : function(w, h){
+ if(this.autoWidth){
+ w = 'auto';
+ }
+ if(this.autoHeight){
+ h = 'auto';
+ }
+ return {width : w, height: h};
+ },
+
+ // private
+ adjustPosition : function(x, y){
+ return {x : x, y: y};
+ }
+});/*
+ * Original code for Roojs - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.XComponent
+ * A delayed Element creator...
+ * Or a way to group chunks of interface together.
+ * technically this is a wrapper around a tree of Roo elements (which defines a 'module'),
+ * used in conjunction with XComponent.build() it will create an instance of each element,
+ * then call addxtype() to build the User interface.
+ *
+ * Mypart.xyx = new Roo.XComponent({
+
+ parent : 'Mypart.xyz', // empty == document.element.!!
+ order : '001',
+ name : 'xxxx'
+ region : 'xxxx'
+ disabled : function() {}
+
+ tree : function() { // return an tree of xtype declared components
+ var MODULE = this;
+ return
+ {
+ xtype : 'NestedLayoutPanel',
+ // technicall
+ }
+ ]
+ *})
+ *
+ *
+ * It can be used to build a big heiracy, with parent etc.
+ * or you can just use this to render a single compoent to a dom element
+ * MYPART.render(Roo.Element | String(id) | dom_element )
+ *
+ *
+ * Usage patterns.
+ *
+ * Classic Roo
+ *
+ * Roo is designed primarily as a single page application, so the UI build for a standard interface will
+ * expect a single 'TOP' level module normally indicated by the 'parent' of the XComponent definition being defined as false.
+ *
+ * Each sub module is expected to have a parent pointing to the class name of it's parent module.
+ *
+ * When the top level is false, a 'Roo.BorderLayout' is created and the element is flagged as 'topModule'
+ * - if mulitple topModules exist, the last one is defined as the top module.
+ *
+ * Embeded Roo
+ *
+ * When the top level or multiple modules are to embedded into a existing HTML page,
+ * the parent element can container '#id' of the element where the module will be drawn.
+ *
+ * Bootstrap Roo
+ *
+ * Unlike classic Roo, the bootstrap tends not to be used as a single page.
+ * it relies more on a include mechanism, where sub modules are included into an outer page.
+ * This is normally managed by the builder tools using Roo.apply( options, Included.Sub.Module )
+ *
+ * Bootstrap Roo Included elements
+ *
+ * Our builder application needs the ability to preview these sub compoennts. They will normally have parent=false set,
+ * hence confusing the component builder as it thinks there are multiple top level elements.
+ *
+ *
+ *
+ * @extends Roo.util.Observable
+ * @constructor
+ * @param cfg {Object} configuration of component
+ *
+ */
+Roo.XComponent = function(cfg) {
+ Roo.apply(this, cfg);
+ this.addEvents({
+ /**
+ * @event built
+ * Fires when this the componnt is built
+ * @param {Roo.XComponent} c the component
+ */
+ 'built' : true
+
+ });
+ this.region = this.region || 'center'; // default..
+ Roo.XComponent.register(this);
+ this.modules = false;
+ this.el = false; // where the layout goes..
+
+
+}
+Roo.extend(Roo.XComponent, Roo.util.Observable, {
+ /**
+ * @property el
+ * The created element (with Roo.factory())
+ * @type {Roo.Layout}
+ */
+ el : false,
+
+ /**
+ * @property el
+ * for BC - use el in new code
+ * @type {Roo.Layout}
+ */
+ panel : false,
+
+ /**
+ * @property layout
+ * for BC - use el in new code
+ * @type {Roo.Layout}
+ */
+ layout : false,
+
+ /**
+ * @cfg {Function|boolean} disabled
+ * If this module is disabled by some rule, return true from the funtion
+ */
+ disabled : false,
+
+ /**
+ * @cfg {String} parent
+ * Name of parent element which it get xtype added to..
+ */
+ parent: false,
+
+ /**
+ * @cfg {String} order
+ * Used to set the order in which elements are created (usefull for multiple tabs)
+ */
+
+ order : false,
+ /**
+ * @cfg {String} name
+ * String to display while loading.
+ */
+ name : false,
+ /**
+ * @cfg {String} region
+ * Region to render component to (defaults to center)
+ */
+ region : 'center',
+
+ /**
+ * @cfg {Array} items
+ * A single item array - the first element is the root of the tree..
+ * It's done this way to stay compatible with the Xtype system...
+ */
+ items : false,
+
+ /**
+ * @property _tree
+ * The method that retuns the tree of parts that make up this compoennt
+ * @type {function}
+ */
+ _tree : false,
+
+ /**
+ * render
+ * render element to dom or tree
+ * @param {Roo.Element|String|DomElement} optional render to if parent is not set.
+ */
+
+ render : function(el)
+ {
+
+ el = el || false;
+ var hp = this.parent ? 1 : 0;
+ Roo.log(this);
+
+ if (!el && typeof(this.parent) == 'string' && this.parent.substring(0,1) == '#') {
+ // if parent is a '#.....' string, then let's use that..
+ var ename = this.parent.substr(1);
+ this.parent = false;
+ Roo.log(ename);
+ switch (ename) {
+ case 'bootstrap-body' :
+ if (typeof(Roo.bootstrap.Body) != 'undefined') {
+ this.parent = { el : new Roo.bootstrap.Body() };
+ Roo.log("setting el to doc body");
+
+ } else {
+ throw "Container is bootstrap body, but Roo.bootstrap.Body is not defined";
+ }
+ break;
+ case 'bootstrap':
+ this.parent = { el : true};
+ // fall through
+ default:
+ el = Roo.get(ename);
+ break;
+ }
+
+
+ if (!el && !this.parent) {
+ Roo.log("Warning - element can not be found :#" + ename );
+ return;
+ }
+ }
+ Roo.log("EL:");Roo.log(el);
+ Roo.log("this.parent.el:");Roo.log(this.parent.el);
+
+ var tree = this._tree ? this._tree() : this.tree();
+
+ // altertive root elements ??? - we need a better way to indicate these.
+ var is_alt = (typeof(Roo.bootstrap) != 'undefined' && tree.xns == Roo.bootstrap) ||
+ (typeof(Roo.mailer) != 'undefined' && tree.xns == Roo.mailer) ;
+
+ if (!this.parent && is_alt) {
+ //el = Roo.get(document.body);
+ this.parent = { el : true };
+ }
+
+
+
+ if (!this.parent) {
+
+ Roo.log("no parent - creating one");
+
+ el = el ? Roo.get(el) : false;
+
+ // it's a top level one..
+ this.parent = {
+ el : new Roo.BorderLayout(el || document.body, {
+
+ center: {
+ titlebar: false,
+ autoScroll:false,
+ closeOnTab: true,
+ tabPosition: 'top',
+ //resizeTabs: true,
+ alwaysShowTabs: el && hp? false : true,
+ hideTabs: el || !hp ? true : false,
+ minTabWidth: 140
+ }
+ })
+ }
+ }
+
+ if (!this.parent.el) {
+ // probably an old style ctor, which has been disabled.
+ return;
+
+ }
+ // The 'tree' method is '_tree now'
+
+ tree.region = tree.region || this.region;
+
+ if (this.parent.el === true) {
+ // bootstrap... - body..
+ this.parent.el = Roo.factory(tree);
+ }
+
+ this.el = this.parent.el.addxtype(tree);
+ this.fireEvent('built', this);
+
+ this.panel = this.el;
+ this.layout = this.panel.layout;
+ this.parentLayout = this.parent.layout || false;
+
+ }
+
+});
+
+Roo.apply(Roo.XComponent, {
+ /**
+ * @property hideProgress
+ * true to disable the building progress bar.. usefull on single page renders.
+ * @type Boolean
+ */
+ hideProgress : false,
+ /**
+ * @property buildCompleted
+ * True when the builder has completed building the interface.
+ * @type Boolean
+ */
+ buildCompleted : false,
+
+ /**
+ * @property topModule
+ * the upper most module - uses document.element as it's constructor.
+ * @type Object
+ */
+
+ topModule : false,
+
+ /**
+ * @property modules
+ * array of modules to be created by registration system.
+ * @type {Array} of Roo.XComponent
+ */
+
+ modules : [],
+ /**
+ * @property elmodules
+ * array of modules to be created by which use #ID
+ * @type {Array} of Roo.XComponent
+ */
+
+ elmodules : [],
+
+ /**
+ * @property build_from_html
+ * Build elements from html - used by bootstrap HTML stuff
+ * - this is cleared after build is completed
+ * @type {boolean} true (default false)
+ */
+
+ build_from_html : false,
+
+ /**
+ * Register components to be built later.
+ *
+ * This solves the following issues
+ * - Building is not done on page load, but after an authentication process has occured.
+ * - Interface elements are registered on page load
+ * - Parent Interface elements may not be loaded before child, so this handles that..
+ *
+ *
+ * example:
+ *
+ * MyApp.register({
+ order : '000001',
+ module : 'Pman.Tab.projectMgr',
+ region : 'center',
+ parent : 'Pman.layout',
+ disabled : false, // or use a function..
+ })
+
+ * * @param {Object} details about module
+ */
+ register : function(obj) {
+
+ Roo.XComponent.event.fireEvent('register', obj);
+ switch(typeof(obj.disabled) ) {
+
+ case 'undefined':
+ break;
+
+ case 'function':
+ if ( obj.disabled() ) {
+ return;
+ }
+ break;
+
+ default:
+ if (obj.disabled) {
+ return;
+ }
+ break;
+ }
+
+ this.modules.push(obj);
+
+ },
+ /**
+ * convert a string to an object..
+ * eg. 'AAA.BBB' -> finds AAA.BBB
+
+ */
+
+ toObject : function(str)
+ {
+ if (!str || typeof(str) == 'object') {
+ return str;
+ }
+ if (str.substring(0,1) == '#') {
+ return str;
+ }
+
+ var ar = str.split('.');
+ var rt, o;
+ rt = ar.shift();
+ /** eval:var:o */
+ try {
+ eval('if (typeof ' + rt + ' == "undefined"){ o = false;} o = ' + rt + ';');
+ } catch (e) {
+ throw "Module not found : " + str;
+ }
+
+ if (o === false) {
+ throw "Module not found : " + str;
+ }
+ Roo.each(ar, function(e) {
+ if (typeof(o[e]) == 'undefined') {
+ throw "Module not found : " + str;
+ }
+ o = o[e];
+ });
+
+ return o;
+
+ },
+
+
+ /**
+ * move modules into their correct place in the tree..
+ *
+ */
+ preBuild : function ()
+ {
+ var _t = this;
+ Roo.each(this.modules , function (obj)
+ {
+ Roo.XComponent.event.fireEvent('beforebuild', obj);
+
+ var opar = obj.parent;
+ try {
+ obj.parent = this.toObject(opar);
+ } catch(e) {
+ Roo.log("parent:toObject failed: " + e.toString());
+ return;
+ }
+
+ if (!obj.parent) {
+ Roo.debug && Roo.log("GOT top level module");
+ Roo.debug && Roo.log(obj);
+ obj.modules = new Roo.util.MixedCollection(false,
+ function(o) { return o.order + '' }
+ );
+ this.topModule = obj;
+ return;
+ }
+ // parent is a string (usually a dom element name..)
+ if (typeof(obj.parent) == 'string') {
+ this.elmodules.push(obj);
+ return;
+ }
+ if (obj.parent.constructor != Roo.XComponent) {
+ Roo.log("Warning : Object Parent is not instance of XComponent:" + obj.name)
+ }
+ if (!obj.parent.modules) {
+ obj.parent.modules = new Roo.util.MixedCollection(false,
+ function(o) { return o.order + '' }
+ );
+ }
+ if (obj.parent.disabled) {
+ obj.disabled = true;
+ }
+ obj.parent.modules.add(obj);
+ }, this);
+ },
+
+ /**
+ * make a list of modules to build.
+ * @return {Array} list of modules.
+ */
+
+ buildOrder : function()
+ {
+ var _this = this;
+ var cmp = function(a,b) {
+ return String(a).toUpperCase() > String(b).toUpperCase() ? 1 : -1;
+ };
+ if ((!this.topModule || !this.topModule.modules) && !this.elmodules.length) {
+ throw "No top level modules to build";
+ }
+
+ // make a flat list in order of modules to build.
+ var mods = this.topModule ? [ this.topModule ] : [];
+
+
+ // elmodules (is a list of DOM based modules )
+ Roo.each(this.elmodules, function(e) {
+ mods.push(e);
+ if (!this.topModule &&
+ typeof(e.parent) == 'string' &&
+ e.parent.substring(0,1) == '#' &&
+ Roo.get(e.parent.substr(1))
+ ) {
+
+ _this.topModule = e;
+ }
+
+ });
+
+
+ // add modules to their parents..
+ var addMod = function(m) {
+ Roo.debug && Roo.log("build Order: add: " + m.name);
+
+ mods.push(m);
+ if (m.modules && !m.disabled) {
+ Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules");
+ m.modules.keySort('ASC', cmp );
+ Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules (after sort)");
+
+ m.modules.each(addMod);
+ } else {
+ Roo.debug && Roo.log("build Order: no child modules");
+ }
+ // not sure if this is used any more..
+ if (m.finalize) {
+ m.finalize.name = m.name + " (clean up) ";
+ mods.push(m.finalize);
+ }
+
+ }
+ if (this.topModule && this.topModule.modules) {
+ this.topModule.modules.keySort('ASC', cmp );
+ this.topModule.modules.each(addMod);
+ }
+ return mods;
+ },
+
+ /**
+ * Build the registered modules.
+ * @param {Object} parent element.
+ * @param {Function} optional method to call after module has been added.
+ *
+ */
+
+ build : function(opts)
+ {
+
+ if (typeof(opts) != 'undefined') {
+ Roo.apply(this,opts);
+ }
+
+ this.preBuild();
+ var mods = this.buildOrder();
+
+ //this.allmods = mods;
+ //Roo.debug && Roo.log(mods);
+ //return;
+ if (!mods.length) { // should not happen
+ throw "NO modules!!!";
+ }
+
+
+ var msg = "Building Interface...";
+ // flash it up as modal - so we store the mask!?
+ if (!this.hideProgress && Roo.MessageBox) {
+ Roo.MessageBox.show({ title: 'loading' });
+ Roo.MessageBox.show({
+ title: "Please wait...",
+ msg: msg,
+ width:450,
+ progress:true,
+ closable:false,
+ modal: false
+
+ });
+ }
+ var total = mods.length;
+
+ var _this = this;
+ var progressRun = function() {
+ if (!mods.length) {
+ Roo.debug && Roo.log('hide?');
+ if (!this.hideProgress && Roo.MessageBox) {
+ Roo.MessageBox.hide();
+ }
+ Roo.XComponent.build_from_html = false; // reset, so dialogs will be build from javascript
+
+ Roo.XComponent.event.fireEvent('buildcomplete', _this.topModule);
+
+ // THE END...
+ return false;
+ }
+
+ var m = mods.shift();
+
+
+ Roo.debug && Roo.log(m);
+ // not sure if this is supported any more.. - modules that are are just function
+ if (typeof(m) == 'function') {
+ m.call(this);
+ return progressRun.defer(10, _this);
+ }
+
+
+ msg = "Building Interface " + (total - mods.length) +
+ " of " + total +
+ (m.name ? (' - ' + m.name) : '');
+ Roo.debug && Roo.log(msg);
+ if (!this.hideProgress && Roo.MessageBox) {
+ Roo.MessageBox.updateProgress( (total - mods.length)/total, msg );
+ }
+
+
+ // is the module disabled?
+ var disabled = (typeof(m.disabled) == 'function') ?
+ m.disabled.call(m.module.disabled) : m.disabled;
+
+
+ if (disabled) {
+ return progressRun(); // we do not update the display!
+ }
+
+ // now build
+
+
+
+ m.render();
+ // it's 10 on top level, and 1 on others??? why...
+ return progressRun.defer(10, _this);
+
+ }
+ progressRun.defer(1, _this);
+
+
+
+ },
+
+
+ /**
+ * Event Object.
+ *
+ *
+ */
+ event: false,
+ /**
+ * wrapper for event.on - aliased later..
+ * Typically use to register a event handler for register:
+ *
+ * eg. Roo.XComponent.on('register', function(comp) { comp.disable = true } );
+ *
+ */
+ on : false
+
+
+
+});
+
+Roo.XComponent.event = new Roo.util.Observable({
+ events : {
+ /**
+ * @event register
+ * Fires when an Component is registered,
+ * set the disable property on the Component to stop registration.
+ * @param {Roo.XComponent} c the component being registerd.
+ *
+ */
+ 'register' : true,
+ /**
+ * @event beforebuild
+ * Fires before each Component is built
+ * can be used to apply permissions.
+ * @param {Roo.XComponent} c the component being registerd.
+ *
+ */
+ 'beforebuild' : true,
+ /**
+ * @event buildcomplete
+ * Fires on the top level element when all elements have been built
+ * @param {Roo.XComponent} the top level component.
+ */
+ 'buildcomplete' : true
+
+ }
+});
+
+Roo.XComponent.on = Roo.XComponent.event.on.createDelegate(Roo.XComponent.event);
+
\ No newline at end of file