source: products/qPloneTabs/tags/0.2.1/skins/qPloneTabs/2.0.5/nodeutilities.js @ 1591

Last change on this file since 1591 was 1, checked in by myroslav, 18 years ago

Building directory structure

File size: 4.6 KB
Line 
1
2function wrapNode(node, wrappertype, wrapperclass){
3    /* utility function to wrap a node in an arbitrary element of type "wrappertype"
4     * with a class of "wrapperclass" */
5    var wrapper = document.createElement(wrappertype)
6    wrapper.className = wrapperclass;
7    var innerNode = node.parentNode.replaceChild(wrapper,node);
8    wrapper.appendChild(innerNode);
9};
10
11function nodeContained(innernode, outernode){
12    // check if innernode is contained in outernode
13    var node = innernode.parentNode;
14    while (node != document) {
15        if (node == outernode) {
16            return true; 
17        }
18        node=node.parentNode;
19    }
20    return false;
21};
22
23function findContainer(node, func) {
24    // Starting with the given node, find the nearest containing element
25    // for which the given function returns true.
26
27    while (node != null) {
28        if (func(node)) {
29            return node;
30        }
31        node = node.parentNode;
32    }
33    return false;
34};
35
36function hasClassName(node, class_name) {
37    return new RegExp('\\b'+class_name+'\\b').test(node.className);
38};
39
40function addClassName(node, class_name) {
41    if (!node.className) {
42        node.className = class_name;
43    } else if (!hasClassName(node, class_name)) {
44        var className = node.className+" "+class_name;
45        // cleanup
46        node.className = className.split(/\s+/).join(' ');
47    }
48};
49
50function removeClassName(node, class_name) {
51    var className = node.className;
52    if (className) {
53        // remove
54        className = className.replace(new RegExp('\\b'+class_name+'\\b'), '');
55        // cleanup
56        className = className.replace(/\s+/g, ' ');
57        node.className = className.replace(/\s+$/g, '');
58    }
59};
60
61function replaceClassName(node, old_class, new_class, ignore_missing) {
62    if (ignore_missing && !hasClassName(node, old_class)) {
63        addClassName(node, new_class);
64    } else {
65        var className = node.className;
66        if (className) {
67            // replace
68            className = className.replace(new RegExp('\\b'+old_class+'\\b'), new_class);
69            // cleanup
70            className = className.replace(/\s+/g, ' ');
71            node.className = className.replace(/\s+$/g, '');
72        }
73    }
74};
75
76function walkTextNodes(node, func, data) {
77    // traverse childnodes and call func when a textnode is found
78    if (!node){return false}
79    if (node.hasChildNodes) {
80        // we can't use for (i in childNodes) here, because the number of
81        // childNodes might change (higlightsearchterms)
82        for (var i=0;i<node.childNodes.length;i++) {
83            walkTextNodes(node.childNodes[i], func, data);
84        }
85        if (node.nodeType == 3) {
86            // this is a text node
87            func(node, data);
88        }
89    }
90};
91
92/* These are two functions, because getInnerTextFast doesn't always return the
93 * the same results, as it depends on the implementation of node.innerText of
94 * the browser. getInnerTextCompatible will always return the same values, but
95 * is a bit slower. The difference is just in the whitespace, so if this
96 * doesn't matter, you should always use getInnerTextFast.
97 */
98
99function getInnerTextCompatible(node) {
100    var result = new Array();
101    walkTextNodes(node,
102                  function(n, d){d.push(n.nodeValue)},
103                  result);
104    return result.join("");
105};
106
107function getInnerTextFast(node) {
108    if (node.innerText) {
109        return node.innerText;
110    } else {
111        return getInnerTextCompatible(node);
112    }
113};
114
115/* This function reorder nodes in the DOM.
116 * fetch_func - the function which returns the value for comparison
117 * cmp_func - the compare function, if not provided then the string of the
118 * value returned by fetch_func is used.
119 */
120function sortNodes(nodes, fetch_func, cmp_func) {
121    // terminate if we hit a non-compliant DOM implementation
122    if (!W3CDOM){return false};
123
124    // wrapper for sorting
125    var SortNodeWrapper = function(node) {
126        this.value = fetch_func(node);
127        this.cloned_node = node.cloneNode(true);
128        this.toString = function() {
129            if (this.value.toString) {
130                return this.value.toString();
131            } else {
132                return this.value;
133            }
134        }
135    }
136
137    // wrap nodes
138    var items = new Array();
139    for (var i=0; i<nodes.length; i++) {
140        items.push(new SortNodeWrapper(nodes[i]));
141    }
142
143    //sort
144    if (cmp_func) {
145        items.sort(cmp_func);
146    } else {
147        items.sort();
148    }
149
150    // reorder nodes
151    for (var i=0; i<items.length; i++) {
152        var dest = nodes[i];
153        dest.parentNode.replaceChild(items[i].cloned_node, dest);
154    }
155};
Note: See TracBrowser for help on using the repository browser.