Browse Source

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 10 năm trước cách đây
mục cha
commit
38a103a04f
2 tập tin đã thay đổi với 72 bổ sung79 xóa
  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>