You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

339 lines
8.6 KiB

  1. // Copyright © 2009-2011, Rob Chandler.
  2. // Please don't use this file without purchasing FAR. http://helpware.net/FAR/
  3. // This effectively licenses you to use my code. This code (before modification) was
  4. // first written by Jean-Claude Manoli.
  5. // Changes
  6. // RWC: 2005-04-01 - Fix image pre-load section. Last line had typo causing some images not to load
  7. // RWC: 2005-05-21 - Some work fixing TOC Sync
  8. // RWC: 2008-01-30 - Change resizeTree() to be compatible with non-MS browsers
  9. // RWC: 2009-06-10 - All files now saved in UTF-8 file format.
  10. // RWC: 2009-09-26 - Allow Opera browser to scroll the tree when syncing TOC.
  11. // RWC: 2011-09-10 - Fix Sync for \\server\ UNC paths.
  12. // RWC: 2011-09-11 - Fix Sync for CJK paths.
  13. /* Original Copyright © 2002 Jean-Claude Manoli [jc@manoli.net]
  14. *
  15. * This software is provided 'as-is', without any express or implied warranty.
  16. * In no event will the author(s) be held liable for any damages arising from
  17. * the use of this software.
  18. *
  19. * Permission is granted to anyone to use this software for any purpose,
  20. * including commercial applications, and to alter it and redistribute it
  21. * freely, subject to the following restrictions:
  22. *
  23. * 1. The origin of this software must not be misrepresented; you must not
  24. * claim that you wrote the original software. If you use this software
  25. * in a product, an acknowledgment in the product documentation would be
  26. * appreciated but is not required.
  27. *
  28. * 2. Altered source versions must be plainly marked as such, and must not
  29. * be misrepresented as being the original software.
  30. *
  31. * 3. This notice may not be removed or altered from any source distribution.
  32. */
  33. var treeSelected = null; //last treeNode clicked
  34. //pre-load tree nodes images
  35. var imgPlus = new Image();
  36. imgPlus.src="treenodeplus.gif";
  37. var imgMinus = new Image();
  38. imgMinus.src="treenodeminus.gif";
  39. var imgDot = new Image();
  40. imgDot.src="treenodedot.gif"; //rwc - fixed. Was... imgPlus.src="treenodedot.gif";
  41. function findNode(el)
  42. {
  43. // Takes element and determines if it is a treeNode.
  44. // If not, seeks a treeNode in its parents.
  45. while (el != null)
  46. {
  47. if (el.className == "treeNode")
  48. {
  49. break;
  50. }
  51. else
  52. {
  53. el = el.parentNode;
  54. }
  55. }
  56. return el;
  57. }
  58. function clickAnchor(el)
  59. {
  60. // handles click on a TOC link
  61. //
  62. expandNode(el.parentNode);
  63. selectNode(el.parentNode);
  64. el.blur();
  65. }
  66. function selectNode(el)
  67. {
  68. // Un-selects currently selected node, if any, and selects the specified node
  69. //
  70. if (treeSelected != null)
  71. {
  72. setSubNodeClass(treeSelected, 'A', 'treeUnselected');
  73. }
  74. setSubNodeClass(el, 'A', 'treeSelected');
  75. treeSelected = el;
  76. }
  77. function setSubNodeClass(el, nodeName, className)
  78. {
  79. // Sets the specified class name on el's first child that is a nodeName element
  80. //
  81. var child;
  82. for (var i=0; i < el.childNodes.length; i++)
  83. {
  84. child = el.childNodes[i];
  85. if (child.nodeName == nodeName)
  86. {
  87. child.className = className;
  88. break;
  89. }
  90. }
  91. }
  92. function expandCollapse(el)
  93. {
  94. // If source treeNode has child nodes, expand or collapse view of treeNode
  95. //
  96. if (el == null)
  97. return; //Do nothing if it isn't a treeNode
  98. var child;
  99. var imgEl;
  100. for(var i=0; i < el.childNodes.length; i++)
  101. {
  102. child = el.childNodes[i];
  103. if (child.src)
  104. {
  105. imgEl = child;
  106. }
  107. else if (child.className == "treeSubnodesHidden")
  108. {
  109. child.className = "treeSubnodes";
  110. imgEl.src = "treenodeminus.gif";
  111. break;
  112. }
  113. else if (child.className == "treeSubnodes")
  114. {
  115. child.className = "treeSubnodesHidden";
  116. imgEl.src = "treenodeplus.gif";
  117. break;
  118. }
  119. }
  120. }
  121. function expandNode(el)
  122. {
  123. // If source treeNode has child nodes, expand it
  124. //
  125. var child;
  126. var imgEl;
  127. for(var i=0; i < el.childNodes.length; i++)
  128. {
  129. child = el.childNodes[i];
  130. if (child.src)
  131. {
  132. imgEl = child;
  133. }
  134. if (child.className == "treeSubnodesHidden")
  135. {
  136. child.className = "treeSubnodes";
  137. imgEl.src = "treenodeminus.gif";
  138. break;
  139. }
  140. }
  141. }
  142. function GetUnixPath(url)
  143. {
  144. var path = url.replace(/\\/g, '/'); // DOS to Unix slash
  145. path = path.replace(/\/\/\//, "//"); // Force 2 slashes xxx://xxx
  146. path = path.replace(/\/\/\//, "//");
  147. path = path.replace(/\/\/\//, "//");
  148. path = path.replace(/\/\/\//, "//");
  149. return path;
  150. }
  151. function syncTree(href)
  152. {
  153. // Selects and scrolls into view the node that references the specified URL
  154. //
  155. //RWC 2005-05-21 - This is the real URL base of the TOC
  156. var gbase = GetUnixPath(location.href);
  157. gbase = decodeURI(gbase);
  158. gbase = gbase.substr(0, gbase.lastIndexOf('/') + 1); //trim off file name. Leave trailing /
  159. var loc = new String();
  160. loc = GetUnixPath(href);
  161. loc = encodeURI(loc); //encode as valid URI
  162. //RWC 2005-05-21 - properly Scrub URL of encoding
  163. loc = decodeURI(loc); //Converts %2520 -> %20 (under FireFox)
  164. loc = decodeURI(loc); //Converts %20 = ' '
  165. var tocEl = findHref(document.getElementById('treeRoot'), loc, gbase);
  166. if (tocEl != null)
  167. {
  168. selectAndShowNode(tocEl);
  169. }
  170. }
  171. function findHref(node, href, base)
  172. {
  173. // find the <a> element with the specified href value
  174. //
  175. //RWC 24/3/2006: Consider any bookmark on the URL to test
  176. var href_BaseURL = '';
  177. var iBookmark = href.indexOf('#');
  178. if (iBookmark > 0)
  179. href_BaseURL = href.substr(0, iBookmark);
  180. var el;
  181. var anchors = node.getElementsByTagName('A');
  182. for (var i = 0; i < anchors.length; i++)
  183. {
  184. el = anchors[i];
  185. var aref = new String();
  186. aref = el.getAttribute('href');
  187. if ((aref.substring(0, 7) != 'http://')
  188. && (aref.substring(0, 8) != 'https://')
  189. && (aref.substring(0, 7) != 'file://'))
  190. {
  191. aref = base + aref;
  192. }
  193. aref = GetUnixPath(decodeURI(aref));
  194. //if (i < 5)
  195. // alert('aref=' + aref + ', href=' + href + ', base=' + base);
  196. //RWC: If href has #bookmark and aref does not then compare without bookmarks
  197. if ((href_BaseURL.length > 0) && (aref.indexOf('#') < 0))
  198. if (aref == href_BaseURL)
  199. return el;
  200. if (aref == href)
  201. {
  202. return el;
  203. }
  204. }
  205. return null;
  206. }
  207. function selectAndShowNode(node)
  208. {
  209. // Selects and scrolls into view the specified node
  210. //
  211. var el = findNode(node);
  212. if (el != null)
  213. {
  214. selectNode(el);
  215. do
  216. {
  217. expandNode(el);
  218. el = findNode(el.parentNode);
  219. } while ((el != null))
  220. //vertical scroll element into view
  221. var windowTop;
  222. var windowBottom;
  223. var treeDiv = document.getElementById('tree');
  224. var ua = window.navigator.userAgent.toLowerCase();
  225. if ((i = ua.indexOf('msie')) != -1)
  226. {
  227. windowTop = node.offsetTop - treeDiv.scrollTop;
  228. windowBottom = treeDiv.clientHeight - windowTop - node.offsetHeight;
  229. }
  230. else if (ua.indexOf('gecko') != -1)
  231. {
  232. windowTop = node.offsetTop - treeDiv.offsetTop - treeDiv.scrollTop;
  233. windowBottom = treeDiv.clientHeight - windowTop - node.offsetHeight;
  234. }
  235. else if (ua.indexOf('opera') != -1)
  236. {
  237. windowTop = node.offsetTop - treeDiv.offsetTop - treeDiv.scrollTop;
  238. windowBottom = treeDiv.clientHeight - windowTop - node.offsetHeight;
  239. }
  240. else
  241. {
  242. return;
  243. }
  244. if (windowTop < 0)
  245. {
  246. treeDiv.scrollTop += windowTop - 18;
  247. return;
  248. }
  249. if (windowBottom < 0)
  250. {
  251. treeDiv.scrollTop -= windowBottom - 18;
  252. return;
  253. }
  254. }
  255. }
  256. function GetFrameWidth()
  257. {
  258. var x = 300;
  259. if (self.innerHeight) // all except Explorer
  260. x = self.innerWidth;
  261. else if (document.documentElement && document.documentElement.clientHeight) // Explorer 6 Strict Mode
  262. x = document.documentElement.clientWidth;
  263. else if (document.body) // other Explorers
  264. x = document.body.clientWidth;
  265. return(x);
  266. }
  267. function GetFrameHeight()
  268. {
  269. var y = 400;
  270. if (self.innerHeight) // all except Explorer
  271. y = self.innerHeight;
  272. else if (document.documentElement && document.documentElement.clientWidth) // Explorer 6 Strict Mode
  273. y = document.documentElement.clientHeight;
  274. else if (document.body) // other Explorers
  275. y = document.body.clientHeight;
  276. return(y);
  277. }
  278. function resizeTree()
  279. {
  280. var treeDiv = document.getElementById("tree");
  281. var DivFooter = document.getElementById("DivFooter");
  282. var xTop = treeDiv.offsetTop;
  283. if ((DivFooter != null) && (DivFooter != undefined))
  284. xTop = xTop + DivFooter.offsetHeight;
  285. treeDiv.style.width = GetFrameWidth();
  286. var HH = GetFrameHeight();
  287. if (HH - xTop > 0)
  288. treeDiv.style.height = HH - xTop;
  289. }
  290. // old original func
  291. //function resizeTree()
  292. //{
  293. // var treeDiv = document.getElementById('tree');
  294. // //treeDiv.setAttribute('style', 'width: ' + document.body.offsetWidth + 'px; height: ' + (document.body.offsetHeight - 27) + 'px;');
  295. // treeDiv.style.width = document.documentElement.offsetWidth;
  296. // treeDiv.style.height = document.documentElement.offsetHeight - 27;
  297. //}