📄 application.js
字号:
return true; }, /** * Determines if this component is or is an ancestor of another component. * * @param {EchoApp.Component} c the component to test * @return true if an ancestor relationship exists * @type Boolean */ isAncestorOf: function(c) { while (c != null && c != this) { c = c.parent; } return c == this; }, /** * Determines the enabled state of this component. * Use isRenderEnabled() to determine whether a component * should be RENDERED as enabled. * * @return the enabled state of this specific component */ isEnabled: function() { return this._enabled; }, /** * Determines whether this <code>Component</code> should be rendered with * an enabled state. * Disabled <code>Component</code>s are not eligible to receive user input. * * @return true if the component should be rendered enabled. * @type Boolean */ isRenderEnabled: function() { var component = this; while (component != null) { if (!component._enabled) { return false; } component = component.parent; } return true; }, /** * Registers / unregisters a component that has been * added/removed to/from a registered hierarchy * (a hierarchy that is registered to an application). * * @param {EchoApp.Application} application the application * (null to unregister the component) */ register: function(application) { // Sanity check. if (application && this.application) { throw new Error("Attempt to re-register or change registered application of component."); } if (!application) { // unregistering if (this.children != null) { // Recursively unregister children. for (var i = 0; i < this.children.length; ++i) { this.children[i].register(false); // Recursively unregister children. } } // Notify application. this.application._unregisterComponent(this); // Change application focus in the event the focused component is being removed. // Note that this is performed after deregistration to ensure any removed modal context is cleared. if (this.application._focusedComponent == this) { this.application.setFocusedComponent(this.parent); } } // Link/unlink with application. this.application = application; if (application) { // registering if (this.renderId == null) { this.renderId = "cl_" + ++EchoApp.Component._nextRenderId; } // Notify application. this.application._registerComponent(this); if (this.children != null) { // Recursively register children. for (var i = 0; i < this.children.length; ++i) { this.children[i].register(application); // Recursively unregister children. } } } }, /** * Returns the value of a property that should be rendered, * based on the value set on this component, in the component's * specified style, and/or in the application's stylesheet. * * @param {String} name the name of the property * @param defaultValue the default value to return if no value is * specified in an internal property, style, or stylesheet * @return the property value */ render: function(name, defaultValue) { var value = this._localStyle[name]; if (value == null) { if (this._style != null) { value = this._style[name]; } if (value == null && this._styleName && this.application && this.application._styleSheet) { var style = this.application._styleSheet.getRenderStyle(this._styleName, this.componentType); if (style) { value = style[name]; } } } return value == null ? defaultValue : value; }, /** * Returns the value of an indexed property that should be rendered, * based on the value set on this component, in the component's * specified style, and/or in the application's stylesheet. * * @param {String} name the name of the property * @param {Number} index the (integer) index of the property * @param defaultValue the default value to return if no value is * specified in an internal property, style, or stylesheet */ renderIndex: function(name, index, defaultValue) { var valueArray = this._localStyle[name]; var value = valueArray ? valueArray[index] : null; if (value == null) { if (this._style != null) { valueArray = this._style[name]; value = valueArray ? valueArray[index] : null; } if (value == null && this._styleName && this.application && this.application._styleSheet) { var style = this.application._styleSheet.getRenderStyle(this._styleName, this.componentType); if (style) { valueArray = style[name]; value = valueArray ? valueArray[index] : null; } } } return value == null ? defaultValue : value; }, /** * Removes a child component. * * @param componentOrIndex * the index of the component to remove, or the component to remove * (values may be of type EchoApp.Component or Number) */ remove: function(componentOrIndex) { var component; var index; if (typeof componentOrIndex == "number") { index = componentOrIndex; component = this.children[index]; if (!component) { throw new Error("Index out of bounds: " + index); } } else { component = componentOrIndex; index = this.indexOf(component); if (index == -1) { // Component is not a child: do nothing. return; } } if (this.application) { component.register(null); } this.children.splice(index, 1); component.parent = null; if (this.application) { this.application.notifyComponentUpdate(this, "children", component, null); } }, /** * Removes all child components. */ removeAll: function() { while (this.children.length > 0) { this.remove(this.children.length - 1); } }, /** * Removes 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) */ removeListener: function(eventType, eventTarget) { if (this._listenerList == null) { return; } this._listenerList.removeListener(eventType, eventTarget); if (this.application) { this.application.notifyComponentUpdate(this, "listeners", eventType, null); } }, /** * Sets the value of a property in the internal style. * * @param {String} name the name of the property * @param value the new value of the property */ set: function(name, newValue) { var oldValue = this._localStyle[name]; this._localStyle[name] = newValue; if (this._listenerList && this._listenerList.hasListeners("property")) { this._listenerList.fireEvent({type: "property", source: this, propertyName: name, oldValue: oldValue, newValue: newValue}); } if (this.application) { this.application.notifyComponentUpdate(this, name, oldValue, newValue); } }, /** * Sets the enabled state of the component. * * @param newValue the new enabled state */ setEnabled: function(newValue) { var oldValue = this._enabled; this._enabled = newValue; if (this.application) { this.application.notifyComponentUpdate(this, "enabled", oldValue, newValue); } }, /** * Sets the value of an indexed property in the internal style. * * @param {String} name the name of the property * @param {Number} index the index of the property * @param newValue the new value of the property */ setIndex: function(name, index, newValue) { var valueArray = this._localStyle[name]; var oldValue = null; if (valueArray) { oldValue = valueArray[index]; } else { valueArray = []; this._localStyle[name] = valueArray; } valueArray[index] = newValue; if (this.application) { this.application.notifyComponentUpdate(this, name, oldValue, newValue); } if (this._listenerList && this._listenerList.hasListeners("property")) { this._listenerList.fireEvent({type: "property", source: this, propertyName: name, index: index, oldValue: oldValue, newValue: newValue}); } }, /** * Sets a component-specific layout direction. * * @param {EchoApp.LayoutDirection} newValue the new layout direction */ setLayoutDirection: function(newValue) { this._layoutDirection = newValue; }, /** * Sets the style of the component. * * @param {Object} newValue the new style */ setStyle: function(newValue) { var oldValue = this._style; this._style = newValue; if (this.application) { this.application.notifyComponentUpdate(this, "style", oldValue, newValue); } }, /** * Sets the name of the style (from the application's style sheet) * assigned to this component. * * @param {String} newValue the style name */ setStyleName: function(newValue) { var oldValue = this._styleName; this._styleName = newValue; if (this.application) { this.application.notifyComponentUpdate(this, "styleName", oldValue, newValue); } }, /** * Returns a string representation of the component (default implementation). * * @param {Boolean} longFormat an optional flag specifying whether all information about * the component should be displayed (e.g., property values) * @return a string representation of the component * @type String */ toString: function(longFormat) { var out = this.renderId + "/" + this.componentType; if (longFormat) { out += "\n"; var componentCount = this.getComponentCount(); out += this.renderId + "/properties:" + this._localStyle + "\n"; for (var i = 0; i < componentCount; ++i) { var component = this.getComponent(i); out += this.renderId + "/child:" + component.renderId + "\n"; out += component.toString(true); } } return out; }});/** * Provides focus management tools for an application. */EchoApp.FocusManager = Core.extend({ _application: null, /** * Focus management handler for a specific application instance. * One FocusManager is created for each application. */ $construct: function(application) { this._application = application; }, /** * Searches the component hierarchy for the next component that should * be focused (based on the currently focused component). * Container components are queried to determine the order in which their * children should naturally be focused (certain components, e.g., SplitPanes, * will have a child focus order that may be different from the order of their * children). * This search is depth first. * * Search order (FORWARD): * * (Start on Component) * First Child, next sibling, parent * * Search order (REVERSE): * Last Child, previous sibling, parent * * * @return the Component which should be focused * @type EchoApp.Component */ find: function(component, reverse) { if (!component) { component = this._application.getFocusedComponent(); if (!component) { component = this._application.rootComponent; } } /** The component which is currently focused by the application. */ var originComponent = component; /** An associative array containing the ids of all previously visited components. */ var visitedComponents = { }; /** The value of 'component' on the previous iteration. */ var lastComponent = null; while (true) { /** The candidate next component to be focused */ var nextComponent = null; if ((reverse && component == originComponent) || (lastComponent && lastComponent.parent == component)) { // Searching in reverse on origin component (OR) Previously moved up: do not move down. } else { var componentCount = component.getComponentCount(); if (componentCount > 0) { // Attempt to move down. // Next component is first child (searching forward) or last child (searching reverse). nextComponent = component.getComponent(reverse ? componentCount - 1 : 0); if (visitedComponents[nextComponent.renderId]) { // Already visited children, cancel the move. nextComponent = null; } } } if (nextComponent == null) { // Attempt to move to next/previous sibling. if (component.parent) { // Get previous sibling. if (reverse) { var componentIndex = component.parent.indexOf(component);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -