--- project tofgui version 1.0.0 unit struct system_target info This project provides a function `tofgui`, that starts a Graphical User Interfact in the browser that supports the management and editing of [TofJs](htttp://tofjs.org) projects. # Usage Start a [NodeJs](http://nodejs.org) REPL, load the required projects (see below) and then call `tofgui(port)`, e.g. > tofgui(55555) Server started listening on port `55555` ... `tofgui` is running now. Point your Firefox browser to `localhost:55555/?home` to get started. undefined > ... By ending the REPL session (e.g. with `Ctrl+C`, `Ctrl+C`) you also terminate the GUI. Alternatively, you could also use the module > require ('./tofgui.tofm.js') . tofgui (55555); # Requirements There are a couple of other projects that are required to run `tofgui`, namely: `type`, `value`, `html`, `augment`, `global`, `system`, `utils`, `flatcode`, `session`, `unit`, `HttpTools`, `tofgui`. --- --- unit value name tofgui type $act (HttpServer.$HttpPortNumber) value function (port) { var httpServer = HttpServer.fileAndDocProducerServer (port) (TofGui.docProducer); httpServer.start(); console.log ( '`tofgui` is running now. Point your Firefox browser to `localhost:%d/?home` to get started.', port ); } info `tofgui(port)` creates a HTTP server that immediately starts to listen to the `$HttpPortNumber` value `port`. For example, Start a [NodeJs](http://nodejs.org) REPL, load the required projects (see below) and then call `tofgui(port)`, e.g. > tofgui(55555) Server started listening on port `55555` ... `tofgui` is running now. Point your Firefox browser to `localhost:55555/?home` to get started. undefined > ... By ending the REPL session (e.g. with `Ctrl+C`, `Ctrl+C`) you also terminate the GUI. comment Recall, that the two lines var httpServer = HttpServer.fileAndDocProducerServer (port) (TofGui.docProducer); httpServer.start(); first create an instance of the `HttpServer` class (see the `HttpTools` project) and then starts it, so that the browser can point to `http://localhost:port` to use this GUI. Recall (see the info in the `HttpTools` project), that the `httpServer` created with `HttpServer.fileAndDocProducerServer(port)(dp)` works as a *file server* as well as a *document producer server*, depending on the URL requested by the browser: * If the URL query part (in fact, the combined query and data part from a GET as well as a POST request) of the URL is empty, the file from the URL path is returned. For example, http://localhost:port/one/two/three.html displays `/one/two/three.html` in the browser window. * If the URL query part is not empty, say if it is `?key1=value1&key2=value2&key3=value3`, the query part is converted into a record `{key1: value1, key2: value2, key3: value3}` and the HTML document produced by `dp({key1: value1, key2: value2, key3: value3})` is shown in the browser window. The second parameter `dp` is a **document producer**, i.e. a function that takes a record `r` and returns an HTML document `dp(r)`. In our case of `tofgui`, the document producer is the [`TofGui.docProducer`](#TofGui-docProducer). --- unit struct name TofGui --- unit value name TofGui.docProducer type $prod ([$Rec, $HtmlDoc]) value function (rec) { if ('home' in rec) { return homePage(); } else { if ('do' in rec) { switch (rec.do) { case 'list': return listProjects (); case 'edit': if ('project' in rec) { return editProject (rec.project); } else { return errorPage ("Cannot edit: no `project` was submitted!"); } case 'compile': if ('project' in rec) { if ('flatcode' in rec) { return compileProject (rec.project) (rec.flatcode); } else { return errorPage ("Cannot compile `" + rec.project + "`, because no `flatcode` was submitted."); } } else { return errorPage ("Cannot compile: no `project` was submitted!"); } case 'open': return openProject (rec); case 'delete': if ('project' in rec) { if ('confirmed' in rec) { return deleteProject ([rec.project, rec.confirmed]); } else { return deleteProject (rec.project); } } else { return errorPage ("do=delete is called, but there is no project specified."); } case 'create': return createProject (rec); case 'move': return moveProject (rec); default: return errorPage ("Unknown `do` value `" + rec.do + "`!"); } } else { return errorPage ("Either a `home` or `do` value must be specified!"); } } } info `TofGui.docProducer(rec)` returns a HTML document, depending on the parameters provided in the record `rec`. In fact, this function works more like a router for a couple of other functions, namely: Parameter HTML document is created by ------------- --------------------------------------------------------------------------------------- `home=*` `homePage()` `do=edit` `editProject(project)` or `editProject([project, log])` `do=compile` `compileProject(project)` `do=list` `listProjects ()` `do=open` `openProject(rec)` where `rec` is the requested record `do=delete` `deleteProject(project)` or `deleteProject([project,confirmed])` `do=create` `createProject (rec)` where `rec` is the requested record `do=move` `moveProject(rec)` where `rec` is the requested record Note, that it is possible to move a project. But you cannot delete a project, at least not with this GUI. If `rec` does not neither have a `home` or `do` property, or if the `do` property does not have one of the defined values (`'edit'`, `'compile'`, etc.), an error is thrown. --- --- --- // Singular page generators //////////////////////////////////////////////////////////////////////////// --- --- unit doc name TofGui header The Single Page Generators --- --- unit value name TofGui.homePage type $prod0 ($HtmlDoc) value function () { var html = '

' + Logo.chiLambdaCanvas + '

\n' + '

The GUI (Graphical User Interface) for editing and managing TofJs projects

\n' + '
\n' + '

home of the TofJs GUI (= this page)

\n' + '

list all projects

\n' + '

open an existing project

\n' + '

create a new project

\n' + '
\n' + '

Server root: ' + process.cwd() + '

\n' ; return Html.htmlDoc ( { title : "Tof.js GUI -- home page" , css : defaultCss } ) ( html ) ; } info `TofGui.homePage()` returns a HTML document of the following layout +----------------------------------------------------------------------------------------------------------------+ | +---------+ | | | chi- | | | | lambda- | | | | logo | | | +---------+ | | | | The GUI (Graphical User Interface) for editing and managing TofJs projects | | | | +------------------------------------------------------------------------------------------------------------+ | | | | | | | home of the TofJs GUI (= this page) | | | | | | | | list all projects | | | | | | | | open an existing project | | | | | | | | create a new project | | | | | | | +------------------------------------------------------------------------------------------------------------+ | | Server root: `/path/to/server/root` | +----------------------------------------------------------------------------------------------------------------+ `TofGui.homePage()` is the HTML page displayed when the `tofgui` server is running and the browser is pointed to http://localhost:port/?home From there, you can choose the first steps and choices when managing your [TofJs](http://tofjs.org) projects. --- unit value name TofGui.errorPage type $prod ([$Html, $HtmlDoc]) value function (html) { return Html.htmlDoc ( { title : 'Error' , css : defaultCss } ) ( '

home

\n' + '

Error

\n' + html ); } info ..... comment The `href` value in the `` tag is not yet specified!!! --- unit value name TofGui.listProjects type $prod0 ($HtmlDoc) value function () { var dir = process.cwd(); var branchL = findProjects (dir); var body = '

home

\n'; if (branchL.length > 0) { body += '

List of all projects found below ' + dir + '

\n'; body += '\n'; body += '\n'; for (var i = 0; i < branchL.length; i++) { var pi = branchL[i]; body += '' + '\n' + '\n' + '\n' + '\n'; } body += '
Project Project files
' + pi + '' + projectFileList(pi) + '' + ' move or copy
' + ' delete ' + '
\n'; } else { body += "

No tof.js projects found below " + dir + ".

\n"; } body += '

home

\n'; var htmlDoc = Html.htmlDoc ({css: defaultCss}) (body); return htmlDoc; } info ..... --- unit value name TofGui.openProject type prod ([$rec($null($String)), $HtmlDoc]) value function (rec) { var projectDir = rec.projectDir || '.'; var projectL, // e.g. `['foo/pi1', 'foo/pi2', 'bar/bla/bla/proj123']` subDirL; // e.g. `['foo', 'bar']` projectL = TofGui.findProjects (projectDir); try { subDirL = System.listDir (projectDir); subDirL = subDirL.filter ( function (id) { return System.isDirectory (System.Path.join ([projectDir, id])); } ); } catch (e) { return errorPage ( '

Something went wrong in TofGui.openProject(' + rec + ')

' + '
' + e + '
' ); } var html = '

home

\n'; html += '

Navigate

\n' + '

' + clickablePathList ({"do":"open", "projectDir":projectDir}, 'projectDir') + '

\n'; html += '\n'; html += '

Available projects under ' + projectDir + '

\n'; html += '\n'; return Html.htmlDoc ( { css: defaultCss , title: 'open project' } ) ( html ); } info `TofGui.openProject(rec)` with lists the subdirectories and all projects that can be found under the `rec.projectDir` directory. It does so recursively until a project has been chosen. --- unit value name TofGui.deleteProject type prod ([$singlePlus ([Unit.$ProjectName, $String]), $Boolean]) value function (args) { // reconstruct the arguments; `args` is either the project name `pi` or `[pi,confirmed]` with string `confirmed` var pi = (typeof args === 'string' ? args : args[0]); var confirmed = (typeof args === 'string' ? false : args[1]); // delete the project and create the HTML text var html = '

home

\n' + '

list

\n'; if (confirmed) { html += '

Deleting ' + pi + ' ...

\n'; try { var n = 0; for (var i = 0; i < projectFileExtensions.length; i++) { var ext = projectFileExtensions [i]; if (System.exists (pi + ext)) { n++; System.removeFile (pi + ext); html += '

' + pi + ext + ' is deleted

'; } } html += '

' + pi + ' is deleted and ' + n + ' files were removed.

'; } catch (e) { return errorPage ( "

Something went wrong in deleting project " + pi + "

\n" + "

" + e + "
" ); } } else { html += '

Are you sure you want to delete the ' + pi + ' project?

\n' + '
\n' + '\n' + '\n' + '\n' + '\n' + '
\n'; } // return the document return Html.htmlDoc ( { css: defaultCss , title: 'delete `' + pi + '`' } ) ( html ); } info ..... --- unit value name TofGui.createProject type $prod ([$Rec, $HtmlDoc]) value function __createProject (rec) { // normalize the input `rec` rec.button = rec.button || 'none'; // value of one of the four
buttons; or `'none'` rec.projectDir = rec.projectDir || ''; rec.projectId = rec.projectId || ''; rec.subDir = rec.subDir || ''; rec.newSubDir = rec.newSubDir || ''; switch (rec.button) { case 'none': return makeHtml (rec); case 'change directory': rec.button = 'none'; if (rec.subDir !== '') { rec.projectDir = Unit.ProjectName.join ([rec.projectDir, rec.subDir]); rec.subDir = ''; } return __createProject (rec); case 'create new subdirectory': rec.newSubDir = Str.trim (rec.newSubDir); if (rec.newSubDir === '') { return errorPage ("You did not specify a new subdirectory."); } else { var newProjectDir = Unit.ProjectName.join ([rec.projectDir, rec.newSubDir]); if (System.exists (newProjectDir)) { return errorPage ("Could not create " + newProjectDir + ", it already exists."); } else { try { rec.button = 'none'; System.mkdir (newProjectDir); rec.projectDir = newProjectDir; rec.newSubDir = ''; return __createProject (rec); } catch (e) { return errorPage ( "

Could not create a new subdirectory.

\n" + "
" + e + "
" ); } } } case 'define project identifier': rec.projectId = Str.trim (rec.projectId); var c = Unit.$ProjectId.complain (rec.projectId); if (c) { return errorPage ( "

" + rec.projectId + " is not a proper project identifier:

\n" + "
" + c + "
" ); } else { rec.button = 'none'; return makeHtml (rec); } case 'create new project': // try to create the new project and finally return the `editProject(project)` page ... try { var project = Unit.ProjectName.join ([rec.projectDir, rec.projectId]); var flatCodeFile = project + '.tofu.flatcode'; if (System.exists (flatCodeFile)) { return errorPage ( 'Cannot create `' + project + '` as a new project.
\n' + '' + flatCodeFile + ' already exists.' ); } else { System.writeFileContent (flatCodeFile) (flatCodeTemplate (rec.projectId)); } return editProject (project); } catch (e) { return errorPage ("Could not create the new project: " + e); } default: return errorPage ( "

Fatal and unpredicted error: `TofGui.createProject(rec)` " + "was called with an undefined `rec.button` value `" + rec.button + "`.

" ); } // `makeHtml(rec)` // produces the HTML document. It assumes a normalized `rec`, otherwise an error is thrown. function makeHtml (rec) { // determine `project`, which is of type `$null($ProjectName)` var project; if (Unit.$ProjectId.chi (rec.projectId)) { if (rec.projectDir === '' || rec.projectDir === '/' || rec.projectDir === '.') { project = rec.projectId; } else { project = Unit.ProjectName.join ([rec.projectDir, rec.projectId]); } } else { project = null; } // determine `subDirL`, the list of all subdirectory names of `rec.projectDir` try { var subDirL = System.listDir (rec.projectDir || '.'); subDirL = subDirL.filter ( function (id) { return System.isDirectory (System.Path.join ([rec.projectDir, id])); } ); } catch (e) { return errorPage ( "

Could not determine the subdirectories of " + rec.projectDir + "

\n" + "
" + e + "
\n" ); } // create the HTML `` and `` var html = '

home

\n'; html += '\n' + '\n' + '\n' + '
\n'; html += '\n'; if (subDirL.length > 0) { html += '\n'; html += '\n'; html += '\n'; html += '\n'; html += '\n'; html += '\n'; html += ''; html += '\n'; html += '\n'; html += '\n'; html += '' html += '\n'; html += '\n'; html += '\n'; } else { // there are not subdirectories, so we exclude the "change directory" selection and button row html += '\n'; html += ''; html += '\n'; html += '\n'; html += '\n'; html += '\n'; html += '' html += '\n'; html += '\n'; html += '\n'; } if (project !== null) { html += '\n' + '\n' + '\n'; } html += '
Navigate:
' + clickablePathList (rec, 'projectDir') + '
\n' + clickablePathList (rec, 'projectDir') + '
New project:
' + project + '
\n' + '
\n'; // finish and return the document return Html.htmlDoc ( { title : 'Create new project' , css : defaultCss } ) ( html ); } } info `TofGui.createProject(rec)` generates a HTML page working as a GUI for the creation of a new project. This HTML page is repeated on every request until the "create new project" button is pressed. Then the output of `createProject(rec)` returns `editProject(project)`. During the input dialog, the structure of the page content is very much like so:
Navigate:
/home/myself/foo/bar / one / two / three / four /
New project:
one/two/three/four/veryNewProject
The parameter record for each request generated by that given formula is this key / item name value default value ------------------------ ------------------------------------------------------------------------------------------------------------------------------------ -------------- `button` values: `'change directory'`, `'create new subdirectory'`, `'define project identifier'`, `'create new project'` and `'none'` `'none'` `projectDir` `one/two/three/four` the project directory `''` `projectId` is a `$ProjectId`, e.g. `veryNewProject` `''` `subDir` value from the `\n' + '\n' + '\n' + '\n'; html += '\n' + '\n' html += '\n'; if (subDirL.length > 0) { html += '\n'; html += '\n'; html += '\n'; html += '\n'; html += '\n'; html += '\n'; html += ''; html += '\n'; html += '\n'; html += '\n'; html += '' html += '\n'; html += '\n'; html += '\n'; } else { // there are not subdirectories, so we exclude the "change directory" selection and button row html += '\n'; html += ''; html += '\n'; html += '\n'; html += '\n'; html += '\n'; html += '' html += '\n'; html += '\n'; html += '\n'; } if (targetProject !== null && targetProject !== rec.sourceProject) { html += '\n' + '\n' + '\n' ; } html += '
Source:
' + rec.sourceProject + '
Navigate:
\n' + clickablePathList (rec, 'targetDir') + '
\n' + clickablePathList (rec, 'targetDir') + '
Target:
' + targetProject + '
' + '' + '' + '
\n' + '\n'; // finish and return the document return Html.htmlDoc ( { title : 'Move or copy a project' , css : defaultCss } ) ( html ); } } info ..... `act=null` means not yet defined, `act='move'` means that the source project is (re)moved, `act='copy'` means that the source project remains. During the input dialog, the structure of the page content is very much like so:
Source:
one/two/foo/bar/someExistingProject
Navigate:
/home/myself/foo/bar / one / two / three / four /
Target:
one/two/three/four/veryNewProject
The parameter record for each request generated by that given formula is this key / item name value default value ------------------------ ---------------------------------------------------------------------------------------------------------------------------------------- --------------------------------- `sourceProject` a `$ProjectName`, e.g.`one/two/foo/bar/someExistingProject` no default (error if not present) `button` `'change directory'`, `'create new subdirectory'`, `'define target identifier'`, `'move the project'`, `'copy the project'` and `'none'` `'none'` `targetDir` `one/two/three/four` the project directory `''` `targetId` is a `$ProjectId`, e.g. `veryNewProject` `''` `subDir` value from the `\n' + '\n' + '\n'; // 2. box var compilerLogBox = '
' + ( log === '' ? '
... not compiled, yet...
\n' : '
' + Html.entityify (log)+ '
\n' ) + '
\n' ; // 3. box var menuBox = '
\n' + '

' + pi + ' project files

\n' + '
' + projectFileList (pi) + '
\n' + '

GUI menu

\n' + '\n' + '

Links

\n' + '\n' + '
\n' ; // The final HTML document return Html.htmlDoc ( { title : "`" + pi + "` project in Tof.js" , css : defaultCss } ) ( textAreaBox + compilerLogBox + menuBox ); } catch (e) { return errorPage (e); } } info Syntax TofGui.editProject (pi) TofGui.editProject ([pi, log]) ..... --- --- --- // Auxiliary functions //////////////////////////////////////////////////////////////////////////// --- --- unit doc name TofGui header Auxiliary functions --- --- unit value name TofGui.findProjects type $prod ([System.$Path, $list(Unit.$ProjectName)]) value function (rootDir) { function __findProjects (branch) { var localPath = System.Path.join ([rootDir, branch]); if (System.exists (localPath)) { if (System.isDirectory (localPath)) { var branchL = []; var nameL = System.listDir (localPath); for (var i = 0; i < nameL.length; i++) { var subBranch = System.Path.join ([branch, nameL[i]]); branchL = branchL.concat (__findProjects (subBranch)); } return branchL; } else { if (System.isFile (localPath) && Str.endsWith (localPath) ('.tofu.flatcode')) { var pi = branch.substr (0, branch.length - 14); // note, that the length of '.tofu.flatcode' is 14 return [pi]; } else { return []; } } } else { return []; } } return __findProjects ('.'); } info `TofGui.findProjects(dir)` returns a list of all branches `[b1,...,bN]` so that each of `dir/b1`, ...., `dir/bN` is a project, i.e. each of `dir/b1.tofu.flatcode`, ..., `dir/bN.tofu.flatcode` is an existing file. An example could be this > TofGui.findProjects('/home/myname/myrepo') [ 'project1', 'subrepo/project23', 'subrepo/project34' ] which means that the following are paths to existing files /home/myname/myrepo/project1.tofu.flatcode /home/myname/myrepo/subrepo/project23.tofu.flatcode /home/myname/myrepo/subrepo/project34.tofu.flatcode --- unit value name TofGui.projectFileList type $prod ([Unit.$ProjectName, $Html]) value function (pi) { var dir = System.Path.dirname (pi); var id = System.Path.basename (pi); var flatCodeFile = id + '.tofu.flatcode'; var tofuFile = id + '.tofu.json'; var moduleFile = id + '.tofm.js'; var globalScriptFile = id + '.tofg.js'; var optimizedModuleFile = id + '.tofm.min.js'; var optimizedGlobalScriptFile = id + '.tofg.min.js'; var docFile = id + '.tofd.html'; var logFile = id + '.toflog.html'; function entry (file, title) { var path = System.Path.join ([dir, file]) . replace ('\\', '/'); // the `path` must be web/UNIX style, not Windows if (System.fileExists (path)) { return ( '
  • ' + file + ', ' + System.fileSize (path) + ' Bytes, ' + ' the ' + title + '
  • \n' ); } else { return ( '
  • ' + file + ',' + ' the ' + title + '
  • \n' ); } } var html = '
      \n' + entry (flatCodeFile, "Flat Code File") + entry (tofuFile, "Tofu File") + entry (moduleFile, "Module File") + entry (globalScriptFile, "Global Script File") + entry (optimizedModuleFile, "Optimized Module File") + entry (optimizedGlobalScriptFile, "Optimized Global Script File") + entry (docFile, "Documentation File") + entry (logFile, "Compilation Log File") + '
    \n'; return html; } info `TofGui.projectFileList(pi)` returns an unordered list, i.e. a `
      ` list, with all the files involved in mentioned project. For example, > display (TofGui.projectFileList ('tofus/simpleSample')) ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │↵ │ │ │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯ undefined --- unit value name TofGui.queryString type $lambda ([$list($rec($null($String))), $Html]) value function queryString (recL) { return '?' + Uri.record2queryString (Rec.updateList (recL)); } info `TofGui.queryString([r_1,...,r_n])` first combines the string records `r_1,...,r_n` into a single record `r`, by means of `Rec.updateList([r1,...,r_n])`, converts this into a query string, by means of `Uri.record2queryString(r)`, and finally adds a question mark `?` at the front. For example, > TofGui.queryString ([{one:'123', two:'234', three:'345'}]) '?one=123&two=234&three=345' > TofGui.queryString ([{one:'123'}, {two:'234'}, {one:'321', three:'345'}]) '?one=321&two=234&three=345' --- unit value name TofGui.clickablePathList type $prod ([$args ([$rec($null($String)), $Id]), $Html]) value function (rec, dirKey) { var dirValue = rec[dirKey] || ''; var steps = Unit.ProjectName.split (dirValue); // e.g. `['one', 'two', 'three', 'four']` var serverRootDirectory = process.cwd(); // e.g. `/home/myself/myprojects/` or `C:\\User\\myself\\myprojects\\` var dir = ''; var newRec = {}; newRec[dirKey] = dir; var href = queryString ([rec, newRec]); var html = '' + serverRootDirectory + '\n'; for (var i = 0; i < steps.length; i++) { dir = Unit.ProjectName.join ([dir, steps[i]]); newRec = {}; newRec[dirKey] = dir; href = queryString ([rec, newRec]); html += '/' + '' + steps[i] + '\n'; } return html; } info `linkedPathList (rec, dirKey)`, where `rec` is a `$rec($null($String))` value and `dirKey` is the key for the (project) directory in `rec`. It should have a `projectDir` key with a value like say `one/two/three/four`, otherwise this value is set to `''`. For example, > TofGui.clickablePathList ({projectDir: 'one/two/three/four', greeting: 'Hello!'}, 'projectDir') ╭────────────────────────────────────────────────────────────────────────────╮ │/home/buc/Dropbox/buc/tofjs4↵ │ │/one↵ │ │/two↵ │ │/three↵ │ │/four↵│ │ │ ╰────────────────────────────────────────────────────────────────────────────╯ --- unit value name TofGui.projectFileExtensions type $list ($String) value ['.tofu.flatcode', '.tofu.json', '.tofg.js', '.tofm.js', '.tofd.html', '.toflog.html' ] info `projectFileExtensions` File ------------------------- ------------------------------------------ `.tofu.flatcode` Flat Code Tofu file `.tofu.json` JSON Tofu file `.tofg.js` Global Script file `.tofm.js` Module file `.tofd.html` Document file `.toflog.html` Compilation log file --- unit value name TofGui.defaultCss value ' body { background-color: ivory; padding: 20px; }' + '\n' + ' td, th { border:solid 1pt; padding:3px; background-color:beige }' info `TofGui.defaultCss` is the style sheet used for all Tof GUI pages. --- unit value name TofGui.flatCodeTemplate type $lambda ([$Id, $FlatCode]) value function (projectId) { return ( '---' + '\n' + 'project' + '\n' + ' ' + projectId + '\n' + 'version' + '\n' + ' 0.0.0' + '\n' + 'unit' + '\n' + ' value' + '\n' + 'info' + '\n' + ' This is a new project.' + '\n' + ' Here we provide some user information in [Markdown](http://en.wikipedia.org/wiki/Markdown) syntax.' + '\n' + 'comment' + '\n' + ' A **comment** is some information for developers, hidden from the ordinary user.' + '\n' + '---' + '\n' + '---' + '\n' ); } info `TofGui.flatCodeTemplate('newProjectId')` returns this Flat Code: ..... comment New version: --- project dummy1 version 0.0.0 unit value info This is a new project. Here we provide some user information in [Markdown](http://en.wikipedia.org/wiki/Markdown) syntax. comment A **comment** is some information for developers, hidden from the ordinary user. --- /*** // Template for proper units: --- unit ... value(anything/struct/construct/type/function)/proto/param [global/local] [constant/variable] ... name ...name... type ...type... value ...value... info ... documentation for this unit ... comment ... information for developers ... --- ***/ --- --- // Logo /////////////////////////////////////////////////////////////////////////////////////////// --- unit struct name TofGui.Logo --- unit value name TofGui.Logo.chiLambdaCanvas type $Html value '\n' + '<' + 'script' + '>' + '\n' + ' var context = document.getElementById("chiLambdaCanvas").getContext("2d");\n' + ' var rg = context.createRadialGradient (80,80,15,100,100,90);\n' + ' rg.addColorStop (0, "yellow");\n' + ' rg.addColorStop (1, "red");\n' + ' context.fillStyle = rg;\n' + ' context.font = "180px monospace";\n' + ' context.shadowOffsetX = 5;\n' + ' context.shadowOffsetY = 5;\n' + ' context.shadowBlur = 3;\n' + ' context.shadowColor = "green"; \n' + ' context.lineWidth = 4.0;\n' + ' context.fillText ("\u03C7", 0, 145);\n' + ' context.fillText ("\u03BB", 75, 145);\n' + '<' + '/' + 'script' + '>' + '\n' info Contains the HTML code for the following `` element and according script. --- --- unit value name TofGui.Logo.tofJsCanvas type $Html value '\n' + '<' + 'script' + '>' + '\n' + ' var context = document.getElementById("tofJsCanvas").getContext("2d");\n' + ' var rg = context.createRadialGradient (80,80,15,100,100,90);\n' + ' rg.addColorStop (0, "yellow");\n' + ' rg.addColorStop (1, "red");\n' + ' context.fillStyle = rg;\n' + ' context.font = "110px monospace";\n' + ' context.shadowOffsetX = 5;\n' + ' context.shadowOffsetY = 5;\n' + ' context.shadowBlur = 4;\n' + ' context.shadowColor = "green"; \n' + ' context.lineWidth = 4.0;\n' + ' context.fillText ("tof.js", 0, 87);\n' + '<' + '/' + 'script' + '>' + '\n' info Contains the HTML code for the following `` element and according script. --- ---