Quellcode durchsuchen

Simplify access of terminal child tags

Create terminal properties pointing to the display and commandline tags
so that shells no longer need to keep specifying `.tags` to get to them.

The commandline is also updated to use riot's observable feature, rather
than make calls to `parent`, to slightly increase modularity.

The commandline tag definition is also moved below the display tag
definition to be somewhat consistent in presentation order.
Weiyi Lou vor 10 Jahren
Ursprung
Commit
38a103a04f
2 geänderte Dateien mit 72 neuen und 79 gelöschten Zeilen
  1. 12 12
      js/pgsh.js
  2. 60 67
      tags/terminal.tag

+ 12 - 12
js/pgsh.js

@@ -19,7 +19,7 @@ Type "help" for list of commands\n\
     'clear': {
       'help': 'Clears the screen\nUsage: clear',
       'run' : function(args, shell, terminal) {
-        terminal.tags.display.clear()
+        terminal.display.clear()
       }
     },
     'version': {
@@ -62,7 +62,7 @@ Type "help" for list of commands\n\
         if (args.length > 0) { return this.help }
         var output = ''
         if (!shell.su) {
-          terminal.tags.commandline.setPrompt('<span style="color:tomato">root </span><span style="color:red">% </span>')
+          terminal.commandline.setPrompt('<span style="color:tomato">root </span><span style="color:red">% </span>')
           shell.su = true
           output = 'With Great Power comes Great'
         }
@@ -75,7 +75,7 @@ Type "help" for list of commands\n\
         if (args.length > 0) { return this.help }
         var output = 'Close browser window to exit'
         if (shell.su) {
-          terminal.tags.commandline.setPrompt(shell.prompt)
+          terminal.commandline.setPrompt(shell.prompt)
           shell.su = false
           output = ''
         }
@@ -85,10 +85,10 @@ Type "help" for list of commands\n\
     'search': {
       'help': 'Search the web\nUsage: search [query]',
       'run': function(args, shell, terminal) {
-        terminal.tags.commandline.hidePrompt()
+        terminal.commandline.hidePrompt()
         setTimeout(function() {
           window.open('https://duckduckgo.com/?q=' + args.join('+'), '_blank')
-          terminal.tags.commandline.showPrompt()
+          terminal.commandline.showPrompt()
           terminal.update()
         }, 1000)
         return 'Searching for "' + args.join(' ') + '" in new window...'
@@ -101,18 +101,18 @@ Type "help" for list of commands\n\
           'run': function(input, terminal) {
             if (!this.running) {
               this.running = true
-              terminal.tags.display.hide()
-              terminal.tags.display.add('Welcome to the questions. Do you wish to continue?')
-              terminal.tags.commandline.hidePrompt()
+              terminal.display.hide()
+              terminal.display.add('Welcome to the questions. Do you wish to continue?')
+              terminal.commandline.hidePrompt()
               return
             }
             if (input != 'exit') {
-              terminal.tags.display.set('You answered the last question with "' + input + '"!\nWould you like another question?\n(Type "exit" to end)')
+              terminal.display.set('You answered the last question with "' + input + '"!\nWould you like another question?\n(Type "exit" to end)')
             } else {
               this.running = false
-              terminal.tags.display.restore()
-              terminal.tags.display.add('Thanks for answering questions!')
-              terminal.tags.commandline.showPrompt()
+              terminal.display.restore()
+              terminal.display.add('Thanks for answering questions!')
+              terminal.commandline.showPrompt()
               terminal.returnToShell()
             }
           }

+ 60 - 67
tags/terminal.tag

@@ -48,8 +48,8 @@
  * The `run()` function can take 2 parameters. The first will contain user input
  * from the command line. The second will contain the terminal object itself -
  * this will allow the shell access to all of the terminal's functions, mainly
- * through its 2 child tags, `terminal.tags.display` and
- * `terminal.tags.commandline`. Refer those tags below for capabilities.
+ * through its 2 child tags, `terminal.display` and
+ * `terminal.commandline`. Refer those tags below for capabilities.
  *
  * A shell can, at its most basic operation, return a string of text or HTML,
  * and this will be appended to the display.
@@ -66,11 +66,11 @@
  *
  *     {
  *       'run': function(input, terminal) {
- *         terminal.tags.commandline.hidePrompt()
- *         terminal.tags.display.add('Hello! inputs will now come to this app.')
+ *         terminal.commandline.hidePrompt()
+ *         terminal.display.add('Hello! inputs will now come to this app.')
  *         if (input == 'exit') {
- *           terminal.tags.display.add('Bye! Returning control to the shell.')
- *           terminal.tags.commandline.showPrompt()
+ *           terminal.display.add('Bye! Returning control to the shell.')
+ *           terminal.commandline.showPrompt()
  *           terminal.returnToShell()
  *         }
  *       }
@@ -90,6 +90,8 @@
   this.active = this.shell
   this.welcome = this.shell.welcome || opts.welcome
   this.prompt = this.shell.prompt || opts.prompt
+  this.display = this.tags.display
+  this.commandline = this.tags.commandline
 
   /**
    * How to process a command:
@@ -97,23 +99,22 @@
    * - Make the input safe by transforming html entities.
    * - Keep the last command line on display before other output.
    * - Based on shell response, append output, or give control to an app object.
-   * - Empty the command line of input.
    * - Update the display.
    */
-  process(prompt, input) {
+  var self = this
+  this.commandline.on('cmdEntered', function(prompt, input) {
     input = he.encode(input)
-    this.tags.display.add(prompt + input + '\n')
-    var response = this.active.run(input, this)
+    self.display.add(prompt + input + '\n')
+    var response = self.active.run(input, self)
     if (typeof response === 'string') {
-      this.tags.display.add(response)
+      self.display.add(response)
     }
     if (typeof response === 'object' && typeof response.run === 'function') {
-      this.active = response
-      response.run(input, this)
+      self.active = response
+      response.run(input, self)
     }
-    this.tags.commandline.command.value = ''
-    this.update()
-  }
+    self.update()
+  })
 
   /**
    * Make the shell the active process.
@@ -125,57 +126,6 @@
   }
 </terminal>
 
-<commandline>
-  <form autocomplete='off' onsubmit={ process }>
-    <raw name='lhs' content={ prompt } show={ visible } />
-    <input type='text' name='command' />
-  </form>
-
-  <style>
-    input[name='command'] {
-      background: transparent;
-      border: none; outline: none;
-      padding: 0; margin: 0;
-      width: 90%;
-    }
-  </style>
-
-  this.prompt = opts.prompt || '$ '
-  this.visible = true
-
-  this.on('mount', function() {
-    document.getElementsByName('command')[0].focus()
-  })
-
-  process() {
-    var prompt = this.visible ? this.prompt : '';
-    this.parent.process(prompt, this.command.value)
-  }
-
-  /**
-   * Set the prompt value.
-   *
-   * Note about `lhs.write()` check:
-   * Terminal tag setup fires `setPrompt()` before `lhs.write()` exists.
-   * At that point, `lhs` is initialised with just its `content` attribute.
-   * After that, `lhs.write()` is called to make all subsequent prompt changes.
-   */
-  setPrompt(value) {
-    if (typeof this.tags.lhs.write !== 'undefined') {
-      this.tags.lhs.write(value)
-    }
-    this.prompt = value
-  }
-
-  hidePrompt() {
-    this.visible = false
-  }
-
-  showPrompt() {
-    this.visible = true
-  }
-</commandline>
-
 <display>
   <div each={ output }>
     <raw content={ content } />
@@ -240,6 +190,49 @@
   this.add(opts.welcome)
 </display>
 
+<commandline>
+  <form autocomplete='off' onsubmit={ process }>
+    <raw name='lhs' content={ prompt } show={ visible } />
+    <input type='text' name='command' />
+  </form>
+
+  <style>
+    input[name='command'] {
+      background: transparent;
+      border: none; outline: none;
+      padding: 0; margin: 0;
+      width: 90%;
+    }
+  </style>
+
+  this.prompt = opts.prompt || '$ '
+  this.visible = true
+
+  this.on('mount', function() {
+    document.getElementsByName('command')[0].focus()
+  })
+
+  process() {
+    var prompt = this.visible ? this.prompt : '';
+    this.trigger('cmdEntered', prompt, this.command.value)
+    this.command.value = ''
+  }
+
+  setPrompt(value) {
+    this.prompt = value
+    // `write()` is called to actually update the `raw` tag's html.
+    this.tags.lhs.write(value)
+  }
+
+  hidePrompt() {
+    this.visible = false
+  }
+
+  showPrompt() {
+    this.visible = true
+  }
+</commandline>
+
 <raw>
   <span></span>