📄 application.js
字号:
/** * Returns the component constructor for the specified type. * * @param {String} typeName the type name * @return the component constructor * @type Function */ getConstructor: function(typeName) { return this._typeToConstructorMap[typeName]; }, /** * Determines the super type of a component, based on the type name of the component. * * @param {String} typeName the component type * @return the parent componetn type * @type String */ getSuperType: function(typeName) { var typeConstructor = this._typeToConstructorMap[typeName]; if (!typeConstructor) { throw new Error("Type not found: " + typeName + "."); } if (typeConstructor.$super) { return typeConstructor.$super.prototype.componentType; } else { return null; } }, /** * Registers a type name to a specific constructor. * * @param typeName the type name * @param typeConstructor the constructor */ registerType: function(typeName, typeConstructor) { if (this._typeToConstructorMap[typeName]) { throw new Error("Type already registered: " + typeName); } this._typeToConstructorMap[typeName] = typeConstructor; }};/** * @class * Base class for components. * Derived classes should always take renderId as the first parameter and pass it to the super-constructor. * A component MUST have its componentType property set before it is used in a hierarchy. Failing to do so * will throw an exception and/or result in indeterminate behavior. */EchoApp.Component = Core.extend({ $static: { /** * The next automatically assigned client render id. * @private * @type Number */ _nextRenderId: 0 }, $load: function() { EchoApp.ComponentFactory.registerType("Component", this); }, $abstract: true, $virtual: { /** * Component type. This must be set by implementors in order for peer discovery to work properly. */ componentType: "Component", /** * Returns the child component at the specified index * after sorting the children in the order which they * should be focused. The default implementation simply * returns the same value as getComponent(). * Implementations should override this method when * the natural order to focus child components is * different than their normal ordering (e.g., when * the component at index 1 is positioned above the * component at index 0). * * @param index the index of the child (in focus order) * @return the child component */ getFocusComponent: function(index) { return this.children[index]; } }, /** * The render id. * This value should be treated as read-only and immutable. * @type String */ renderId: null, /** * The parent component. * This value is read-only. * @type EchoApp.Component */ parent: null, /** * The registered application. * This value is read-only. * @type EchoApp.Application */ application: null, /** * Listener list. Lazily created. * @private * @type Core.ListenerList */ _listenerList: null, /** * Referenced external style * @private * @type Object */ _style: null, /** * Assigned style name from application-level style sheet. * @private * @type String */ _styleName: null, /** * Enabled state of the component (default true). * @private * @type Boolean */ _enabled: true, /** * Array of child components. * This value is read-only. Modifying this array will result in undefined behavior. * @type Array */ children: null, /** * Internal style used to store properties set directly on component. * @private * @type Object */ _localStyle: null, /** * Creates a new Component. * * @param {String} renderId the render id * @param {Object} associative mapping of initial property values (may be null) * By default, all properties will be placed into the local style, except for the following: * <ul> * <li><code>styleName</code> specifies the component stylesheet style name</li> * <li><code>style</code> specifies the referenced component style</li> * <li><code>renderId</code> specifies the render id</li> * </ul> * @constructor */ $construct: function(properties) { this.children = []; this._localStyle = { }; if (properties) { for (var name in properties) { switch (name) { case "style": this._style = properties.style; break; case "styleName": this._styleName = properties.styleName; break; case "renderId": this._renderId = properties.renderId; break; case "children": for (var i = 0; i < properties.children.length; ++i) { this.add(properties.children[i]); } break; case "events": for (var eventType in properties.events) { this.addListener(eventType, properties.events[eventType]); } break; default: this._localStyle[name] = properties[name]; break; } } } }, /** * Adds a component as a child. * * @param {EchoApp.Component} component the component to add * @param {Number} index the (integer) index at which to add it (optional, omission * will cause component to be appended to end) */ add: function(component, index) { if (!(component instanceof EchoApp.Component)) { throw new Error("Cannot add child: specified component object is not derived from EchoApp.Component. " + "Parent: " + this + ", Child: " + component); } if (!component.componentType) { throw new Error("Cannot add child: specified component object does not have a componentType property. " + "Parent: " + this + ", Child: " + component); } if (component.parent) { component.parent.remove(component); } component.parent = this; if (index == null || index == this.children.length) { this.children.push(component); } else { this.children.splice(index, 0, component); } if (this.application) { component.register(this.application); this.application.notifyComponentUpdate(this, "children", null, component); } }, /** * Adds an arbitrary event listener. * * @param {String} eventType the event type name * @param {Function} eventTarget the method to invoke when the event occurs * (the event will be passed as the single argument) */ addListener: function(eventType, eventTarget) { if (this._listenerList == null) { this._listenerList = new Core.ListenerList(); } this._listenerList.addListener(eventType, eventTarget); if (this.application) { this.application.notifyComponentUpdate(this, "listeners", null, eventType); } }, /** * Provides notification of an arbitrary event. * Listeners will be notified based on the event's type property. * * @param event the event to fire */ fireEvent: function(event) { if (this._listenerList == null) { return; } this._listenerList.fireEvent(event); }, /** * Returns an arbitrary property value. * * @param {String} name the name of the property * @return the property value */ get: function(name) { return this._localStyle[name]; }, /** * Retrieves the child component at the specified index. * * @param {Number} index the (integer) index * @return the child component * @type EchoApp.Component */ getComponent: function(index) { return this.children[index]; }, /** * Returns the number of child components * * @return the number of child components * @type Number */ getComponentCount: function() { return this.children.length; }, /** * Returns an arbitrary indexed property value. * * @param {String} name the name of the property * @param {Number} index the index to return * @return the property value */ getIndex: function(name, index) { var valueArray = this._localStyle[name]; return valueArray ? valueArray[index] : null; }, /** * Returns the component layout direction. * * @return the component layout direction * @type EchoApp.LayoutDirection */ getLayoutDirection: function() { return this._layoutDirection; }, /** * Retrieves local style property map associations. * This method should only be used by a deserialized for * the purpose of rapidly loading properties into a new * component. * * @return the internal style property map associations * (an associative array). */ getLocalStyleData: function() { return this._localStyle; }, /** * Returns the layout direction with which the component should be * rendered, based on analyzing the component's layout direction, * its parent's, and/or the application's. * * @return the rendering layout direction * @type EchoApp.LayoutDirection */ getRenderLayoutDirection: function() { var component = this; while (component) { if (component._layoutDirection) { return component._layoutDirection; } component = component.parent; } if (this.application) { return this.application.getLayoutDirection(); } return null; }, /** * Returns the style assigned to this component, if any. * * @return the assigned style * @type Object */ getStyle: function() { return this._style; }, /** * Returns the name of the style (from the application's style sheet) * assigned to this component. * * @return the style name * @type String */ getStyleName: function() { return this._styleName; }, /** * Returns the index of a child component, or -1 if the component * is not a child. * * @param {EchoApp.Component} component the component * @return the index * @type Number */ indexOf: function(component) { for (var i = 0; i < this.children.length; ++i) { if (this.children[i] == component) { return i; } } return -1; }, /** * Determines if the component is active, that is, within the current modal context * and ready to receive input. * * @return the active state * @type Boolean */ isActive: function() { // Verify the component and its ancestors are all enabled. if (!this.isRenderEnabled()) { return false; } // Verify component is registered to an application, and that the application is active. if (!this.application || !this.application.isActive()) { return false; } // Verify component is in modal context. var modalContextRoot = this.application.getModalContextRoot(); if (modalContextRoot != null && !modalContextRoot.isAncestorOf(this)) { return false; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -