1/*******************************************************************************
2 * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 *    Marc R. Hoffmann - initial API and implementation
10 *
11 *******************************************************************************/
12
13(function () {
14
15  /**
16   * Sets the initial sorting derived from the hash.
17   *
18   * @param linkelementids
19   *          list of element ids to search for links to add sort inidcator
20   *          hash links
21   */
22  function initialSort(linkelementids) {
23    window.linkelementids = linkelementids;
24    var hash = window.location.hash;
25    if (hash) {
26      var m = hash.match(/up-./);
27      if (m) {
28        var header = window.document.getElementById(m[0].charAt(3));
29        if (header) {
30          sortColumn(header, true);
31        }
32        return;
33      }
34      var m = hash.match(/dn-./);
35      if (m) {
36        var header = window.document.getElementById(m[0].charAt(3));
37        if (header) {
38          sortColumn(header, false);
39        }
40        return
41      }
42    }
43  }
44
45  /**
46   * Sorts the columns with the given header dependening on the current sort state.
47   */
48  function toggleSort(header) {
49    var sortup = header.className.indexOf('down ') == 0;
50    sortColumn(header, sortup);
51  }
52
53  /**
54   * Sorts the columns with the given header in the given direction.
55   */
56  function sortColumn(header, sortup) {
57    var table = header.parentNode.parentNode.parentNode;
58    var body = table.tBodies[0];
59    var colidx = getNodePosition(header);
60
61    resetSortedStyle(table);
62
63    var rows = body.rows;
64    var sortedrows = [];
65    for (var i = 0; i < rows.length; i++) {
66      r = rows[i];
67      sortedrows[parseInt(r.childNodes[colidx].id.slice(1))] = r;
68    }
69
70    var hash;
71
72    if (sortup) {
73      for (var i = sortedrows.length - 1; i >= 0; i--) {
74        body.appendChild(sortedrows[i]);
75      }
76      header.className = 'up ' + header.className;
77      hash = 'up-' + header.id;
78    } else {
79      for (var i = 0; i < sortedrows.length; i++) {
80        body.appendChild(sortedrows[i]);
81      }
82      header.className = 'down ' + header.className;
83      hash = 'dn-' + header.id;
84    }
85
86    setHash(hash);
87  }
88
89  /**
90   * Adds the sort indicator as a hash to the document URL and all links.
91   */
92  function setHash(hash) {
93    window.document.location.hash = hash;
94    ids = window.linkelementids;
95    for (var i = 0; i < ids.length; i++) {
96        setHashOnAllLinks(document.getElementById(ids[i]), hash);
97    }
98  }
99
100  /**
101   * Extend all links within the given tag with the given hash.
102   */
103  function setHashOnAllLinks(tag, hash) {
104    links = tag.getElementsByTagName("a");
105    for (var i = 0; i < links.length; i++) {
106        var a = links[i];
107        var href = a.href;
108        var hashpos = href.indexOf("#");
109        if (hashpos != -1) {
110            href = href.substring(0, hashpos);
111        }
112        a.href = href + "#" + hash;
113    }
114  }
115
116  /**
117   * Calculates the position of a element within its parent.
118   */
119  function getNodePosition(element) {
120    var pos = -1;
121    while (element) {
122      element = element.previousSibling;
123      pos++;
124    }
125    return pos;
126  }
127
128  /**
129   * Remove the sorting indicator style from all headers.
130   */
131  function resetSortedStyle(table) {
132    for (var c = table.tHead.firstChild.firstChild; c; c = c.nextSibling) {
133      if (c.className) {
134        if (c.className.indexOf('down ') == 0) {
135          c.className = c.className.slice(5);
136        }
137        if (c.className.indexOf('up ') == 0) {
138          c.className = c.className.slice(3);
139        }
140      }
141    }
142  }
143
144  window['initialSort'] = initialSort;
145  window['toggleSort'] = toggleSort;
146
147})();