Browse files Major changes: Terminal() now supports turning on/off 'a…

…utowrap mode'. This means that lines that are longer than the width of the terminal will be wrapped by the browser instead of inside Terminal() *unless* autowrap mode is enabled. The biggest impact of this change will be if you copy a long line it will now show up as *one long line* instead of a bunch of lines (hard-wrapped based on the width of the terminal). Some intelligence was added to Terminal.carriage_return() to detect when the underlying program is expecting a hard-wrap even when autowrap is set to False. This should get the best of both worlds (as a default).  Terminal.newline() now automatically sets the cursor back to the beginning of the line (CR).  No change in behavior here since Terminal.write() did this on its own previously.  Renamed Terminal._carriage_return() to Terminal.carriage_return().  Not sure why I had an underscore there originally--there's nothing special or private about it.
gateone.js:  Changed the timeout for enabling scrollback back to 500.  3500ms is too long.
gateone.js:  Modified GateOne.Terminal.termUpdateFromWorker() to only call enableScrollback() if the incoming scrollback buffer is different from the existing scrollback buffer.  This should make terminals slightly more responsive as well.  The only downside to this change is this:  If (and only if) you have lines in the current screen that are longer than the screen's width it can result in the view being scrolled up slightly when resuming from an alternate screen buffer (e.g. you're done editing a file in vim).  This is a rare enough situation and is only mildly annoying so I think it will be OK until I figure out a workaround (low priority unless someone finds it to be a real problem).
gateone.js:  Fixed a bug where if you used middle click to paste highlighted text (note: not the same as native middle-click-to-paste on Unix) it would cause the next paste to also include the previously-pasted text (a double-paste).
gateone.js:  Tweaked the logic that hides the pastearea when the mouse is over it to act in a smoother and more natural fashion.
gateone.js:  Tweaked the logic that adjusts the size of terminals when the browser window is resized.  It will now adjust the size of *all* terminals; not just the one you're looking at.  Also, it will correctly deal with the situation of lines being added then later removed (multiple re-sizes could get a little wonky before this change).
gateone.js:  The terminal will no longer scroll to the bottom when pressing a modifier key (e.g. shift).
gateone.js:  GateOne.Visual.displayMessage() has been tweaked to include a close icon (X) that will make messages go away instantly when clicked.  This was necessary since there's always a possibility that a displayed message could be huge with a long timeout.  It would be really annoying to have to avoid moving your mouse while waiting for it to go away.
Text Colors:  Added some new syntax highlighting classes that could be useful for text transforms and tweaked things a bit all-around.
CSS Themes:  Added span.screen and span.scrollback to work in conjunction with the changes to gateone.js.
CSS Themes:  Added some extra classes for the new close X icon in #noticecontainer.
Logging Plugin:  In logging.js, added support for the additional console.log() options that exist in some browsers.  e.g. console.warn() and console.error().
Convenience Plugin:  Tweaked the IPv4 regex slightly so it won't match on things like 'SomePackage-'.
Convenience Plugin:  Tweaked the syslog regex to make use of the multi-line flag ('m').  This should make it more reliable.
Convenience Plugin:  Tweaked the syslog replacement string to make lines clickable...  When you click on a line it will highlight it a bit with a background color.  It could be useful or it could be annoying.  Need actual feedback to make a determination either way.
  • Loading branch information...
liftoff committed Oct 8, 2012
1 parent 0127d7b commit 9ee072461d06a013cf1dc06e15873ab23c836332
@@ -39,11 +39,11 @@ GateOne.Base.update(GateOne.Convenience, {
Registers a text transform that makes IPv4 addresses into spans that will execute `host <IP address>` when clicked.
- var IPv4Pattern = /(\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)(?!\.)/g,
+ var IPv4Pattern = /(\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)(?![\.\w-_])/g,
IPv4ReplacementString = "<span class='clickable' onclick='GateOne.Convenience.IPInfo(this)'>$1</span>";
t.registerTextTransform("IPv4", IPv4Pattern, IPv4ReplacementString);
// Just a little regex to capture IPv6...
- var IPv6Pattern = /(\b((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\b)/g,
+ var IPv6Pattern = /(\b((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\b)(?![\:])/g,
IPv6ReplacementString = "<span class='clickable' onclick='GateOne.Convenience.IPInfo(this)'>$1</span>";
t.registerTextTransform("IPv6", IPv6Pattern, IPv6ReplacementString);
@@ -267,9 +267,20 @@ GateOne.Base.update(GateOne.Convenience, {
Registers a text transform that makes standard syslog output easier on the eyes.
- var timeRegex = /(^|\n)((Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+[0-9]+(st|th|nd)?)\s+([0-9][0-9]\:[0-9][0-9]\:[0-9][0-9])\s+(\w+)\s+(.+?\:)?/g,
- timeReplacementString = "$1<span class='date'>$2</span> <span class='time'>$5</span> <span class='hostname'>$6</span> <span class='service'>$7</span>";
+ var timeRegex = /^((Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+[0-9]+(st|th|nd)?)\s+([0-9][0-9]\:[0-9][0-9]\:[0-9][0-9])\s+(\w+)\s+(.+?\:)?(.*?)$/mg,
+ timeReplacementString = "<span class='row' onclick='GateOne.Convenience.toggleBackground(this)'><span class='date' onclick='this.parentElement.onclick()'>$1</span> <span class='time' onclick='this.parentElement.onclick()'>$4</span> <span class='hostname' onclick='this.parentElement.onclick()'>$5</span> <span class='service' onclick='this.parentElement.onclick()'>$6</span><span class='message' onclick='this.parentElement.onclick()'>$7</span></span>";
t.registerTextTransform("syslogtime", timeRegex, timeReplacementString);
+ },
+ toggleBackground: function(elem) {
+ /**:GateOne.Convenience.groupInfoError(result)
+ Toggles a background color on and off for the given *elem* by adding or removing the 'selectedrow' class.
+ */
+ if (elem.className.indexOf('selectedrow') == -1) {
+ elem.className += ' selectedrow';
+ } else {
+ elem.className = elem.className.replace('selectedrow', '');
+ }
@@ -65,12 +65,43 @@ GateOne.Base.update(GateOne.Logging, {
l.level = level;
- /** @id MochiKit.Logging.Logger.prototype.logToConsole */
- logToConsole: function (msg) {
+ logToConsole: function (msg, /*opt*/level) {
+ /**:GateOne.Logging.logToConsole(msg, level)
+ Logs the given *msg* to the browser's JavaScript console. If *level* is provided it will attempt to use the appropriate console logger (e.g. console.warn()).
+ .. note:: Original version of this function is from: MochiKit.Logging.Logger.prototype.logToConsole.
+ */
if (typeof(window) != "undefined" && window.console && window.console.log) {
// Safari and FireBug 0.4
// Percent replacement is a workaround for cute Safari crashing bug
- window.console.log(msg.replace(/%/g, '\uFF05'));
+ msg = msg.replace(/%/g, '\uFF05');
+ if (!level) {
+ window.console.log(msg);
+ return;
+ } else if (level == 'ERROR' || level == 'FATAL') {
+ if (typeof(window.console.error) == "function") {
+ window.console.error(msg);
+ return;
+ }
+ } else if (level == 'WARN') {
+ if (typeof(window.console.warn) == "function") {
+ window.console.warn(msg);
+ return;
+ }
+ } else if (level == 'DEBUG') {
+ if (typeof(window.console.debug) == "function") {
+ window.console.debug(msg);
+ return;
+ }
+ } else if (level == 'INFO') {
+ if (typeof( == "function") {
+ return;
+ }
+ }
+ // Fallback to default
+ window.console.warn(msg);
} else if (typeof(opera) != "undefined" && opera.postError) {
// Opera
@@ -95,15 +126,15 @@ GateOne.Base.update(GateOne.Logging, {
If undefined, the level will be set to GateOne.Logging.level.
If null (as opposed to undefined), level info will not be included in the log message.
- If *destination* is given (must be a function) it will be used to log messages like so: destination(message). The usual conversion of *msg* to *message* will apply.
+ If *destination* is given (must be a function) it will be used to log messages like so: destination(message, levelStr). The usual conversion of *msg* to *message* will apply.
var l = GateOne.Logging,
now = new Date(),
message = "";
if (typeof(level) == 'undefined') {
level = l.level;
- if (level === parseInt(level,10)) { // It's an integer
+ if (level === parseInt(level, 10)) { // It's an integer
if (l.levels[level]) {
levelStr = l.levels[level]; // Get string
} else {
@@ -125,10 +156,10 @@ GateOne.Base.update(GateOne.Logging, {
if (message) {
if (!destination) {
for (var dest in l.destinations) {
- l.destinations[dest](message);
+ l.destinations[dest](message, levelStr);
} else {
- destination(message);
+ destination(message, levelStr);
Oops, something went wrong.

0 comments on commit 9ee0724

Please sign in to comment.