<commit_before>import Path          from 'path';
import BrowserWindow from 'browser-window';
import Util          from '../common/Util.js';
import { IPCKeys }   from '../common/Constants.js';

/**
 * Define the type of window.
 * @type {Object}
 */
export const WindowTypes = {
  Main:  'main',
  About: 'about'
};

/**
 * Manage the window.
 */
export default class WindowManager {
  /**
   * Initialize instance.
   *
   * @param {Main} context Application context.
   */
  constructor( context ) {
    /**
     * Application context.
     * @type {Main}
     */
    this._context = context;

    /**
     * Collection of a managed window.
     * @type {Map}
     */
    this._windows = new Map();

    // IPC handlers
    context.ipc.on( IPCKeys.RequestShowURL, this._onRequestShowURL.bind( this ) );
  }

  /**
   * Get the window from key.
   *
   * @param {WindowTypes} type Window type.
   *
   * @return {BrowserWindow} Successful if window instance, otherwise undefined.
   */
  getWindow( type ) {
    return this._windows.get( type );
  }

  /**
   * Close a window.
   *
   * @param {WindowTypes} type Window type.
   */
  close( type ) {
    const w = this._windows.get( type );
    if( !( w ) ) { return; }

    w.close();
  }

  /**
   * Show a window.
   *
   * @param {WindowTypes} type Window type.
   */
  show( type ) {
    switch( type ) {
      case WindowTypes.Main:
        this._showMain();
        break;

      case WindowTypes.About:
        this._showAbout();
        break;

      case WindowTypes.GraphicEqualizer:
        this._showGraphicEqualizer();
        break;

      default:
        break;
    }
  }

  /**
   * Switch the window display, Show or hide.
   *
   * @param {WindowTypes} type Window type.
   */
  toggle( type ) {
    // Main window is always showing
    if( type === WindowTypes.Main ) { return; }

    const w = this._windows.get( type );
    if( w ) {
      if( w.isVisible() ) {
        w.hide();
      } else {
        w.show();
      }
    } else {
      this.show( type );
    }
  }

  /**
   * Reload the focused window, For debug.
   */
  reload() {
    const w = BrowserWindow.getFocusedWindow();
    if( w ) {
      w.reload();
    }
  }

  /**
   * Switch the display of the developer tools window at focused window, For debug.
   */
  toggleDevTools() {
    const w = BrowserWindow.getFocusedWindow();
    if( w ) {
      w.toggleDevTools();
    }
  }

  /**
   * Show the main window.
   */
  _showMain() {
    if( this._windows.get( WindowTypes.Main ) ) { return; }

    const w = new BrowserWindow( {
      width: 600,
      height: 480,
      minWidth: 480,
      minHeight: 320,
      resizable: true
    } );

    w.on( 'closed', () => {
      if( DEBUG ) { Util.log( 'The main window was closed.' ); }

      // Close an other windows
      this._windows.forEach( ( value, key ) => {
        if( key === WindowTypes.Main ) { return; }

        value.close();
      } );

      this._windows.delete( WindowTypes.Main );
    } );

    const filePath = Path.join( __dirname, 'window-main.html' );
    w.loadURL( 'file://' + filePath );

    this._windows.set( WindowTypes.Main, w );
  }

  /**
   * Show the about application window.
   */
  _showAbout() {
    if( this._windows.get( WindowTypes.About ) ) { return; }

    const w = new BrowserWindow( {
      width: 400,
      height: 256,
      resizable: false,
      alwaysOnTop: true
    } );

    w.setMenu( null );

    w.on( 'closed', () => {
      if( DEBUG ) { Util.log( 'The about application window was closed.' ); }

      this._windows.delete( WindowTypes.About );
    } );

    const filePath = Path.join( __dirname, 'window-about.html' );
    w.loadURL( 'file://' + filePath );

    this._windows.set( WindowTypes.About, w );
  }

  /**
   * Occurs when a show link requested.
   *
   * @param {IPCEvent} ev  Event data.
   * @param {String}   url URL.
   */
  _onRequestShowURL( ev, url ) {
    console.log( url );
    this._context.shell.openExternal( url );
    ev.sender.send( IPCKeys.FinishShowURL );
  }
}<commit_msg>#66 Fix update the ID list when the window has been removed<commit_after>import Path          from 'path';
import BrowserWindow from 'browser-window';
import Util          from '../common/Util.js';
import { IPCKeys }   from '../common/Constants.js';

/**
 * Manage the window.
 */
export default class WindowManager {
  /**
   * Initialize instance.
   *
   * @param {Main} context Application context.
   */
  constructor( context ) {
    /**
     * Application context.
     * @type {Main}
     */
    this._context = context;

    /**
     * Collection of a managed window.
     * @type {Map.<String, BrowserWindow>}
     */
    this._windows = new Map();

    /**
     * About dialog.
     * @type {BrowserWindow}
     */
    this._aboutDialog = null;

    context.ipc.on( IPCKeys.RequestCreateNewWindow, this._onRequestCreateNewWindow.bind( this ) );
    context.ipc.on( IPCKeys.RequestSendMessage, this._onRequestSendMessage.bind( this ) );
    context.ipc.on( IPCKeys.RequestGetWindowIDs, this._onRequestGetWindowIDs.bind( this ) );
  }

  /**
   * Reload the focused window, For debug.
   */
  reload() {
    const w = BrowserWindow.getFocusedWindow();
    if( w ) {
      w.reload();
    }
  }

  /**
   * Switch the display of the developer tools window at focused window, For debug.
   */
  toggleDevTools() {
    const w = BrowserWindow.getFocusedWindow();
    if( w ) {
      w.toggleDevTools();
    }
  }

  /**
   * Create a new window.
   *
   * @return {BrowserWindow} Created window.
   */
  createNewWindow() {
    const w = new BrowserWindow( {
      width: 400,
      height: 400,
      minWidth: 400,
      minHeight: 400,
      resizable: true
    } );

    const id = w.id;

    w.on( 'closed', () => {
      if( DEBUG ) { Util.log( 'Window was closed, id = ' + id ); }

      // Unregister
      this._windows.delete( id );
      this._notifyUpdateWindowIDs( id );

      if( this._windows.size === 0 && this._aboutDialog ) {
        this._aboutDialog.close();
      }
    } );

    const filePath = Path.join( __dirname, 'window-main.html' );
    w.loadURL( 'file://' + filePath + '#' + w.id );
    this._windows.set( id, w );

    return w;
  }

  /**
   * Show the about application window.
   */
  createAboutWindow() {
    if( this._aboutDialog ) { return; }

    const w = new BrowserWindow( {
      width: 400,
      heigh: 256,
      resizable: false,
      alwaysOnTop: true
    } );

    w.setMenu( null );

    w.on( 'closed', () => {
      if( DEBUG ) { Util.log( 'The about application window was closed.' ); }

      this._aboutDialog = null;
    } );

    const filePath = Path.join( __dirname, 'window-about.html' );
    w.loadURL( 'file://' + filePath );

    this._aboutDialog = w;
  }

  /**
   * Notify that the window ID list has been updated.
   *
   * @param {Number} excludeID Exclude ID.
   */
  _notifyUpdateWindowIDs( excludeID ) {
    const windowIDs = [];
    for( let key of this._windows.keys() ) {
      windowIDs.push( key );
    }

    this._windows.forEach( ( w ) => {
      if( w.id === excludeID ) { return; }

      w.webContents.send( IPCKeys.UpdateWindowIDs, windowIDs );
    } );
  }

  /**
   * Occurs when a show new window requested.
   *
   * @param {IPCEvent} ev Event data.
   */
  _onRequestCreateNewWindow( ev ) {
    const createdWindow = this.createNewWindow();
    ev.sender.send( IPCKeys.FinishCreateNewWindow );

    // Because it may not receive the message, explicit request ( RequestGetWindowIDs ) later
    this._notifyUpdateWindowIDs( createdWindow.id );
  }

  /**
   * Occurs when a send message requested.
   *
   * @param {IPCEvent} ev      Event data.
   * @param {Number}   id      Target window's identifier.
   * @param {String}   message Message.
   */
  _onRequestSendMessage( ev, id, message ) {
    const w = this._windows.get( id );
    if( w ) {
      w.webContents.send( IPCKeys.UpdateMessage, message );
    }

    ev.sender.send( IPCKeys.FinishSendMessage );
  }

  /**
   * Occurs when a get window identifiers requested.
   *
   * @param {IPCEvent} ev Event data.
   */
  _onRequestGetWindowIDs( ev ) {
    const windowIDs = Array.from( this._windows.keys() );
    ev.sender.send( IPCKeys.FinishGetWindowIDs, windowIDs );
  }
}
{'fraction_non_alphanumeric': 0.14103028109542767, 'fraction_numerical': 0.004705030763662686, 'mean_word_length': 2.156892612338157, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2392745', 'n_tokens_mistral': 2761, 'n_tokens_neox': 2634, 'n_words': 675}