home *** CD-ROM | disk | FTP | other *** search
/ Online Praxis 1998 March / Image.iso / CD-ROM / NETSCAPE / CCK / INSTBLDR.Z / nav40l.z / System.js < prev    next >
Encoding:
JavaScript  |  1997-10-22  |  23.6 KB  |  800 lines

  1. /* ==================================================================
  2.  
  3. FILE:   System.js
  4.  
  5. DESCR:  System class for Netscape Help implementation.
  6.  
  7. NOTES:  
  8.  
  9. ================================================================== */
  10.  
  11. // Dev. switches.
  12.  
  13. var TRACE           = false
  14.  
  15. var ASSERT          = true
  16.  
  17. var ERR_DLGS        = true
  18.  
  19. var ERRS_TO_CONSOLE = false
  20.  
  21.  
  22.  
  23. // "Constants."
  24.  
  25. var VERSION         = "2.0-970514"
  26.  
  27. var LAYERED_TOPICS  = false
  28.  
  29. var JAVA_DEPENDENT  = false
  30.  
  31. var STAMP_CONSOLE   = false
  32.  
  33. var OK_NAV_VERSIONS = ".4."
  34.  
  35. var CHECK_HREFS     = false
  36.  
  37. var CONTENTS        = "CntTool.htm"
  38.  
  39. var INDEX           = "IdxTool.htm"
  40.  
  41. var SEARCH          = "SrhTool.htm"
  42.  
  43. var NAVUI           = "NavUI.htm"
  44.  
  45. var TOOLUI          = "ToolUI.htm"
  46.  
  47. var STATUS          = "Status.htm"
  48.  
  49. var MESSAGE_BGCOLOR = "#fafad2"
  50.  
  51. var TOOL_BGCOLOR    = "#99ccff"
  52.  
  53.  
  54.  
  55. //trace( "System.js" )
  56.  
  57.  
  58.  
  59. // Runtime error handling.
  60.  
  61. // window.onerror = errHandler
  62.  
  63.  
  64.  
  65. // Version stamp.
  66.  
  67. if ( STAMP_CONSOLE && navigator.javaEnabled() ) {
  68.  
  69.    java.lang.System.out.println( "System.js, version " + VERSION )
  70.  
  71.    java.lang.System.out.println( "Client: " + navigator.appVersion )
  72.  
  73. }
  74.  
  75.  
  76.  
  77. /*
  78.  
  79. DESCR:   Handles the onhelp event.
  80.  
  81. PARAMS:  URL  The URL to load.
  82.  
  83. RETURNS: 
  84.  
  85. NOTES:   
  86.  
  87. */
  88.  
  89. function onHelpHandler( URL )
  90.  
  91. {
  92.  
  93.    //trace( "onHelpHandler(" + URL + ")" )
  94.  
  95.    //alert( "onHelpHandler(" + URL + ")" )
  96.  
  97.  
  98.  
  99.    systemObj.loadTopic( URL, false )
  100.  
  101. }
  102.  
  103.  
  104.  
  105. /*
  106.  
  107. DESCR:   Traces execution to the console.
  108.  
  109. PARAMS:  msg  The trace text.
  110.  
  111. RETURNS: 
  112.  
  113. NOTES:   
  114.  
  115. */
  116.  
  117. function trace( msg )
  118.  
  119. {
  120.  
  121.    if ( TRACE ) java.lang.System.out.println( "System: " + msg )
  122.  
  123. }
  124.  
  125.  
  126.  
  127. // Create system object.
  128.  
  129. var systemObj = new system( JAVA_DEPENDENT, OK_NAV_VERSIONS )
  130.  
  131. assert( ( typeof( systemObj ) == "object" ), SYS_CONSTRUCT )
  132.  
  133.  
  134.  
  135. /*
  136.  
  137. DESCR:   Help implementation system class.
  138.  
  139. PARAMS:  bJavaDependent  Pass true if the system is Java dependent,
  140.  
  141.                          false if not.
  142.  
  143.          OKNavVersions   String representing valid versions of Navigator.
  144.  
  145. RETURNS: 
  146.  
  147. NOTES:   
  148.  
  149. */
  150.  
  151. function system( bJavaDependent, OKNavVersions )
  152.  
  153. {
  154.  
  155.    //trace( "system constructor" )
  156.  
  157.  
  158.  
  159.    this.backStack    = new stack()
  160.  
  161.    this.forwardStack = new stack()
  162.  
  163.  
  164.  
  165.    this.navVersion
  166.  
  167.    this.topic
  168.  
  169.    this.contents
  170.  
  171.  
  172.  
  173.    //this.aSysSecWnds = new Array()  // Sys-owned secondary windows.
  174.  
  175.  
  176.  
  177.    this.currentTool       = CONTENTS  // Set default tool.
  178.  
  179.    this.bIdxTitlesPageUp  = false
  180.  
  181.    this.currentSubsystem  = ""
  182.  
  183.    this.visibleLayerIdx   = ""
  184.  
  185.  
  186.  
  187.    this.bToolUIloaded   = false
  188.  
  189.    this.bNavUIloaded    = false
  190.  
  191.    this.bContentsLoaded = false
  192.  
  193.    this.bIndexLoaded    = false
  194.  
  195.    this.bStarted        = false
  196.  
  197.  
  198.  
  199.    this.bNewSubsystem = false
  200.  
  201.  
  202.  
  203.    this.preproc           = preproc
  204.  
  205.    this.componentCallback = componentCallback
  206.  
  207.    this.idxTitlesUp       = idxTitlesUp
  208.  
  209.    this.loadTopic         = loadTopic
  210.  
  211.    this.newSubsystem      = newSubsystem
  212.  
  213.    this.exit              = exit
  214.  
  215.    this.print             = print
  216.  
  217.    this.find              = find
  218.  
  219.    this.back              = back
  220.  
  221.    this.forward           = forward
  222.  
  223.    //this.openSecWnd        = openSecWnd
  224.  
  225.    this.loadTool          = loadTool
  226.  
  227.    this.setToolButton     = setToolButton
  228.  
  229.    this.msg               = msg
  230.  
  231.    this.manageLayers      = manageLayers
  232.  
  233.    this.badURLerror       = badURLerror
  234.  
  235.  
  236.  
  237.    this.componentsReadyEvt = componentsReadyEvt
  238.  
  239.    this.loadEvt            = loadEvt
  240.  
  241.    this.unloadEvt          = unloadEvt
  242.  
  243.  
  244.  
  245.    this.stashPersistentData  = stashPersistentData
  246.  
  247.    this.snatchPersistentData = snatchPersistentData
  248.  
  249.  
  250.  
  251.    // Preprocessing.
  252.  
  253.    if ( !this.preproc( bJavaDependent, OKNavVersions ) ) {
  254.  
  255.       return
  256.  
  257.    }
  258.  
  259.  
  260.  
  261.    // Load components.
  262.  
  263.    top.StatusFrame.location.replace( STATUS )
  264.  
  265.    top.ToolUIFrame.location.replace( TOOLUI )
  266.  
  267.    top.NavFrame.location.replace( NAVUI )
  268.  
  269.    top.ToolFrame.location.replace( this.currentTool )
  270.  
  271. }
  272.  
  273.  
  274.  
  275.    /*
  276.  
  277.    DESCR:   Pre-Help processing.
  278.  
  279.    PARAMS:  bJavaDependent  Pass true if the system is Java dependent,
  280.  
  281.                             false if not.
  282.  
  283.             OKNavVersions   String representing valid versions of Navigator.
  284.  
  285.    RETURNS: 
  286.  
  287.    NOTES:   
  288.  
  289.    */
  290.  
  291.    function preproc( bJavaDependent, OKNavVersions )
  292.  
  293.    {
  294.  
  295.       //trace( "preproc()" )
  296.  
  297.       
  298.  
  299.       // Make sure Java is enabled if needed. Otherwise, abort.
  300.  
  301.       if ( bJavaDependent && !navigator.javaEnabled() ) {
  302.  
  303.          this.msg( NO_JAVA_ERR_MSG, "" )
  304.  
  305.          return false
  306.  
  307.       }
  308.  
  309.  
  310.  
  311.       // Validate version of navigator. Render in ".integer." form.
  312.  
  313.       var version = navigator.appVersion
  314.  
  315.       this.navVersion =
  316.  
  317.          "." + version.substring( 0, ( version.indexOf( "." ) + 1 ) )
  318.  
  319.       if ( OKNavVersions.indexOf( this.navVersion ) == -1 ) {
  320.  
  321.          this.msg( WRONG_NAV_VER_ERR_MSG, "" )
  322.  
  323.          return false
  324.  
  325.       }
  326.  
  327.  
  328.  
  329.       return true
  330.  
  331.    }
  332.  
  333.  
  334.  
  335.    /*
  336.  
  337.    DESCR:   Tracks component loading.
  338.  
  339.    PARAMS:  componentName  The document-name of the component.
  340.  
  341.    RETURNS: 
  342.  
  343.    NOTES:   Components call this method on load. Triggers ready
  344.  
  345.             event when all loaded.
  346.  
  347.    */
  348.  
  349.    function componentCallback( componentName )
  350.  
  351.    {
  352.  
  353.       //trace( "componentCallback(" + componentName + ")" )
  354.  
  355.       //alert( "componentCallback(" + componentName + ")" )
  356.  
  357.  
  358.  
  359.       // Track component loading.
  360.  
  361.  
  362.  
  363.       // Note: for some reason, can't write to status frame until Contents
  364.  
  365.       // is loaded, so we do this later.
  366.  
  367.       //if ( componentName == STATUS ) top.StatusFrame.setStatusWait()
  368.  
  369.  
  370.  
  371.       if ( componentName == TOOLUI ) this.bToolUIloaded = true
  372.  
  373.  
  374.  
  375.       if ( componentName == NAVUI ) this.bNavUIloaded = true
  376.  
  377.  
  378.  
  379.       if ( componentName == CONTENTS ) {
  380.  
  381.  
  382.  
  383.          // Keep house.
  384.  
  385.          top.StatusFrame.setStatusWait()
  386.  
  387.          top.ToolUIFrame.bDisableBtnBar = false
  388.  
  389.          this.bContentsLoaded = true
  390.  
  391.          this.bIndexLoaded = false
  392.  
  393.  
  394.  
  395.          // Create a Contents object.
  396.  
  397.          this.contents = new top.ToolFrame.contents( TOOL_BGCOLOR )
  398.  
  399.          assert( ( typeof( this.contents ) == "object" ), CNT_CONSTRUCT )
  400.  
  401.  
  402.  
  403.          // If this is not a system load and we're just changing to the
  404.  
  405.          // Contents tool, set the Content's dataset and update. Otherwise,
  406.  
  407.          // this will happen when a topic is loaded.
  408.  
  409.          if ( this.bStarted ) {
  410.  
  411.            this.contents.setDataset( this.currentSubsystem )
  412.  
  413.            this.contents.updateTree( this.topic.URL )
  414.  
  415.  
  416.  
  417.            top.StatusFrame.setStatusClear()
  418.  
  419.          }
  420.  
  421.       }
  422.  
  423.  
  424.  
  425.       if ( componentName == INDEX ) {
  426.  
  427.          top.ToolUIFrame.bDisableBtnBar = false
  428.  
  429.          this.bIndexLoaded = true
  430.  
  431.          this.bContentsLoaded = false
  432.  
  433.  
  434.  
  435.          if ( this.bStarted ) top.StatusFrame.setStatusClear()
  436.  
  437.       }
  438.  
  439.  
  440.  
  441.       // Set the blender button down for the current tool.
  442.  
  443.       if ( componentName == TOOLUI ) {
  444.  
  445.          this.setToolButton( ( this.currentTool == CONTENTS ? 0 : 1 ), 1 )
  446.  
  447.       }
  448.  
  449.  
  450.  
  451.       // Get moving if we're ready, but not already underway.
  452.  
  453.       if ( !this.bStarted &&
  454.  
  455.            this.bToolUIloaded && this.bNavUIloaded &&
  456.  
  457.            ( this.bContentsLoaded || this.bIndexLoaded ) ) {
  458.  
  459.          this.bStarted = true
  460.  
  461.          this.componentsReadyEvt()   
  462.  
  463.       }
  464.  
  465.    }
  466.  
  467.  
  468.  
  469.    /*
  470.  
  471.    DESCR:   Handles components ready "event."
  472.  
  473.    PARAMS:  
  474.  
  475.    RETURNS: 
  476.  
  477.    NOTES:   
  478.  
  479.    */
  480.  
  481.    function componentsReadyEvt()
  482.  
  483.    {
  484.  
  485.       //trace( "componentsReadyEvt()" )
  486.  
  487.  
  488.  
  489.       // Set onhelp handler.
  490.  
  491.       top.setOnhelpHandler( "onHelpHandler" )
  492.  
  493.    }
  494.  
  495.  
  496.  
  497.    /*
  498.  
  499.    DESCR:   Enables external state-setting of the tool UI button bar.
  500.  
  501.    PARAMS:  buttonIdx  Identifies the button on the bar.
  502.  
  503.             newState   The state to set.
  504.  
  505.    RETURNS: 
  506.  
  507.    NOTES:   
  508.  
  509.    */
  510.  
  511.    function setToolButton( buttonIdx, newState )
  512.  
  513.    {
  514.  
  515.       //trace( "setToolButton" )
  516.  
  517.  
  518.  
  519.       assert( defined( top.ToolUIFrame.btnBar ), TOOLUI )
  520.  
  521.       if ( defined( top.ToolUIFrame.btnBar ) ) {
  522.  
  523.  
  524.  
  525.          // Set.
  526.  
  527.          with ( top.ToolUIFrame.btnBar.aButtons[ buttonIdx ] ) {
  528.  
  529.             setState( newState )
  530.  
  531.             bOn = true
  532.  
  533.          }
  534.  
  535.       }
  536.  
  537.    }
  538.  
  539.  
  540.  
  541.    /*
  542.  
  543.    DESCR:   onload handler.
  544.  
  545.    PARAMS:  
  546.  
  547.    RETURNS: 
  548.  
  549.    NOTES:   
  550.  
  551.    */
  552.  
  553.    function loadEvt()
  554.  
  555.    {
  556.  
  557.       //trace( "loadEvt()" )
  558.  
  559.       //alert( "loadEvt()" )
  560.  
  561.  
  562.  
  563.       // Snatch important data for persistence on reload due to window resizing.
  564.  
  565.       this.snatchPersistentData()
  566.  
  567.    }
  568.  
  569.  
  570.  
  571.    /*
  572.  
  573.    DESCR:   onunload handler.
  574.  
  575.    PARAMS:  
  576.  
  577.    RETURNS: 
  578.  
  579.    NOTES:   
  580.  
  581.    */
  582.  
  583.    function unloadEvt()
  584.  
  585.    {
  586.  
  587.       //trace( "unloadEvt()" )
  588.  
  589.       //alert( "unloadEvt()" )
  590.  
  591.  
  592.  
  593.       // Stash important data for persistence on reload due to window resizing.
  594.  
  595.       this.stashPersistentData()
  596.  
  597.  
  598.  
  599.       // Clean up topic (topic-owned secondary windows, etc.).
  600.  
  601.       if ( defined( this.topic ) ) this.topic.destruct()
  602.  
  603.  
  604.  
  605.       // Close any system-owned secondary windows.
  606.  
  607.       //for ( var i = 0; i < this.aSysSecWnds.length; i++ ) {
  608.  
  609.       //   if ( defined( this.aSysSecWnds[ i ] ) ) this.aSysSecWnds[ i ].close()
  610.  
  611.       //}
  612.  
  613.    }
  614.  
  615.  
  616.  
  617.    /*
  618.  
  619.    DESCR:   Stores data needed to maintain state on reload due to resize.
  620.  
  621.    PARAMS:  
  622.  
  623.    RETURNS: 
  624.  
  625.    NOTES:   
  626.  
  627.    */
  628.  
  629.    function stashPersistentData()
  630.  
  631.    {
  632.  
  633.       //trace( "stashPersistentData" )
  634.  
  635.  
  636.  
  637.       if ( defined( top.aPersistentData ) ) {
  638.  
  639.          var i = 0
  640.  
  641.          top.aPersistentData[ i++ ] = this.currentTool
  642.  
  643.          top.aPersistentData[ i++ ] = this.forwardStack
  644.  
  645.          top.aPersistentData[ i++ ] = this.backStack
  646.  
  647.          //this.topic
  648.  
  649.          //this.visibleLayerIdx
  650.  
  651.       }
  652.  
  653.    }
  654.  
  655.  
  656.  
  657.    /*
  658.  
  659.    DESCR:   Retrieves data needed to maintain state on reload due to resize.
  660.  
  661.    PARAMS:  
  662.  
  663.    RETURNS: 
  664.  
  665.    NOTES:   
  666.  
  667.    */
  668.  
  669.    function snatchPersistentData()
  670.  
  671.    {
  672.  
  673.       //trace( "snatchPersistentData" )
  674.  
  675.  
  676.  
  677.       if ( defined( top.aPersistentData[ 0 ] ) ) {
  678.  
  679.          var i = 0
  680.  
  681.          this.currentTool  = top.aPersistentData[ i++ ]
  682.  
  683.          this.forwardStack = top.aPersistentData[ i++ ] 
  684.  
  685.          this.backStack    = top.aPersistentData[ i++ ]
  686.  
  687.       }
  688.  
  689.    }
  690.  
  691.  
  692.  
  693.    /*
  694.  
  695.    DESCR:   Loads the Contents, Index, or Find tool.
  696.  
  697.    PARAMS:  toolName  The document-name of the tool.
  698.  
  699.    RETURNS: 
  700.  
  701.    NOTES:   
  702.  
  703.    */
  704.  
  705.    function loadTool( toolName )
  706.  
  707.    {
  708.  
  709.       //trace( "loadTool(" + toolName + ")" )
  710.  
  711.  
  712.  
  713.       assert( ( toolName == CONTENTS ||
  714.  
  715.                 toolName == INDEX ||
  716.  
  717.                 toolName == SEARCH ), TOOLNAME )
  718.  
  719.  
  720.  
  721.       this.currentTool = toolName
  722.  
  723.  
  724.  
  725.       // Contents tool.
  726.  
  727.       if ( toolName == CONTENTS && !this.bContentsLoaded ) {
  728.  
  729.  
  730.  
  731.          // Keep house.
  732.  
  733.          top.StatusFrame.setStatusWait()
  734.  
  735.          top.ToolUIFrame.bDisableBtnBar = true
  736.  
  737.  
  738.  
  739.          top.ToolFrame.location.replace( toolName )
  740.  
  741.       }
  742.  
  743.  
  744.  
  745.       // Index tool.
  746.  
  747.       else if ( toolName == INDEX && !this.bIndexLoaded ) {
  748.  
  749.  
  750.  
  751.          // Keep house.
  752.  
  753.          top.StatusFrame.setStatusWait()
  754.  
  755.          top.ToolUIFrame.bDisableBtnBar = true
  756.  
  757.  
  758.  
  759.          top.ToolFrame.location.replace( toolName )
  760.  
  761.       }
  762.  
  763.  
  764.  
  765.       // Search tool.
  766.  
  767.       else if ( toolName == SEARCH ) {
  768.  
  769.  
  770.  
  771.          // We are using native find functionality in lieu of Search tool.
  772.  
  773.          // Be sure to invoke Find against the topic frame.
  774.  
  775.          top.TopicFrame.find()
  776.  
  777.       }
  778.  
  779.    }
  780.  
  781.  
  782.  
  783.    /*
  784.  
  785.    DESCR:   Closes the Help window.
  786.  
  787.    PARAMS:  
  788.  
  789.    RETURNS: 
  790.  
  791.    NOTES:   
  792.  
  793.    */
  794.  
  795.    function exit()
  796.  
  797.    {
  798.  
  799.       //trace( "exit()" )
  800.  
  801.  
  802.  
  803.       // Close frameset.
  804.  
  805.       top.close()
  806.  
  807.    }
  808.  
  809.  
  810.  
  811.    /*
  812.  
  813.    DESCR:   Moves back in Help history.
  814.  
  815.    PARAMS:  
  816.  
  817.    RETURNS: 
  818.  
  819.    NOTES:   Presumes button is disabled on empty stack.
  820.  
  821.    */
  822.  
  823.    function back()
  824.  
  825.    {
  826.  
  827.       //trace( "back()" )
  828.  
  829.  
  830.  
  831.       // Since the Index's titles page may be in the topic frame, but not
  832.  
  833.       // part of history, we don't really wan't to go Back. Just restore
  834.  
  835.       // the current topic without adding it to history.
  836.  
  837.       if ( this.bIdxTitlesPageUp ) {
  838.  
  839.          this.loadTopic( this.topic.URL, false )
  840.  
  841.          return
  842.  
  843.       }
  844.  
  845.  
  846.  
  847.       assert( !this.backStack.isEmpty(), BACK_STACK )
  848.  
  849.       this.forwardStack.push( this.topic.URL )
  850.  
  851.       this.loadTopic( this.backStack.pop(), true )
  852.  
  853.    }
  854.  
  855.  
  856.  
  857.    /*
  858.  
  859.    DESCR:   Moves forward in Help history.
  860.  
  861.    PARAMS:  
  862.  
  863.    RETURNS: 
  864.  
  865.    NOTES:   Presumes button is disabled on empty stack.
  866.  
  867.    */
  868.  
  869.    function forward()
  870.  
  871.    {
  872.  
  873.       //trace( "forward()" )
  874.  
  875.  
  876.  
  877.       assert( !this.forwardStack.isEmpty(), FORWARD_STACK )
  878.  
  879.       this.backStack.push( this.topic.URL )
  880.  
  881.       this.loadTopic( this.forwardStack.pop(), true )
  882.  
  883.    }
  884.  
  885.  
  886.  
  887.    /*
  888.  
  889.    DESCR:   Tracks the Index's topic titles page in the topic window.
  890.  
  891.    PARAMS:  
  892.  
  893.    RETURNS: 
  894.  
  895.    NOTES:   
  896.  
  897.    */
  898.  
  899.    function idxTitlesUp()
  900.  
  901.    {
  902.  
  903.       //trace ( "idxTitlesUp()" )
  904.  
  905.       
  906.  
  907.       this.bIdxTitlesPageUp = true
  908.  
  909.  
  910.  
  911.       // The Index titles page is not part of the topics history, so make
  912.  
  913.       // sure that Forward is disabled and Back is enabled.
  914.  
  915.       assert( defined( top.NavFrame.btnBar ), NAV_BAR )
  916.  
  917.       if ( defined( top.NavFrame.btnBar ) ) {
  918.  
  919.          top.NavFrame.btnBar.aButtons[ 0 ].enable( true )
  920.  
  921.          top.NavFrame.btnBar.aButtons[ 1 ].enable( false )
  922.  
  923.       }
  924.  
  925.    }
  926.  
  927.  
  928.  
  929.    /*
  930.  
  931.    DESCR:   Handles tasks when the Help subsystem changes.
  932.  
  933.    PARAMS:  newSubsystem  A simple filename representing the subsystem
  934.  
  935.                           (the topic filename).
  936.  
  937.    RETURNS: 
  938.  
  939.    NOTES:   
  940.  
  941.    */
  942.  
  943.    function newSubsystem( newSubsystem )
  944.  
  945.    {
  946.  
  947.       //trace( "newSubsystem('" + newSubsystem + "')" )
  948.  
  949.       //alert( "newSubsystem('" + newSubsystem + "')" )
  950.  
  951.  
  952.  
  953.       assert( ( newSubsystem.toLowerCase().indexOf( ".htm" ) > -1 ),
  954.  
  955.               SUBSYS_VALUE + newSubsystem )
  956.  
  957.  
  958.  
  959.       // Track the current subsystem.
  960.  
  961.       this.currentSubsystem = newSubsystem
  962.  
  963.  
  964.  
  965.       // Reinitialize the visible layer index, since nothing is visible yet.
  966.  
  967.       this.visibleLayerIdx = ""
  968.  
  969.  
  970.  
  971.       // Load the new header.
  972.  
  973.       top.HeaderFrame.location.replace( this.topic.headerURL )
  974.  
  975.  
  976.  
  977.       // Set the Contents tool's dataset.
  978.  
  979.       if ( this.currentTool == CONTENTS ) {
  980.  
  981.          this.contents.setDataset( newSubsystem )
  982.  
  983.       }
  984.  
  985.    }
  986.  
  987.  
  988.  
  989.    /*
  990.  
  991.    DESCR:   Loads a topic.
  992.  
  993.    PARAMS:  URL           The non-nethelp version of the URL.
  994.  
  995.             bHistoryLoad  true if this is a load due to Back or Forward;
  996.  
  997.                           false, otherwise.
  998.  
  999.    RETURNS: 
  1000.  
  1001.    NOTES:   
  1002.  
  1003.    */
  1004.  
  1005.    function loadTopic( URL, bHistoryLoad )
  1006.  
  1007.    {
  1008.  
  1009.       //trace( "loadTopic(" + URL + ")" )
  1010.  
  1011.  
  1012.  
  1013.       assert( ( URL.toLowerCase().indexOf( ".htm" ) > -1 ), URL_VALUE + URL )
  1014.  
  1015.  
  1016.  
  1017.       // Update Index titles page flag. If we are loading a topic, it can't
  1018.  
  1019.       // be the URL in the topic window.
  1020.  
  1021.       this.bIdxTitlesPageUp = false
  1022.  
  1023.  
  1024.  
  1025.       // Keep house if there is an existing topic...
  1026.  
  1027.       if ( defined( this.topic ) ) {
  1028.  
  1029.  
  1030.  
  1031.          // Track as history, if this is _not_ a history load, and if we are
  1032.  
  1033.          // not reloading the same URL for some (good) reason. Note that
  1034.  
  1035.          // forward stack should be cleared.
  1036.  
  1037.          if ( !bHistoryLoad && ( this.topic.URL != URL ) ) {
  1038.  
  1039.             this.backStack.push( this.topic.URL )
  1040.  
  1041.             this.forwardStack.clear()
  1042.  
  1043.          }
  1044.  
  1045.  
  1046.  
  1047.          // "Destruct" the current topic.
  1048.  
  1049.          this.topic.destruct()
  1050.  
  1051.       } 
  1052.  
  1053.  
  1054.  
  1055.       // See if we need to change subsystems.
  1056.  
  1057.       var bNewSubsystem =
  1058.  
  1059.          ( makeSimpleFilename( URL ) != this.currentSubsystem ? true : false )
  1060.  
  1061.  
  1062.  
  1063.       // If we're loading a new topic file, set the wait indicator.
  1064.  
  1065.       if ( bNewSubsystem ) top.StatusFrame.setStatusWait()
  1066.  
  1067.  
  1068.  
  1069.       // Create new topic object. Must happen before updating subsystem.
  1070.  
  1071.       this.topic = new helpTopic( URL )
  1072.  
  1073.       assert( ( typeof( this.topic ) == "object" ), TOPIC_CONSTRUCT )
  1074.  
  1075.  
  1076.  
  1077.       // Update current subsystem. Must happen before updating Contents tree
  1078.  
  1079.       // or managing layers.
  1080.  
  1081.       if ( bNewSubsystem ) this.newSubsystem( makeSimpleFilename( URL ) )
  1082.  
  1083.  
  1084.  
  1085.       // Enable/disable history buttons.
  1086.  
  1087.       assert( defined( top.NavFrame.btnBar ), NAV_BAR )
  1088.  
  1089.       if ( defined( top.NavFrame.btnBar ) ) {
  1090.  
  1091.          var bEnable
  1092.  
  1093.          bEnable = ( this.backStack.isEmpty() ? false : true )
  1094.  
  1095.          top.NavFrame.btnBar.aButtons[ 0 ].enable( bEnable )
  1096.  
  1097.          bEnable = ( this.forwardStack.isEmpty() ? false : true )
  1098.  
  1099.          top.NavFrame.btnBar.aButtons[ 1 ].enable( bEnable )
  1100.  
  1101.       }
  1102.  
  1103.  
  1104.  
  1105.       // Update Contents tree.
  1106.  
  1107.       if ( this.currentTool == CONTENTS ) this.contents.updateTree( URL )
  1108.  
  1109.  
  1110.  
  1111.       // Layers are managed on topic file load (to ensure the layers exist),
  1112.  
  1113.       // but since an anchor "load" in the current URL generates no load
  1114.  
  1115.       // event, we need to call manageLayers() here under such conditions.
  1116.  
  1117.       if ( LAYERED_TOPICS && !this.bNewSubsystem ) this.manageLayers()
  1118.  
  1119.    }
  1120.  
  1121.  
  1122.  
  1123.    /*
  1124.  
  1125.    DESCR:   Manages layers if layered topics is turned on.
  1126.  
  1127.    PARAMS:  
  1128.  
  1129.    RETURNS: 
  1130.  
  1131.    NOTES:   This is called from the topic onload handler, to be sure the
  1132.  
  1133.             document is loaded, or it is called from loadTopic() if the
  1134.  
  1135.             subsystem has not changed, since such a load is via a named
  1136.  
  1137.             anchor and does not raise an onload event. 
  1138.  
  1139.    */
  1140.  
  1141.    function manageLayers()
  1142.  
  1143.    {
  1144.  
  1145.       //trace( "manageLayers()" )
  1146.  
  1147.  
  1148.  
  1149.       if ( !LAYERED_TOPICS ) return
  1150.  
  1151.  
  1152.  
  1153.       // Bail if there are no layered topics.
  1154.  
  1155.       if ( !defined( top.TopicFrame.document.layers[ 0 ] ) ) return
  1156.  
  1157.  
  1158.  
  1159.       // Hide any currently visible topic.
  1160.  
  1161.       if ( this.visibleLayerIdx != "" ) {
  1162.  
  1163.          top.TopicFrame.document.layers[ this.visibleLayerIdx ].hidden = true
  1164.  
  1165.       }
  1166.  
  1167.  
  1168.  
  1169.       // Unhide the topic layer.
  1170.  
  1171.       top.TopicFrame.document.layers[ this.topic.fragmentSpec ].hidden = false
  1172.  
  1173.  
  1174.  
  1175.       // Stash this index.
  1176.  
  1177.       this.visibleLayerIdx = this.topic.fragmentSpec
  1178.  
  1179.    }
  1180.  
  1181.  
  1182.  
  1183.    /*
  1184.  
  1185.    DESCR:   Creates an always-on-top message box with an OK button.
  1186.  
  1187.    PARAMS:  msgText     The message text.
  1188.  
  1189.             msgCaption  The window caption.
  1190.  
  1191.    RETURNS: 
  1192.  
  1193.    NOTES:   The message box is asynchronous, except that the OK button's
  1194.  
  1195.             window.close() will not execute until the JS in the calling
  1196.  
  1197.             window executes. Note that parser can't hack whitespace in
  1198.  
  1199.             third parm of open().
  1200.  
  1201.    */
  1202.  
  1203.    function msg( msgText, msgCaption )
  1204.  
  1205.    {
  1206.  
  1207.       //trace( "msg(" + msgText + ")" )
  1208.  
  1209.  
  1210.  
  1211.       if ( msgCaption == "" ) msgCaption = DEFAULT_MESSAGE_CAPTION
  1212.  
  1213.  
  1214.  
  1215.       var msgDlg =
  1216.  
  1217.          window.open( "", "",
  1218.  
  1219.                       "SCROLLBARS=no,WIDTH=350,HEIGHT=200,SCROLLBARS=yes,ALWAYSRAISED=yes,DEPENDENT=yes,TITLEBAR=no,MENUBAR=no,HOTKEYS=no" )
  1220.  
  1221.  
  1222.  
  1223.       var html
  1224.  
  1225.       html = "<HEAD><TITLE>" + msgCaption +
  1226.  
  1227.              "</TITLE></HEAD><BODY BGCOLOR = " + MESSAGE_BGCOLOR + ">"
  1228.  
  1229.       html += msgText
  1230.  
  1231.       html += "<BR><BR><BR><BR>"
  1232.  
  1233.       html += "<CENTER><FORM METHOD = POST>"
  1234.  
  1235.       html += "<INPUT TYPE = button NAME = 'OK' VALUE = '   " +
  1236.  
  1237.               OK_BTN_LABEL +
  1238.  
  1239.               "   ' ONCLICK = 'window.close()'></FORM></CENTER></BODY>"
  1240.  
  1241.  
  1242.  
  1243.       msgDlg.document.write( html )
  1244.  
  1245.       msgDlg.document.close()
  1246.  
  1247.    }
  1248.  
  1249.  
  1250.  
  1251.    /*
  1252.  
  1253.    DESCR:   Creates a secondary content window.
  1254.  
  1255.    PARAMS:  URL         The content URL.
  1256.  
  1257.             name        The window name.
  1258.  
  1259.             features    The feature string.
  1260.  
  1261.             bSystem     true if the window should be system-owned (i.e.,
  1262.  
  1263.                         window will not be closed when parent topic
  1264.  
  1265.                         closes, only when the system shuts down);
  1266.  
  1267.                         false, if topic-owned.
  1268.  
  1269.             bReturnObj  true if the window object should be returned.
  1270.  
  1271.    RETURNS: Optionally, the window object.
  1272.  
  1273.    NOTES:   
  1274.  
  1275.    */
  1276.  
  1277.    /*
  1278.  
  1279.    function openSecWnd( URL, name, features, bSystem, bReturnObj )
  1280.  
  1281.    {
  1282.  
  1283.       //trace( "openSecWnd(" + URL + ")" )
  1284.  
  1285.  
  1286.  
  1287.       // Create a system- or topic-owned seconadary window.
  1288.  
  1289.       var newWnd
  1290.  
  1291.       var bAlreadyExists = false
  1292.  
  1293.       if ( bSystem ) {
  1294.  
  1295.          newWnd = window.open( URL, name, features )
  1296.  
  1297.  
  1298.  
  1299.          // Add window to list only if it is a new window (user may create
  1300.  
  1301.          // a secondary more than once).
  1302.  
  1303.          for ( var i = 0; i < this.aSysSecWnds.length; i++ ) {
  1304.  
  1305.             if ( this.aSysSecWnds[ i ] == newWnd ) {
  1306.  
  1307.                if ( bReturnObj ) return newWnd
  1308.  
  1309.                else bAlreadyExists = true
  1310.  
  1311.             }
  1312.  
  1313.          }
  1314.  
  1315.          if ( !bAlreadyExists ) { 
  1316.  
  1317.             this.aSysSecWnds[ this.aSysSecWnds.length ] = newWnd
  1318.  
  1319.             if ( bReturnObj ) return newWnd
  1320.  
  1321.          }
  1322.  
  1323.       }
  1324.  
  1325.       else {
  1326.  
  1327.          newWnd = this.topic.addSecondary( URL, name, features )
  1328.  
  1329.          if ( bReturnObj ) return newWnd
  1330.  
  1331.       }
  1332.  
  1333.    }
  1334.  
  1335.    */
  1336.  
  1337.  
  1338.  
  1339.    /*
  1340.  
  1341.    DESCR:   Creates a bad URL type error.
  1342.  
  1343.    PARAMS:  href  The offending href.
  1344.  
  1345.    RETURNS: 
  1346.  
  1347.    NOTES:   
  1348.  
  1349.    */
  1350.  
  1351.    function badURLerror( href )
  1352.  
  1353.    {
  1354.  
  1355.       this.msg( BAD_HREF_ERR_MSG + "<P>" + href, "" )
  1356.  
  1357.    }
  1358.  
  1359.  
  1360.  
  1361.    /*
  1362.  
  1363.    DESCR:   Prints the content in the topic frame.
  1364.  
  1365.    PARAMS:  
  1366.  
  1367.    RETURNS: 
  1368.  
  1369.    NOTES:   
  1370.  
  1371.    */
  1372.  
  1373.    function print()
  1374.  
  1375.    {
  1376.  
  1377.       //trace( "print()" )
  1378.  
  1379.  
  1380.  
  1381.       top.TopicFrame.print()
  1382.  
  1383.    }
  1384.  
  1385.  
  1386.  
  1387. // End class definition: system.
  1388.  
  1389.  
  1390.  
  1391. /*
  1392.  
  1393. DESCR:   Help topic class.
  1394.  
  1395. PARAMS:  URL  The non-nethelp form of the URL.
  1396.  
  1397. RETURNS: 
  1398.  
  1399. NOTES:   
  1400.  
  1401. */
  1402.  
  1403. function helpTopic( URL )
  1404.  
  1405. {
  1406.  
  1407.    //trace( "helpTopic constructor" )
  1408.  
  1409.  
  1410.  
  1411.    assert( ( URL.toLowerCase().indexOf( ".htm" ) > -1 ),
  1412.  
  1413.            TOPIC_URL_VALUE + URL )
  1414.  
  1415.  
  1416.  
  1417.    this.headerURL
  1418.  
  1419.  
  1420.  
  1421.    this.URL = URL
  1422.  
  1423.  
  1424.  
  1425.    this.fragmentSpec = URL.substring( URL.lastIndexOf( "#" ) + 1 )
  1426.  
  1427.    assert( this.fragmentSpec != "", FRAG_SPEC )
  1428.  
  1429.  
  1430.  
  1431.    //this.aSecWnds = new Array()  // Secondary windows.
  1432.  
  1433.  
  1434.  
  1435.    this.destruct         = destruct
  1436.  
  1437.    //this.addSecondary     = addSecondary
  1438.  
  1439.    //this.closeSecondaries = closeSecondaries
  1440.  
  1441.  
  1442.  
  1443.    // Determine header URL by naming convention.
  1444.  
  1445.    var extPos
  1446.  
  1447.    extentionPos = this.URL.indexOf( ".htm" )
  1448.  
  1449.    if ( extentionPos == -1 ) extentionPos = this.URL.indexOf( ".HTM" )
  1450.  
  1451.    assert( ( extentionPos != -1 ), TOPIC_FILENAME )
  1452.  
  1453.    this.headerURL = this.URL.substring( 0, extentionPos ) + "Hdr.htm"
  1454.  
  1455.  
  1456.  
  1457.    // Load URL in the topic frame.
  1458.  
  1459.    top.TopicFrame.location.replace( this.URL )
  1460.  
  1461. }
  1462.  
  1463.  
  1464.  
  1465.    /*
  1466.  
  1467.    DESCR:   Adds a secondary window.
  1468.  
  1469.    PARAMS:  URL       The content URL.
  1470.  
  1471.             name      The window name.
  1472.  
  1473.             features  The feature string.
  1474.  
  1475.    RETURNS: 
  1476.  
  1477.    NOTES:   
  1478.  
  1479.    */
  1480.  
  1481.    /*
  1482.  
  1483.    function addSecondary( URL, name, features )
  1484.  
  1485.    {
  1486.  
  1487.       //trace( "addSecondary()" )
  1488.  
  1489.  
  1490.  
  1491.       var newWnd = window.open( URL, name, features )
  1492.  
  1493.       
  1494.  
  1495.       // Add window to list only if it is a new window (user may
  1496.  
  1497.       // create a secondary more than once).
  1498.  
  1499.       for ( var i = 0; i < this.aSecWnds.length; i++ ) {
  1500.  
  1501.          if ( this.aSecWnds[ i ] == newWnd ) return newWnd
  1502.  
  1503.       }
  1504.  
  1505.       this.aSecWnds[ this.aSecWnds.length ] = newWnd
  1506.  
  1507.  
  1508.  
  1509.       return newWnd
  1510.  
  1511.    }
  1512.  
  1513.    */
  1514.  
  1515.  
  1516.  
  1517.    /*
  1518.  
  1519.    DESCR:   Closes all secondary windows.
  1520.  
  1521.    PARAMS:  
  1522.  
  1523.    RETURNS: 
  1524.  
  1525.    NOTES:   
  1526.  
  1527.    */
  1528.  
  1529.    /*
  1530.  
  1531.    function closeSecondaries()
  1532.  
  1533.    {
  1534.  
  1535.       //trace( "closeSecondaries()" )
  1536.  
  1537.  
  1538.  
  1539.       for ( var i = 0; i < this.aSecWnds.length; i++ ) {
  1540.  
  1541.          if ( defined( this.aSecWnds[ i ] ) ) this.aSecWnds[ i ].close()
  1542.  
  1543.       }
  1544.  
  1545.    }
  1546.  
  1547.    */
  1548.  
  1549.    
  1550.  
  1551.    /*
  1552.  
  1553.    DESCR:   "Destructor."
  1554.  
  1555.    PARAMS:  
  1556.  
  1557.    RETURNS: 
  1558.  
  1559.    NOTES:   
  1560.  
  1561.    */
  1562.  
  1563.    function destruct()
  1564.  
  1565.    {
  1566.  
  1567.       //trace( "helpTopic destruct()" )
  1568.  
  1569.  
  1570.  
  1571.       // Close any secondary windows owned by current topic.
  1572.  
  1573.       //this.closeSecondaries()
  1574.  
  1575.    }
  1576.  
  1577.  
  1578.  
  1579. // End class definition: helpTopic.
  1580.  
  1581.  
  1582.  
  1583. /*
  1584.  
  1585. DESCR:   Popup class.
  1586.  
  1587. PARAMS:  
  1588.  
  1589. RETURNS: 
  1590.  
  1591. NOTES:   
  1592.  
  1593. */
  1594.  
  1595.  
  1596.  
  1597. // End class definition: popup.
  1598.  
  1599.