📄 render.js
字号:
EchoRender._disposedComponents = null; // Inform UpdateManager that all updates have been completed. updateManager.purge(); // Perform focus update if required. if (client.focusUpdateRequired) { var focusedComponent = client.application.getFocusedComponent(); if (focusedComponent && focusedComponent.peer && focusedComponent.peer.renderFocus) { focusedComponent.peer.renderFocus(); client.focusUpdateRequired = false; } } }, /** * Registers a component type name with an instantiable peer class. * Components of the specified type name will be assigned new instasnces of the peer class * when rendered for the first time. * * @param {String} componentName the component type name * @param {Function} peerObject the peer class object */ registerPeer: function(componentName, peerObject) { if (this._peers[componentName]) { throw new Error("Peer already registered: " + componentName); } this._peers[componentName] = peerObject; }, /** * Renders a new component inside of a DOM element. * This method should be called by container components in order to render their children. * * @param {EchoApp.Update.ComponentUpdate} update the revelant ComponentUpdate * @param {EchoApp.Component} component the component to add * @param {Element} parentElement the DOM element to which the rendered component should be added */ renderComponentAdd: function(update, component, parentElement) { if (!component.parent || !component.parent.peer || !component.parent.peer.client) { throw new Error("Cannot find reference to the Client with which this component should be associated: " + "cannot load peer. This is due to the component's parent's peer not being associated with a Client. " + "Component = " + component); } EchoRender._loadPeer(component.parent.peer.client, component); EchoRender._setPeerDisposedState(component, false); component.peer.renderAdd(update, parentElement); }, /** * Manually invokes renderDisplay on a component (and its descendants) that was added to the * hierarchy outside of processUpdates(). This method is only used in special cases, * e.g., by in the case of Application Rendered Components that need to render children. * * @param parent the parent component of the sub-hierarchy on which renderDisplay() should * be invoked (note that renderDisplay WILL be invoked on the parent as well * as its descendants) */ renderComponentDisplay: function(parent) { this._doRenderDisplay(parent, true); }, /** * Disposes of a component and its descendants. * This method should be invoked by any peer that will be updating a component in such * a fashion that it will be destroying the rendering of its children and re-rendering them. * It is not necessary to invoke this method on components that may not contain children. * * @param update the <code>ComponentUpdate</code> for which this change is being performed * @param component the <code>Component</code> to be disposed */ renderComponentDispose: function(update, component) { this._renderComponentDisposeImpl(update, component); }, /** * Recursive implementation of renderComponentDispose. Invokes * renderDispose() on all child peers, sets disposed state on each. * * @param update the <code>ComponentUpdate</code> for which this change is being performed * @param component the <code>Component</code> to be disposed * @private */ _renderComponentDisposeImpl: function(update, component) { if (!component.peer || component.peer.disposed) { return; } EchoRender._setPeerDisposedState(component, true); component.peer.renderDispose(update); for (var i = 0; i < component.children.length; ++i) { EchoRender._renderComponentDisposeImpl(update, component.children[i]); } }, /** * Sets the peer disposed state of a component. * The peer disposed state indicates whether the renderDispose() * method of the component has been executed since it was last rendered. * * @param {EchoApp.Component} component the component * @param {Boolean} disposed the disposed state, true indicating the component has * been disposed * @private */ _setPeerDisposedState: function(component, disposed) { if (disposed) { component.peer.disposed = true; EchoRender._disposedComponents[component.renderId] = component; } else { component.peer.disposed = false; delete EchoRender._disposedComponents[component.renderId]; } }, // FIXME. Ensure this is properly invoked and no peers are being leaked. /** * Destroys a component synchronization peer for a specific compoennt. * The peer will be removed from the "peer" property of the component. * The client will be removed from the "client" property of the component. * The peer to component association will be removed. * * @param {EchoApp.Component} component the component * @private */ _unloadPeer: function(component) { component.peer.client = null; component.peer.component = null; component.peer = null; }};/** * @class * Component synchronization peer. */EchoRender.ComponentSync = Core.extend({ $static: { FOCUS_PERMIT_ARROW_UP: 0x1, FOCUS_PERMIT_ARROW_DOWN: 0x2, FOCUS_PERMIT_ARROW_LEFT: 0x4, FOCUS_PERMIT_ARROW_RIGHT: 0x8, FOCUS_PERMIT_ARROW_ALL: 0xf }, /** * The client supported by this peer. * @type EchoClient */ client: null, /** * The component instance supported by this peer. * Each peer instance will support a single component instance. * @type EchoApp.Component */ component: null, /** * Creates a new copmonent synchronization peer. * @constructor */ $construct: function() { }, $abstract: { /** * Renders the component to the DOM. * The supplied update will refer to a ancestor component of the supported component * being updated. * * @param {EchoApp.Update.ComponentUpdate} update the update being rendered */ renderAdd: function(update, parentElement) { throw new Error("Operation \"renderAdd\" not supported (Component: " + this.component + ")."); }, /** * Invoked when the rendered component is about to be removed from the DOM. * This method should dispose of any client resources in use by the component, e.g., * unregistering event listeners and removing any DOM elements that are not children of * the parent component's DOM element. * The DOM should NOT be modified to remove the element(s) representing this component * for performance as well as aesthetic reasons (e.g., in the case where a parent component * might be using an animated transition effect to remove the component. * The supplied update will refer to a ancestor component of the supported component * being updated. * * A component may be re-added to the screen after being disposed, e.g., in the case * where a parent component does not possess a 'partial update' capability and removes * a child component hierarchy and then re-renders it. A synchronization peer should * allow for the fact that its renderAdd() method may be invoked at some point in time * after renderDispose() has been invoked. * * @param {EchoApp.Update.ComponentUpdate} update the update being rendered */ renderDispose: function(update) { throw new Error("Operation \"renderDispose\" not supported (Component: " + this.component + ")."); }, /** * Renders an update to a component, e.g., children added/removed, properties updated. * The supplied update will refer specifically to an update of the supported component. * * @param {EchoApp.Update.ComponentUpdate} update the update being rendered * @return true if this invocation has re-rendered all child components, false otherwise */ renderUpdate: function(update) { throw new Error("Operation \"renderUpdate\" not supported (Component: " + this.component + ")."); } }, $virtual: { getFocusFlags: null, /** * Invoked when component is rendered focused. */ renderFocus: null, /** * Optional method. Invoked when the component has been added to the hierarchy and first appears * on screen, and when ancestors of the component (or the containing window) have * resized. */ renderDisplay: null }});/** * Creates a new root component synchronization peer. * The root component is not managed by the server, but rather is an existing * element within which the Echo application is rendered. * This is a very special case in that there is no renderAdd() method. * * @constructor * @class Root component synchronization peer. */EchoRender.RootSync = Core.extend(EchoRender.ComponentSync, { renderAdd: function(update, parentElement) { throw new Error("Unsupported operation: renderAdd()."); }, renderDispose: function(update) { }, renderUpdate: function(update) { var fullRender = false; if (update.hasAddedChildren() || update.hasRemovedChildren()) { WebCore.DOM.removeAllChildren(this.client.domainElement); for (var i = 0; i < update.parent.children.length; ++i) { EchoRender.renderComponentAdd(update, update.parent.children[i], this.client.domainElement); } fullRender = true; } if (update.hasUpdatedProperties()) { var titleUpdate = update.getUpdatedProperty("title"); if (titleUpdate) { document.title = titleUpdate.newValue; } } return fullRender; }});/** * @class * Namespace for utility objects. */EchoRender.Util = { // FIXME abstract this somehow so it works with FreeClient too TRANSPARENT_IMAGE: "?sid=Echo.TransparentImage"};EchoRender.registerPeer("Root", EchoRender.RootSync);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -