2 * sourceforge wiki.xml to multi page html
7 var startTime = ( new Date()).getTime(),
9 CLEAN_TARGET_ELEMENT = 'script,style,object,applet,embed,iframe,frame,base,bgsound,frameset,listing'.split( ','),
10 root = DOC.getElementById('wiki-container'),
11 navi = DOC.getElementById('page-navi-container'),
12 ELM_BODY_CONTAINER = DOC.getElementById('page-body-container'),
15 elmBuilder = DOC.createElement( 'div'),
16 WikiPageClass = function( id, title, elmNavi, elmAnchor, elmWrapper, elmBody){
19 titleArray.push( title);
20 anchorArray.push( elmAnchor);
22 elmAnchor.onclick = jumpPage;
24 setTimeout( buildInnerLink, 0);
26 function buildInnerLink(){
27 var _nodes = elmBody.getElementsByTagName( 'a'),
32 _array.push( _nodes[ i]);
34 while( _array.length > 0){
35 _jump = _array.shift();
36 _index = getPageIndexByTitle( _jump.childNodes[0].nodeValue);
38 _jump.href = '#page' +( _index +1);
39 _jump.onclick = jumpPage;
40 _jump.className += ' internalLink';
42 _jump.target = '_blank';
43 _jump.className += ' externalLink';
49 fixCommentToHtml: function(){
50 elmBuilder.innerHTML = elmBody.childNodes[0].nodeValue.replace( /\[\[BR\]\]/g, '');
51 cleanElement( elmBuilder);
53 var _fragment = DOC.createDocumentFragment();
54 while( elmBody.firstChild){
55 elmBody.removeChild( elmBody.firstChild);
57 while( elmBuilder.firstChild){
58 _fragment.appendChild( elmBuilder.firstChild);
60 elmBody.appendChild( _fragment);
61 delete this.fixCommentToHtml;
64 if( id === _id && visible === false){
65 elmWrapper.className = 'page-wrapper-current';
66 elmWrapper.style.display = 'block';
67 elmNavi.className = 'page-navi-current';
68 ELM_BODY_CONTAINER.appendChild( elmWrapper);
71 if( id !== _id && visible === true){
72 elmWrapper.className = 'page-wrapper';
73 elmWrapper.style.display = '';
74 elmNavi.className = 'page-navi';
75 ELM_BODY_CONTAINER.removeChild( elmWrapper);
82 wikiPageArray = ( function(){
85 _children = ( function(){
87 _nodes = navi.getElementsByTagName( 'li');
88 for( var i=0, l=_nodes.length; i<l; ++i){
89 _ret.push( _nodes[ i]);
94 _child, _a, _title, _id, _wrap,
97 _body.appendChild( elmBuilder);
99 for(var i=0; i<l; ++i){
100 _child = _children[i];
101 if( _child.className.indexOf( 'page-navi') !== -1){
102 _a = _child.getElementsByTagName( 'a')[0];
103 _title = _a ? _a.firstChild.nodeValue : null;
104 _id = _a ? _a.href.split('#')[1] : null;
105 _wrap = DOC.getElementById( _id);
106 _page = new WikiPageClass( _id, _title, _child, _a, _wrap, _wrap.getElementsByTagName( 'div')[1]);
107 !DOC.all && _page.fixCommentToHtml();
111 _body.removeChild( elmBuilder);
115 NUM_PAGE = wikiPageArray.length,
116 FRONT_ID = 'FrontPage',
117 FRONT_INDEX = getPageIndexByTitle( FRONT_ID) +1,
118 CLASS_OPEN = 'expander-open',
119 CLASS_CLOSE = 'expander-close',
120 ANGLE_OPEN = String.fromCharCode( 9660),
121 ANGLE_CLOSE = String.fromCharCode( 9658),
122 hash = DOC.location.href.split('#')[1],
124 _fragment = DOC.createDocumentFragment(),
125 _elmOrign = ( function(){
126 var ret = DOC.createElement( 'li'),
127 a = DOC.createElement( 'a'),
128 toggle = DOC.createElement( 'span'),
129 title = DOC.createElement( 'span'),
130 count = DOC.createElement( 'span'),
131 ul = DOC.createElement( 'ul');
133 a.className = 'group';
136 toggle.appendChild( DOC.createTextNode( ANGLE_CLOSE));
137 a.appendChild( toggle);
138 toggle.className = 'group-toggle';
140 a.appendChild( title);
141 title.className = 'group-title';
143 a.appendChild( count);
144 count.className = 'group-count';
146 ret.appendChild( ul);
147 ret.className = CLASS_CLOSE;
151 _groupArray = [], _title,
153 _regTitle2 = /(^[A-Z][a-z0-9]+[A-Z][a-z0-9]+)\w+/,
154 _regTitle1 = /(^[A-Z][a-z0-9]+)\w+/,
155 _checkArray = new Array( NUM_PAGE );
157 DOC.all && cleanElement( ELM_BODY_CONTAINER);
159 // build hierarchy to navi
160 for( i=0; i<NUM_PAGE; ++i){
161 _title = titleArray[ i ];
162 if( _title.match( _regTitle2)){
163 _group = _title.replace( _regTitle2, '$1');
164 if( !hierarchyTmp[ _group]){
165 hierarchyTmp[ _group] = [];
167 hierarchyTmp[ _group].push( _title);
169 if( hierarchyTmp[ _group].length === 1){
170 if( _title.match( _regTitle1)){
171 _group = _title.replace( _regTitle1, '$1');
172 if( !hierarchyTmp[ _group]){
173 hierarchyTmp[ _group] = [];
175 hierarchyTmp[ _group].push( _title);
180 for( var _group in hierarchyTmp){
181 _array = hierarchyTmp[ _group];
182 if( _array.length > 1){
183 _groupArray.push( _group);
188 for( i=_groupArray.length; i>0; --i){
189 _group = _groupArray[ i - 1 ];
190 _array = hierarchyTmp[ _group];
191 if( _array.length > 1){
193 while( j<_array.length ){
194 _index = getPageIndexByTitle( _array[ j ]);
195 if( _index === -1 || _checkArray[ _index ] === true){
196 _array.splice( j, 1);
198 _checkArray[ _index ] = true;
205 for( i=_groupArray.length; i>0; --i){
206 _group = _groupArray[ i - 1 ];
207 _array = hierarchyTmp[ _group];
208 if( _array.length > 1){
209 _elmLi = _elmOrign.cloneNode( true);
210 for( j=0, l=_array.length; j<l; ++j){
211 _index = getPageIndexByTitle( _array[ j ]);
212 _index !== -1 && _elmLi.getElementsByTagName( 'ul')[ 0].appendChild( anchorArray[ _index].parentNode );
214 _elmLi.onclick = switchExpander;
215 _elmLi.getElementsByTagName( 'span')[ 1].appendChild( DOC.createTextNode( _group));
216 _elmLi.getElementsByTagName( 'span')[ 2].appendChild( DOC.createTextNode( l));
217 _fragment.appendChild( _elmLi);
221 navi.appendChild( _fragment);
222 _array = _fragment = _elmOrign = _elmLi = _group = hierarchyTmp = root = navi = elmBuilder = _jump = null;
227 jumpPage( hash && hash.match( /page\d/) ? hash : 'page' + FRONT_INDEX);
232 DOC.getElementById( 'boot-time').appendChild( DOC.createTextNode(( new Date()).getTime() - startTime ));
234 function cleanElement( _targetElm){
235 var l = CLEAN_TARGET_ELEMENT.length,
236 elms, array, elm, i, j, m;
238 elms = _targetElm.getElementsByTagName( CLEAN_TARGET_ELEMENT[ i]);
240 for( j=0, m = elms.length; j<m; ++j){
241 array.push( elms[ j]);
243 while( array.length > 0){
245 elm.parentNode && elm.parentNode.removeChild( elm);
248 elms = _targetElm.getElementsByTagName( '*');
250 for( i=0, l = elms.length; i<l; ++i){
251 array.push( elms[ i]);
253 while( array.length > 0){
255 if( elm.nodeType === 3){
256 elm.parentNode && elm.parentNode.removeChild( elm);
258 if( elm.style.filter || elm.style.filter !== ''){
259 elm.style.filter = '';
261 if( elm.style.behavior || elm.style.behavior !== ''){
262 elm.style.behavior = '';
266 function getPageIndexByTitle( _title){
267 for(var i=0; i<NUM_PAGE; ++i){
268 if( titleArray[ i] === _title) return i;
272 function jumpPage( id){
273 var id = typeof id === 'string' ? id : this.href.split('#')[1];
274 for(var i=0; i<NUM_PAGE; ++i){
275 wikiPageArray[i].show( id);
279 function switchExpander(){
280 var _open = this.className.indexOf( CLASS_CLOSE) !== -1;
281 this.className = _open ? CLASS_OPEN : CLASS_CLOSE;
282 this.getElementsByTagName( 'span')[ 0].firstChild.data = _open ? ANGLE_OPEN : ANGLE_CLOSE;
290 Changes links that link to other parts of this page to scroll
291 smoothly to those links rather than jump to them directly, which
292 can be a little disorienting.
294 sil, http://www.kryogenix.org/
297 v1.1 2005-06-16 wrap it up in an object
301 fixAllLinks: function() {
302 // Get a list of all links in the page
303 var allLinks = document.getElementsByTagName('a');
304 // Walk through the list
305 for (var i=0;i<allLinks.length;i++) {
306 var lnk = allLinks[i];
307 if ((lnk.href && lnk.href.indexOf('#') != -1) &&
308 ( (lnk.pathname == location.pathname) ||
309 ('/'+lnk.pathname == location.pathname) ) &&
310 (lnk.search == location.search)) {
311 // If the link is internal to the page (begins in #)
312 // then attach the smoothScroll function as an onclick
314 ss.addEvent(lnk,'click',ss.smoothScroll);
319 smoothScroll: function(e) {
320 // This is an event handler; get the clicked on element,
321 // in a cross-browser fashion
323 target = window.event.srcElement;
328 // Make sure that the target is an element, not a text node
330 if (target.nodeName.toLowerCase() != 'a') {
331 target = target.parentNode;
334 // Paranoia; check this is an A tag
335 if (target.nodeName.toLowerCase() != 'a') return;
337 // Find the <a name> tag corresponding to this href
338 // First strip off the hash (first character)
339 anchor = target.hash.substr(1);
340 // Now loop all A tags until we find one with that name
341 var allLinks = document.getElementsByTagName('a');
342 var destinationLink = null;
343 for (var i=0;i<allLinks.length;i++) {
344 var lnk = allLinks[i];
345 if (lnk.name && (lnk.name == anchor)) {
346 destinationLink = lnk;
350 if (!destinationLink) destinationLink = document.getElementById(anchor);
352 // If we didn't find a destination, give up and let the browser do
354 if (!destinationLink) return true;
356 // Find the destination's position
357 var destx = destinationLink.offsetLeft;
358 var desty = destinationLink.offsetTop;
359 var thisNode = destinationLink;
360 while (thisNode.offsetParent &&
361 (thisNode.offsetParent != document.body)) {
362 thisNode = thisNode.offsetParent;
363 destx += thisNode.offsetLeft;
364 desty += thisNode.offsetTop;
367 // Stop any current scrolling
368 clearInterval(ss.INTERVAL);
370 cypos = ss.getCurrentYPos();
372 ss_stepsize = parseInt((desty-cypos)/ss.STEPS);
373 ss.INTERVAL = setInterval('ss.scrollWindow('+ss_stepsize+','+desty+',"'+anchor+'")',10);
375 // And stop the actual click happening
377 window.event.cancelBubble = true;
378 window.event.returnValue = false;
380 if (e && e.preventDefault && e.stopPropagation) {
386 scrollWindow: function(scramount,dest,anchor) {
387 wascypos = ss.getCurrentYPos();
388 isAbove = (wascypos < dest);
389 window.scrollTo(0,wascypos + scramount);
390 iscypos = ss.getCurrentYPos();
391 isAboveNow = (iscypos < dest);
392 if ((isAbove != isAboveNow) || (wascypos == iscypos)) {
393 // if we've just scrolled past the destination, or
394 // we haven't moved from the lpageWrapperArraycroll (i.e., we're at the
395 // bottom of the page) then scroll exactly to the link
396 window.scrollTo(0,dest);
397 // cancel the repeating timer
398 clearInterval(ss.INTERVAL);
399 // and jump to the link directly so the URL's right
400 location.hash = anchor;
404 getCurrentYPos: function() {
405 if (document.body && document.body.scrollTop)
406 return document.body.scrollTop;
407 if (document.documentElement && document.documentElement.scrollTop)
408 return document.documentElement.scrollTop;
409 if (window.pageYOffset)
410 return window.pageYOffset;
414 addEvent: function(elm, evType, fn, useCapture) {
415 // addEvent and removeEvent
416 // cross-browser event handling for IE5+, NS6 and Mozilla
418 if (elm.addEventListener){
419 elm.addEventListener(evType, fn, useCapture);
421 } else if (elm.attachEvent){
422 var r = elm.attachEvent("on"+evType, fn);
425 alert("Handler could not be removed");
432 ss.addEvent(window,"load",ss.fixAllLinks);