import { ResourceManager } from "../resources" ; import { HelpScreen } from "./help" ; /** The page files to load and show, ordered. */ const PAGES = [ 'webport' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '10' , '11' , '12' , '13' , '14' , '15' , '16' , '17' , '18' , '19' , '20' , '21' , '22' ] ; const FORMAT_COMMAND_REGEX = /<.+?>/g ; const ANCHOR_REGEX = /&lt;a:(.+?)&gt;(.+?)&lt;\/a&gt;/g ; export class MbpHelpScreen extends HelpScreen { pagePicker = document . querySelector ( '#mbp-help-picker' ) ; pageElements : HTMLDivElement [ ] = [ ] ; initProperties ( ) { this . div = document . querySelector ( '#mbp-help' ) ; this . homeButton = document . querySelector ( '#mbp-help-home' ) ; this . homeButtonSrc = 'manual/home' ; } /** Fetches all the pages for this help page. */ async init ( ) { let promises = [ ] ; for ( let page of PAGES ) { let path = `./assets/ui_mbp/manual/pages/${ page }.txt` ; promises . push ( ResourceManager . loadResource ( path ) ) ; } let blobs = await Promise . all ( promises ) ; let texts = await Promise . all ( blobs . map ( x => ResourceManager . readBlobAsText ( x ) ) ) ; for ( let text of texts ) { let heading = text . slice ( 0 , text . indexOf ( '\n' ) ) ; let selector = document . createElement ( 'div' ) ; selector . textContent = heading ; selector . addEventListener ( 'mousedown' , ( ) => this . selectPage ( texts . indexOf ( text ) ) ) ; this . pagePicker . appendChild ( selector ) ; let pageElement = document . createElement ( 'div' ) ; pageElement . classList . add ( '_page' , 'hidden' ) ; pageElement . innerHTML = this . generatePageHtml ( text ) ; this . pageElements . push ( pageElement ) ; this . div . appendChild ( pageElement ) ; } this . selectPage ( 0 ) ; } selectPage ( index ) { for ( let child of this . pagePicker . children ) child . classList . remove ( 'selected' ) ; this . pagePicker . children [ index ] . classList . add ( 'selected' ) ; for ( let page of this . pageElements ) page . classList . add ( 'hidden' ) ; this . pageElements [ index ] . classList . remove ( 'hidden' ) ; this . pageElements [ index ] . scrollTop = 0 ; } /** Turns a subset of TorqueML into HTML. */ generatePageHtml ( text ) { let currentStyle = '' ; let styleStack = [ ] ; let html = '' ; let heading = text . slice ( 0 , text . indexOf ( '\n' ) ) ; let headingElement = document . createElement ( 'h1' ) ; headingElement . textContent = heading ; html += headingElement . outerHTML ; text = text . slice ( text . indexOf ( '\n' ) + 1 ) ; while ( true ) { FORMAT_COMMAND_REGEX . lastIndex = 0 ; let nextCommand ; while ( nextCommand = FORMAT_COMMAND_REGEX . exec ( text ) ) { if ( nextCommand [ 0 ] . startsWith ( '<just' ) || nextCommand [ 0 ] . startsWith ( '<font' ) || nextCommand [ 0 ] === '<spush>' || nextCommand [ 0 ] === '<spop>' ) break ; } let div = document . createElement ( 'div' ) ; if ( currentStyle ) div . setAttribute ( 'style' , currentStyle ) ; if ( ! nextCommand ) { div . textContent = text ; if ( div . innerHTML ) html += div . outerHTML ; break ; } div . textContent = text . slice ( 0 , nextCommand . index ) ; if ( div . innerHTML ) html += div . outerHTML ; if ( nextCommand [ 0 ] . startsWith ( '<just' ) ) { currentStyle += 'text-align: ' + nextCommand [ 0 ] . slice ( 6 , - 1 ) + ';' ; } else if ( nextCommand [ 0 ] . startsWith ( '<font' ) ) { let font = nextCommand [ 0 ] . slice ( 6 , nextCommand [ 0 ] . lastIndexOf ( ':' ) ) ; let size = nextCommand [ 0 ] . slice ( nextCommand [ 0 ] . lastIndexOf ( ':' ) + 1 , - 1 ) ; currentStyle += `font-family: ${ font };font-size: ${ size }px;` ; } else if ( nextCommand [ 0 ] === '<spush>' ) { styleStack . push ( currentStyle ) ; } else if ( nextCommand [ 0 ] === '<spop>' ) { currentStyle = styleStack . pop ( ) ; } text = text . slice ( nextCommand . index + nextCommand [ 0 ] . length ) ; } html = html . replace ( ANCHOR_REGEX , '<a href="http://$1" target="_blank">$2</a>' ) ; return html ; } }