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

📄 treeoutline.js

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 JS
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2007 Apple Inc.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1.  Redistributions of source code must retain the above copyright *     notice, this list of conditions and the following disclaimer.  * 2.  Redistributions in binary form must reproduce the above copyright *     notice, this list of conditions and the following disclaimer in the *     documentation and/or other materials provided with the distribution.  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of *     its contributors may be used to endorse or promote products derived *     from this software without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */function TreeOutline(listNode){    this.children = [];    this.selectedTreeElement = null;    this._childrenListNode = listNode;    this._childrenListNode.removeChildren();    this._knownTreeElements = [];    this._treeElementsExpandedState = [];    this.expandTreeElementsWhenArrowing = false;    this.root = true;    this.hasChildren = false;    this.expanded = true;    this.selected = false;    this.treeOutline = this;}TreeOutline._knownTreeElementNextIdentifier = 1;TreeOutline._appendChild = function(child){    if (!child)        throw("child can't be undefined or null");    var lastChild = this.children[this.children.length - 1];    if (lastChild) {        lastChild.nextSibling = child;        child.previousSibling = lastChild;    } else {        child.previousSibling = null;        child.nextSibling = null;    }    this.children.push(child);    this.hasChildren = true;    child.parent = this;    child.treeOutline = this.treeOutline;    child.treeOutline._rememberTreeElement(child);    var current = child.children[0];    while (current) {        current.treeOutline = this.treeOutline;        current.treeOutline._rememberTreeElement(current);        current = current.traverseNextTreeElement(false, child, true);    }    if (child.hasChildren && child.treeOutline._treeElementsExpandedState[child.identifier] !== undefined)        child.expanded = child.treeOutline._treeElementsExpandedState[child.identifier];    if (!this._childrenListNode) {        this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");        this._childrenListNode.parentTreeElement = this;        this._childrenListNode.addStyleClass("children");        if (this.hidden)            this._childrenListNode.addStyleClass("hidden");    }    child._attach();}TreeOutline._insertChild = function(child, index){    if (!child)        throw("child can't be undefined or null");    var previousChild = (index > 0 ? this.children[index - 1] : null);    if (previousChild) {        previousChild.nextSibling = child;        child.previousSibling = previousChild;    } else {        child.previousSibling = null;    }    var nextChild = this.children[index];    if (nextChild) {        nextChild.previousSibling = child;        child.nextSibling = nextChild;    } else {        child.nextSibling = null;    }    this.children.splice(index, 0, child);    this.hasChildren = true;    child.parent = this;    child.treeOutline = this.treeOutline;    child.treeOutline._rememberTreeElement(child);    var current = child.children[0];    while (current) {        current.treeOutline = this.treeOutline;        current.treeOutline._rememberTreeElement(current);        current = current.traverseNextTreeElement(false, child, true);    }    if (child.hasChildren && child.treeOutline._treeElementsExpandedState[child.identifier] !== undefined)        child.expanded = child.treeOutline._treeElementsExpandedState[child.identifier];    if (!this._childrenListNode) {        this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");        this._childrenListNode.parentTreeElement = this;        this._childrenListNode.addStyleClass("children");        if (this.hidden)            this._childrenListNode.addStyleClass("hidden");    }    child._attach();}TreeOutline._removeChildAtIndex = function(childIndex){    if (childIndex < 0 || childIndex >= this.children.length)        throw("childIndex out of range");    var child = this.children[childIndex];    this.children.splice(childIndex, 1);    child.deselect();    if (child.previousSibling)        child.previousSibling.nextSibling = child.nextSibling;    if (child.nextSibling)        child.nextSibling.previousSibling = child.previousSibling;    if (child.treeOutline) {        child.treeOutline._forgetTreeElement(child);        child.treeOutline._forgetChildrenRecursive(child);    }    child._detach();    child.treeOutline = null;    child.parent = null;    child.nextSibling = null;    child.previousSibling = null;}TreeOutline._removeChild = function(child){    if (!child)        throw("child can't be undefined or null");    var childIndex = this.children.indexOf(child);    if (childIndex === -1)        throw("child not found in this node's children");    TreeOutline._removeChildAtIndex.call(this, childIndex);}TreeOutline._removeChildren = function(){    for (var i = 0; i < this.children.length; ++i) {        var child = this.children[i];        child.deselect();        if (child.treeOutline) {            child.treeOutline._forgetTreeElement(child);            child.treeOutline._forgetChildrenRecursive(child);        }        child._detach();        child.treeOutline = null;        child.parent = null;        child.nextSibling = null;        child.previousSibling = null;    }    this.children = [];}TreeOutline._removeChildrenRecursive = function(){    var childrenToRemove = this.children;    var child = this.children[0];    while (child) {        if (child.children.length)            childrenToRemove = childrenToRemove.concat(child.children);        child = child.traverseNextTreeElement(false, this, true);    }    for (var i = 0; i < childrenToRemove.length; ++i) {        var child = childrenToRemove[i];        child.deselect();        if (child.treeOutline)            child.treeOutline._forgetTreeElement(child);        child._detach();        child.children = [];        child.treeOutline = null;        child.parent = null;        child.nextSibling = null;        child.previousSibling = null;    }    this.children = [];}TreeOutline.prototype._rememberTreeElement = function(element){    if (!this._knownTreeElements[element.identifier])        this._knownTreeElements[element.identifier] = [];    // check if the element is already known    var elements = this._knownTreeElements[element.identifier];    if (elements.indexOf(element) !== -1)        return;    // add the element    elements.push(element);}TreeOutline.prototype._forgetTreeElement = function(element){    if (this._knownTreeElements[element.identifier])        this._knownTreeElements[element.identifier].remove(element, true);}TreeOutline.prototype._forgetChildrenRecursive = function(parentElement){    var child = parentElement.children[0];    while (child) {        this._forgetTreeElement(child);        child = child.traverseNextTreeElement(false, this, true);    }}TreeOutline.prototype.findTreeElement = function(representedObject, isAncestor, getParent, equal){    if (!representedObject)        return null;    if (!equal)        equal = function(a, b) { return a === b };    if ("__treeElementIdentifier" in representedObject) {        // If this representedObject has a tree element identifier, and it is a known TreeElement        // in our tree we can just return that tree element.        var elements = this._knownTreeElements[representedObject.__treeElementIdentifier];        if (elements) {            for (var i = 0; i < elements.length; ++i)                if (equal(elements[i].representedObject, representedObject))                    return elements[i];        }    }    if (!isAncestor || !(isAncestor instanceof Function) || !getParent || !(getParent instanceof Function))        return null;    // The representedObject isn't know, so we start at the top of the tree and work down to find the first    // tree element that represents representedObject or one of its ancestors.    var item;    var found = false;    for (var i = 0; i < this.children.length; ++i) {        item = this.children[i];        if (equal(item.representedObject, representedObject) || isAncestor(item.representedObject, representedObject)) {            found = true;            break;        }    }    if (!found)        return null;    // Make sure the item that we found is connected to the root of the tree.    // Build up a list of representedObject's ancestors that aren't already in our tree.    var ancestors = [];    var currentObject = representedObject;    while (currentObject) {        ancestors.unshift(currentObject);        if (equal(currentObject, item.representedObject))            break;        currentObject = getParent(currentObject);    }    // For each of those ancestors we populate them to fill in the tree.    for (var i = 0; i < ancestors.length; ++i) {        // Make sure we don't call findTreeElement with the same representedObject        // again, to prevent infinite recursion.        if (equal(ancestors[i], representedObject))            continue;        // FIXME: we could do something faster than findTreeElement since we will know the next        // ancestor exists in the tree.        item = this.findTreeElement(ancestors[i], isAncestor, getParent, equal);        if (item && item.onpopulate)            item.onpopulate(item);    }    // Now that all the ancestors are populated, try to find the representedObject again. This time    // without the isAncestor and getParent functions to prevent an infinite recursion if it isn't found.    return this.findTreeElement(representedObject, null, null, equal);}TreeOutline.prototype.treeElementFromPoint = function(x, y){    var node = this._childrenListNode.ownerDocument.elementFromPoint(x, y);    var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(["ol", "li"]);    if (listNode)        return listNode.parentTreeElement || listNode.treeElement;    return null;}TreeOutline.prototype.handleKeyEvent = function(event){    if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)        return false;    var handled = false;    var nextSelectedElement;    if (event.keyIdentifier === "Up" && !event.altKey) {        nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true);        while (nextSelectedElement && !nextSelectedElement.selectable)            nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);        handled = nextSelectedElement ? true : false;    } else if (event.keyIdentifier === "Down" && !event.altKey) {        nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true);        while (nextSelectedElement && !nextSelectedElement.selectable)            nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);        handled = nextSelectedElement ? true : false;    } else if (event.keyIdentifier === "Left") {        if (this.selectedTreeElement.expanded) {            if (event.altKey)                this.selectedTreeElement.collapseRecursively();            else                this.selectedTreeElement.collapse();            handled = true;        } else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {            handled = true;            if (this.selectedTreeElement.parent.selectable) {                nextSelectedElement = this.selectedTreeElement.parent;                handled = nextSelectedElement ? true : false;            } else if (this.selectedTreeElement.parent)                this.selectedTreeElement.parent.collapse();        }    } else if (event.keyIdentifier === "Right") {        if (!this.selectedTreeElement.revealed()) {            this.selectedTreeElement.reveal();            handled = true;        } else if (this.selectedTreeElement.hasChildren) {            handled = true;            if (this.selectedTreeElement.expanded) {                nextSelectedElement = this.selectedTreeElement.children[0];                handled = nextSelectedElement ? true : false;            } else {                if (event.altKey)                    this.selectedTreeElement.expandRecursively();                else                    this.selectedTreeElement.expand();            }        }    }    if (nextSelectedElement) {        nextSelectedElement.reveal();        nextSelectedElement.select();    }    if (handled) {        event.preventDefault();        event.stopPropagation();    }    return handled;}TreeOutline.prototype.expand = function(){    // this is the root, do nothing}TreeOutline.prototype.collapse = function(){    // this is the root, do nothing}TreeOutline.prototype.revealed = function(){    return true;}TreeOutline.prototype.reveal = function(){    // this is the root, do nothing}TreeOutline.prototype.appendChild = TreeOutline._appendChild;TreeOutline.prototype.insertChild = TreeOutline._insertChild;TreeOutline.prototype.removeChild = TreeOutline._removeChild;TreeOutline.prototype.removeChildAtIndex = TreeOutline._removeChildAtIndex;TreeOutline.prototype.removeChildren = TreeOutline._removeChildren;TreeOutline.prototype.removeChildrenRecursive = TreeOutline._removeChildrenRecursive;function TreeElement(title, representedObject, hasChildren){    this._title = title;    this.representedObject = (representedObject || {});    if (this.representedObject.__treeElementIdentifier)        this.identifier = this.representedObject.__treeElementIdentifier;    else {

⌨️ 快捷键说明

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