0.8.1.0 - New connection dialog, flow control

* New nassh binary:
  - Support for flow control (try aafire!)
  - Use Pepper host resolver when possible.
  - Smaller TCP window in ssh (try ^C in aafire!)
* nassh.html: Update script tags.
* nassh_connect_dialog.html:
  - New file, connect dialog UI, making liberal use of nassh_box.css.
  - TODO: i18n, a11y.
* nassh_google_relay.html: Moved from google_relay.html
* colors.js:
  - Added Ned Stark reference.
  - Added rgba color support.
  - Added setAlpha(), mix(), and crackRGB().
* frame.js:
  - First draft of the interface between the terminal and a third party dialog.
  - This will change substantially as the interface is fleshed out.
* google_relay_html.js: moved to nassh_google_relay_html.js.
* hterm.js:
  - Add getURL().
  - Rename old ferr() to fthrow(), make ferr() be like flog() except using
    console.error().
  - Add removeFile() and readDirectory() utility functions.
* nassh.js:
  - Moved most code out into nassh_command_instance.js, some into nassh_main.js.
  - Only static utility functions (and the namespace delcaration) remaing here,
    since this file is now shared by nassh_command_instance.js and
    nassh_connect_dialog.js.
* nassh_column_list.js: "Resuable" multicolumn list control.
* nassh_command_instance.js:
  - Sorry, rename and modifications in the same CL.
  - Update to work with Dmitry's outputWindow changes.
  - Add another session variable so we can distinguish between a
    reload-for-relay-auth, and a user initiated reload.  Now we can re-display
    the connect dialog ONLY for user initiated reloads, even when using a relay.
  - Integrate with nassh_connect_dialog.js.
* nassh_connect_dialog.js:
  - New file containing most of the code backing the new connect dialog.
  - TODO: i18n.
* nassh_css_variables.js:
  - OMG.  CSS variables hack until they land for real.
  - This allows the connect dialog to adapt to the user's color scheme.
* nassh_google_relay.js:
  - s/NaSSH./nassh./g
  - Refactor "destination" into "resumePath", since it was really only being
    used as an opaque place to resume to.
  - Integrate with Dmitry's writeWindow changes.
* nassh_google_relay_html.js: Move from google_relay_html.js.
* nassh_main.js: Split out of nassh.js.
* nassh_preferences.js:
  - New file containing nassh specific preferences.
  - Contains "global" nassh preferences, as well as a collection of remembered
    connection "profiles".
* nassh_streams.js: s/NaSSH./nassh./g
* preference_manager.js:
  - Promote out of the hterm namespace.
  - Allow for multiple preference observers.
  - Allow for after-the-fact registration of preference observers.
  - Throw an error when set() called for unknown pref.
  - Add setLater to set a pref after a timeout and coalesce multiple calls.
  - Fix error when notified about changes to prefs that are no longer declared.
* screen.js:
  - Cache textContent in deleteChars for a decent speedup.
* scrollport.js:
  - Remove focus outline now that the cursor changes style for focus.
* terminal.js:
  - Cache foreground and background colors for major speedup.
  - Add focus/unfocused cursor styles.
  - Remove default background gradient.
* terminal_io.js:
  - Add createFrame().
  - Add setTerminalProfile().
* vt.js: s/cssToX11/rgbToX11/.

BUG=chromium-os:25417, Split screen scrolling in hterm about 5x slower than in
    konsole
BUG=chromium-os:25563, Support specifying imported keys files in hterm
BUG=chromium-os:30103, Add a UI for port forwarding.
BUG=chromium-os:30302, CSI K (erase in line) does not clear wrap-around flag

TEST=test_manager.html, 60/60 tests passed.

Change-Id: Ia6e50309677858138516eb76115f4d5d99140b33
Reviewed-on: https://gerrit.chromium.org/gerrit/23102
Reviewed-by: Marius Schilder <mschilder@google.com>
Commit-Ready: Robert Ginda <rginda@chromium.org>
Reviewed-by: Robert Ginda <rginda@chromium.org>
Tested-by: Robert Ginda <rginda@chromium.org>
diff --git a/hterm/js/terminal.js b/hterm/js/terminal.js
index 16cd352..16590f4 100644
--- a/hterm/js/terminal.js
+++ b/hterm/js/terminal.js
@@ -75,6 +75,8 @@
   // each output and keystroke.
   this.scrollOnOutput_ = this.prefs_.get('scroll-on-output');
   this.scrollOnKeystroke_ = this.prefs_.get('scroll-on-keystroke');
+  this.foregroundColor_ = this.prefs_.get('foreground-color');
+  this.backgroundColor_ = this.prefs_.get('background-color');
 
   // Terminal bell sound.
   this.bellAudio_ = this.document_.createElement('audio');
@@ -132,7 +134,7 @@
 
   this.profileName_ = profileName.replace(/\//g, '');
 
-  this.prefs_ = new hterm.PreferenceManager(
+  this.prefs_ = new PreferenceManager(
       '/hterm/prefs/profiles/' + this.profileName_);
 
   var self = this;
@@ -175,22 +177,14 @@
      * The background color for text with no other color attributes.
      */
     ['background-color', 'rgb(16, 16, 16)', function(v) {
-        self.scrollPort_.setBackgroundColor(v);
+        self.setBackgroundColor(v);
       }
     ],
 
     /**
      * The background image.
-     *
-     * Defaults to a subtle light-to-transparent-to-dark gradient that is
-     * mostly transparent.
      */
-    ['background-image',
-     ('-webkit-linear-gradient(bottom, ' +
-      'rgba(0,0,0,0.01) 0%, ' +
-      'rgba(0,0,0,0) 30%, ' +
-      'rgba(255,255,255,0) 70%, ' +
-      'rgba(255,255,255,0.05) 100%)'),
+    ['background-image', '',
      function(v) {
         self.scrollPort_.setBackgroundImage(v);
       }
@@ -237,7 +231,7 @@
      * The color of the visible cursor.
      */
     ['cursor-color', 'rgba(255,0,0,0.5)', function(v) {
-        self.cursorNode_.style.backgroundColor = v;
+        self.setCursorColor(v);
       }
     ],
 
@@ -289,7 +283,7 @@
      * The foreground color for text with no other color attributes.
      */
     ['foreground-color', 'rgb(240, 240, 240)', function(v) {
-        self.scrollPort_.setForegroundColor(v);
+        self.setForegroundColor(v);
       }
     ],
 
@@ -365,6 +359,36 @@
     this.prefs_.notifyAll();
 };
 
+
+/**
+ * Set the color for the cursor.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ */
+hterm.Terminal.prototype.setCursorColor = function(color) {
+  this.cursorNode_.style.backgroundColor = color;
+  this.cursorNode_.style.borderColor = color;
+};
+
+/**
+ * Return the current cursor color as a string.
+ */
+hterm.Terminal.prototype.getCursorColor = function() {
+  return this.cursorNode_.style.backgroundColor;
+};
+
+/**
+ * Set the background color.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ */
+hterm.Terminal.prototype.setBackgroundColor = function(color) {
+  this.backgroundColor_ = hterm.colors.normalizeCSS(color);
+  this.scrollPort_.setBackgroundColor(color);
+};
+
 /**
  * Return the current terminal background color.
  *
@@ -372,7 +396,18 @@
  * prefs_ object.
  */
 hterm.Terminal.prototype.getBackgroundColor = function() {
-  return this.prefs_.get('background-color');
+  return this.backgroundColor_;
+};
+
+/**
+ * Set the foreground color.
+ *
+ * If you want this setting to persist, set it through prefs_, rather than
+ * with this method.
+ */
+hterm.Terminal.prototype.setForegroundColor = function(color) {
+  this.foregroundColor_ = hterm.colors.normalizeCSS(color);
+  this.scrollPort_.setForegroundColor(color);
 };
 
 /**
@@ -382,7 +417,7 @@
  * prefs_ object.
  */
 hterm.Terminal.prototype.getForegroundColor = function() {
-  return this.prefs_.get('foreground-color');
+  return this.foregroundColor_;
 };
 
 /**
@@ -462,6 +497,13 @@
 };
 
 /**
+ * Get the current font family.
+ */
+hterm.Terminal.prototype.getFontFamily = function() {
+  return this.scrollPort_.getFontFamily();
+};
+
+/**
  * Set the CSS "font-family" for this terminal.
  */
 hterm.Terminal.prototype.syncFontFamily = function() {
@@ -911,15 +953,31 @@
 
   this.document_ = this.scrollPort_.getDocument();
 
+  this.document_.body.firstChild.addEventListener(
+      'focus', this.onFocusChange_.bind(this, true));
+  this.document_.body.firstChild.addEventListener(
+      'blur', this.onFocusChange_.bind(this, false));
+
+  var style = this.document_.createElement('style');
+  style.textContent =
+      ('.cursor-node[focus="false"] {' +
+       '  box-sizing: border-box;' +
+       '  background-color: transparent !important;' +
+       '  border-width: 2px;' +
+       '  border-style: solid;' +
+       '}');
+  this.document_.head.appendChild(style);
+
   this.cursorNode_ = this.document_.createElement('div');
+  this.cursorNode_.className = 'cursor-node';
   this.cursorNode_.style.cssText =
       ('position: absolute;' +
        'top: -99px;' +
        'display: block;' +
        'width: ' + this.scrollPort_.characterSize.width + 'px;' +
        'height: ' + this.scrollPort_.characterSize.height + 'px;' +
-       '-webkit-transition: opacity, background-color 100ms linear;' +
-       'background-color: ' + this.prefs_.get('cursor-color'));
+       '-webkit-transition: opacity, background-color 100ms linear;');
+  this.setCursorColor(this.prefs_.get('cursor-color'));
   this.document_.body.appendChild(this.cursorNode_);
 
   this.setCursorBlink(!!this.prefs_.get('cursor-blink'));
@@ -2092,6 +2150,13 @@
 };
 
 /**
+ * React when focus changes.
+ */
+hterm.Terminal.prototype.onFocusChange_ = function(state) {
+  this.cursorNode_.setAttribute('focus', state ? 'true' : 'false');
+};
+
+/**
  * React when the ScrollPort is scrolled.
  */
 hterm.Terminal.prototype.onScroll_ = function() {