/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @implements {UI.Searchable}
 * @implements {UI.Replaceable}
 * @implements {SourceFrame.SourcesTextEditorDelegate}
 * @unrestricted
 */
export class SourceFrameImpl extends UI.SimpleView {
  /**
   * @param {function(): !Promise<!Common.DeferredContent>} lazyContent
   * @param {!UI.TextEditor.Options=} codeMirrorOptions
   */
  constructor(lazyContent, codeMirrorOptions) {
    super(Common.UIString('Source'));

    this._lazyContent = lazyContent;

    this._pretty = false;
    /** @type {?string} */
    this._rawContent = null;
    /** @type {?Promise<{content: string, map: !Formatter.FormatterSourceMapping}>} */
    this._formattedContentPromise = null;
    /** @type {?Formatter.FormatterSourceMapping} */
    this._formattedMap = null;
    this._prettyToggle = new UI.ToolbarToggle(ls`Pretty print`, 'largeicon-pretty-print');
    this._prettyToggle.addEventListener(UI.ToolbarButton.Events.Click, () => {
      this._setPretty(!this._prettyToggle.toggled());
    });
    this._shouldAutoPrettyPrint = false;
    this._prettyToggle.setVisible(false);

    this._textEditor = new SourceFrame.SourcesTextEditor(this, codeMirrorOptions);
    this._textEditor.show(this.element);

    /** @type {?number} */
    this._prettyCleanGeneration = null;
    this._cleanGeneration = 0;

    this._searchConfig = null;
    this._delayedFindSearchMatches = null;
    this._currentSearchResultIndex = -1;
    this._searchResults = [];
    this._searchRegex = null;
    this._loadError = false;

    this._textEditor.addEventListener(
        SourceFrame.SourcesTextEditor.Events.EditorFocused, this._resetCurrentSearchResultIndex, this);
    this._textEditor.addEventListener(
        SourceFrame.SourcesTextEditor.Events.SelectionChanged, this._updateSourcePosition, this);
    this._textEditor.addEventListener(UI.TextEditor.Events.TextChanged, event => {
      if (!this._muteChangeEventsForSetContent) {
        this.onTextChanged(event.data.oldRange, event.data.newRange);
      }
    });
    /** @type {boolean} */
    this._muteChangeEventsForSetContent = false;

    this._sourcePosition = new UI.ToolbarText();

    /**
     * @type {?UI.SearchableView}
     */
    this._searchableView = null;
    this._editable = false;
    this._textEditor.setReadOnly(true);

    /** @type {?{line: number, column: (number|undefined), shouldHighlight: (boolean|undefined)}} */
    this._positionToReveal = null;
    this._lineToScrollTo = null;
    this._selectionToSet = null;
    this._loaded = false;
    this._contentRequested = false;
    this._highlighterType = '';
    /** @type {!SourceFrame.Transformer} */
    this._transformer = {
      /**
       * @param {number} editorLineNumber
       * @param {number=} editorColumnNumber
       * @return {!Array<number>}
       */
      editorToRawLocation: (editorLineNumber, editorColumnNumber = 0) => {
        if (!this._pretty) {
          return [editorLineNumber, editorColumnNumber];
        }
        return this._prettyToRawLocation(editorLineNumber, editorColumnNumber);
      },

      /**
       * @param {number} lineNumber
       * @param {number=} columnNumber
       * @return {!Array<number>}
       */
      rawToEditorLocation: (lineNumber, columnNumber = 0) => {
        if (!this._pretty) {
          return [lineNumber, columnNumber];
        }
        return this._rawToPrettyLocation(lineNumber, columnNumber);
      }
    };
  }

  /**
   * @param {boolean} canPrettyPrint
   * @param {boolean=} autoPrettyPrint
   */
  setCanPrettyPrint(canPrettyPrint, autoPrettyPrint) {
    this._shouldAutoPrettyPrint = canPrettyPrint && !!autoPrettyPrint;
    this._prettyToggle.setVisible(canPrettyPrint);
  }

  /**
   * @param {boolean} value
   * @return {!Promise}
   */
  async _setPretty(value) {
    this._pretty = value;
    this._prettyToggle.setEnabled(false);

    const wasLoaded = this.loaded;
    const selection = this.selection();
    let newSelection;
    if (this._pretty) {
      const formatInfo = await this._requestFormattedContent();
      this._formattedMap = formatInfo.map;
      this.setContent(formatInfo.content, null);
      this._prettyCleanGeneration = this._textEditor.markClean();
      const start = this._rawToPrettyLocation(selection.startLine, selection.startColumn);
      const end = this._rawToPrettyLocation(selection.endLine, selection.endColumn);
      newSelection = new TextUtils.TextRange(start[0], start[1], end[0], end[1]);
    } else {
      this.setContent(this._rawContent, null);
      this._cleanGeneration = this._textEditor.markClean();
      const start = this._prettyToRawLocation(selection.startLine, selection.startColumn);
      const end = this._prettyToRawLocation(selection.endLine, selection.endColumn);
      newSelection = new TextUtils.TextRange(start[0], start[1], end[0], end[1]);
    }
    if (wasLoaded) {
      this.textEditor.revealPosition(newSelection.endLine, newSelection.endColumn, this._editable);
      this.textEditor.setSelection(newSelection);
    }
    this._prettyToggle.setEnabled(true);
    this._updatePrettyPrintState();
  }

  _updatePrettyPrintState() {
    this._prettyToggle.setToggled(this._pretty);
    this._textEditor.element.classList.toggle('pretty-printed', this._pretty);
    if (this._pretty) {
      this._textEditor.setLineNumberFormatter(lineNumber => {
        const line = this._prettyToRawLocation(lineNumber - 1, 0)[0] + 1;
        if (lineNumber === 1) {
          return String(line);
        }
        if (line !== this._prettyToRawLocation(lineNumber - 2, 0)[0] + 1) {
          return String(line);
        }
        return '-';
      });
    } else {
      this._textEditor.setLineNumberFormatter(lineNumber => {
        return String(lineNumber);
      });
    }
  }

  /**
   * @return {!SourceFrame.Transformer}
   */
  transformer() {
    return this._transformer;
  }


  /**
   * @param {number} line
   * @param {number} column
   * @return {!Array<number>}
   */
  _prettyToRawLocation(line, column) {
    if (!this._formattedMap) {
      return [line, column];
    }
    return this._formattedMap.formattedToOriginal(line, column);
  }

  /**
   * @param {number} line
   * @param {number} column
   * @return {!Array<number>}
   */
  _rawToPrettyLocation(line, column) {
    if (!this._formattedMap) {
      return [line, column];
    }
    return this._formattedMap.originalToFormatted(line, column);
  }

  /**
   * @param {boolean} editable
   * @protected
   */
  setEditable(editable) {
    this._editable = editable;
    if (this._loaded) {
      this._textEditor.setReadOnly(!editable);
    }
  }

  /**
   * @return {boolean}
   */
  hasLoadError() {
    return this._loadError;
  }

  /**
   * @override
   */
  wasShown() {
    this._ensureContentLoaded();
    this._wasShownOrLoaded();
  }

  /**
   * @override
   */
  willHide() {
    super.willHide();

    this._clearPositionToReveal();
  }

  /**
   * @override
   * @return {!Array<!UI.ToolbarItem>}
   */
  syncToolbarItems() {
    return [this._prettyToggle, this._sourcePosition];
  }

  get loaded() {
    return this._loaded;
  }

  get textEditor() {
    return this._textEditor;
  }

  /**
   * @protected
   */
  get pretty() {
    return this._pretty;
  }

  async _ensureContentLoaded() {
    if (!this._contentRequested) {
      this._contentRequested = true;
      const {content, error} = (await this._lazyContent());
      this._rawContent = error || content || '';
      this._formattedContentPromise = null;
      this._formattedMap = null;
      this._prettyToggle.setEnabled(true);

      if (error) {
        this.setContent(null, error);
        this._prettyToggle.setEnabled(false);

        // Occasionally on load, there can be a race in which it appears the CodeMirror plugin
        // runs the highlighter type assignment out of order. In case of an error then, set
        // the highlighter type after a short delay. This appears to only occur the first
        // time that CodeMirror is initialized, likely because the highlighter type was first
        // initialized based on the file type, and the syntax highlighting is in a race
        // with the new highlighter assignment. As the option is just an option and is not
        // observable, we can't handle waiting for it here.
        // https://github.com/codemirror/CodeMirror/issues/6019
        // CRBug 1011445
        setTimeout(() => this.setHighlighterType('text/plain'), 50);
      } else {
        if (this._shouldAutoPrettyPrint && TextUtils.isMinified(content || '')) {
          await this._setPretty(true);
        } else {
          this.setContent(this._rawContent, null);
        }
      }
    }
  }

  /**
   * @return {!Promise<{content: string, map: !Formatter.FormatterSourceMapping}>}
   */
  _requestFormattedContent() {
    if (this._formattedContentPromise) {
      return this._formattedContentPromise;
    }
    let fulfill;
    this._formattedContentPromise = new Promise(x => fulfill = x);
    new Formatter.ScriptFormatter(this._highlighterType, this._rawContent || '', (content, map) => {
      fulfill({content, map});
    });
    return this._formattedContentPromise;
  }

  /**
   * @param {number} line 0-based
   * @param {number=} column
   * @param {boolean=} shouldHighlight
   */
  revealPosition(line, column, shouldHighlight) {
    this._lineToScrollTo = null;
    this._selectionToSet = null;
    this._positionToReveal = {line: line, column: column, shouldHighlight: shouldHighlight};
    this._innerRevealPositionIfNeeded();
  }

  _innerRevealPositionIfNeeded() {
    if (!this._positionToReveal) {
      return;
    }

    if (!this.loaded || !this.isShowing()) {
      return;
    }

    const [line, column] =
        this._transformer.rawToEditorLocation(this._positionToReveal.line, this._positionToReveal.column);

    this._textEditor.revealPosition(line, column, this._positionToReveal.shouldHighlight);
    this._positionToReveal = null;
  }

  _clearPositionToReveal() {
    this._textEditor.clearPositionHighlight();
    this._positionToReveal = null;
  }

  /**
   * @param {number} line
   */
  scrollToLine(line) {
    this._clearPositionToReveal();
    this._lineToScrollTo = line;
    this._innerScrollToLineIfNeeded();
  }

  _innerScrollToLineIfNeeded() {
    if (this._lineToScrollTo !== null) {
      if (this.loaded && this.isShowing()) {
        this._textEditor.scrollToLine(this._lineToScrollTo);
        this._lineToScrollTo = null;
      }
    }
  }

  /**
   * @return {!TextUtils.TextRange}
   */
  selection() {
    return this.textEditor.selection();
  }

  /**
   * @param {!TextUtils.TextRange} textRange
   */
  setSelection(textRange) {
    this._selectionToSet = textRange;
    this._innerSetSelectionIfNeeded();
  }

  _innerSetSelectionIfNeeded() {
    if (this._selectionToSet && this.loaded && this.isShowing()) {
      this._textEditor.setSelection(this._selectionToSet, true);
      this._selectionToSet = null;
    }
  }

  _wasShownOrLoaded() {
    this._innerRevealPositionIfNeeded();
    this._innerSetSelectionIfNeeded();
    this._innerScrollToLineIfNeeded();
  }

  /**
   * @param {!TextUtils.TextRange} oldRange
   * @param {!TextUtils.TextRange} newRange
   */
  onTextChanged(oldRange, newRange) {
    const wasPretty = this.pretty;
    this._pretty = this._prettyCleanGeneration !== null && this.textEditor.isClean(this._prettyCleanGeneration);
    if (this._pretty !== wasPretty) {
      this._updatePrettyPrintState();
    }
    this._prettyToggle.setEnabled(this.isClean());

    if (this._searchConfig && this._searchableView) {
      this.performSearch(this._searchConfig, false, false);
    }
  }

  /**
   * @return {boolean}
   */
  isClean() {
    return this.textEditor.isClean(this._cleanGeneration) ||
        (this._prettyCleanGeneration !== null && this.textEditor.isClean(this._prettyCleanGeneration));
  }

  contentCommitted() {
    this._cleanGeneration = this._textEditor.markClean();
    this._prettyCleanGeneration = null;
    this._rawContent = this.textEditor.text();
    this._formattedMap = null;
    this._formattedContentPromise = null;
    if (this._pretty) {
      this._pretty = false;
      this._updatePrettyPrintState();
    }
    this._prettyToggle.setEnabled(true);
  }

  /**
   * @param {string} content
   * @param {string} mimeType
   * @return {string}
   */
  _simplifyMimeType(content, mimeType) {
    if (!mimeType) {
      return '';
    }
    // There are plenty of instances where TSX/JSX files are served with out the trailing x, i.e. JSX with a 'js' suffix
    // which breaks the formatting. Therefore, if the mime type is TypeScript or JavaScript, we switch to the TSX/JSX
    // superset so that we don't break formatting.
    if (mimeType.indexOf('typescript') >= 0) {
      return 'text/typescript-jsx';
    }
    if (mimeType.indexOf('javascript') >= 0 || mimeType.indexOf('jscript') >= 0 ||
        mimeType.indexOf('ecmascript') >= 0) {
      return 'text/jsx';
    }
    // A hack around the fact that files with "php" extension might be either standalone or html embedded php scripts.
    if (mimeType === 'text/x-php' && content.match(/\<\?.*\?\>/g)) {
      return 'application/x-httpd-php';
    }
    return mimeType;
  }

  /**
   * @param {string} highlighterType
   */
  setHighlighterType(highlighterType) {
    this._highlighterType = highlighterType;
    this._updateHighlighterType('');
  }

  /**
   * @protected
   * @return {string}
   */
  highlighterType() {
    return this._highlighterType;
  }

  /**
   * @param {string} content
   */
  _updateHighlighterType(content) {
    this._textEditor.setMimeType(this._simplifyMimeType(content, this._highlighterType));
  }

  /**
   * @param {?string} content
   * @param {?string} loadError
   */
  setContent(content, loadError) {
    this._muteChangeEventsForSetContent = true;
    if (!this._loaded) {
      this._loaded = true;
      if (!loadError) {
        this._textEditor.setText(content || '');
        this._cleanGeneration = this._textEditor.markClean();
        this._textEditor.setReadOnly(!this._editable);
        this._loadError = false;
      } else {
        this._textEditor.setText(loadError || '');
        this._highlighterType = 'text/plain';
        this._textEditor.setReadOnly(true);
        this._loadError = true;
      }
    } else {
      const scrollTop = this._textEditor.scrollTop();
      const selection = this._textEditor.selection();
      this._textEditor.setText(content || '');
      this._textEditor.setScrollTop(scrollTop);
      this._textEditor.setSelection(selection);
    }

    this._updateHighlighterType(content || '');
    this._wasShownOrLoaded();

    if (this._delayedFindSearchMatches) {
      this._delayedFindSearchMatches();
      this._delayedFindSearchMatches = null;
    }
    this._muteChangeEventsForSetContent = false;
  }

  /**
   * @param {?UI.SearchableView} view
   */
  setSearchableView(view) {
    this._searchableView = view;
  }

  /**
   * @param {!UI.SearchableView.SearchConfig} searchConfig
   * @param {boolean} shouldJump
   * @param {boolean} jumpBackwards
   */
  _doFindSearchMatches(searchConfig, shouldJump, jumpBackwards) {
    this._currentSearchResultIndex = -1;
    this._searchResults = [];

    const regex = searchConfig.toSearchRegex();
    this._searchRegex = regex;
    this._searchResults = this._collectRegexMatches(regex);

    if (this._searchableView) {
      this._searchableView.updateSearchMatchesCount(this._searchResults.length);
    }

    if (!this._searchResults.length) {
      this._textEditor.cancelSearchResultsHighlight();
    } else if (shouldJump && jumpBackwards) {
      this.jumpToPreviousSearchResult();
    } else if (shouldJump) {
      this.jumpToNextSearchResult();
    } else {
      this._textEditor.highlightSearchResults(regex, null);
    }
  }

  /**
   * @override
   * @param {!UI.SearchableView.SearchConfig} searchConfig
   * @param {boolean} shouldJump
   * @param {boolean=} jumpBackwards
   */
  performSearch(searchConfig, shouldJump, jumpBackwards) {
    if (this._searchableView) {
      this._searchableView.updateSearchMatchesCount(0);
    }

    this._resetSearch();
    this._searchConfig = searchConfig;
    if (this.loaded) {
      this._doFindSearchMatches(searchConfig, shouldJump, !!jumpBackwards);
    } else {
      this._delayedFindSearchMatches = this._doFindSearchMatches.bind(this, searchConfig, shouldJump, !!jumpBackwards);
    }

    this._ensureContentLoaded();
  }

  _resetCurrentSearchResultIndex() {
    if (!this._searchResults.length) {
      return;
    }
    this._currentSearchResultIndex = -1;
    if (this._searchableView) {
      this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);
    }
    this._textEditor.highlightSearchResults(/** @type {!RegExp} */ (this._searchRegex), null);
  }

  _resetSearch() {
    this._searchConfig = null;
    this._delayedFindSearchMatches = null;
    this._currentSearchResultIndex = -1;
    this._searchResults = [];
    this._searchRegex = null;
  }

  /**
   * @override
   */
  searchCanceled() {
    const range = this._currentSearchResultIndex !== -1 ? this._searchResults[this._currentSearchResultIndex] : null;
    this._resetSearch();
    if (!this.loaded) {
      return;
    }
    this._textEditor.cancelSearchResultsHighlight();
    if (range) {
      this.setSelection(range);
    }
  }

  jumpToLastSearchResult() {
    this.jumpToSearchResult(this._searchResults.length - 1);
  }

  /**
   * @return {number}
   */
  _searchResultIndexForCurrentSelection() {
    return this._searchResults.lowerBound(this._textEditor.selection().collapseToEnd(), TextUtils.TextRange.comparator);
  }

  /**
   * @override
   */
  jumpToNextSearchResult() {
    const currentIndex = this._searchResultIndexForCurrentSelection();
    const nextIndex = this._currentSearchResultIndex === -1 ? currentIndex : currentIndex + 1;
    this.jumpToSearchResult(nextIndex);
  }

  /**
   * @override
   */
  jumpToPreviousSearchResult() {
    const currentIndex = this._searchResultIndexForCurrentSelection();
    this.jumpToSearchResult(currentIndex - 1);
  }

  /**
   * @override
   * @return {boolean}
   */
  supportsCaseSensitiveSearch() {
    return true;
  }

  /**
   * @override
   * @return {boolean}
   */
  supportsRegexSearch() {
    return true;
  }

  jumpToSearchResult(index) {
    if (!this.loaded || !this._searchResults.length) {
      return;
    }
    this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
    if (this._searchableView) {
      this._searchableView.updateCurrentMatchIndex(this._currentSearchResultIndex);
    }
    this._textEditor.highlightSearchResults(
        /** @type {!RegExp} */ (this._searchRegex), this._searchResults[this._currentSearchResultIndex]);
  }

  /**
   * @override
   * @param {!UI.SearchableView.SearchConfig} searchConfig
   * @param {string} replacement
   */
  replaceSelectionWith(searchConfig, replacement) {
    const range = this._searchResults[this._currentSearchResultIndex];
    if (!range) {
      return;
    }
    this._textEditor.highlightSearchResults(/** @type {!RegExp} */ (this._searchRegex), null);

    const oldText = this._textEditor.text(range);
    const regex = searchConfig.toSearchRegex();
    let text;
    if (regex.__fromRegExpQuery) {
      text = oldText.replace(regex, replacement);
    } else {
      text = oldText.replace(regex, function() {
        return replacement;
      });
    }

    const newRange = this._textEditor.editRange(range, text);
    this._textEditor.setSelection(newRange.collapseToEnd());
  }

  /**
   * @override
   * @param {!UI.SearchableView.SearchConfig} searchConfig
   * @param {string} replacement
   */
  replaceAllWith(searchConfig, replacement) {
    this._resetCurrentSearchResultIndex();

    let text = this._textEditor.text();
    const range = this._textEditor.fullRange();

    const regex = searchConfig.toSearchRegex(true);
    if (regex.__fromRegExpQuery) {
      text = text.replace(regex, replacement);
    } else {
      text = text.replace(regex, function() {
        return replacement;
      });
    }

    const ranges = this._collectRegexMatches(regex);
    if (!ranges.length) {
      return;
    }

    // Calculate the position of the end of the last range to be edited.
    const currentRangeIndex = ranges.lowerBound(this._textEditor.selection(), TextUtils.TextRange.comparator);
    const lastRangeIndex = mod(currentRangeIndex - 1, ranges.length);
    const lastRange = ranges[lastRangeIndex];
    const replacementLineEndings = replacement.computeLineEndings();
    const replacementLineCount = replacementLineEndings.length;
    const lastLineNumber = lastRange.startLine + replacementLineEndings.length - 1;
    let lastColumnNumber = lastRange.startColumn;
    if (replacementLineEndings.length > 1) {
      lastColumnNumber =
          replacementLineEndings[replacementLineCount - 1] - replacementLineEndings[replacementLineCount - 2] - 1;
    }

    this._textEditor.editRange(range, text);
    this._textEditor.revealPosition(lastLineNumber, lastColumnNumber);
    this._textEditor.setSelection(TextUtils.TextRange.createFromLocation(lastLineNumber, lastColumnNumber));
  }

  _collectRegexMatches(regexObject) {
    const ranges = [];
    for (let i = 0; i < this._textEditor.linesCount; ++i) {
      let line = this._textEditor.line(i);
      let offset = 0;
      let match;
      do {
        match = regexObject.exec(line);
        if (match) {
          const matchEndIndex = match.index + Math.max(match[0].length, 1);
          if (match[0].length) {
            ranges.push(new TextUtils.TextRange(i, offset + match.index, i, offset + matchEndIndex));
          }
          offset += matchEndIndex;
          line = line.substring(matchEndIndex);
        }
      } while (match && line);
    }
    return ranges;
  }

  /**
   * @override
   * @return {!Promise}
   */
  populateLineGutterContextMenu(contextMenu, editorLineNumber) {
    return Promise.resolve();
  }

  /**
   * @override
   * @return {!Promise}
   */
  populateTextAreaContextMenu(contextMenu, editorLineNumber, editorColumnNumber) {
    return Promise.resolve();
  }

  /**
   * @return {boolean}
   */
  canEditSource() {
    return this._editable;
  }

  _updateSourcePosition() {
    const selections = this._textEditor.selections();
    if (!selections.length) {
      return;
    }
    if (selections.length > 1) {
      this._sourcePosition.setText(Common.UIString('%d selection regions', selections.length));
      return;
    }
    let textRange = selections[0];
    if (textRange.isEmpty()) {
      const location = this._prettyToRawLocation(textRange.endLine, textRange.endColumn);
      this._sourcePosition.setText(ls`Line ${location[0] + 1}, Column ${location[1] + 1}`);
      return;
    }
    textRange = textRange.normalize();

    const selectedText = this._textEditor.text(textRange);
    if (textRange.startLine === textRange.endLine) {
      this._sourcePosition.setText(Common.UIString('%d characters selected', selectedText.length));
    } else {
      this._sourcePosition.setText(Common.UIString(
          '%d lines, %d characters selected', textRange.endLine - textRange.startLine + 1, selectedText.length));
    }
  }
}

/**
 * @interface
 */
export class LineDecorator {
  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
   * @param {string} type
   */
  decorate(uiSourceCode, textEditor, type) {}
}

/* Legacy exported object */
self.SourceFrame = self.SourceFrame || {};

/* Legacy exported object */
SourceFrame = SourceFrame || {};

/** @constructor */
SourceFrame.SourceFrame = SourceFrameImpl;

/** @interface */
SourceFrame.LineDecorator = LineDecorator;

/**
 * @typedef {{
  *  editorToRawLocation: function(number, number=):!Array<number>,
  *  rawToEditorLocation: function(number, number=):!Array<number>
  * }}
  */
SourceFrame.Transformer;
