7 * @author Sebastian Rose, Hannover, Germany - sebastian_rose at gmx dot de
10 * This software is subject to the GNU General Public Licens version 3:
11 * see: http://www.gnu.org/licenses/
17 * Org-mode > 6.23 (commit a68eb4b1e64cbe6e495fdd2c1eaf8ae597bf8602):
18 * You'll need at least org-info.js v.0.1.0.1
22 * Include this scipt into the Header of your HTML-exported org files by
23 * customizing the variable org-export-html-style (TODO: add file local export
25 * You will also need this here somewhere in the HTML-page:
27 * <script type="text/javascript" language="JavaScript" src="org-info.js"></script>
28 * <script type="text/javascript" language="JavaScript">
29 * <![CDATA[ // comment around this one
30 * org_html_manager.set("LOCAL_TOC", "1");
31 * org_html_manager.set("VIEW", "info");
32 * org_html_manager.set("VIEW_BUTTONS", "true");
33 * org_html_manager.set("LINK_UP", "http://full/path/to/index/of/this/directory.html");
34 * org_html_manager.set("LINK_HOME", "http://full/path/to/homepage.html");
35 * org_html_manager.set("MOUSE_HINT", "underline"); // or a color like '#eeeeee'
36 * org_html_manager.setup ();
37 * ]]> // comment around this one
41 * The script is now roughly devided in sections by form-feeds. Editors can
42 * move section wise using the common emacs commands for this purpos ('C-x ]'
46 * 1. This comment block.
47 * 2. Everything around =OrgNodes=.
48 * 3. =org_html_manager= constructor and setup.
49 * 4. =org_html_manager= folding and view related stuff.
50 * 5. =org_html_manager= history related methods.
51 * 6. =org_html_manager= minibuffer handling.
52 * 7. =org_html_manager= user input.
53 * 8. =org_html_manager= search functonality.
54 * 9. =org_html_manager= misc.
55 * 10. Global functions.
63 * Creates a new OrgNode.
64 * An OrgOutline stores some refs to its assoziated node in the document tree
65 * along with some additional properties.
67 function OrgNode ( _div, _heading, _link, _depth, _parent, _base_id, _toc_anchor)
71 t.BASE_ID = _base_id; // The suffix that's common to the heading and the diffs.
72 t.IDX = -1; // The index in OrgHtmlManager::SECS[]
75 t.HAS_HIGHLIGHT = false; // Node highlighted (search)
77 t.DIRTY = false; // Node is dirty, when children get
79 t.STATE = OrgNode.STATE_FOLDED;
81 t.DEPTH = _depth; // The Rootelement will have
82 // the depth 0. All other
83 // Nodes get the depth from
84 // their h-level (h1, h2...)
86 t.CHILDREN = new Array();
87 t.NAV = ""; // The info navigation
90 if(null != t.PARENT) {
91 t.PARENT.addChild(this);
95 var folder = document.getElementById("text-"+t.BASE_ID);
96 if(null == folder && _base_id) {
97 var fid = _base_id.substring(4);
98 folder = document.getElementById("text-"+fid); // try old schema
103 t.isTargetFor = new Object();
104 t.isTargetFor['#' + t.BASE_ID] = 2;
105 OrgNode.findTargetsIn(t.isTargetFor, t.HEADING, 1); // 1 == prefere this one as section link.
106 OrgNode.findTargetsIn(t.isTargetFor, t.FOLDER, 3);
110 OrgNode.STATE_FOLDED = 0;
111 OrgNode.STATE_HEADLINES = 1;
112 OrgNode.STATE_UNFOLDED = 2;
120 OrgNode.findTargetsIn = function(safe, container, priority)
123 var a = container.getElementsByTagName("a");
125 for(var i=0;i<a.length;++i) {
126 var n = a[i].getAttribute('id');
127 if(n) safe['#' + n] = priority;
129 n = a[i].getAttribute('name');
130 if(n) safe['#' + n] = priority;
133 OrgNode.hideElement = function (e)
135 if(e && e['style']) { // test for e['style'] is just quick fix for error elsewhere (fixed toc and title)
136 e.style.display = 'none';
137 e.style.visibility = 'hidden';
141 OrgNode.showElement = function (e)
143 if(e && e['style']) {
144 e.style.display = 'block';
145 e.style.visibility = 'visible';
149 OrgNode.unhideElement = function (e)
152 e.style.visibility="";
155 OrgNode.isHidden = function(e)
157 if(e.style.display=='none' || e.style.visibility=='hidden')
162 OrgNode.toggleElement = function (e)
164 if(e.style.display == 'none') {
165 e.style.display = 'block';
166 e.style.visibility = 'visible';
168 e.style.display = 'none';
169 e.style.visibility = 'hidden';
174 * Find the OrgNode containing a DOM-text-node.
175 * @param dom The text node.
176 * @param org The OrgNode containing the OrgNode in question.
178 OrgNode.textNodeToIdx = function (dom, org)
180 while(dom.nodeType != 1 /* IE has no Node.ELEMENT_NODE... */
181 || -1 == dom.attributes["id"].value.indexOf("outline-container-")) {
182 dom = dom.parentNode;
184 var base_id = dom.attributes["id"].value.substr(18);
185 return OrgNode.idxForBaseId(base_id, org);
189 * Find an OrgNode with base_id inside an OrgNode and return it's idx.
190 * @param base The base_id.
191 * @param org The OrgNode.
193 OrgNode.idxForBaseId = function(base, org)
195 if(org.BASE_ID == base) return org;
196 for(var i = 0; i < org.CHILDREN.length; ++i) {
197 var o = OrgNode.idxForBaseId(idx, org.CHILDREN[i]);
198 if(null != o) return o;
207 OrgNode.prototype.addChild = function (child)
209 this.CHILDREN.push(child);
215 // OrgNode methods for paging (info mode)
218 OrgNode.prototype.hide = function ()
220 OrgNode.hideElement(this.DIV);
225 OrgNode.prototype.show = function ()
227 OrgNode.showElement(this.DIV);
232 OrgNode.prototype.showAllChildren = function ()
234 for(var i=0;i<this.CHILDREN.length;++i) { this.CHILDREN[i].showAllChildren(); }
238 OrgNode.prototype.hideAllChildren = function ()
240 for(var i=0;i<this.CHILDREN.length;++i) { this.CHILDREN[i].hideAllChildren(); }
245 * Set class for links to current page to current and visited pages to visited_after_load
246 * Note: visited pages will be reset after reload!
248 OrgNode.prototype.setLinkClass = function (on)
251 if(on) this.TOC.className = "current";
252 else this.TOC.className = "visited_after_load";
257 // OrgNode methods for folding
261 * This one is called onclick() to toggle the folding state of the node.
262 * This one sets it's parent dirty, since node is folded individually. Hence the
263 * next folding of parent has to collapse all.
264 * @param show_childrens_folders Boolean. This is only used for the special way
265 * of toggling of the ROOT element. If true, prevents this OrgNode from showing
268 OrgNode.prototype.fold = function (hide_folder)
271 this.PARENT.DIRTY = true;
274 this.STATE = OrgNode.STATE_UNFOLDED; // so next state is FOLDED. See below.
277 if(null != this.FOLDER) {
279 if(this.STATE == OrgNode.STATE_FOLDED) {
280 // I was folded but one could click on me. So now show Headlines
282 if(this.CHILDREN.length) {
283 this.STATE = OrgNode.STATE_HEADLINES;
284 OrgNode.hideElement(this.FOLDER);
285 for(var i=0;i<this.CHILDREN.length;++i) { this.CHILDREN[i].setState(OrgNode.STATE_HEADLINES); }
286 } else if (! hide_folder) {
287 // without children jump to unfolded state:
288 this.STATE = OrgNode.STATE_UNFOLDED;
289 OrgNode.showElement(this.FOLDER);
292 else if(this.STATE == OrgNode.STATE_HEADLINES) {
293 // show all content recursive
294 this.STATE = OrgNode.STATE_UNFOLDED;
295 OrgNode.showElement(this.FOLDER);
296 for(var i=0;i<this.CHILDREN.length;++i) { this.CHILDREN[i].setState(OrgNode.STATE_UNFOLDED); }
299 // collapse. Show only own headline
300 this.STATE = OrgNode.STATE_FOLDED;
301 OrgNode.hideElement(this.FOLDER);
302 for(var i=0;i<this.CHILDREN.length;++i) { this.CHILDREN[i].setState(OrgNode.STATE_FOLDED); }
308 * Recursive state switching. This functions folds children of activated
309 * parents. The states have a slightly different meaning here. Here the
310 * surrounding div (outline-container-id) gets hidden too.
311 * Maybe add OrgNode.STATE_HIDDEN with same value?
313 OrgNode.prototype.setState = function (state)
316 for(var i=0;i<t.CHILDREN.length;++i) {
317 t.CHILDREN[i].setState(state);
321 case OrgNode.STATE_FOLDED:
322 OrgNode.hideElement(t.FOLDER);
323 OrgNode.hideElement(t.DIV);
325 case OrgNode.STATE_HEADLINES:
326 OrgNode.hideElement(t.FOLDER);
327 OrgNode.showElement(t.DIV);
330 OrgNode.showElement(t.FOLDER);
331 OrgNode.showElement(t.DIV);
341 * OrgManager manages OrgNodes.
342 * We don't create anything in the constructor, since the document is not loaded
345 var org_html_manager = {
347 MOUSE_HINT: 0, // Highlight heading under mouse?
348 BODY:null, // The container all the contents live in.
349 PLAIN_VIEW: 0, // We're in plain view mode. On startup:= overview
350 CONTENT_VIEW: 1, // plain view show structure
351 ALL_VIEW: 2, // plain view show all
352 INFO_VIEW: 3, // We're in info view mode
353 SLIDE_VIEW: 4, // Slidemode.
354 VIEW: this.CONTENT_VIEW, // Default view mode (s. setup())
355 LOCAL_TOC: false, // Create sub indexes (s. setup()): "0", "1" "above", "below" (==1, default)
356 LINK_HOME: 0, // Link to this.LINK_HOME?
357 LINK_UP: 0, // Link to this.LINK_UP?
358 LINKS: "", // Prepare the links for later use (see setup),
359 RUN_MAX: 1200, // Max attempts to scan (results in ~2 minutes)
360 RUN_INTERVAL: 100, // Interval of scans in milliseconds.
361 HIDE_TOC: false, // Hide the table of contents.
362 TOC_DEPTH: 0, // Level to cut the table of contents. No cutting if 0.
363 STARTUP_MESSAGE: 0, // Show info at startup?
364 POSTAMBLE: null, // cache the 'postamble' element.
366 BASE_URL: document.URL, // URL without '#sec-x.y.z'
367 Q_PARAM: "", // A query param like `?VIEW=content'
368 ROOT: null, // Root element or our OrgNode tree
369 NODE: null, // The current node
370 TITLE: null, // Save the title for hide/show
371 INNER_TITLE: false, // The cloned title in sec-1.
372 LOAD_CHECK: null, // Saves the setTimeout()'s value
373 WINDOW: null, // A div to display info view mode
374 SECS: new Array(), // The OrgNode tree
375 REGEX: /(#)(.*$)/, // identify a section link in toc
376 SID_REGEX: /(^#)(sec-\d+([._]\d+)*$)/, // identify a plain section ID
377 UNTAG_REGEX: /<[^>]+>/i, // Remove HTML tags
378 ORGTAG_REGEX: /^(.*)<span\s+class=[\'\"]tag[\'\"]>(<span[^>]+>[^<]+<\/span>)+<\/span>/i, // Remove Org tags
379 TRIMMER: /^(\s*)([^\s].*)(\s*)$/, // Trim
380 // FNREF_REGEX: /(fnr\.*)/, // Footnote ref FIXME: not in use!?!
382 RUNS: 0, // Count the scan runs.
383 HISTORY: new Array(50), // Save navigation history.
385 SKIP_HISTORY: false, // popHistory() set's this to true.
386 FIXED_TOC: false, // Leave toc alone if position=[fixed|absolute]?
388 CONSOLE: null, // The div containing the minibuffer.
391 CONSOLE_OFFSET: "50px",
392 OCCUR: "", // The search string.
394 SEARCH_HL_REGEX: new RegExp('(<span class="org-info-js_search-highlight">)([^<]*?)(<\/span>)', "gi"),
395 MESSAGING: 0, // Is there a message in the console?
396 MESSAGING_INPLACE: 1,
400 // console in read mode?
402 // if yes, which command caused the readmode?
404 // numerical commands are internal commands.
405 READ_COMMAND_NULL: "_0",
406 READ_COMMAND_HTML_LINK: "_1",
407 READ_COMMAND_ORG_LINK: "_2",
408 READ_COMMAND_PLAIN_URL_LINK: "_03",
410 TAB_INDEX: 1000, // Users could have defined tabindexes!
411 SEARCH_HIGHLIGHT_ON: false,
412 TAGS: {}, // Tags: {tag:[index,index2...],tag2:[index1,index2...]}
413 SORTED_TAGS: new Array(), // Sorted tags
414 TAGS_INDEX: null, // Caches the tags-index screen
415 CLICK_TIMEOUT: null, // Mousehandling
416 SECNUM_MAP: {}, // Map section numbers to OrgNodes
417 TOC_LINK: null, // Last link used in TOC
418 HOOKS: { run_hooks: false, // Hoooks. run_hooks is false until onReady() is run.
423 * Setup the OrgHtmlManager for scanning.
424 * Here the timeout func gets set, that tells the wakes up org_html_mager
425 * for the next attempt to scan the document.
426 * All user setable config vars (the documented ones) are checked and adjusted
432 if(window['orgInfoHooks']) {
433 for(var i in orgInfoHooks) {
434 t.HOOKS[i] = orgInfoHooks[i];
436 t.HOOKS['run_hooks'] = false;
439 if(location.search) { // enable overwriting of settings
440 var sets = location.search.substring(1).split('&');
441 for(var i = 0; i < sets.length; ++i) {
442 var pos = sets[i].indexOf('=');
444 var v = sets[i].substring(pos+1);
445 var k = sets[i].substring(0, pos);
447 // Explicitely allow overwrites.
457 t.set(k, decodeURIComponent(v));
464 t.VIEW = t.VIEW ? t.VIEW : t.PLAIN_VIEW;
465 t.VIEW_BUTTONS = (t.VIEW_BUTTONS && t.VIEW_BUTTONS != "0") ? true : false;
466 t.STARTUP_MESSAGE = (t.STARTUP_MESSAGE && t.STARTUP_MESSAGE != "0") ? true : false;
467 t.LOCAL_TOC = (t.LOCAL_TOC && t.LOCAL_TOC != "0") ? t.LOCAL_TOC : false;
468 t.HIDE_TOC = (t.TOC && t.TOC != "0") ? false : true;
469 t.INNER_TITLE = (t.INNER_TITLE && t.INNER_TITLE != "title_above") ? false : true;
470 if(t.FIXED_TOC && t.FIXED_TOC != "0") {
474 else t.FIXED_TOC = false;
477 ((t.LINK_UP && t.LINK_UP != document.URL) ? '<a href="'+t.LINK_UP+'">Up</a> / ' : "") +
478 ((t.LINK_HOME && t.LINK_HOME != document.URL) ? '<a href="'+t.LINK_HOME+'">HOME</a> / ' : "") +
479 '<a href="javascript:org_html_manager.showHelp();">HELP</a> / ';
481 t.LOAD_CHECK = window.setTimeout("OrgHtmlManagerLoadCheck()", 50);
486 var r = this.TRIMMER.exec(s);
490 removeTags: function (s)
493 while(s.match(this.UNTAG_REGEX)) {
494 s = s.substr(0, s.indexOf('<')) + s.substr(s.indexOf('>') + 1);
500 * Remove tags from headline's inner HTML.
501 * @param s The headline's inner HTML.
502 * @return @c s with all tags stripped.
504 removeOrgTags: function (s)
506 if(s.match(this.ORGTAG_REGEX)) {
507 var matches = this.ORGTAG_REGEX.exec(s);
517 t.BODY = document.getElementById("content");
520 t.LOAD_CHECK = window.setTimeout("OrgHtmlManagerLoadCheck()", t.RUN_INTERVAL);
522 } else { // be backward compatible
523 t.BODY = document.getElementsByTagName("body")[0];
526 t.WINDOW = document.createElement("div");
527 t.WINDOW.style.marginBottom = "40px";
528 t.WINDOW.id = "org-info-js-window";
530 var theIndex = document.getElementById('table-of-contents');
532 if(! t.initFromTOC()) {
533 if( t.RUNS < t.RUN_MAX ) {
534 t.LOAD_CHECK = window.setTimeout("OrgHtmlManagerLoadCheck()", t.RUN_INTERVAL);
537 // CANCELED: warn if not scanned_all ??
540 var start_section = 0;
541 var start_section_explicit = false;
543 if("" != location.hash) {
544 t.BASE_URL = t.BASE_URL.substring(0, t.BASE_URL.indexOf('#'));
545 // Search for the start section:
546 for(var i=0;i<t.SECS.length;++i) {
547 if(t.SECS[i].isTargetFor[location.hash]) {
549 start_section_explicit = 1;
554 if("" != location.search) {
555 t.Q_PARAM = t.BASE_URL.substring(t.BASE_URL.indexOf('?'));
556 t.BASE_URL = t.BASE_URL.substring(0, t.BASE_URL.indexOf('?'));
559 t.convertLinks(); // adjust internal links. BASE_URL has to be stripped.
561 var pa=document.getElementById('postamble');
562 if(pa) t.POSTAMBLE=pa;
563 // Temporary FIX for missing P element if skip:nil
565 var n = b.firstChild;
566 if(3 == n.nodeType) { // IE has no ....
567 var neu = n.cloneNode(true);
568 var p = document.createElement("p");
569 p.id = "text-before-first-headline";
571 b.replaceChild(p, n);
573 // END OF temporary FIX.
575 t.CONSOLE = document.createElement("div");
576 t.CONSOLE.innerHTML = '<form action="" style="margin:0px;padding:0px;" onsubmit="org_html_manager.evalReadCommand(); return false;">'
577 +'<table id="org-info-js_console" style="width:100%;margin:0px 0px 0px 0px;border-style:none;" cellpadding="0" cellspacing="0" summary="minibuffer">'
578 +'<tbody><tr><td id="org-info-js_console-icon" style="padding:0px 0px 0px 0px;border-style:none;"> </td><td style="width:100%;vertical-align:middle;padding:0px 0px 0px 0px;border-style:none;">'
579 +'<table style="width:100%;margin:0px 0px 0px 0px;border-style:none;" cellpadding="0" cellspacing="2">'
580 +'<tbody><tr><td id="org-info-js_console-label" style="white-space:nowrap;padding:0px 0px 0px 0px;border-style:none;"></td></tr>'
581 +'<tr><td style="width:100%;vertical-align:middle;padding:0px 0px 0px 0px;border-style:none;">'
582 +'<input type="text" id="org-info-js_console-input" onkeydown="org_html_manager.getKey();"'
583 +' onclick="this.select();" maxlength="150" style="width:100%;padding:0px;margin:0px 0px 0px 0px;border-style:none;"'
584 +' value=""/></td></tr></tbody></table></td><td style="padding:0px 0px 0px 0px;border-style:none;"> </td></tr></tbody></table>'
586 t.CONSOLE.style.position = 'relative';
587 t.CONSOLE.style.marginTop = "-" + t.CONSOLE_OFFSET;
588 t.CONSOLE.style.top = "-" + t.CONSOLE_OFFSET;
589 t.CONSOLE.style.left = '0px';
590 t.CONSOLE.style.width = '100%';
591 t.CONSOLE.style.height = '40px';
592 t.CONSOLE.style.overflow = 'hidden';
593 t.CONSOLE.style.verticalAlign = 'middle';
594 t.CONSOLE.style.zIndex = '9';
595 t.CONSOLE.style.border = "1px solid #cccccc";
596 t.CONSOLE.id = 'org-info-js_console-container';
598 t.BODY.insertBefore(t.CONSOLE, t.BODY.firstChild);
600 t.CONSOLE_LABEL = document.getElementById("org-info-js_console-label");
601 t.CONSOLE_INPUT = document.getElementById("org-info-js_console-input");
602 document.onkeypress=OrgHtmlManagerKeyEvent;
604 if(t.VIEW == t.INFO_VIEW) {
605 t.infoView(start_section);
606 t.showSection(start_section);
607 // For Opera 10 - want to see the title and buttons on (re-)load.
608 window.setTimeout(function(){window.scrollTo(0, 0);}, 100);
610 else if(t.VIEW == t.SLIDE_VIEW) {
611 t.slideView(start_section);
612 t.showSection(start_section);
615 var v = t.VIEW; // will be changed in t.plainView()!
616 t.plainView(start_section, 1);
618 t.ROOT_STATE = OrgNode.STATE_UNFOLDED;
624 if(start_section_explicit) // Unfold the requested section
625 t.showSection(start_section);
629 t.CONSOLE_INPUT.value = t.OCCUR;
630 t.READ_COMMAND = 'o';
634 if(t.STARTUP_MESSAGE) {
635 t.warn("This page uses org-info.js. Press '?' for more information.", true);
637 t.HOOKS.run_hooks = true; // Unblock all hooks.
638 t.runHooks('onReady', this.NODE);
642 initFromTOC: function ()
645 // scan the document for sections. We do it by scanning the toc,
646 // so we do what is customized for orgmode (depth of sections in toc).
647 if(t.RUNS == 1 || ! t.ROOT) {
648 var toc = document.getElementById("table-of-contents");
653 for(i;heading == null && i < 7;++i)
654 heading = toc.getElementsByTagName("h"+i)[0];
655 heading.onclick = function() {org_html_manager.fold(0);};
656 heading.style.cursor = "pointer";
658 heading.onmouseover = function(){org_html_manager.highlightHeadline(0);};
659 heading.onmouseout = function(){org_html_manager.unhighlightHeadline(0);};
663 heading.setAttribute('onclick', 'org_html_manager.toggleGlobaly();');
664 t.ROOT = new OrgNode( null,
665 t.BODY.getElementsByTagName("h1")[0],
666 'javascript:org_html_manager.navigateTo(0);',
668 null ); // the root node
669 t.TOC = new OrgNode( toc,
671 'javascript:org_html_manager.navigateTo(0);',
673 null ); // the root node
677 t.ROOT = new OrgNode( null,
678 t.BODY.getElementsByTagName("h1")[0],
679 'javascript:org_html_manager.navigateTo(0);',
681 null ); // the root node
683 t.TOC = new OrgNode( toc,
685 'javascript:org_html_manager.navigateTo(0);',
689 OrgNode.hideElement(toc);
692 t.TOC = new OrgNode( toc,
694 'javascript:org_html_manager.navigateTo(0);',
696 t.ROOT ); // the root node
702 if(t.TOC) t.TOC.FOLDER = document.getElementById("text-table-of-contents");
708 var theIndex = t.TOC.FOLDER.getElementsByTagName("ul")[0]; // toc
710 // Could we scan the document all the way down?
711 // Return false if not.
712 if(! t.ulToOutlines(theIndex))
715 var fn = document.getElementById('footnotes');
717 var fnheading = null;
718 var c = fn.childNodes;
719 for(var i=0;i<c.length;++i) {
720 if("footnotes"== c[i].className) {
723 var sec = t.SECS.length;
724 fnheading.onclick = function() {org_html_manager.fold("" + sec);};
725 fnheading.style.cursor = "pointer";
727 fnheading.onmouseover = function() {org_html_manager.highlightHeadline("" + sec);};
728 fnheading.onmouseout = function() {org_html_manager.unhighlightHeadline("" + sec);};
730 var link = 'javascript:org_html_manager.navigateTo(' + sec + ')';
731 var fnsec= new OrgNode ( fn, fnheading, link, 1, t.ROOT, "footnotes");
736 t.cutToc(theIndex, 1);
739 // Move the title into the first visible section.
740 // TODO: show title above everything if FIXED_TOC !!!
741 t.TITLE = t.BODY.getElementsByTagName("h1")[0];
742 if(t.INNER_TITLE && !t.FIXED_TOC && t.VIEW != t.SLIDE_VIEW) {
743 t.INNER_TITLE = t.TITLE.cloneNode(true);
744 /* TODO: this is still based on wrong behaviour of browsers (same id for two elements)
745 * But this here does not work:
746 * t.INNER_TITLE.style = t.TITLE.style;
747 * t.INNER_TITLE.id = "org-info-js-inner-title";
749 t.SECS[0].DIV.insertBefore(t.INNER_TITLE, t.SECS[0].DIV.firstChild);
750 OrgNode.hideElement(t.TITLE);
753 // Create all the navigation links:
757 t.BODY.insertBefore(t.WINDOW, t.NODE.DIV);
763 * Used by OrgHtmlManager::initFromToc
765 ulToOutlines: function (ul)
767 if(ul.hasChildNodes() && ! ul.scanned_for_org) {
768 for(var i=0; i<ul.childNodes.length; ++i) {
769 if(false == this.liToOutlines(ul.childNodes[i])) {
773 ul.scanned_for_org = 1;
779 * Used by OrgHtmlManager::initFromToc
781 liToOutlines: function (li)
783 if(! li.scanned_for_org) {
784 for(var i=0; i<li.childNodes.length; ++i) {
785 var c = li.childNodes[i];
786 switch (c.nodeName) {
788 var newHref = this.mkNodeFromHref(c);
789 if(false == newHref) {
794 c.tabIndex = this.TAB_INDEX;
795 c.onfocus=function(){org_html_manager.TOC_LINK=this;void 0;};
796 if(null==this.TOC_LINK) this.TOC_LINK=c;
801 return this.ulToOutlines(c);
805 li.scanned_for_org = 1;
811 * Used by OrgHtmlManager::initFromToc
813 cutToc: function (ul, cur_depth)
816 if(ul.hasChildNodes()) {
817 for(var i=0; i < ul.childNodes.length; ++i) {
818 var li = ul.childNodes[i];
819 for(var j=0; j < li.childNodes.length; ++j) {
820 var c = li.childNodes[j];
821 if(c.nodeName == "UL") {
822 if(cur_depth > this.TOC_DEPTH)
825 this.cutToc(c, cur_depth); }}}}
829 * Used by OrgHtmlManager::liToOutlines
830 * @param anchor <a...> element in the TOC, that links to a section.
832 mkNodeFromHref: function (anchor)
835 if(s.match(this.REGEX)) {
836 var matches = this.REGEX.exec(s);
838 var h = document.getElementById(id);
839 // This heading could be null, if the document is not yet entirely loaded.
840 // So we stop scanning and set the timeout func in caller.
841 // We could even count the <ul> and <li> elements above to speed up the next
846 var div = h.parentNode;
847 var sec = this.SECS.length;
848 var depth = div.className.substr(8);
849 h.onclick = function() {org_html_manager.fold("" + sec);};
850 h.style.cursor = "pointer";
851 if(this.MOUSE_HINT) {
852 h.onmouseover = function() {org_html_manager.highlightHeadline("" + sec);};
853 h.onmouseout = function() {org_html_manager.unhighlightHeadline("" + sec);};
855 var link = 'javascript:org_html_manager.navigateTo(' + sec + ')';
856 if(depth > this.NODE.DEPTH) {
857 this.NODE = new OrgNode ( div, h, link, depth, this.NODE, id, anchor);
859 else if (depth == 2) {
860 this.NODE = new OrgNode ( div, h, link, depth, this.ROOT, id, anchor);
864 while(p.DEPTH > depth) p = p.PARENT;
865 this.NODE = new OrgNode ( div, h, link, depth, p.PARENT, id, anchor);
867 this.SECS.push(this.NODE);
868 // Prepare the tags-index:
869 var spans = h.getElementsByTagName("span");
871 for(var i = 0; i < spans.length; ++i) {
872 if(spans[i].className == "tag") {
873 var tags = spans[i].innerHTML.split(" ");
874 for(var j = 0; j < tags.length; ++j) {
875 var t = this.removeTags(tags[j]);
877 this.TAGS[t] = new Array();
878 this.SORTED_TAGS.push(t);
880 this.TAGS[t].push(sec);
883 else if(spans[i].className.match(this.SECNUM_REGEX)) {
884 this.SECNUM_MAP[this.trim(spans[i].innerHTML)] = this.NODE;
891 // return the link as it was, if no section link:
896 * Creates all the navigation links for this.SECS.
897 * This is called from initFromStructure() and initFromToc() as well.
899 * @todo Apply style classes to the generated links.
903 var index_name = this.TITLE.innerHTML;
904 var min_subindex_sec = 0;
906 for(var i = 0; i < this.SECS.length; ++i)
908 this.SECS[i].IDX = i;
909 var html = '<table class="org-info-js_info-navigation" width="100%" border="0" style="border-bottom:1px solid black;">'
910 +'<tr><td colspan="3" style="text-align:left;border-style:none;vertical-align:bottom;">'
911 +'<span style="float:left;display:inline;text-align:left;">'
912 +'Top: <a accesskey="t" href="javascript:org_html_manager.navigateTo(0);">'+index_name+'</a></span>'
913 +'<span style="float:right;display:inline;text-align:right;font-size:70%;">'
915 +'<a accesskey="m" href="javascript:org_html_manager.toggleView('+i+');">toggle view</a></span>'
916 +'</td></tr><tr><td style="text-align:left;border-style:none;vertical-align:bottom;width:22%">';
919 html += '<a accesskey="p" href="'+this.SECS[i-1].L
920 +'" title="Go to: '+this.removeTags(this.SECS[i-1].HEADING.innerHTML)+'">Previous</a> | ';
922 html += 'Previous | ';
924 if(i < this.SECS.length - 1)
925 html += '<a accesskey="n" href="'+this.SECS[i+1].L
926 +'" title="Go to: '+this.removeTags(this.SECS[i+1].HEADING.innerHTML)+'">Next</a>';
930 html += '</td><td style="text-align:center;vertical-align:bottom;border-style:none;width:56%;">';
932 if(i>0 && this.SECS[i].PARENT.PARENT) // != this.ROOT)
933 html += '<a href="'+this.SECS[i].PARENT.L
934 +'" title="Go to: '+this.removeTags(this.SECS[i].PARENT.HEADING.innerHTML)+'">'
935 +'<span style="font-variant:small-caps;font-style:italic;">'
936 +this.SECS[i].PARENT.HEADING.innerHTML+'</span></a>';
938 html += '<span style="font-variant:small-caps;font-style:italic;">'+this.SECS[i].HEADING.innerHTML+'</span>';
941 html += '</td><td style="text-align:right;vertical-align:bottom;border-style:none;width:22%">';
942 html += (i + 1) +'</td></tr></table>';
945 this.SECS[i].BUTTONS = document.createElement("div");
946 this.SECS[i].BUTTONS.innerHTML = '<div class="org-info-js_header-navigation" style="display:inline;float:right;text-align:right;font-size:70%;font-weight:normal;">'
948 + '<a accesskey="m" href="javascript:org_html_manager.toggleView('+i+');">toggle view</a></div>';
949 if(this.SECS[i].FOLDER)
950 // this.SECS[i].HEADING.appendChild(this.SECS[i].BUTTONS);
951 this.SECS[i].DIV.insertBefore(this.SECS[i].BUTTONS, this.SECS[i].HEADING); //div.firstChild.nextSibling);
952 else if(this.SECS[i].DIV.hasChildNodes()) {
953 this.SECS[i].DIV.insertBefore(this.SECS[i].BUTTONS, this.SECS[i].DIV.firstChild);
955 if(!this.VIEW_BUTTONS) OrgNode.hideElement(this.SECS[i].BUTTONS);
956 this.SECS[i].NAV = html;
958 // subindex for sections containing subsections:
959 if(0 < this.SECS[i].CHILDREN.length && this.LOCAL_TOC)
961 var navi2 = document.createElement("div");
962 navi2.className="org-info-js_local-toc";
963 html = 'Contents:<br /><ul>';
964 for(var k=0; k < this.SECS[i].CHILDREN.length; ++k) {
965 html += '<li><a href="'
966 +this.SECS[i].CHILDREN[k].L+'">'
967 +this.removeTags(this.removeOrgTags(this.SECS[i].CHILDREN[k].HEADING.innerHTML))+'</a></li>';
970 navi2.innerHTML = html;
971 if("above" == this.LOCAL_TOC) {
972 if(this.SECS[i].FOLDER)
973 this.SECS[i].FOLDER.insertBefore(navi2, this.SECS[i].FOLDER.firstChild);
975 this.SECS[i].DIV.insertBefore(
976 navi2, this.SECS[i].DIV.getElementsByTagName("h"+this.SECS[i].DEPTH)[0].nextSibling);
978 if(this.SECS[i].FOLDER)
979 this.SECS[i].FOLDER.appendChild(navi2);
981 this.SECS[i].DIV.appendChild(navi2);
985 // Setup the Tags for sorted output:
986 this.SORTED_TAGS.sort();
990 * Execute arbitrary JavaScript code. Used for configuration.
992 set: function (eval_key, eval_val)
994 if("VIEW" == eval_key) {
995 var pos = eval_val.indexOf('_');
997 this.INNER_TITLE=eval_val.substr(pos + 1); // might be info_title_above now.
998 eval_val=eval_val.substr(0, pos);
1000 var overview = this.PLAIN_VIEW;
1001 var content = this.CONTENT_VIEW;
1002 var showall = this.ALL_VIEW;
1003 var info = this.INFO_VIEW;
1004 var info_title_above = this.INFO_VIEW;
1005 var slide = this.SLIDE_VIEW;
1006 eval("this."+eval_key+"="+eval_val+";");
1008 else if("HELP" == eval_key)
1009 eval("this.STARTUP_MESSAGE="+eval_val+";");
1012 eval("this."+eval_key+"='"+eval_val+"';");
1014 eval("this."+eval_key+"=0;");
1018 convertLinks: function ()
1020 var i = (this.HIDE_TOC ? 0 : 1);
1022 var foot_sec = this.SECS.length - 1;
1023 // for(i; i < this.SECS.length; ++i) {
1024 var links = document.getElementsByTagName("a"); // must be document!
1025 for(j=0; j<links.length; ++j) {
1026 var href = links[j].href.replace(this.BASE_URL, '');
1027 // could use quicksort like search here:
1028 for(var k = 0; k < this.SECS.length; ++k) {
1029 if(this.SECS[k].isTargetFor[href]) {
1030 links[j].href="javascript:org_html_manager.navigateTo("+k+")";
1038 * Show a certain section.
1040 * NOTE: Replacing window.location might change the view mode, if the mode was
1041 * requested using an URL like "?VIEW=...¶m=value" and the mode was
1042 * different from the one specified in the <head> section. The solution is, to
1043 * track the query parameter until the user changes the view mode for the
1046 * You can avoid the URL-replacing by setting @c org_html_manager.NODE to the
1047 * same node you want to display before calling this function. This
1048 * <u>should</u> be the case on startup.
1050 * @param sec The section to show. This is the index
1053 showSection: function (sec)
1056 var section = parseInt(sec);
1057 var last_node = t.NODE;
1058 var hook = 'onShowSection';
1059 if(t.HIDE_TOC && t.NODE == t.TOC && !t.FIXED_TOC) {
1060 OrgNode.hideElement(t.TOC.DIV);
1061 if(t.PLAIN_VIEW == t.VIEW) {
1062 t.ROOT.showAllChildren();
1063 for(var i=0;i<t.ROOT.CHILDREN.length;++i) {
1064 t.ROOT.CHILDREN[i].STATE = OrgNode.STATE_UNFOLDED;
1065 t.ROOT.CHILDREN[i].fold();
1069 if('?/toc/?' != sec && null != t.TOC_LINK) t.TOC_LINK.blur();
1070 if('?/toc/?' == sec || (!isNaN(section) && t.SECS[section])) {
1071 if('?/toc/?' == sec && t.HIDE_TOC)
1075 t.ROOT.hideAllChildren();
1076 if(t.INFO_VIEW == t.VIEW)
1077 t.WINDOW.innerHTML = t.NODE.DIV.innerHTML;
1079 t.NODE.setState(OrgNode.STATE_UNFOLDED);
1080 window.scrollTo(0, 0);
1084 t.NODE = t.SECS[section];
1085 if(t.SLIDE_VIEW == t.VIEW || t.INFO_VIEW == t.VIEW) {
1086 OrgNode.hideElement(t.NODE.BUTTONS);
1087 t.NODE.setState(OrgNode.STATE_UNFOLDED);
1088 for(var i=0;i<t.NODE.CHILDREN.length; ++i)
1089 t.NODE.CHILDREN[i].hide();
1090 if(t.SLIDE_VIEW == t.VIEW) t.WINDOW.innerHTML = t.NODE.DIV.innerHTML;
1091 else t.WINDOW.innerHTML = t.NODE.NAV + t.NODE.DIV.innerHTML;
1093 // Hide the body, to avoid jumping page when replacing the
1094 // location. Unfortunatly we cannot do this with a fixed TOC,
1095 // because the fixed TOC will jump then, causing links towards the
1096 // bottom to disapear again.
1097 if(! t.FIXED_TOC) OrgNode.hideElement(document.body);
1098 if(last_node.IDX != t.NODE.IDX)
1099 if('?/toc/?' != sec) window.location.replace(t.BASE_URL + t.Q_PARAM + t.getDefaultTarget());
1100 if(! t.FIXED_TOC) OrgNode.showElement(document.body);
1103 if(! t.VIEW_BUTTONS) OrgNode.hideElement(last_node.BUTTONS);
1104 OrgNode.showElement(t.NODE.BUTTONS);
1105 t.NODE.setState(OrgNode.UNFOLDED);
1107 if(last_node.IDX != t.NODE.IDX)
1108 window.location.replace(t.BASE_URL + t.Q_PARAM + t.getDefaultTarget());
1109 if(t.NODE.IDX == 0) window.scrollTo(0, 0);
1110 else t.NODE.DIV.scrollIntoView(true);
1114 last_node.setLinkClass();
1115 t.NODE.setLinkClass(true);
1116 t.runHooks(hook, {'last': last_node, 'current': t.NODE});
1119 plainView: function (sec, skip_show_section)
1122 document.onclick = null;
1123 document.ondblclick = null;
1124 t.VIEW = t.PLAIN_VIEW;
1125 OrgNode.hideElement(t.WINDOW);
1126 if(t.INNER_TITLE) OrgNode.hideElement(t.INNER_TITLE);
1127 OrgNode.showElement(t.TITLE);
1128 // For Opera and accesskeys we have to remove the navigation here to get it
1129 // working when toggeling back to info view again:
1130 if(t.WINDOW.firstChild) // might not be set after init
1131 t.WINDOW.removeChild(t.WINDOW.firstChild);
1132 t.ROOT.showAllChildren();
1133 for(var i=0;i<t.ROOT.CHILDREN.length;++i) {
1134 t.ROOT.CHILDREN[i].STATE = OrgNode.STATE_UNFOLDED;
1135 t.ROOT.CHILDREN[i].fold();
1137 if(!skip_show_section)
1139 if(t.POSTAMBLE) OrgNode.showElement(t.POSTAMBLE);
1140 if(t.NODE.IDX == 0) window.scrollTo(0, 0);
1141 else t.NODE.DIV.scrollIntoView(true);
1144 infoView: function (sec, skip_show_section)
1147 document.onclick = null;
1148 document.ondblclick = null;
1149 t.VIEW = t.INFO_VIEW;
1150 t.unhighlightHeadline(t.NODE.IDX);
1151 if(t.INNER_TITLE && !t.FIXED_TOC) {
1152 OrgNode.showElement(t.INNER_TITLE);
1153 OrgNode.hideElement(t.TITLE);
1155 OrgNode.showElement(t.WINDOW);
1156 t.ROOT.hideAllChildren();
1157 if(t.TOC && !t.FIXED_TOC) OrgNode.hideElement(t.TOC.DIV);
1158 if(t.POSTAMBLE) OrgNode.showElement(t.POSTAMBLE);
1159 if(!skip_show_section)
1161 window.scrollTo(0, 0);
1164 slideView: function (sec, skip_show_section)
1167 t.VIEW = t.SLIDE_VIEW;
1168 t.unhighlightHeadline(t.NODE.IDX);
1169 OrgNode.hideElement(t.TITLE);
1170 if(t.INNER_TITLE) OrgNode.hideElement(t.INNER_TITLE);
1171 if(t.TOC) OrgNode.hideElement(t.TOC.DIV);
1172 OrgNode.showElement(t.TITLE);
1173 OrgNode.showElement(t.WINDOW);
1174 t.ROOT.hideAllChildren();
1175 OrgNode.hideElement(t.TOC.DIV);
1176 if(t.POSTAMBLE) OrgNode.hideElement(t.POSTAMBLE);
1178 if(!skip_show_section) t.showSection(sec);
1181 // hide/show List-items. show > 0: show next listitem, < 0 hide last listitem. null means new section.
1182 adjustSlide: function(sec, show)
1184 var nextForward = true;
1185 var nextBack = true;
1187 if(sec > this.NODE.IDX) next = true;
1188 if(null == show) next = true;
1191 for(var n=this.SECS[sec].FOLDER.firstChild;null != n;n=n.nextSibling){
1192 if("UL" == n.nodeName){
1193 var lis=n.getElementsByTagName("li");
1194 for(var i=1;i<lis.length;++i) {
1196 OrgNode.hideElement(l); nextForward = false;
1202 var lists = this.WINDOW.getElementsByTagName("ul");
1203 for(var n=0; n < lists.length; ++n){
1204 var lis=lists[n].getElementsByTagName("li");
1205 for(var i=1;i<lis.length;++i) {
1208 if(OrgNode.isHidden(l)) {
1209 OrgNode.unhideElement(l);
1210 if(i< (lis.length-1)) nextForward=false;
1211 if(0<i) nextBack=false;
1216 if(!OrgNode.isHidden(l)) {
1219 OrgNode.hideElement(lis[i - 1]);
1229 document.onclick = function(){org_html_manager.scheduleClick("org_html_manager.nextSection(org_html_manager.NODE.IDX + 1)");};
1231 document.onclick = function(){org_html_manager.scheduleClick("org_html_manager.adjustSlide(org_html_manager.NODE.IDX, +1)");};
1233 document.ondblclick = function(){org_html_manager.scheduleClick("org_html_manager.previousSection()");};
1235 document.ondblclick = function(){org_html_manager.scheduleClick("org_html_manager.adjustSlide("+this.NODE.IDX+", -1)");};
1239 * Toggle the view mode.
1240 * This also resets the <code>Q_PARAM</code> to an empty string.
1241 * @param sec The section index to show.
1243 toggleView: function (sec)
1248 if(t.VIEW == t.INFO_VIEW)
1254 fold: function (sec)
1258 var section = parseInt(sec);
1259 t.SECS[section].fold();
1260 if(! t.VIEW_BUTTONS) OrgNode.hideElement(t.NODE.BUTTONS);
1261 t.NODE = t.SECS[section];
1262 OrgNode.showElement(t.NODE.BUTTONS);
1265 toggleGlobaly: function ()
1269 t.ROOT.STATE = OrgNode.STATE_UNFOLDED;
1272 if(OrgNode.STATE_UNFOLDED == t.ROOT.STATE) {
1273 for(var i=0;i<t.ROOT.CHILDREN.length;++i) {
1274 // Pretend they are unfolded. They will toggle to FOLDED then:
1275 t.ROOT.CHILDREN[i].STATE = OrgNode.STATE_UNFOLDED;
1276 t.ROOT.CHILDREN[i].fold(true);
1278 t.ROOT.STATE = OrgNode.STATE_UNFOLDED;
1279 t.ROOT.STATE = OrgNode.STATE_FOLDED;
1281 else if(OrgNode.STATE_FOLDED == t.ROOT.STATE) {
1282 for(var i=0;i<t.ROOT.CHILDREN.length;++i)
1283 t.ROOT.CHILDREN[i].fold(true);
1284 t.ROOT.STATE = OrgNode.STATE_HEADLINES;
1287 for(var i=0;i<t.ROOT.CHILDREN.length;++i)
1288 t.ROOT.CHILDREN[i].fold();
1289 t.ROOT.STATE = OrgNode.STATE_UNFOLDED;
1292 // All this sets ROOT dirty again. So clean it:
1293 t.ROOT.DIRTY = false;
1298 executeClick: function(func)
1301 if (t.READING) { t.endRead(); t.hideConsole(); }
1302 else if(t.MESSAGING) { t.removeWarning(); }
1304 if(null != t.CLICK_TIMEOUT) t.CLICK_TIMEOUT = null;
1307 scheduleClick: function(func, when)
1309 if(null == when) when = 250;
1310 if(null == this.CLICK_TIMEOUT) {
1311 this.CLICK_TIMEOUT = window.setTimeout("org_html_manager.executeClick(" + func + ")", when);
1314 window.clearTimeout(this.CLICK_TIMEOUT);
1315 this.CLICK_TIMEOUT = null;
1321 nextSection: function()
1324 var i = T.NODE.IDX + 1;
1325 if(i<T.SECS.length) T.navigateTo(i);
1326 else T.warn("Already last section.");
1329 previousSection: function()
1333 if(i>0) t.navigateTo(i-1);
1334 else t.warn("Already first section.");
1339 * This one is just here, because we might want to push different than
1340 * navigational commands on the history in the future. Is this true?
1342 navigateTo: function (sec)
1345 if (t.READING) { t.endRead(); t.hideConsole(); }
1346 else if(t.MESSAGING) { t.removeWarning(); }
1347 if(t.VIEW == t.SLIDE_VIEW) t.adjustSlide(sec);
1348 t.pushHistory(sec, t.NODE.IDX);
1354 * All undoable navigation commands should push the oposit here
1356 pushHistory: function (command, undo)
1359 if(! t.SKIP_HISTORY) {
1360 t.HISTORY[t.HIST_INDEX] = new Array(command, undo);
1361 t.HIST_INDEX = (t.HIST_INDEX + 1) % 50;
1363 t.SKIP_HISTORY = false;
1364 t.CONSOLE_INPUT.value = "";
1368 * only 'b' and 'B' trigger this one
1370 popHistory: function (foreward)
1374 if(t.HISTORY[t.HIST_INDEX]) {
1375 var s = parseInt(t.HISTORY[t.HIST_INDEX][0]);
1376 if(! isNaN(s) || '?/toc/?' == t.HISTORY[t.HIST_INDEX][0]) {
1377 t.showSection(t.HISTORY[t.HIST_INDEX][0]);
1378 t.CONSOLE_INPUT.value = "";
1381 t.SKIP_HISTORY = true;
1382 t.CONSOLE_INPUT.value = t.HISTORY[t.HIST_INDEX][0];
1385 t.HIST_INDEX = (t.HIST_INDEX + 1) % 50;
1388 else if(t.HFO && history.length) history.forward();
1391 t.warn("History: No where to foreward go from here. Any key and `B' to move to next file in history.");
1394 if(t.HISTORY[t.HIST_INDEX - 1]) {
1395 t.HIST_INDEX = t.HIST_INDEX == 0 ? 49 : t.HIST_INDEX - 1;
1396 var s = parseInt(t.HISTORY[t.HIST_INDEX][1]);
1397 if(! isNaN(s) || '?/toc/?' == t.HISTORY[t.HIST_INDEX][1]) {
1398 t.showSection(t.HISTORY[t.HIST_INDEX][1]);
1399 t.CONSOLE_INPUT.value = "";
1402 t.SKIP_HISTORY = true;
1403 t.CONSOLE_INPUT.value = t.HISTORY[t.HIST_INDEX][1];
1408 else if(t.HBO && history.length) history.back();
1411 t.warn("History: No where to back go from here. Any key and `b' to move to previous file in history.");
1420 warn: function (what, harmless, value)
1423 if(null == value) value = "";
1424 t.CONSOLE_INPUT.value = value;
1425 if(! harmless) t.CONSOLE_LABEL.style.color = "red";
1426 t.CONSOLE_LABEL.innerHTML = "<span style='float:left;'>"+what +"</span>"+
1427 "<span style='float:right;color:#aaaaaa;font-weight:normal;'>(press any key to proceed)</span>";
1429 // wait until keyup was processed:
1430 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.value=value;}, 50);
1433 startRead: function (command, label, value, shortcuts)
1436 if(null == value) value = "";
1437 if(null == shortcuts) shortcuts = "";
1438 t.READ_COMMAND = command;
1440 t.CONSOLE_LABEL.innerHTML = "<span style='float:left;'>"+label+"</span>"+
1441 "<span style='float:right;color:#aaaaaa;font-weight:normal;'>("+shortcuts+"RET to close)</span>";
1443 document.onkeypress=null;
1444 t.CONSOLE_INPUT.focus();
1445 t.CONSOLE_INPUT.onblur = function() {org_html_manager.CONSOLE_INPUT.focus();};
1446 // wait until keyup was processed:
1447 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.value=value;}, 50);
1450 endRead: function (command, label)
1454 t.READ_COMMAND = "";
1455 t.CONSOLE_INPUT.onblur = null;
1456 t.CONSOLE_INPUT.blur();
1457 document.onkeypress=OrgHtmlManagerKeyEvent;
1460 removeWarning: function()
1463 t.CONSOLE_LABEL.style.color = "#333333";
1467 showConsole: function()
1471 if(t.VIEW == t.PLAIN_VIEW) {
1472 // Maybe clone the CONSOLE?
1473 t.BODY.removeChild(t.BODY.firstChild);
1474 t.NODE.DIV.insertBefore(t.CONSOLE, t.NODE.DIV.firstChild);
1475 t.NODE.DIV.scrollIntoView(true);
1476 t.MESSAGING = t.MESSAGING_INPLACE;
1478 t.MESSAGING = t.MESSAGING_TOP;
1479 window.scrollTo(0, 0);
1481 t.CONSOLE.style.marginTop = '0px';
1482 t.CONSOLE.style.top = '0px';
1486 hideConsole: function()
1490 t.CONSOLE.style.marginTop = "-" + t.CONSOLE_OFFSET;
1491 t.CONSOLE.style.top = "-" + t.CONSOLE_OFFSET;
1492 t.CONSOLE_LABEL.innerHTML = "";
1493 t.CONSOLE_INPUT.value = "";
1494 if(t.MESSAGING_INPLACE == t.MESSAGING) {
1495 t.NODE.DIV.removeChild(t.NODE.DIV.firstChild);
1496 t.BODY.insertBefore(t.CONSOLE, t.BODY.firstChild);
1497 if(t.NODE.IDX != 0) t.NODE.DIV.scrollIntoView();
1499 t.MESSAGING = false;
1508 * All commands that add something to the history should return.
1513 var s = t.CONSOLE_INPUT.value;
1514 // return, if s is empty:
1516 if(t.HELPING) { t.showHelp(); return; }
1517 if(t.MESSAGING && !t.READING) t.removeWarning();
1521 // the easiest is to just drop everything and clean the console.
1522 // User has to retype again.
1523 if(t.MESSAGING && !t.READING) {
1527 else if(t.HELPING) {
1529 t.CONSOLE_INPUT.value = "";
1532 else if(t.READING) {
1536 t.CONSOLE_INPUT.value = "";
1537 t.CONSOLE_INPUT.blur();
1539 // Always remove TOC from history, if HIDE_TOC
1540 if(t.HIDE_TOC && t.TOC == t.NODE && "v" != s && "V" != s && "\t" != s) {
1543 else if("\t" == s) {
1550 // SINGLE KEY COMMANDS GO HERE //
1552 if (1 == s.length) // one char wide commands
1557 else if ('B' == s) {
1560 else if ('c' == s) {
1561 t.removeSearchHighlight();
1562 if(t.VIEW == t.INFO_VIEW || t.VIEW == t.SLIDE_VIEW) {
1563 // redisplay in info view mode:
1564 t.showSection(t.NODE.IDX);
1567 else if ('i' == s) {
1569 if (t.HIDE_TOC) t.navigateTo('?/toc/?');
1571 else if(0 != t.NODE.IDX) t.navigateTo(0);
1573 if(null != t.TOC_LINK) t.TOC_LINK.focus();
1575 else if ('m' == s) {
1576 t.toggleView(t.NODE.IDX);
1579 else if ('x' == s) {
1580 t.slideView(t.NODE.IDX);
1582 else if ('n' == s) {
1583 if(t.NODE.STATE == OrgNode.STATE_FOLDED && t.VIEW == t.PLAIN_VIEW) {
1584 t.showSection(t.NODE.IDX);
1586 else if(t.NODE.IDX < t.SECS.length - 1) {
1587 t.navigateTo(t.NODE.IDX + 1);
1589 t.warn("Already last section.");
1590 return; // rely on what happends if messaging
1593 else if ('N' == s) {
1594 if(t.NODE.IDX < t.SECS.length - 1) {
1595 var d = t.NODE.DEPTH;
1596 var idx = t.NODE.IDX + 1;
1597 while(idx < t.SECS.length - 1 && t.SECS[idx].DEPTH >= d) {
1598 if(t.SECS[idx].DEPTH == d) {
1605 t.warn("No next sibling.");
1606 return; // rely on what happends if messaging
1608 else if ('p' == s) {
1609 if(t.NODE.IDX > 0) {
1610 t.navigateTo(t.NODE.IDX - 1);
1612 t.warn("Already first section.");
1613 return; // rely on what happends if messaging
1616 else if ('P' == s) {
1617 if(t.NODE.IDX > 0) {
1618 var d = t.NODE.DEPTH;
1619 var idx = t.NODE.IDX - 1;
1620 while(idx >= 0 && t.SECS[idx].DEPTH >= d) {
1621 if(t.SECS[idx].DEPTH == d) {
1628 t.warn("No previous sibling.");
1630 else if ('q' == s) {
1631 if(window.confirm("Really close this file?")) {
1635 else if ('<' == s || 't' == s) {
1636 if(0 != t.NODE.IDX) t.navigateTo(0);
1637 else window.scrollTo(0,0);
1639 else if ('>' == s || 'E' == s || 'e' == s) {
1640 if((t.SECS.length - 1) != t.NODE.IDX) t.navigateTo(t.SECS.length - 1);
1641 else t.SECS[t.SECS.length - 1].DIV.scrollIntoView(true);
1643 else if ('v' == s) {
1644 if(window.innerHeight)
1645 window.scrollBy(0, window.innerHeight - 30);
1646 else if(document.documentElement.clientHeight)
1647 window.scrollBy(0, document.documentElement.clientHeight - 30);
1649 window.scrollBy(0, document.body.clientHeight - 30);
1651 else if ('V' == s) {
1652 if(window.innerHeight)
1653 window.scrollBy(0, -(window.innerHeight - 30));
1654 else if(document.documentElement.clientHeight)
1655 window.scrollBy(0, -(document.documentElement.clientHeight - 30));
1657 window.scrollBy(0, -(document.body.clientHeight - 30));
1659 else if ('u' == s) {
1660 if(t.NODE.PARENT != t.ROOT) {
1661 t.NODE = t.NODE.PARENT;
1662 t.showSection(t.NODE.IDX);
1665 else if ('W' == s) {
1666 t.plainView(t.NODE.IDX);
1667 t.ROOT.DIRTY = true;
1668 t.ROOT_STATE = OrgNode.STATE_UNFOLDED;
1674 else if ('f' == s) {
1675 if(t.VIEW != t.INFO_VIEW) {
1677 t.NODE.DIV.scrollIntoView(true);
1680 else if ('F' == s) {
1681 if(t.VIEW != t.INFO_VIEW) {
1683 t.NODE.DIV.scrollIntoView(true);
1686 else if ('?' == s || '¿' == s) {
1689 else if ('C' == s) {
1690 if(t.SORTED_TAGS.length) t.showTagsIndex();
1691 else t.warn("No Tags found.");
1693 else if ('H' == s && t.LINK_HOME) {
1694 window.document.location.href = t.LINK_HOME;
1696 else if ('h' == s && t.LINK_UP) {
1697 window.document.location.href = t.LINK_UP;
1700 /* === READ COMMANDS === */
1702 else if ('l' == s) {
1704 t.startRead(t.READ_COMMAND_HTML_LINK, "Choose HTML-link type: 's' = section, 'o' = occur");
1706 t.startRead(s, "HTML-link:",
1707 '<a href="' + t.BASE_URL + t.getDefaultTarget() + '">' +
1708 document.title + ", Sec. '" + t.removeTags(t.NODE.HEADING.innerHTML) + "'</a>",
1710 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.select();}, 100);
1714 else if ('L' == s) {
1716 t.startRead(t.READ_COMMAND_ORG_LINK, "Choose Org-link type: 's' = section, 'o' = occur");
1718 t.startRead(s, "Org-link:",
1719 '[[' + t.BASE_URL + t.getDefaultTarget() + '][' +
1720 document.title + ", Sec. '" + t.removeTags(t.NODE.HEADING.innerHTML) + "']]",
1722 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.select();}, 100);
1726 else if ('U' == s) {
1728 t.startRead(t.READ_COMMAND_PLAIN_URL_LINK, "Choose Org-link type: 's' = section, 'o' = occur");
1730 t.startRead(s, "Plain URL Link:", t.BASE_URL + t.getDefaultTarget(),
1732 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.select();}, 100);
1736 else if ('g' == s) {
1737 t.startRead(s, "Enter section number:");
1740 else if ('o' == s) {
1741 if("" != t.OCCUR) t.startRead(s, "Occur:", t.OCCUR, "RET to use previous, DEL ");
1742 else t.startRead(s, "Occur:", t.OCCUR);
1743 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.value=org_html_manager.OCCUR;org_html_manager.CONSOLE_INPUT.select();}, 100);
1746 else if ('s' == s) {
1747 if("" != t.OCCUR) t.startRead(s, "Search forward:", t.OCCUR, "RET to use previous, DEL ");
1748 else t.startRead(s, "Search forward:", t.OCCUR);
1749 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.value=org_html_manager.OCCUR;org_html_manager.CONSOLE_INPUT.select();}, 100);
1752 else if ('S' == s) {
1755 t.startRead(s, "Search forward:");
1759 t.evalReadCommand();
1763 else if ('r' == s) {
1764 if("" != t.OCCUR) t.startRead(s, "Search backwards:", t.OCCUR, "RET to use previous, DEL ");
1765 else t.startRead(s, "Search backwards:", t.OCCUR);
1766 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.value=org_html_manager.OCCUR;org_html_manager.CONSOLE_INPUT.select();}, 100);
1769 else if ('R' == s) {
1772 t.startRead(s, "Search backwards:");
1776 t.evalReadCommand();
1786 * Please return, if you want the minibuffer to stay on screen.
1787 * Remember to call this.endRead()!
1789 evalReadCommand: function()
1792 var command = t.READ_COMMAND;
1793 var result = t.trim(t.CONSOLE_INPUT.value);
1797 if("" == command || "" == result) {
1802 // VALID INPUT? COMMANDS FOLLOW HERE
1804 if(command == 'g') { // goto section
1805 var sec = t.SECNUM_MAP[result];
1808 t.navigateTo(sec.IDX);
1811 t.warn("Goto section: no such section.", false, result);
1815 else if(command == 's') { // search
1816 if("" == result) return false;
1817 if(t.SEARCH_HIGHLIGHT_ON) t.removeSearchHighlight();
1818 var restore = t.OCCUR;
1820 if(result == t.OCCUR) plus++;
1822 t.makeSearchRegexp();
1823 for(var i = t.NODE.IDX + plus; i < t.SECS.length; ++i) {
1824 if(t.searchTextInOrgNode(i)) {
1827 t.navigateTo(t.SECS[i].IDX);
1831 t.warn("Search forwards: text not found.", false, t.OCCUR);
1836 else if(command == 'S') { // repeat search
1837 for(var i = t.NODE.IDX + 1; i < t.SECS.length; ++i) {
1838 if(t.searchTextInOrgNode(i)) {
1840 t.navigateTo(t.SECS[i].IDX);
1844 t.warn("Search forwards: text not found.", false, t.OCCUR);
1848 else if(command == 'r') { // search backwards
1849 if("" == result) return false;
1850 if(t.SEARCH_HIGHLIGHT_ON) t.removeSearchHighlight();
1851 var restore = t.OCCUR;
1854 if(result == t.OCCUR) plus++;
1855 t.makeSearchRegexp();
1856 for(var i = t.NODE.IDX - plus; i > -1; --i) {
1857 if(t.searchTextInOrgNode(i)) {
1859 t.navigateTo(t.SECS[i].IDX);
1863 t.warn("Search backwards: text not found.", false, t.OCCUR);
1868 else if(command == 'R') { // repeat search backwards
1869 for(var i = t.NODE.IDX - 1; i > -1; --i) {
1870 result = t.removeTags(t.SECS[i].HEADING.innerHTML);
1871 if(t.searchTextInOrgNode(i)) {
1873 t.navigateTo(t.SECS[i].IDX);
1877 t.warn("Search backwards: text not found.", false, t.OCCUR);
1881 else if(command == 'o') { // occur
1882 if("" == result) return false;
1883 if(t.SEARCH_HIGHLIGHT_ON) t.removeSearchHighlight();
1884 var restore = t.OCCUR;
1886 t.makeSearchRegexp();
1887 var occurs = new Array();
1888 for(var i = 0; i < t.SECS.length; ++i) {
1889 if(t.searchTextInOrgNode(i)) {
1893 if(0 == occurs.length) {
1894 t.warn("Occur: text not found.", false, t.OCCUR);
1900 if(t.PLAIN_VIEW != t.VIEW) t.plainView();
1901 t.ROOT.DIRTY = true;
1903 for(var i = 0; i < t.SECS.length; ++i) {
1904 OrgNode.showElement(t.SECS[i].DIV);
1905 OrgNode.hideElement(t.SECS[i].FOLDER);
1907 for(var i = (occurs.length - 1); i >= 1; --i) {
1908 OrgNode.showElement(t.SECS[occurs[i]].FOLDER);
1910 t.showSection(occurs[0]);
1913 else if(command == t.READ_COMMAND_ORG_LINK) {
1914 var c = result.charAt(0);
1916 t.startRead(t.READ_COMMAND_NULL, "Org-link to this section:",
1917 '[[' + t.BASE_URL + t.getDefaultTarget() + '][' +
1918 document.title + ", Sec. '" + t.removeTags(t.NODE.HEADING.innerHTML) + "']]",
1920 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.select();}, 100);
1921 } else if('o' == c) {
1922 t.startRead(t.READ_COMMAND_NULL, "Org-link, occurences of <i>""+t.OCCUR+""</i>:",
1923 '[[' + t.BASE_URL + "?OCCUR=" + t.OCCUR + '][' +
1924 document.title + ", occurences of '" + t.OCCUR + "']]",
1926 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.select();}, 100);
1928 t.warn(c + ": No such link type!");
1932 else if(command == t.READ_COMMAND_HTML_LINK) {
1933 var c = result.charAt(0);
1935 t.startRead(t.READ_COMMAND_NULL, "HTML-link to this section:",
1936 '<a href="' + t.BASE_URL + t.getDefaultTarget() + '">' +
1937 document.title + ", Sec. '" + t.removeTags(t.NODE.HEADING.innerHTML) + "'</a>",
1939 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.select();}, 100);
1940 } else if('o' == c) {
1941 t.startRead(t.READ_COMMAND_NULL, "HTML-link, occurences of <i>""+t.OCCUR+""</i>:",
1942 '<a href="' + t.BASE_URL + "?OCCUR=" + t.OCCUR + '">' +
1943 document.title + ", occurences of '" + t.OCCUR + "'</a>",
1945 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.select();}, 100);
1947 t.warn(c + ": No such link type!");
1951 else if(command == t.READ_COMMAND_PLAIN_URL_LINK) {
1952 var c = result.charAt(0);
1954 t.startRead(t.READ_COMMAND_NULL, "Plain-link to this section:",
1955 t.BASE_URL + t.getDefaultTarget(),
1957 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.select();}, 100);
1958 } else if('o' == c) {
1959 t.startRead(t.READ_COMMAND_NULL, "Plain-link, occurences of <i>""+t.OCCUR+""</i>:",
1960 t.BASE_URL + "?OCCUR=" + t.OCCUR,
1962 window.setTimeout(function(){org_html_manager.CONSOLE_INPUT.select();}, 100);
1964 t.warn(c + ": No such link type!");
1970 getDefaultTarget: function(node)
1972 if(null == node) node = this.NODE;
1973 var loc = "#" + this.NODE.BASE_ID;
1974 for(var s in node.isTargetFor) {
1975 if(! s.match(this.SID_REGEX)){loc = s; break;}
1984 makeSearchRegexp: function()
1986 var tmp = this.OCCUR.replace(/>/g, ">").
1987 replace(/</g, "<").
1988 replace(/=/g, "\\=").
1989 replace(/\\/g, "\\\\").
1990 replace(/\?/g, "\\?").
1991 replace(/\)/g, "\\)").
1992 replace(/\(/g, "\\(").
1993 replace(/\./g, "[^<>]").
1994 replace(/\"/g, """);
1995 this.SEARCH_REGEX = new RegExp(">([^<]*)?("+tmp+")([^>]*)?<","ig");
1998 searchTextInOrgNode: function(i)
2002 if(null != t.SECS[i]) {
2003 if(t.SEARCH_REGEX.test(t.SECS[i].HEADING.innerHTML)) {
2005 t.setSearchHighlight(t.SECS[i].HEADING);
2006 t.SECS[i].HAS_HIGHLIGHT = true;
2007 t.SEARCH_HIGHLIGHT_ON = true;
2009 if(t.SEARCH_REGEX.test(t.SECS[i].FOLDER.innerHTML)) {
2011 t.setSearchHighlight(t.SECS[i].FOLDER);
2012 t.SECS[i].HAS_HIGHLIGHT = true;
2013 t.SEARCH_HIGHLIGHT_ON = true;
2020 setSearchHighlight: function(dom)
2022 var tmp = dom.innerHTML;
2023 dom.innerHTML = tmp.replace(this.SEARCH_REGEX,
2024 '>$1<span class="org-info-js_search-highlight">$2</span>$3<');
2027 removeSearchHighlight: function()
2030 for(var i = 0; i < t.SECS.length; ++i) {
2031 if(t.SECS[i].HAS_HIGHLIGHT) {
2032 while(t.SEARCH_HL_REGEX.test(t.SECS[i].HEADING.innerHTML)) {
2033 var tmp = t.SECS[i].HEADING.innerHTML;
2034 t.SECS[i].HEADING.innerHTML = tmp.replace(t.SEARCH_HL_REGEX, '$2');
2036 while(t.SEARCH_HL_REGEX.test(t.SECS[i].FOLDER.innerHTML)) {
2037 var tmp = t.SECS[i].FOLDER.innerHTML;
2038 t.SECS[i].FOLDER.innerHTML = tmp.replace(t.SEARCH_HL_REGEX, '$2');
2040 t.SECS[i].HAS_HIGHLIGHT = false;
2043 t.SEARCH_HIGHLIGHT_ON = false;
2050 highlightHeadline: function(h)
2052 var i = parseInt(h);
2053 if(this.PLAIN_VIEW == this.VIEW && this.MOUSE_HINT) {
2054 if('underline' == this.MOUSE_HINT)
2055 this.SECS[i].HEADING.style.borderBottom = "1px dashed #666666";
2057 this.SECS[i].HEADING.style.backgroundColor = this.MOUSE_HINT;
2061 unhighlightHeadline: function(h)
2063 var i = parseInt(h);
2064 if('underline' == this.MOUSE_HINT) {
2065 this.SECS[i].HEADING.style.borderBottom = "";
2068 this.SECS[i].HEADING.style.backgroundColor = "";
2071 showHelp: function ()
2074 if (t.READING) { t.endRead(); }
2075 else if(t.MESSAGING) { t.removeWarning(); }
2076 /* This is an OrgMode version of the table. Turn on orgtbl-mode in
2077 this buffer, edit the table, then press C-c C-c with the cursor
2078 in the table. The table will then be translated an inserted below.
2079 #+ORGTBL: SEND Shortcuts orgtbl-to-generic :splice t :skip 2 :lstart "\t+'<tr>" :lend "</tr>'" :fmt (1 "<td><code><b>%s</b></code></td>" 2 "<td>%s</td>") :hline "\t+'</tbody><tbody>'"
2081 |--------------+---------------------------------------------------------|
2082 | ? / ¿ | show this help screen |
2083 |--------------+---------------------------------------------------------|
2084 | | <b>Moving around</b> |
2085 | n / p | goto the next / previous section |
2086 | N / P | goto the next / previous sibling |
2087 | t / E | goto the first / last section |
2088 | g | goto section... |
2089 | u | go one level up (parent section) |
2090 | i / C | show table of contents / tags index |
2091 | b / B | go back to last / forward to next visited section. |
2092 | h / H | go to main index in this directory / link HOME page |
2093 |--------------+---------------------------------------------------------|
2095 | m / x | toggle the view mode between info and plain / slides |
2096 | f / F | fold current section / whole document (plain view only) |
2097 |--------------+---------------------------------------------------------|
2098 | | <b>Searching</b> |
2099 | s / r | search forward / backward.... |
2100 | S / R | search again forward / backward |
2102 | c | clear search-highlight |
2103 |--------------+---------------------------------------------------------|
2105 | l / L / U | display HTML link / Org link / Plain-URL |
2106 | v / V | scroll down / up |
2109 t.HELPING = t.HELPING ? 0 : 1;
2111 t.LAST_VIEW_MODE = t.VIEW;
2112 if(t.PLAIN_VIEW == t.VIEW) t.infoView(true);
2113 t.WINDOW.innerHTML = 'Press any key or <a href="javascript:org_html_manager.showHelp();">click here</a> to proceed.'
2114 +'<h2>Keyboard Shortcuts</h2>'
2115 +'<table cellpadding="3" rules="groups" frame="hsides" style="caption-side:bottom;margin:20px;border-style:none;" border="0";>'
2116 +'<caption><small>org-info.js, v.###VERSION###</small></caption>'
2118 // BEGIN RECEIVE ORGTBL Shortcuts
2119 +'<tr><td><code><b>? / ¿</b></code></td><td>show this help screen</td></tr>'
2121 +'<tr><td><code><b></b></code></td><td><b>Moving around</b></td></tr>'
2122 +'<tr><td><code><b>n / p</b></code></td><td>goto the next / previous section</td></tr>'
2123 +'<tr><td><code><b>N / P</b></code></td><td>goto the next / previous sibling</td></tr>'
2124 +'<tr><td><code><b>t / E</b></code></td><td>goto the first / last section</td></tr>'
2125 +'<tr><td><code><b>g</b></code></td><td>goto section...</td></tr>'
2126 +'<tr><td><code><b>u</b></code></td><td>go one level up (parent section)</td></tr>'
2127 +'<tr><td><code><b>i / C</b></code></td><td>show table of contents / tags index</td></tr>'
2128 +'<tr><td><code><b>b / B</b></code></td><td>go back to last / forward to next visited section.</td></tr>'
2129 +'<tr><td><code><b>h / H</b></code></td><td>go to main index in this directory / link HOME page</td></tr>'
2131 +'<tr><td><code><b></b></code></td><td><b>View</b></td></tr>'
2132 +'<tr><td><code><b>m / x</b></code></td><td>toggle the view mode between info and plain / slides</td></tr>'
2133 +'<tr><td><code><b>f / F</b></code></td><td>fold current section / whole document (plain view only)</td></tr>'
2135 +'<tr><td><code><b></b></code></td><td><b>Searching</b></td></tr>'
2136 +'<tr><td><code><b>s / r</b></code></td><td>search forward / backward....</td></tr>'
2137 +'<tr><td><code><b>S / R</b></code></td><td>search again forward / backward</td></tr>'
2138 +'<tr><td><code><b>o</b></code></td><td>occur-mode</td></tr>'
2139 +'<tr><td><code><b>c</b></code></td><td>clear search-highlight</td></tr>'
2141 +'<tr><td><code><b></b></code></td><td><b>Misc</b></td></tr>'
2142 +'<tr><td><code><b>l / L / U</b></code></td><td>display HTML link / Org link / Plain-URL</td></tr>'
2143 +'<tr><td><code><b>v / V</b></code></td><td>scroll down / up</td></tr>'
2144 +'<tr><td><code><b>W</b></code></td><td>Print</td></tr>'
2145 // END RECEIVE ORGTBL Shortcuts
2147 +'</table><br />Press any key or <a href="javascript:org_html_manager.showHelp();">click here</a> to proceed.';
2148 window.scrollTo(0, 0);
2151 if(t.PLAIN_VIEW == t.LAST_VIEW_MODE) {
2154 else if(t.SLIDE_VIEW == t.LAST_VIEW_MODE) {
2157 t.showSection(t.NODE.IDX);
2162 showTagsIndex: function ()
2165 if (t.READING) { t.endRead(); }
2166 else if(t.MESSAGING) { t.removeWarning(); }
2167 t.HELPING = t.HELPING ? 0 : 1;
2169 t.LAST_VIEW_MODE = t.VIEW;
2170 if(t.PLAIN_VIEW == t.VIEW) t.infoView(true);
2171 if(null == t.TAGS_INDEX) {
2172 t.TAGS_INDEX = 'Press any key or <a href="javascript:org_html_manager.showTagsIndex();">click here</a> to proceed.'
2173 +'<br /><br />Click the headlines to expand the contents.'
2174 +'<h2>Index of Tags</h2>';
2175 for(var i = 0; i < t.SORTED_TAGS.length; ++i) {
2176 var tag = t.SORTED_TAGS[i];
2177 var fid = 'org-html-manager-sorted-tags-' + tag;
2178 t.TAGS_INDEX += '<a href="javascript:OrgNode.toggleElement(document.getElementById(\''
2179 + fid + '\'));"><h3>' + tag + '</h3></a>'
2180 + '<div id="' + fid + '" style="visibility:hidden;display:none;"><ul>';
2181 for(var j = 0; j < t.TAGS[tag].length; ++j) {
2182 var idx = t.TAGS[tag][j];
2183 t.TAGS_INDEX += '<li><a href="javascript:org_html_manager.showSection('
2185 + t.SECS[idx].HEADING.innerHTML +'</a></li>';
2187 t.TAGS_INDEX += '</ul></div>';
2190 t.TAGS_INDEX += '<br />Press any key or <a href="javascript:org_html_manager.showTagsIndex();">click here</a> to proceed.';
2192 t.WINDOW.innerHTML = t.TAGS_INDEX;
2193 window.scrollTo(0, 0);
2196 if(t.PLAIN_VIEW == t.LAST_VIEW_MODE) {
2199 else if(t.SLIDE_VIEW == t.LAST_VIEW_MODE) {
2202 t.showSection(t.NODE.IDX);
2214 * @param name Name of the hook to be executed. One of the indicies in the
2215 * <code>OrgHtmlManager.HOOKS</code> variable.
2216 * @param args The arguments to be passed to the hook function.
2217 * E.g. <code>{an: "object"}</code> or <code>["array"]</code>.
2218 * The first argument passed to the hook is the OrgHtmlManager
2221 runHooks: function(name, args)
2223 if(this.HOOKS.run_hooks && this.HOOKS[name]) {
2224 for(var i=0; i<this.HOOKS[name].length; ++i) {
2225 this.HOOKS[name][i](this, args);
2232 * If <code>this.HOOKS[name]</code> is not an array, it is created.
2233 * @param name Name of the hook, i.e. the index in <code>this.HOOKS</code>.
2234 * @param func The function object.
2236 addHook: function(name, func)
2238 if('run_hooks' != name) {
2239 this.HOOKS[name].push(func);
2245 * @param name Name of the hook, i.e. the index in <code>this.HOOKS</code>.
2246 * @param func The function object to be removed from the hook. JavaScript
2247 * considers two functions written the same way identical.
2249 removeHook: function(name, func)
2251 if(this.HOOKS[name]) {
2252 for(var i = this.HOOKS[name].length - 1; i >= 0; --i) {
2253 if(this.HOOKS[name][i] == func) {
2254 this.HOOKS[name].splice(i, 1);
2268 function OrgHtmlManagerKeyEvent (e)
2271 if (!e) e = window.event;
2272 if (e.which) c = e.which;
2273 else if (e.keyCode) c = e.keyCode;
2275 if(e.ctrlKey) return;
2277 var s = String.fromCharCode(c);
2279 org_html_manager.CONSOLE_INPUT.value = org_html_manager.CONSOLE_INPUT.value + s;
2281 org_html_manager.CONSOLE_INPUT.value = org_html_manager.CONSOLE_INPUT.value + s.toLowerCase();
2283 org_html_manager.getKey();
2288 * Wait for document.body to be loaded and call org_html_manager.init().
2289 * In Opera document.body is true, even if not loaded (try with big big
2290 * file). This case is handled by the OrgHtmlManager class itself.
2292 function OrgHtmlManagerLoadCheck()
2294 org_html_manager.init();