// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
 * @implements {Sources.TabbedEditorContainerDelegate}
 * @implements {UI.Searchable}
 * @implements {UI.Replaceable}
 * @unrestricted
 */
Sources.SourcesView = class extends UI.VBox {
  /**
   * @suppressGlobalPropertiesCheck
   */
  constructor() {
    super();
    this.registerRequiredCSS('sources/sourcesView.css');
    this.element.id = 'sources-panel-sources-view';
    this.setMinimumAndPreferredSizes(88, 52, 150, 100);

    const workspace = Workspace.workspace;

    this._searchableView = new UI.SearchableView(this, 'sourcesViewSearchConfig');
    this._searchableView.setMinimalSearchQuerySize(0);
    this._searchableView.show(this.element);

    /** @type {!Map.<!Workspace.UISourceCode, !UI.Widget>} */
    this._sourceViewByUISourceCode = new Map();

    this._editorContainer = new Sources.TabbedEditorContainer(
        this, Common.settings.createLocalSetting('previouslyViewedFiles', []), this._placeholderElement(),
        this._focusedPlaceholderElement);
    this._editorContainer.show(this._searchableView.element);
    this._editorContainer.addEventListener(
        Sources.TabbedEditorContainer.Events.EditorSelected, this._editorSelected, this);
    this._editorContainer.addEventListener(Sources.TabbedEditorContainer.Events.EditorClosed, this._editorClosed, this);

    this._historyManager = new Sources.EditingLocationHistoryManager(this, this.currentSourceFrame.bind(this));

    this._toolbarContainerElement = this.element.createChild('div', 'sources-toolbar');
    if (!Root.Runtime.experiments.isEnabled('sourcesPrettyPrint')) {
      this._toolbarEditorActions = new UI.Toolbar('', this._toolbarContainerElement);
      self.runtime.allInstances(Sources.SourcesView.EditorAction).then(appendButtonsForExtensions.bind(this));
    }
    /**
     * @param {!Array.<!Sources.SourcesView.EditorAction>} actions
     * @this {Sources.SourcesView}
     */
    function appendButtonsForExtensions(actions) {
      for (let i = 0; i < actions.length; ++i) {
        this._toolbarEditorActions.appendToolbarItem(actions[i].button(this));
      }
    }
    this._scriptViewToolbar = new UI.Toolbar('', this._toolbarContainerElement);
    this._scriptViewToolbar.element.style.flex = 'auto';
    this._bottomToolbar = new UI.Toolbar('', this._toolbarContainerElement);

    /** @type {?Common.EventTarget.EventDescriptor} */
    this._toolbarChangedListener = null;

    UI.startBatchUpdate();
    workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
    UI.endBatchUpdate();

    workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
    workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this);
    workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this._projectRemoved.bind(this), this);

    /**
     * @param {!Event} event
     */
    function handleBeforeUnload(event) {
      if (event.returnValue) {
        return;
      }

      let unsavedSourceCodes = [];
      const projects = Workspace.workspace.projectsForType(Workspace.projectTypes.FileSystem);
      for (let i = 0; i < projects.length; ++i) {
        unsavedSourceCodes =
            unsavedSourceCodes.concat(projects[i].uiSourceCodes().filter(sourceCode => sourceCode.isDirty()));
      }

      if (!unsavedSourceCodes.length) {
        return;
      }

      event.returnValue = Common.UIString('DevTools have unsaved changes that will be permanently lost.');
      UI.viewManager.showView('sources');
      for (let i = 0; i < unsavedSourceCodes.length; ++i) {
        Common.Revealer.reveal(unsavedSourceCodes[i]);
      }
    }

    if (!window.opener) {
      window.addEventListener('beforeunload', handleBeforeUnload, true);
    }

    this._shortcuts = {};
    this.element.addEventListener('keydown', this._handleKeyDown.bind(this), false);
  }

  /**
   * @return {!Element}
   */
  _placeholderElement() {
    /** @type {!Array.<{element: !Element, handler: !Function}>} */
    this._placeholderOptionArray = [];

    const shortcuts = [
      {actionId: 'quickOpen.show', description: ls`Open file`},
      {actionId: 'commandMenu.show', description: ls`Run command`},
      {actionId: 'sources.add-folder-to-workspace', description: ls`Drop in a folder to add to workspace`}
    ];

    const element = createElementWithClass('div');
    const list = element.createChild('div', 'tabbed-pane-placeholder');
    list.addEventListener('keydown', this._placeholderOnKeyDown.bind(this), false);
    UI.ARIAUtils.markAsList(list);
    UI.ARIAUtils.setAccessibleName(list, ls`Source View Actions`);

    for (let i = 0; i < shortcuts.length; i++) {
      const shortcut = shortcuts[i];
      const shortcutKeyText = UI.shortcutRegistry.shortcutTitleForAction(shortcut.actionId);
      const listItemElement = list.createChild('div');
      UI.ARIAUtils.markAsListitem(listItemElement);
      const row = listItemElement.createChild('div', 'tabbed-pane-placeholder-row');
      row.tabIndex = -1;
      UI.ARIAUtils.markAsButton(row);
      if (shortcutKeyText) {
        row.createChild('div', 'tabbed-pane-placeholder-key').textContent = shortcutKeyText;
        row.createChild('div', 'tabbed-pane-placeholder-value').textContent = shortcut.description;
      } else {
        row.createChild('div', 'tabbed-pane-no-shortcut').textContent = shortcut.description;
      }
      const action = UI.actionRegistry.action(shortcut.actionId);
      const actionHandler = action.execute.bind(action);
      this._placeholderOptionArray.push({element: row, handler: actionHandler});
    }

    const firstElement = this._placeholderOptionArray[0].element;
    firstElement.tabIndex = 0;
    this._focusedPlaceholderElement = firstElement;
    this._selectedIndex = 0;

    element.appendChild(UI.XLink.create(
        'https://developers.google.com/web/tools/chrome-devtools/sources?utm_source=devtools&utm_campaign=2018Q1',
        'Learn more'));

    return element;
  }

  /**
   * @param {!Event} event
   */
  _placeholderOnKeyDown(event) {
    if (isEnterOrSpaceKey(event)) {
      this._placeholderOptionArray[this._selectedIndex].handler.call();
      return;
    }

    let offset = 0;
    if (event.key === 'ArrowDown') {
      offset = 1;
    } else if (event.key === 'ArrowUp') {
      offset = -1;
    }

    const newIndex = Math.max(Math.min(this._placeholderOptionArray.length - 1, this._selectedIndex + offset), 0);
    const newElement = this._placeholderOptionArray[newIndex].element;
    const oldElement = this._placeholderOptionArray[this._selectedIndex].element;
    if (newElement !== oldElement) {
      oldElement.tabIndex = -1;
      newElement.tabIndex = 0;
      UI.ARIAUtils.setSelected(oldElement, false);
      UI.ARIAUtils.setSelected(newElement, true);
      this._selectedIndex = newIndex;
      newElement.focus();
    }
  }

  _resetPlaceholderState() {
    this._placeholderOptionArray[this._selectedIndex].element.tabIndex = -1;
    this._placeholderOptionArray[0].element.tabIndex = 0;
    this._selectedIndex = 0;
  }

  /**
   * @return {!Map.<!Workspace.UISourceCode, number>}
   */
  static defaultUISourceCodeScores() {
    /** @type {!Map.<!Workspace.UISourceCode, number>} */
    const defaultScores = new Map();
    const sourcesView = UI.context.flavor(Sources.SourcesView);
    if (sourcesView) {
      const uiSourceCodes = sourcesView._editorContainer.historyUISourceCodes();
      for (let i = 1; i < uiSourceCodes.length; ++i)  // Skip current element
      {
        defaultScores.set(uiSourceCodes[i], uiSourceCodes.length - i);
      }
    }
    return defaultScores;
  }

  /**
   * @return {!UI.Toolbar}
   */
  leftToolbar() {
    return this._editorContainer.leftToolbar();
  }

  /**
   * @return {!UI.Toolbar}
   */
  rightToolbar() {
    return this._editorContainer.rightToolbar();
  }

  /**
   * @return {!UI.Toolbar}
   */
  bottomToolbar() {
    return this._bottomToolbar;
  }

  /**
   * @param {!Array.<!UI.KeyboardShortcut.Descriptor>} keys
   * @param {function(!Event=):boolean} handler
   */
  _registerShortcuts(keys, handler) {
    for (let i = 0; i < keys.length; ++i) {
      this._shortcuts[keys[i].key] = handler;
    }
  }

  _handleKeyDown(event) {
    const shortcutKey = UI.KeyboardShortcut.makeKeyFromEvent(event);
    const handler = this._shortcuts[shortcutKey];
    if (handler && handler()) {
      event.consume(true);
    }
  }

  /**
   * @override
   */
  wasShown() {
    super.wasShown();
    UI.context.setFlavor(Sources.SourcesView, this);
  }

  /**
   * @override
   */
  willHide() {
    UI.context.setFlavor(Sources.SourcesView, null);
    this._resetPlaceholderState();
    super.willHide();
  }

  /**
   * @return {!Element}
   */
  toolbarContainerElement() {
    return this._toolbarContainerElement;
  }

  /**
   * @return {!UI.SearchableView}
   */
  searchableView() {
    return this._searchableView;
  }

  /**
   * @return {?UI.Widget}
   */
  visibleView() {
    return this._editorContainer.visibleView;
  }

  /**
   * @return {?Sources.UISourceCodeFrame}
   */
  currentSourceFrame() {
    const view = this.visibleView();
    if (!(view instanceof Sources.UISourceCodeFrame)) {
      return null;
    }
    return /** @type {!Sources.UISourceCodeFrame} */ (view);
  }

  /**
   * @return {?Workspace.UISourceCode}
   */
  currentUISourceCode() {
    return this._editorContainer.currentFile();
  }

  /**
   * @return {boolean}
   */
  _onCloseEditorTab() {
    const uiSourceCode = this._editorContainer.currentFile();
    if (!uiSourceCode) {
      return false;
    }
    this._editorContainer.closeFile(uiSourceCode);
    return true;
  }

  _onJumpToPreviousLocation() {
    this._historyManager.rollback();
  }

  _onJumpToNextLocation() {
    this._historyManager.rollover();
  }

  /**
   * @param {!Common.Event} event
   */
  _uiSourceCodeAdded(event) {
    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
    this._addUISourceCode(uiSourceCode);
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  _addUISourceCode(uiSourceCode) {
    if (uiSourceCode.project().isServiceProject()) {
      return;
    }
    if (uiSourceCode.project().type() === Workspace.projectTypes.FileSystem &&
        Persistence.FileSystemWorkspaceBinding.fileSystemType(uiSourceCode.project()) === 'overrides') {
      return;
    }
    this._editorContainer.addUISourceCode(uiSourceCode);
  }

  _uiSourceCodeRemoved(event) {
    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
    this._removeUISourceCodes([uiSourceCode]);
  }

  /**
   * @param {!Array.<!Workspace.UISourceCode>} uiSourceCodes
   */
  _removeUISourceCodes(uiSourceCodes) {
    this._editorContainer.removeUISourceCodes(uiSourceCodes);
    for (let i = 0; i < uiSourceCodes.length; ++i) {
      this._removeSourceFrame(uiSourceCodes[i]);
      this._historyManager.removeHistoryForSourceCode(uiSourceCodes[i]);
    }
  }

  _projectRemoved(event) {
    const project = event.data;
    const uiSourceCodes = project.uiSourceCodes();
    this._removeUISourceCodes(uiSourceCodes);
  }

  _updateScriptViewToolbarItems() {
    this._scriptViewToolbar.removeToolbarItems();
    const view = this.visibleView();
    if (view instanceof UI.SimpleView) {
      for (const item of (/** @type {?UI.SimpleView} */ (view)).syncToolbarItems()) {
        this._scriptViewToolbar.appendToolbarItem(item);
      }
    }
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @param {number=} lineNumber 0-based
   * @param {number=} columnNumber
   * @param {boolean=} omitFocus
   * @param {boolean=} omitHighlight
   */
  showSourceLocation(uiSourceCode, lineNumber, columnNumber, omitFocus, omitHighlight) {
    this._historyManager.updateCurrentState();
    this._editorContainer.showFile(uiSourceCode);
    const currentSourceFrame = this.currentSourceFrame();
    if (currentSourceFrame && typeof lineNumber === 'number') {
      currentSourceFrame.revealPosition(lineNumber, columnNumber, !omitHighlight);
    }
    this._historyManager.pushNewState();
    if (!omitFocus) {
      this.visibleView().focus();
    }
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @return {!UI.Widget}
   */
  _createSourceView(uiSourceCode) {
    let sourceFrame;
    let sourceView;
    const contentType = uiSourceCode.contentType();

    if (contentType === Common.resourceTypes.Image) {
      sourceView = new SourceFrame.ImageView(uiSourceCode.mimeType(), uiSourceCode);
    } else if (contentType === Common.resourceTypes.Font) {
      sourceView = new SourceFrame.FontView(uiSourceCode.mimeType(), uiSourceCode);
    } else {
      sourceFrame = new Sources.UISourceCodeFrame(uiSourceCode);
    }

    if (sourceFrame) {
      this._historyManager.trackSourceFrameCursorJumps(sourceFrame);
    }

    const widget = /** @type {!UI.Widget} */ (sourceFrame || sourceView);
    this._sourceViewByUISourceCode.set(uiSourceCode, widget);
    return widget;
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @return {!UI.Widget}
   */
  _getOrCreateSourceView(uiSourceCode) {
    return this._sourceViewByUISourceCode.get(uiSourceCode) || this._createSourceView(uiSourceCode);
  }

  /**
   * @override
   * @param {!Sources.UISourceCodeFrame} sourceFrame
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  recycleUISourceCodeFrame(sourceFrame, uiSourceCode) {
    this._sourceViewByUISourceCode.delete(sourceFrame.uiSourceCode());
    sourceFrame.setUISourceCode(uiSourceCode);
    this._sourceViewByUISourceCode.set(uiSourceCode, sourceFrame);
  }

  /**
   * @override
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @return {!UI.Widget}
   */
  viewForFile(uiSourceCode) {
    return this._getOrCreateSourceView(uiSourceCode);
  }

  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  _removeSourceFrame(uiSourceCode) {
    const sourceView = this._sourceViewByUISourceCode.get(uiSourceCode);
    this._sourceViewByUISourceCode.remove(uiSourceCode);
    if (sourceView && sourceView instanceof Sources.UISourceCodeFrame) {
      /** @type {!Sources.UISourceCodeFrame} */ (sourceView).dispose();
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _editorClosed(event) {
    const uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data);
    this._historyManager.removeHistoryForSourceCode(uiSourceCode);

    let wasSelected = false;
    if (!this._editorContainer.currentFile()) {
      wasSelected = true;
    }

    // SourcesNavigator does not need to update on EditorClosed.
    this._removeToolbarChangedListener();
    this._updateScriptViewToolbarItems();
    this._searchableView.resetSearch();

    const data = {};
    data.uiSourceCode = uiSourceCode;
    data.wasSelected = wasSelected;
    this.dispatchEventToListeners(Sources.SourcesView.Events.EditorClosed, data);
  }

  /**
   * @param {!Common.Event} event
   */
  _editorSelected(event) {
    const previousSourceFrame =
        event.data.previousView instanceof Sources.UISourceCodeFrame ? event.data.previousView : null;
    if (previousSourceFrame) {
      previousSourceFrame.setSearchableView(null);
    }
    const currentSourceFrame =
        event.data.currentView instanceof Sources.UISourceCodeFrame ? event.data.currentView : null;
    if (currentSourceFrame) {
      currentSourceFrame.setSearchableView(this._searchableView);
    }

    this._searchableView.setReplaceable(!!currentSourceFrame && currentSourceFrame.canEditSource());
    this._searchableView.refreshSearch();
    this._updateToolbarChangedListener();
    this._updateScriptViewToolbarItems();

    this.dispatchEventToListeners(Sources.SourcesView.Events.EditorSelected, this._editorContainer.currentFile());
  }

  _removeToolbarChangedListener() {
    if (this._toolbarChangedListener) {
      Common.EventTarget.removeEventListeners([this._toolbarChangedListener]);
    }
    this._toolbarChangedListener = null;
  }

  _updateToolbarChangedListener() {
    this._removeToolbarChangedListener();
    const sourceFrame = this.currentSourceFrame();
    if (!sourceFrame) {
      return;
    }
    this._toolbarChangedListener = sourceFrame.addEventListener(
        Sources.UISourceCodeFrame.Events.ToolbarItemsChanged, this._updateScriptViewToolbarItems, this);
  }

  /**
   * @override
   */
  searchCanceled() {
    if (this._searchView) {
      this._searchView.searchCanceled();
    }

    delete this._searchView;
    delete this._searchConfig;
  }

  /**
   * @override
   * @param {!UI.SearchableView.SearchConfig} searchConfig
   * @param {boolean} shouldJump
   * @param {boolean=} jumpBackwards
   */
  performSearch(searchConfig, shouldJump, jumpBackwards) {
    const sourceFrame = this.currentSourceFrame();
    if (!sourceFrame) {
      return;
    }

    this._searchView = sourceFrame;
    this._searchConfig = searchConfig;

    this._searchView.performSearch(this._searchConfig, shouldJump, jumpBackwards);
  }

  /**
   * @override
   */
  jumpToNextSearchResult() {
    if (!this._searchView) {
      return;
    }

    if (this._searchView !== this.currentSourceFrame()) {
      this.performSearch(this._searchConfig, true);
      return;
    }

    this._searchView.jumpToNextSearchResult();
  }

  /**
   * @override
   */
  jumpToPreviousSearchResult() {
    if (!this._searchView) {
      return;
    }

    if (this._searchView !== this.currentSourceFrame()) {
      this.performSearch(this._searchConfig, true);
      if (this._searchView) {
        this._searchView.jumpToLastSearchResult();
      }
      return;
    }

    this._searchView.jumpToPreviousSearchResult();
  }

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

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

  /**
   * @override
   * @param {!UI.SearchableView.SearchConfig} searchConfig
   * @param {string} replacement
   */
  replaceSelectionWith(searchConfig, replacement) {
    const sourceFrame = this.currentSourceFrame();
    if (!sourceFrame) {
      console.assert(sourceFrame);
      return;
    }
    sourceFrame.replaceSelectionWith(searchConfig, replacement);
  }

  /**
   * @override
   * @param {!UI.SearchableView.SearchConfig} searchConfig
   * @param {string} replacement
   */
  replaceAllWith(searchConfig, replacement) {
    const sourceFrame = this.currentSourceFrame();
    if (!sourceFrame) {
      console.assert(sourceFrame);
      return;
    }
    sourceFrame.replaceAllWith(searchConfig, replacement);
  }

  _showOutlineQuickOpen() {
    QuickOpen.QuickOpen.show('@');
  }

  _showGoToLineQuickOpen() {
    if (this._editorContainer.currentFile()) {
      QuickOpen.QuickOpen.show(':');
    }
  }

  _save() {
    this._saveSourceFrame(this.currentSourceFrame());
  }

  _saveAll() {
    const sourceFrames = this._editorContainer.fileViews();
    sourceFrames.forEach(this._saveSourceFrame.bind(this));
  }

  /**
   * @param {?UI.Widget} sourceFrame
   */
  _saveSourceFrame(sourceFrame) {
    if (!(sourceFrame instanceof Sources.UISourceCodeFrame)) {
      return;
    }
    const uiSourceCodeFrame = /** @type {!Sources.UISourceCodeFrame} */ (sourceFrame);
    uiSourceCodeFrame.commitEditing();
  }

  /**
   * @param {boolean} active
   */
  toggleBreakpointsActiveState(active) {
    this._editorContainer.view.element.classList.toggle('breakpoints-deactivated', !active);
  }
};

/** @enum {symbol} */
Sources.SourcesView.Events = {
  EditorClosed: Symbol('EditorClosed'),
  EditorSelected: Symbol('EditorSelected'),
};

/**
 * @interface
 */
Sources.SourcesView.EditorAction = function() {};

Sources.SourcesView.EditorAction.prototype = {
  /**
   * @param {!Sources.SourcesView} sourcesView
   * @return {!UI.ToolbarButton}
   */
  button(sourcesView) {}
};

/**
 * @implements {UI.ActionDelegate}
 * @unrestricted
 */
Sources.SourcesView.SwitchFileActionDelegate = class {
  /**
   * @param {!Workspace.UISourceCode} currentUISourceCode
   * @return {?Workspace.UISourceCode}
   */
  static _nextFile(currentUISourceCode) {
    /**
     * @param {string} name
     * @return {string}
     */
    function fileNamePrefix(name) {
      const lastDotIndex = name.lastIndexOf('.');
      const namePrefix = name.substr(0, lastDotIndex !== -1 ? lastDotIndex : name.length);
      return namePrefix.toLowerCase();
    }

    const uiSourceCodes = currentUISourceCode.project().uiSourceCodes();
    const candidates = [];
    const url = currentUISourceCode.parentURL();
    const name = currentUISourceCode.name();
    const namePrefix = fileNamePrefix(name);
    for (let i = 0; i < uiSourceCodes.length; ++i) {
      const uiSourceCode = uiSourceCodes[i];
      if (url !== uiSourceCode.parentURL()) {
        continue;
      }
      if (fileNamePrefix(uiSourceCode.name()) === namePrefix) {
        candidates.push(uiSourceCode.name());
      }
    }
    candidates.sort(String.naturalOrderComparator);
    const index = mod(candidates.indexOf(name) + 1, candidates.length);
    const fullURL = (url ? url + '/' : '') + candidates[index];
    const nextUISourceCode = currentUISourceCode.project().uiSourceCodeForURL(fullURL);
    return nextUISourceCode !== currentUISourceCode ? nextUISourceCode : null;
  }

  /**
   * @override
   * @param {!UI.Context} context
   * @param {string} actionId
   * @return {boolean}
   */
  handleAction(context, actionId) {
    const sourcesView = UI.context.flavor(Sources.SourcesView);
    const currentUISourceCode = sourcesView.currentUISourceCode();
    if (!currentUISourceCode) {
      return false;
    }
    const nextUISourceCode = Sources.SourcesView.SwitchFileActionDelegate._nextFile(currentUISourceCode);
    if (!nextUISourceCode) {
      return false;
    }
    sourcesView.showSourceLocation(nextUISourceCode);
    return true;
  }
};


/**
 * @implements {UI.ActionDelegate}
 * @unrestricted
 */
Sources.SourcesView.ActionDelegate = class {
  /**
   * @override
   * @param {!UI.Context} context
   * @param {string} actionId
   * @return {boolean}
   */
  handleAction(context, actionId) {
    const sourcesView = UI.context.flavor(Sources.SourcesView);
    if (!sourcesView) {
      return false;
    }

    switch (actionId) {
      case 'sources.close-all':
        sourcesView._editorContainer.closeAllFiles();
        return true;
      case 'sources.jump-to-previous-location':
        sourcesView._onJumpToPreviousLocation();
        return true;
      case 'sources.jump-to-next-location':
        sourcesView._onJumpToNextLocation();
        return true;
      case 'sources.close-editor-tab':
        return sourcesView._onCloseEditorTab();
      case 'sources.go-to-line':
        sourcesView._showGoToLineQuickOpen();
        return true;
      case 'sources.go-to-member':
        sourcesView._showOutlineQuickOpen();
        return true;
      case 'sources.save':
        sourcesView._save();
        return true;
      case 'sources.save-all':
        sourcesView._saveAll();
        return true;
    }

    return false;
  }
};
