• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2// (C) Copyright 2003-2007 Jonathan Turkanis
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
5
6//--------------Event-handlers------------------------------------------------//
7
8function toggle(id) { get_tree().find(id).toggle(); }
9function blur_tree()
10{
11    if (  window.event &&
12          window.event.srcElement &&
13          window.event.srcElement.blur &&
14          window.event.srcElement != document.body  )
15        window.event.srcElement.blur();
16    else if (target_frame())
17        target_frame().window.focus();
18}
19document.onclick = blur_tree;
20
21//--------------Netscape 4.x-specific-----------------------------------------//
22
23window.saved_width = window.outerWidth;
24function reload_tree()
25{
26    if (window.outerWidth != window.saved_width)
27        window.location.reload();
28}
29if (window.Event && Event.RESIZE) {
30    window.captureEvents(Event.RESIZE);
31    window.onResize = reload_tree;
32}
33
34//--------------Functions for browser-sniffing--------------------------------//
35
36function major_version(app)
37{
38    var index = navigator.userAgent.indexOf(app);
39    if (index == -1)
40        return -1;
41    return parseInt(navigator.userAgent.charAt(index + app.length + 1));
42}
43function dom_support()
44{
45    if (dom_support.cache == null)
46        dom_support.cache = dom_support_impl();
47    return dom_support.cache;
48}
49function dom_support_impl()
50{
51    var version;
52    if ( (version = major_version("Mozilla")) != -1 &&
53         navigator.userAgent.indexOf("compatible") == -1 )
54        return version > 4;
55    if ((version = major_version("Opera")) != -1)
56        return version > 6;
57    if ((version = major_version("Konqueror")) != -1)
58        return version > 2;
59    if ((version = major_version("Links")) != -1)
60        return false;
61    return document.getElementById || document.all;
62}
63
64//--------------Utility functions---------------------------------------------//
65
66function target_frame()
67{
68    return get_tree() ? top.frames[get_tree().target] : null;
69}
70function get_tree() { return document.tree_control; }
71function static_display() { return !dom_support() || get_tree().dump_html; }
72function elt_by_id(id)
73{
74    return document.all ?
75        document.all[id] :
76        document.getElementById ?
77            document.getElementById(id) :
78            null;
79}
80function replace_query(url, query)
81{
82    var pos;
83    if ((pos = url.indexOf("?")) != -1)
84        url = url.substring(0, pos);
85    return url + "?" + query;
86}
87
88//--------------Functions for HTML-generation---------------------------------//
89
90function icon_char(state)
91{
92    return state == tree_node.expanded ?
93                "-" :
94                state == tree_node.collapsed ?
95                    "+" :
96                    " ";
97}
98function html_list(id, display, margin)
99{
100    return "<div id='" + id + "' style='white-space:nowrap;display:" +
101           display + "'>";
102}
103function html_list_item(content)
104{
105    return "\n<div class='tree-item'>" + content + "</div>";
106}
107function html_anchor(content, cl, href, target)
108{
109    return "<a class='" + cl + "' onfocus='blur_tree()" +
110           "' href='" +  href + "'" +
111           (target ? " target='" + target + "'" : "") +
112           ">" + content + "</a>";
113}
114
115//--------------Definition of class tree_node---------------------------------//
116
117function tree_node__add(text_or_node, link_or_hide, hide)
118{
119    if (this.state == tree_node.neutral)
120        this.state = tree_node.collapsed;
121    var k;
122    if (text_or_node.length != null) {
123        k = new tree_node(text_or_node, link_or_hide);
124        k.hide_kids = hide != null ? hide : false;
125    } else {
126        k = text_or_node;
127        k.hide_kids = link_or_hide != null ? link_or_hide : false;
128    }
129    k.mom = this;
130    if (this.kids == null)
131        this.kids = new Array();
132    this.kids[this.kids.length] = k;
133    return k;
134}
135function tree_node__level()
136{
137    var level;
138    var node;
139    for (node = this.mom, level = -1; node; node = node.mom, ++level)
140        ;
141    return level;
142}
143function tree_node__parent() { return this.mom; }
144function tree_node__print()
145{
146    var icon =
147        !static_display() ?
148            "<span style='font-family:monospace' class='tree-icon' id='icon" +
149                 this.id + "'>" + icon_char(this.state) + "</span>&nbsp;&nbsp;" :
150            "";
151    var handler =
152        !static_display() && this.kids ?
153            "javascript:toggle(\"id" + this.id + "\")" :
154            "";
155    var text = "<span class='tree-text'>" + this.text + "</span>"
156    var tree = get_tree();
157    var indent = tree.indent * this.level();
158    return html_list_item(
159               "<div style='margin-left:" + (2 * indent) +
160               ";text-indent:-" + indent + "'>" +
161               ( !tree.dump_html ?
162                     this.kids ?
163                         html_anchor(icon, "tree-icon", handler) :
164                         icon :
165                     "" ) +
166               ( tree.numbered ?
167                     "" + "<span class='tree-label'>" +
168                         this.id.substring(1) + "</span>" :
169                     "" ) +
170               "&nbsp;&nbsp;" +
171               ( this.link ?
172                     html_anchor( text, "tree-text", this.link,
173                                  tree.target ) :
174                     text ) +
175               "</div>" +
176               this.print_kids()
177           );
178}
179function tree_node__print_kids(margin)
180{
181    var result = "";
182    if (this.kids != null && (!static_display() || !this.hide_kids)) {
183        if (margin == null)
184            margin = get_tree().indent;
185        result += html_list( "list" + this.id,
186                             this.state == tree_node.collapsed &&
187                             !static_display()
188                                ? "none" : "",
189                             margin );
190        for (var z = 0; z < this.kids.length; ++z) {
191            var k = this.kids[z];
192            k.id = this.id + "." + (z + 1);
193            result += k.print();
194        }
195        result += "</div>";
196    }
197    return result;
198}
199function tree_node__toggle(expand)
200{
201    if ( static_display() ||
202         this.kids == null ||
203         expand != null && expand ==
204            (this.state == tree_node.expanded) )
205    {
206        return;
207    }
208    this.state =
209        this.state == tree_node.expanded ?
210            tree_node.collapsed :
211            tree_node.expanded;
212    elt_by_id("icon" + this.id).innerHTML =
213        icon_char(this.state);
214    elt_by_id("list" + this.id).style.display =
215        this.state == tree_node.expanded ?
216            "" :
217            "none";
218}
219function add_methods(obj)
220{
221    obj.add = tree_node__add;
222    obj.level = tree_node__level;
223    obj.parent = tree_node__parent;
224    obj.print = tree_node__print;
225    obj.print_kids = tree_node__print_kids;
226    obj.toggle = tree_node__toggle;
227}
228function tree_node(text, link)
229{
230    // Member data
231    this.text = text;
232    this.link = link;
233    this.mom = null;
234    this.kids = null;
235    this.id = null;
236    this.state = 0; // Neutral.
237
238    if (!add_methods.prototype)
239        add_methods(this);
240}
241tree_node.neutral = 0;
242tree_node.expanded = 1;
243tree_node.collapsed = 2;
244if (tree_node.prototype)
245    add_methods(tree_node.prototype);
246
247//--------------Definition of class tree_control------------------------------//
248
249function tree_control__add(text, link, hide)
250{
251    return this.root.add(text, link, hide);
252}
253function tree_control__draw()
254{
255    var tree    = get_tree();
256    var dom     = dom_support();
257    var element = dom ? elt_by_id('tree_control') : null;
258    if (element || !dom || tree.drawn) {
259        var html = tree.html();
260        if (tree.dump_html) {
261            var pat = new RegExp("<", "g");
262            html = "<pre>" + html.replace(pat, "&lt;") + "</pre>";
263            if (document.body.innerHTML)
264                document.body.innerHTML = html;
265            else
266                document.write(html);
267        } else if (dom) {
268            element.innerHTML = html;
269        } else {
270            document.open();
271            document.write(
272                "<body>" + html +
273                ( major_version("MSIE") == 3 ?
274                     "<noscript>" :
275                     document.layers ?
276                         "<layer visibility='hide'>" :
277                         "<table width=0 height=0 style='" +
278                         "visibility:hidden;display:none'><tr><td>" )
279            );
280            document.close();
281        }
282        tree.drawn = true;
283        tree.load();
284    } else {
285        var t = navigator.userAgent.indexOf("Clue") != -1 ? 500 : 100;
286        setTimeout("tree_control__draw()", t);
287    }
288}
289function tree_control__find(id)
290{
291    var indices = id.split(".");
292    var node = this.root;
293    for (var z = 1; z < indices.length; ++z)
294        node = node.kids[indices[z] - 1];
295    return node;
296}
297function tree_control__html()
298{
299    return  "<table><tr><td align='left'><table width=150><tr><td>" +
300            "<h1 class=tree-caption>" + this.caption + "</h1></td></tr>" +
301            ( !static_display() ?
302                  "<tr><td><p class='tree-sync'><a title='reload current " +
303                      "page with a url suitable for bookmarking' class=" +
304                      "'tree-sync' href='javascript:get_tree().sync()'>" +
305                      "[link to this page]</a></p></td></tr>" :
306                  "" ) +
307            "</table></td></tr><tr><td>" + this.root.print_kids(0) +
308            "</td></tr></table>";
309}
310function load_target(url)
311{
312    var target;
313    if ((target = target_frame()) && target.location.href != url)
314        target.location.replace(url);
315    else {
316        setTimeout("load_target('" + url + "')", 100);
317    }
318}
319function tree_control__load()
320{
321    var query;
322    if ((query = top.location.search).length == 0)
323        return;
324    query = query.substring(1);
325    var eq;
326    if ((eq = query.indexOf("=")) != -1) {
327        if (query.substring(0, 4) == "page") {
328            load_target(unescape(query.substring(eq + 1)));
329            return;
330        }
331        query = query.substring(eq + 1);
332    }
333    var indices = query.split(".");
334    if (!indices.length)
335        return;
336    this.reset();
337    var node = this.root;
338    for (var z = 0; z < indices.length; ++z) {
339        var i = parseInt(indices[z]) - 1;
340        if (!node.kids || i < 0 || node.kids.length <= i)
341            break;
342        node = node.kids[i];
343        node.toggle(/*z != indices.length - 1*/);
344    }
345    if (node.link)
346        load_target(node.link);
347}
348function tree_control__recurse(op)
349{
350    var stack = new Array();
351    stack[stack.length] = this.root;
352    while (stack.length) {
353        var node = stack[stack.length - 1];
354        stack.length -=1 ; // Konqueror 2.
355        op(node);
356        if (node.kids)
357            for (var z = 0; z < node.kids.length; ++z)
358                stack[stack.length] = node.kids[z];
359    }
360}
361function tree_control__reset()
362{
363    if (!dom_support())
364        return;
365    this.recurse(new Function("x", "if (x.parent()) x.toggle(false);"));
366}
367function sync_node(node)
368{
369    if (!node.link)
370        return;
371    var tgt = target_frame().location.href;
372    var pos;
373    if ((pos = tgt.indexOf("?")) != -1)
374        tgt = tgt.substring(0, pos);
375    if (node.link.indexOf("://") != -1) {
376        if (node.link != tgt)
377            return;
378    } else {
379        var base = window.location.href;
380        if ((pos = base.lastIndexOf("/")) != -1)
381            base = base.substring(0, pos + 1);
382        if (base + node.link != tgt)
383            return;
384    }
385    window.success = true;
386    var href = replace_query( get_tree().top_url,
387                              "path=" + node.id.substring(1) );
388    top.location.replace(href);
389}
390function tree_control__sync()
391{
392    if (!dom_support() || self == top)
393        return;
394    window.success = false;
395    get_tree().recurse(sync_node);
396    if (!window.success)
397        top.location.replace(
398            replace_query( get_tree().top_url,
399                           "page=" + escape(target_frame().location.href) )
400        );
401}
402function tree_control(target)
403{
404    // Member data
405    this.root = new tree_node("");
406    this.target = target ? target : "_self";
407    this.dump_html = false;
408    this.caption = "Contents";
409    this.numbered = true;
410    this.indent = 15;
411    this.drawn = false;
412    this.top_url = top.location.href; // For Opera.
413
414    this.root.state = tree_node.expanded;
415    this.root.id = "";
416
417    // Member functions
418    this.add = tree_control__add;
419    this.draw = tree_control__draw;
420    this.find = tree_control__find;
421    this.html = tree_control__html;
422    this.load = tree_control__load;
423    this.recurse = tree_control__recurse;
424    this.reset = tree_control__reset;
425    this.sync = tree_control__sync;
426    document.tree_control = this;
427}
428tree_control.sync = tree_control__sync;