📄 application.js
字号:
if (componentIndex > 0) { nextComponent = component.parent.getComponent(componentIndex - 1); } } else { var componentIndex = component.parent.indexOf(component); if (componentIndex < component.parent.getComponentCount() - 1) { nextComponent = component.parent.getComponent(componentIndex + 1); } } } } if (nextComponent == null) { // Attempt to move up. nextComponent = component.parent; } if (nextComponent == null) { return null; } lastComponent = component; component = nextComponent; visitedComponents[component.renderId] = true; if (component != originComponent && component.isActive() && component.focusable) { return component; } } }, /** * Finds next (or previous) focusable descendant of a parent component. * This method requires that the application's currently focused component * be a descendant of the specified parent component. The search will * be limited to descendants of the parent component, i.e., if a suitable descendant * component cannot be found, null will be returned. * * @param parentComponent the parent component to search * @param reverse the search direction, false indicating to search forward, true * indicating reverse * @param minimumDistance FIXME */ findInParent: function(parentComponent, reverse, minimumDistance) { if (!minimumDistance) { minimumDistance = 1; } var focusedComponent = this._application.getFocusedComponent(); var focusedIndex = this._getDescendantIndex(parentComponent, focusedComponent); if (focusedIndex == -1) { return null; } var componentIndex = focusedIndex; var component = focusedComponent; do { component = this.find(component, reverse); if (component == null) { return null; } componentIndex = this._getDescendantIndex(parentComponent, component); } while (Math.abs(componentIndex - focusedIndex) < minimumDistance && component != focusedComponent); if (component == focusedComponent) { // Search wrapped, only one focusable component. return null; } this._application.setFocusedComponent(component); return component; }, _getDescendantIndex: function(parentComponent, descendant) { while (descendant.parent != parentComponent && descendant.parent != null) { descendant = descendant.parent; } if (descendant.parent == null) { return -1; } return parentComponent.indexOf(descendant); }});// Fundamental Property Types/** * Describes the layout direction of text and content to provide support * for bidirectional localization. */EchoApp.LayoutDirection = Core.extend({ /** * Flag indicating whether layout direction is left-to-right. * @type Boolean */ _ltr: false, /** * LayoutDirection property. Do not instantiate, use LTR/RTL constants. * @constructor */ $construct: function(ltr) { this._ltr = ltr; }, /** * Determines if the layout direction is left-to-right. * * @return true if the layout direction is left-to-right * @type Boolean */ isLeftToRight: function() { return this._ltr; }});/** * Global instance representing a left-to-right layout direction. * @type EchoApp.LayoutDirection * @final */EchoApp.LayoutDirection.LTR = new EchoApp.LayoutDirection(true);/** * Global instance representing a right-to-left layout direction. * @type EchoApp.LayoutDirection * @final */EchoApp.LayoutDirection.RTL = new EchoApp.LayoutDirection(false);// StyleSheets/** * @class * An application style sheet. */EchoApp.StyleSheet = Core.extend({ _nameToStyleMap: null, _renderCache: null, /** * Creates a new style sheet. * * @param initialValues an optional mapping between style names * and maps between component types and styles */ $construct: function(initialValues) { this._renderCache = { }; this._nameToStyleMap = { }; if (initialValues) { for (var styleName in initialValues) { for (var componentType in initialValues[styleName]) { this.setStyle(styleName, componentType, initialValues[styleName][componentType]); } } } }, /** * Returns the style that should be used for a component. * * @param {String} name the component's style name * @param {String} componentType the type of the component * @return the style * @type Object */ getRenderStyle: function(name, componentType) { // Retrieve style from cache. var typeToStyleMap = this._renderCache[name]; if (!typeToStyleMap) { return null; } var style = typeToStyleMap[componentType]; if (style !== undefined) { // If style found in cache, return immediately. return style; } else { return this._loadRenderStyle(name, componentType); } }, _loadRenderStyle: function(name, componentType) { // Retrieve value (type-to-style-map) from name-to-style-map with specified name key. var typeToStyleMap = this._nameToStyleMap[name]; if (typeToStyleMap == null) { // No styles available for specified name, mark cache entry as null and return null. this._renderCache[name][componentType] = null; return null; } // Retrieve style for specific componentType. style = typeToStyleMap[componentType]; if (style == null) { var testType = componentType; while (style == null) { // Search super types of testType to find style until found. testType = EchoApp.ComponentFactory.getSuperType(testType); if (testType == null) { // No style available for component type, mark cache entry as null and return null. this._renderCache[name][testType] = null; return null; } style = typeToStyleMap[testType]; } } this._renderCache[name][componentType] = style; return style; }, /** * Retrieves a specific style from the style sheet. * * @param {String} name the style name * @param {String} componentType the component type * @return the style * @type Object */ getStyle: function(name, componentType) { var typeToStyleMap = this._nameToStyleMap[name]; if (typeToStyleMap == null) { return null; } return typeToStyleMap[componentType]; }, /** * Stores a style in the style sheet. * * @param {String} name the style name * @param {String} componentType the component type * @param {Object} the style */ setStyle: function(name, componentType, style) { // Create or clear cache entry for name. this._renderCache[name] = {}; var typeToStyleMap = this._nameToStyleMap[name]; if (typeToStyleMap == null) { typeToStyleMap = {}; this._nameToStyleMap[name] = typeToStyleMap; } typeToStyleMap[componentType] = style; }});// Update Management/** * Namespace for update management. Non-instantiable object. * Provides capabilities for storing property changes made to applications and components * such that display redraws may be performed efficiently. */EchoApp.Update = { };/** * @class Representation of an update to a single existing component * which is currently rendered on the screen. */EchoApp.Update.ComponentUpdate = Core.extend({ $static: { /** * Data object representing the old and new states of a changed property. * * @param oldValue the old value of the property * @param newValue the new value of the property */ PropertyUpdate: function(oldValue, newValue) { this.oldValue = oldValue; this.newValue = newValue; } }, /** * The <code>Manager</code> to which this update belongs. * @type Array */ _manager: null, /** * The parent component represented in this <code>ServerComponentUpdate</code>. * @type EchoApp.Component */ parent: null, /** * Storage for contextual information used by application container to render this update. * Object type and content are specified by the application container, this variable is not * used by the application module in any capacity. */ renderContext : null, /** * The set of child Component ids added to the <code>parent</code>. * @type Array */ _addedChildIds: null, /** * A mapping between property names of the parent component and * <code>PropertyUpdate</code>s. * @type Object */ _propertyUpdates: null, /** * The set of child Component ids removed from the <code>parent</code>. * @type Array */ _removedChildIds: null, /** * The set of descendant Component ids which are implicitly removed * as they were children of removed children. * @type Array */ _removedDescendantIds: null, /** * The set of child Component ids whose <code>LayoutData</code> * was updated. * @type Array */ _updatedLayoutDataChildIds: null, /** * Creates a new ComponentUpdate. * * @constructor * @param parent the updated component */ $construct: function(manager, parent) { /** * The <code>Manager</code> to which this update belongs. * @type Array */ this._manager = manager; /** * The parent component represented in this <code>ServerComponentUpdate</code>. * @type EchoApp.Component */ this.parent = parent; }, /** * Records the addition of a child to the parent component. * * @param {EchoApp.Component} child the added child * @private */ _addChild: function(child) { if (!this._addedChildIds) { this._addedChildIds = []; } this._addedChildIds.push(child.renderId); this._manager._idMap[child.renderId] = child; }, /** * Appends removed children and descendants from another update to this * update as removed descendants. * This method is invoked when a component is removed that is an ancestor * of a component that has an update in the update manager. * * @private * @param {EchoApp.Update.CompoenntUpdate} update the update from which to pull * removed components/descendants */ _appendRemovedDescendants: function(update) { // Append removed descendants. if (update._removedDescendantIds != null) { if (this._removedDescendantIds == null) { this._removedDescendantIds = []; } for (var x in update._removedDescendantIds) { this._removedDescendantIds.push(x); } } // Append removed children. if (update._removedChildIds != null) { if (this._removedDescendantIds == null) { this._removedDescendantIds = []; } for (var x in update._removedChildIds) { this._removedDescendantIds.push(x); } } if (this._removedDescendantIds != null) { Core.Arrays.removeDuplicates(this._removedDescendantIds); } }, /** * Returns an array containing the children added in this update, * or null if none were added. * * @return the added children * @type Array */ getAddedChildren: function() { if (!this._addedChildIds) { return null; } var components = new Array(this._addedChildIds.length);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -