⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 render.accordionpane.js

📁 一个ajax富客户端的ajax类库
💻 JS
📖 第 1 页 / 共 2 页
字号:
// FIXME Update animation to use WebCore.Scheduler.
// FIXME handle enabled/disabled state

/**
 * Component rendering peer: AccordionPane
 */
ExtrasRender.ComponentSync.AccordionPane = Core.extend(EchoRender.ComponentSync, {

    $static: {
        _paneInsets: 0,
        _defaultTabBackground: "#cfcfcf",
        _defaultTabBorder: "1px outset #cfcfcf",
        _defaultTabForeground: "#000000",
        _defaultTabHeight: "20px",
        _defaultTabInsets: "2px 5px",
        _defaultTabContentInsets: this._paneInsets
    },
    
    $load: function() {
        EchoRender.registerPeer("ExtrasApp.AccordionPane", this);
    },
    
    _animationTime: 0,
    
    $construct: function() {
        this._paneDivElement = null;
        this._activeTabId = null;
        this._tabs = [];
        this._rotation = null;
        this._animationEnabled = true;
        this._animationSleepInterval = 1;
    },
    
    renderAdd: function(update, parentElement) {
        this._animationTime = this.component.render("animationTime", ExtrasApp.AccordionPane.DEFAULT_ANIMATION_TIME);
        this._activeTabId = this.component.get("activeTab");
        
        this._paneDivElement = this._render();
        
        var componentCount = this.component.getComponentCount();
        for (var i = 0; i < componentCount; ++i) {
            var child = this.component.getComponent(i);
            var tab = new ExtrasRender.ComponentSync.AccordionPane.Tab(child, this);
            this._tabs.push(tab);
            tab._render(this.client, update);
            this._paneDivElement.appendChild(tab._tabDivElement);
            this._paneDivElement.appendChild(tab._contentDivElement);
        }
        
        this._redrawTabs();
        
        parentElement.appendChild(this._paneDivElement);
    },
    
    renderDisplay: function() {
        for (var i = 0; i < this._tabs.length; ++i) {
            this._tabs[i]._renderDisplay();
        }
    },
    
    renderUpdate: function(update) {
        var fullRender;

        if (update.hasUpdatedLayoutDataChildren() || update.hasAddedChildren() || update.hasRemovedChildren()) {
            // Add/remove/layout data change: full render.
            fullRender = true;
        } else {
            var propertyNames = update.getUpdatedPropertyNames();
            if (propertyNames.length == 1 && propertyNames[0] == "activeTab") {
                this._selectTab(update.getUpdatedProperty("activeTab").newValue);
                fullRender = false;
            } else {
                fullRender = true;
            }
        }

        if (fullRender) {
            var element = this._paneDivElement;
            var containerElement = element.parentNode;
            EchoRender.renderComponentDispose(update, update.parent);
            containerElement.removeChild(element);
            this.renderAdd(update, containerElement);
        }

        return fullRender;
    },

    renderDispose: function(update) {
        if (this._rotation) {
            this._rotation._dispose();
        }
        this._activeTabId = null;
        for (var i = 0; i < this._tabs.length; i++) {
            this._tabs[i]._dispose();
        }
        this._tabs = [];
        this._paneDivElement.id = "";
        this._paneDivElement = null;
    },
    
    _render: function() {
        var paneDivElement = document.createElement("div");
        paneDivElement.id = this.component.renderId;
        paneDivElement.style.position = "absolute";
        paneDivElement.style.overflow = "hidden";
        paneDivElement.style.width = "100%";
        paneDivElement.style.height = "100%";
        EchoAppRender.Color.renderFB(this.component, paneDivElement);
        EchoAppRender.Font.render(this.component.render("font"), paneDivElement);
        return paneDivElement;
    },
    
    /**
     * Selects a specific tab.
     * 
     * @param tabId {String} the id of the tab to select
     */
    _selectTab: function(tabId) {
        if (tabId == this._activeTabId) {
            return;
        }
        this.component.set("activeTab", tabId);
        
        var oldTabId = this._activeTabId;
        this._activeTabId = tabId;
        if (oldTabId != null && this._animationEnabled) {
            this._rotateTabs(oldTabId, tabId);
        } else {
            this._redrawTabs();
        }
    },
    
    /**
     * Removes a tab from an AccordionPane.
     *
     * @param tab the tab to remove
     */
    _removeTab: function(tab) {
        var tabIndex = Core.Arrays.indexOf(this._tabs, tab);
        this._tabs.splice(tabIndex, 1);
    
        tab._tabDivElement.parentNode.removeChild(tab._tabDivElement);
        tab._contentDivElement.parentNode.removeChild(tab._contentDivElement);
        tab._dispose();
    },
    
    /**
     * Redraws tabs in the appropriate positions, exposing the content of the 
     * selected tab.
     */
    _redrawTabs: function() {
        if (this._rotation) {
            this._rotation._cancel();
        }
        
        if (this._activeTabId == null || this._getTabById(this._activeTabId) == null) {
            if (this._tabs.length > 0) {
                this._activeTabId = this._tabs[0]._childComponent.renderId;
            } else {
                this._activeTabId = null;
            }
        }
        
        var selectionPassed = false;
        var tabHeight = this._calculateTabHeight();
        for (var i = 0; i < this._tabs.length; ++i) {
            var tab = this._tabs[i];
            var tabDivElement = tab._tabDivElement;
            var contentDivElement = tab._contentDivElement;
            
            if (selectionPassed) {
                tabDivElement.style.top = "";
                tabDivElement.style.bottom = (tabHeight * (this._tabs.length - i - 1)) + "px";
            } else {
                tabDivElement.style.bottom = "";
                tabDivElement.style.top = (tabHeight * i) + "px";
            }
    
            contentDivElement.style.height = "";
            
            if (this._activeTabId == tab._childComponent.renderId) {
                selectionPassed = true;
                contentDivElement.style.display = "block";
                contentDivElement.style.top = (tabHeight * (i + 1)) + "px";
                var bottomPx = tabHeight * (this._tabs.length - i - 1);
                contentDivElement.style.bottom = bottomPx + "px";
            } else {
                contentDivElement.style.display = "none";
            }
        }
    },
    
    /**
     * "Rotates" the AccordionPane to display the specified tab.
     *
     * @param oldTabId {String} the currently displayed tab id
     * @param newTabId {String} the id of the tab that will be displayed
     */
    _rotateTabs: function(oldTabId, newTabId) {
        if (this._animationTime < 1) {
            this._redrawTabs();
            return;
        }
        var oldTab = this._getTabById(oldTabId);
        if (oldTab == null) {
            // Old tab has been removed.
            this._redrawTabs();
            return;
        }
        if (this._rotation) {
            // Rotation was already in progress, cancel
            this._rotation._cancel();
            this._redrawTabs();
        } else {
            // Start new rotation.
            var newTab = this._getTabById(newTabId);
            this._rotation = new ExtrasRender.ComponentSync.AccordionPane.Rotation(this, oldTab, newTab);
        }
    },
    
    /**
     * Retrieves the tab instance with the specified tab id.
     * 
     * @param tabId the tab id
     * @return the tab, or null if no tab is present with the specified id
     */
    _getTabById: function(tabId) {
        for (var i = 0; i < this._tabs.length; ++i) {
            var tab = this._tabs[i];
            if (tab._childComponent.renderId == tabId) {
                return tab;
            }
        }
        return null;
    },
    
    _getTabBackground: function() {
        var background = this.component.render("tabBackground");
        return background ? background : ExtrasRender.ComponentSync.AccordionPane._defaultTabBackground;
    },
    
    _getTabBorder: function() {
        var border = this.component.render("tabBorder");
        return border ? border : ExtrasRender.ComponentSync.AccordionPane._defaultTabBorder;
    },
    
    _getTabInsets: function() {
        var insets = this.component.render("tabInsets");
        return insets ? insets : ExtrasRender.ComponentSync.AccordionPane._defaultTabInsets;
    },
    
    /**
     * @return the tab height in pixels
     * @type {Number}
     */
    _calculateTabHeight: function() {
        var height = EchoAppRender.Extent.toPixels(ExtrasRender.ComponentSync.AccordionPane._defaultTabHeight);
        var insets = EchoAppRender.Insets.toPixels(this._getTabInsets());
        var border = this._getTabBorder();
        return height + insets.top + insets.bottom + EchoAppRender.Border.getPixelSize(border) * 2;
    }
});

ExtrasRender.ComponentSync.AccordionPane.Tab = Core.extend({
    
    $construct: function(childComponent, parent) {
        this._childComponent = childComponent;
        this._parent = parent;
        this._rendered = false;
        this._tabDivElement = null;
        this._contentDivElement = null;
    },
    
    _render: function(client, update) {
        this._tabDivElement = document.createElement("div");
        this._tabDivElement.id = this._parent.component.renderId + "_tab_" + this._childComponent.renderId;
        this._tabDivElement.style.cursor = "pointer";
        this._tabDivElement.style.height = ExtrasRender.ComponentSync.AccordionPane._defaultTabHeight;
        EchoAppRender.Insets.render(this._parent._getTabInsets(), this._tabDivElement, "padding");
        this._tabDivElement.style.position = "absolute";
        this._tabDivElement.style.left = "0px";
        this._tabDivElement.style.right = "0px";
        this._tabDivElement.style.overflow = "hidden";
        this._tabDivElement.appendChild(document.createTextNode(this._getTitle()));
    
        this._contentDivElement = document.createElement("div");
        this._contentDivElement.id = this._parent.component.renderId + "_content_" + this._childComponent.renderId;
        this._contentDivElement.style.display = "none";
        this._contentDivElement.style.position = "absolute";
        this._contentDivElement.style.left = "0px";
        this._contentDivElement.style.right = "0px";
        EchoAppRender.Insets.render(this._getContentInsets(), this._contentDivElement, "padding");
        this._contentDivElement.style.overflow = "auto";
    
        EchoRender.renderComponentAdd(update, this._childComponent, this._contentDivElement);
        
        this._highlight(false);
        this._addEventListeners();
    },
    
    _renderDisplay: function() {
        WebCore.VirtualPosition.redraw(this._tabDivElement);
        WebCore.VirtualPosition.redraw(this._contentDivElement);
    },
    
    _dispose: function() {
        WebCore.EventProcessor.removeAll(this._tabDivElement);
        
        this._parent = null;
        this._childComponent = null;
        this._tabDivElement.id = "";
        this._tabDivElement = null;
        this._contentDivElement.id = "";
        this._contentDivElement = null;
    },
    
    _highlight: function(state) {
        var tabDivElement = this._tabDivElement;
        if (state) {
            var background = this._parent.component.render("tabRolloverBackground");
            if (!background) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -