]> git.proxmox.com Git - mirror_xterm.js.git/commitdiff
Merge remote-tracking branch 'ups/master' into 553_find_api
authorDaniel Imms <daimms@microsoft.com>
Sun, 9 Jul 2017 06:07:57 +0000 (23:07 -0700)
committerDaniel Imms <daimms@microsoft.com>
Sun, 9 Jul 2017 06:07:57 +0000 (23:07 -0700)
1  2 
demo/index.html
gulpfile.js
src/SelectionManager.ts
src/xterm.js

diff --combined demo/index.html
index 9546b697818fc9bba6a073d51042b7750d3fc319,ce58e1923bcca9ce5cd9910f3a99bce45d358eaf..9bba5bd03334a5b84db1c29620bc9df14e9e7e8d
@@@ -5,12 -5,12 +5,13 @@@
          <link rel="stylesheet" href="/build/xterm.css" />
          <link rel="stylesheet" href="/build/addons/fullscreen/fullscreen.css" />
          <link rel="stylesheet" href="style.css" />
+               <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.auto.min.js"></script>
                <script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/1.0.0/fetch.min.js"></script>
          <script src="/build/xterm.js" ></script>
          <script src="/build/addons/attach/attach.js" ></script>
          <script src="/build/addons/fit/fit.js" ></script>
          <script src="/build/addons/fullscreen/fullscreen.js" ></script>
 +        <script src="/build/addons/search/search.js" ></script>
      </head>
      <body>
          <h1>xterm.js: xterm, in the browser</h1>
diff --combined gulpfile.js
index 1dd49887fc130aca69a12ee0bed55fab3a39c5c9,d9ab8714758dce52820977e69cf6c37e5718a09d..48bf9df9f1d51434171149e4f398ff8edb88d468
@@@ -14,7 -14,6 +14,7 @@@ const ts = require('gulp-typescript')
  
  let buildDir = process.env.BUILD_DIR || 'build';
  let tsProject = ts.createProject('tsconfig.json');
 +let tsProjectSearchAddon = ts.createProject('./src/addons/search/tsconfig.json');
  let srcDir = tsProject.config.compilerOptions.rootDir;
  let outDir = tsProject.config.compilerOptions.outDir;
  
@@@ -31,18 -30,13 +31,18 @@@ gulp.task('tsc', function () 
    let tsResult = tsProject.src().pipe(sourcemaps.init()).pipe(tsProject());
    let tsc = tsResult.js.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest(outDir));
  
 +  fs.emptyDirSync(`${outDir}/addons`);
 +  fs.emptyDirSync(`${outDir}/addons/search`);
 +  let tsResultSearchAddon = tsProjectSearchAddon.src().pipe(sourcemaps.init()).pipe(tsProjectSearchAddon());
 +  let tscSearchAddon = tsResultSearchAddon.js.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest(`${outDir}/addons/search`));
 +
    // Copy all addons from ${srcDir}/ to ${outDir}/
 -  let copyAddons = gulp.src(`${srcDir}/addons/**/*`).pipe(gulp.dest(`${outDir}/addons`));
 +  let copyAddons = gulp.src([`${srcDir}/addons/**/*`, `!${srcDir}/addons/search`, `!${srcDir}/addons/search/**`]).pipe(gulp.dest(`${outDir}/addons`));
  
    // Copy stylesheets from ${srcDir}/ to ${outDir}/
    let copyStylesheets = gulp.src(`${srcDir}/**/*.css`).pipe(gulp.dest(outDir));
  
 -  return merge(tsc, copyAddons, copyStylesheets);
 +  return merge(tsc, tscSearchAddon, copyAddons, copyStylesheets);
  });
  
  /**
@@@ -56,7 -50,7 +56,7 @@@ gulp.task('browserify', ['tsc'], functi
    let browserifyOptions = {
      basedir: buildDir,
      debug: true,
-     entries: [`../${outDir}/xterm.js`],
+     entries: [`${outDir}/xterm.js`],
      standalone: 'Terminal',
      cache: {},
      packageCache: {}
          .pipe(sourcemaps.write('./'))
          .pipe(gulp.dest(buildDir));
  
 +  let browserifyOptionsSearchAddon = {
 +    basedir: buildDir,
 +    debug: true,
 +    entries: [`../${outDir}/addons/search/search.js`],
 +    cache: {},
 +    packageCache: {}
 +  };
 +  let bundleStreamSearchAddon = browserify(browserifyOptionsSearchAddon)
 +        .bundle()
 +        .pipe(source('./addons/search/search.js'))
 +        .pipe(buffer())
 +        .pipe(sourcemaps.init({loadMaps: true, sourceRoot: '..'}))
 +        .pipe(sourcemaps.write('./'))
 +        .pipe(gulp.dest(buildDir));
 +
    // Copy all add-ons from ${outDir}/ to buildDir
 -  let copyAddons = gulp.src(`${outDir}/addons/**/*`).pipe(gulp.dest(`${buildDir}/addons`));
 +  let copyAddons = gulp.src([`${outDir}/addons/**/*`, `!${outDir}/addons/search`, `!${outDir}/addons/search/**`]).pipe(gulp.dest(`${buildDir}/addons`));
  
    // Copy stylesheets from ${outDir}/ to ${buildDir}/
    let copyStylesheets = gulp.src(`${outDir}/**/*.css`).pipe(gulp.dest(buildDir));
  
 -  return merge(bundleStream, copyAddons, copyStylesheets);
 +  return merge(bundleStream, bundleStreamSearchAddon, copyAddons, copyStylesheets);
  });
  
  gulp.task('instrument-test', function () {
diff --combined src/SelectionManager.ts
index a99cfa09234751e3f145e649c89519c442a7f7a1,f13549b2ffb764a7b89b5b1c7a82845e9b16d3ec..189d73e826bc5e3e0167835930aac9ee74ae4f9a
@@@ -9,7 -9,6 +9,7 @@@ import { CircularList } from './utils/C
  import { EventEmitter } from './EventEmitter';
  import { ITerminal } from './Interfaces';
  import { SelectionModel } from './SelectionModel';
 +import { translateBufferLineToString } from './utils/BufferLine';
  
  /**
   * The number of pixels the mouse needs to be above or below the viewport in
@@@ -43,7 -42,7 +43,7 @@@ const CLEAR_MOUSE_DISTANCE = 10
   * A string containing all characters that are considered word separated by the
   * double click to select work logic.
   */
- const WORD_SEPARATORS = ' ()[]{}:\'"';
+ const WORD_SEPARATORS = ' ()[]{}\'"';
  
  // TODO: Move these constants elsewhere, they belong in a buffer or buffer
  //       data/line class.
@@@ -179,11 -178,9 +179,12 @@@ export class SelectionManager extends E
     */
    public setBuffer(buffer: CircularList<any>): void {
      this._buffer = buffer;
+     this.clearSelection();
    }
  
 +  public get selectionStart(): [number, number] { return this._model.finalSelectionStart; }
 +  public get selectionEnd(): [number, number] { return this._model.finalSelectionEnd; }
 +
    /**
     * Gets whether there is an active text selection.
     */
      // Get first row
      const startRowEndCol = start[1] === end[1] ? end[0] : null;
      let result: string[] = [];
 -    result.push(this._translateBufferLineToString(this._buffer.get(start[1]), true, start[0], startRowEndCol));
 +    result.push(translateBufferLineToString(this._buffer.get(start[1]), true, start[0], startRowEndCol));
  
      // Get middle rows
      for (let i = start[1] + 1; i <= end[1] - 1; i++) {
        const bufferLine = this._buffer.get(i);
 -      const lineText = this._translateBufferLineToString(bufferLine, true);
 +      const lineText = translateBufferLineToString(bufferLine, true);
        if (bufferLine.isWrapped) {
          result[result.length - 1] += lineText;
        } else {
      // Get final row
      if (start[1] !== end[1]) {
        const bufferLine = this._buffer.get(end[1]);
 -      const lineText = this._translateBufferLineToString(bufferLine, true, 0, end[0]);
 +      const lineText = translateBufferLineToString(bufferLine, true, 0, end[0]);
        if (bufferLine.isWrapped) {
          result[result.length - 1] += lineText;
        } else {
      // and joining the array into a multi-line string.
      const formattedResult = result.map(line => {
        return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' ');
-     }).join('\n');
+     }).join(Browser.isMSWindows ? '\r\n' : '\n');
  
      return formattedResult;
    }
      this.refresh();
    }
  
 -  /**
 -   * Translates a buffer line to a string, with optional start and end columns.
 -   * Wide characters will count as two columns in the resulting string. This
 -   * function is useful for getting the actual text underneath the raw selection
 -   * position.
 -   * @param line The line being translated.
 -   * @param trimRight Whether to trim whitespace to the right.
 -   * @param startCol The column to start at.
 -   * @param endCol The column to end at.
 -   */
 -  private _translateBufferLineToString(line: any, trimRight: boolean, startCol: number = 0, endCol: number = null): string {
 -    // TODO: This function should live in a buffer or buffer line class
 -
 -    // Get full line
 -    let lineString = '';
 -    let widthAdjustedStartCol = startCol;
 -    let widthAdjustedEndCol = endCol;
 -    for (let i = 0; i < line.length; i++) {
 -      const char = line[i];
 -      lineString += char[LINE_DATA_CHAR_INDEX];
 -      // Adjust start and end cols for wide characters if they affect their
 -      // column indexes
 -      if (char[LINE_DATA_WIDTH_INDEX] === 0) {
 -        if (startCol >= i) {
 -          widthAdjustedStartCol--;
 -        }
 -        if (endCol >= i) {
 -          widthAdjustedEndCol--;
 -        }
 -      }
 -    }
 -
 -    // Calculate the final end col by trimming whitespace on the right of the
 -    // line if needed.
 -    let finalEndCol = widthAdjustedEndCol || line.length;
 -    if (trimRight) {
 -      const rightWhitespaceIndex = lineString.search(/\s+$/);
 -      if (rightWhitespaceIndex !== -1) {
 -        finalEndCol = Math.min(finalEndCol, rightWhitespaceIndex);
 -      }
 -      // Return the empty string if only trimmed whitespace is selected
 -      if (finalEndCol <= widthAdjustedStartCol) {
 -        return '';
 -      }
 -    }
 -
 -    return lineString.substring(widthAdjustedStartCol, finalEndCol);
 -  }
 -
    /**
     * Queues a refresh, redrawing the selection on the next opportunity.
     * @param isNewSelection Whether the selection should be registered as a new
      return charIndex;
    }
  
 +  public setSelection(col: number, row: number, length: number): void {
 +    this._model.clearSelection();
 +    this._removeMouseDownListeners();
 +    this._model.selectionStart = [col, row];
 +    this._model.selectionStartLength = length;
 +    this.refresh();
 +  }
 +
    /**
     * Gets positional information for the word at the coordinated specified.
     * @param coords The coordinates to get the word at.
     */
    private _getWordAt(coords: [number, number]): IWordPosition {
      const bufferLine = this._buffer.get(coords[1]);
 -    const line = this._translateBufferLineToString(bufferLine, false);
 +    const line = translateBufferLineToString(bufferLine, false);
  
      // Get actual index, taking into consideration wide characters
      let endIndex = this._convertViewportColToCharacterIndex(bufferLine, coords);
diff --combined src/xterm.js
index 374037886717ae952931ef8dfe0fd2132d6f4d32,dc3b940b849d6e6cc5eedcf67a8534a4e26b8422..7421c9eef1331539d126e4bfe48a8618adf7252d
@@@ -26,7 -26,6 +26,7 @@@ import * as Browser from './utils/Brows
  import * as Mouse from './utils/Mouse';
  import { CHARSETS } from './Charsets';
  import { getRawByteCoords } from './utils/Mouse';
 +import { translateBufferLineToString } from './utils/BufferLine';
  
  /**
   * Terminal Emulation References:
@@@ -420,6 -419,15 +420,15 @@@ Terminal.prototype.setOption = function
    }
    switch (key) {
      case 'scrollback':
+       if (value < this.rows) {
+         let msg = 'Setting the scrollback value less than the number of rows ';
+         msg += `(${this.rows}) is not allowed.`;
+         console.warn(msg);
+         return false;
+       }
        if (this.options[key] !== value) {
          if (this.lines.length > value) {
            const amountToTrim = this.lines.length - value;
@@@ -653,7 -661,6 +662,6 @@@ Terminal.prototype.open = function(pare
    this.element.classList.add('xterm-theme-' + this.theme);
    this.setCursorBlinking(this.options.cursorBlink);
  
-   this.element.style.height;
    this.element.setAttribute('tabindex', 0);
  
    this.viewportElement = document.createElement('div');
@@@ -1088,6 -1095,18 +1096,18 @@@ Terminal.prototype.bindMouse = function
      self.viewport.onWheel(ev);
      return self.cancel(ev);
    });
+   on(el, 'touchstart', function(ev) {
+     if (self.mouseEvents) return;
+     self.viewport.onTouchStart(ev);
+     return self.cancel(ev);
+   });
+   on(el, 'touchmove', function(ev) {
+     if (self.mouseEvents) return;
+     self.viewport.onTouchMove(ev);
+     return self.cancel(ev);
+   });
  };
  
  /**
@@@ -1128,7 -1147,7 +1148,7 @@@ Terminal.prototype.queueLinkification 
        this.linkifier.linkifyRow(i);
      }
    }
- }
+ };
  
  /**
   * Display the cursor element
@@@ -1239,25 -1258,25 +1259,25 @@@ Terminal.prototype.scrollDisp = functio
   */
  Terminal.prototype.scrollPages = function(pageCount) {
    this.scrollDisp(pageCount * (this.rows - 1));
- }
+ };
  
  /**
   * Scrolls the display of the terminal to the top.
   */
  Terminal.prototype.scrollToTop = function() {
    this.scrollDisp(-this.ydisp);
- }
+ };
  
  /**
   * Scrolls the display of the terminal to the bottom.
   */
  Terminal.prototype.scrollToBottom = function() {
    this.scrollDisp(this.ybase - this.ydisp);
- }
+ };
  
  /**
   * Writes text to the terminal.
-  * @param {string} text The text to write to the terminal.
+  * @param {string} data The text to write to the terminal.
   */
  Terminal.prototype.write = function(data) {
    this.writeBuffer.push(data);
        self.innerWrite();
      });
    }
- }
+ };
  
  Terminal.prototype.innerWrite = function() {
    var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);
  
  /**
   * Writes text to the terminal, followed by a break line character (\n).
-  * @param {string} text The text to write to the terminal.
+  * @param {string} data The text to write to the terminal.
   */
  Terminal.prototype.writeln = function(data) {
    this.write(data + '\r\n');
@@@ -1339,25 -1358,25 +1359,25 @@@ Terminal.prototype.attachCustomKeydownH
    let message = 'attachCustomKeydownHandler() is DEPRECATED and will be removed soon. Please use attachCustomKeyEventHandler() instead.';
    console.warn(message);
    this.attachCustomKeyEventHandler(customKeydownHandler);
- }
+ };
  
  /**
   * Attaches a custom key event handler which is run before keys are processed, giving consumers of
   * xterm.js ultimate control as to what keys should be processed by the terminal and what keys
   * should not.
-  * @param {function} customKeypressHandler The custom KeyboardEvent handler to attach. This is a
+  * @param {function} customKeyEventHandler The custom KeyboardEvent handler to attach. This is a
   *   function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent
   *   the default action. The function returns whether the event should be processed by xterm.js.
   */
  Terminal.prototype.attachCustomKeyEventHandler = function(customKeyEventHandler) {
    this.customKeyEventHandler = customKeyEventHandler;
- }
+ };
  
  /**
   * Attaches a http(s) link handler, forcing web links to behave differently to
   * regular <a> tags. This will trigger a refresh as links potentially need to be
   * reconstructed. Calling this with null will remove the handler.
-  * @param {LinkHandler} handler The handler callback function.
+  * @param {LinkMatcherHandler} handler The handler callback function.
   */
  Terminal.prototype.setHypertextLinkHandler = function(handler) {
    if (!this.linkifier) {
    this.linkifier.setHypertextLinkHandler(handler);
    // Refresh to force links to refresh
    this.refresh(0, this.rows - 1);
- }
+ };
  
  /**
   * Attaches a validation callback for hypertext links. This is useful to use
   * @param {LinkMatcherValidationCallback} callback The callback to use, this can
   * be cleared with null.
   */
- Terminal.prototype.setHypertextValidationCallback = function(handler) {
+ Terminal.prototype.setHypertextValidationCallback = function(callback) {
    if (!this.linkifier) {
      throw new Error('Cannot attach a hypertext validation callback before Terminal.open is called');
    }
-   this.linkifier.setHypertextValidationCallback(handler);
+   this.linkifier.setHypertextValidationCallback(callback);
    // Refresh to force links to refresh
    this.refresh(0, this.rows - 1);
- }
+ };
  
  /**
     * Registers a link matcher, allowing custom link patterns to be matched and
     * @param {RegExp} regex The regular expression to search for, specifically
     * this searches the textContent of the rows. You will want to use \s to match
     * a space ' ' character for example.
-    * @param {LinkHandler} handler The callback when the link is called.
+    * @param {LinkMatcherHandler} handler The callback when the link is called.
     * @param {LinkMatcherOptions} [options] Options for the link matcher.
     * @return {number} The ID of the new matcher, this can be used to deregister.
   */
@@@ -1399,7 -1418,7 +1419,7 @@@ Terminal.prototype.registerLinkMatcher 
      this.refresh(0, this.rows - 1);
      return matcherId;
    }
- }
+ };
  
  /**
   * Deregisters a link matcher if it has been registered.
@@@ -1411,14 -1430,14 +1431,14 @@@ Terminal.prototype.deregisterLinkMatche
        this.refresh(0, this.rows - 1);
      }
    }
- }
+ };
  
  /**
   * Gets whether the terminal has an active selection.
   */
  Terminal.prototype.hasSelection = function() {
    return this.selectionManager.hasSelection;
- }
+ };
  
  /**
   * Gets the terminal's current selection, this is useful for implementing copy
   */
  Terminal.prototype.getSelection = function() {
    return this.selectionManager.selectionText;
- }
+ };
  
  /**
   * Clears the current terminal selection.
   */
  Terminal.prototype.clearSelection = function() {
    this.selectionManager.clearSelection();
- }
+ };
  
  /**
   * Selects all text within the terminal.
   */
  Terminal.prototype.selectAll = function() {
    this.selectionManager.selectAll();
- }
+ };
  
  /**
   * Handle a keydown event
@@@ -1908,6 -1927,10 +1928,10 @@@ Terminal.prototype.resize = function(x
      return;
    }
  
+   if (y > this.getOption('scrollback')) {
+     this.setOption('scrollback', y)
+   }
    var line
    , el
    , i
            // There is room above the buffer and there are no empty elements below the line,
            // scroll up
            this.ybase--;
-           addToY++
+           addToY++;
            if (this.ydisp > 0) {
              // Viewport is at the top of the buffer, must increase downwards
              this.ydisp--;
@@@ -2426,7 -2449,6 +2450,7 @@@ function keys(obj) 
   * Expose
   */
  
 +Terminal.translateBufferLineToString = translateBufferLineToString;
  Terminal.EventEmitter = EventEmitter;
  Terminal.inherits = inherits;