<commit_before>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var _ = require('lodash');
var debug = require('debug')('background:index');
var domready = require('domready');

var AuthHandler = require('./auth-handler');
var extensionErrors = require('../../../src/browser/extension-errors');
var getOrigin = require('./util').getOrigin;
var Nacl = require('./nacl');


domready(function() {
  // Start!
  var bp = new BackgroundPage();
  chrome.runtime.onConnect.addListener(
    bp.handleNewContentScriptConnection.bind(bp));

  // Set bp on the window so it will be accessable from options page.
  window.bp = bp;
  // Expose the state object so options page and background can share it and
  // stay in sync.
  bp.state = require('../state');
});

function BackgroundPage() {
  if (!(this instanceof BackgroundPage)) {
    return new BackgroundPage();
  }

  // Map that stores instanceId -> port so messages can be routed back to the
  // port they came from.
  this.ports = {};

  // Map that stores portId -> instanceId so browspr can do cleanup on the
  // instanceId when the port closes.
  this.instanceIds = {};

  debug('background script loaded');
}

// Start listening to messages from the Nacl plugin.
BackgroundPage.prototype.registerNaclListeners = function() {
  this.nacl.on('message', this.handleMessageFromNacl.bind(this));
  this.nacl.on('crash', this.handleNaclCrash.bind(this));
};

// Handle messages coming from Nacl by send them to the associated port.
BackgroundPage.prototype.handleMessageFromNacl = function(msg) {
  var instanceId = msg.instanceId;
  var port = this.ports[instanceId];
  if (!port) {
    console.error('Message received not matching instance id: ', instanceId);
    return;
  }
  port.postMessage(msg);
};


// Handle messages coming from a content script.
BackgroundPage.prototype.handleMessageFromContentScript = function(port, msg) {
  if (!this.naclPluginIsActive()) {
    // Start the plugin if it is not started.
    this.startNaclPlugin();
  }

  // Wrap in process.nextTick so chrome stack traces can use sourceMap.
  var bp = this;
  process.nextTick(function() {
    debug('background received message from content script.', msg);

    // Dispatch on the type of the message.
    switch (msg.type) {
      case 'browsprMsg':
        return bp.handleBrowsprMessage(port, msg);
      case 'browsprCleanup':
        return bp.handleBrowsprCleanup(port, msg);
      case 'createInstance':
        return bp.handleCreateInstance(port, msg);
      case 'auth':
        return bp.authHandler.handleAuthMessage(port);
      case 'assocAccount:finish':
        return bp.authHandler.handleFinishAuth(port, msg);
      case 'intentionallyPanic': // Only for tests.
        return bp._triggerIntentionalPanic();
      default:
        console.error('unknown message.', msg);
    }
  });
};

// Trigger a panic in the plug-in (only for tests).
BackgroundPage.prototype._triggerIntentionalPanic = function() {
  if (process.env.ALLOW_INTENTIONAL_CRASH) {
      var panicMsg = {
        type: 'intentionallyPanic',
        instanceId: 0,
        origin: '',
        body: ''
      };
      this.nacl.sendMessage(panicMsg);
    }
};

// Handle a content script connecting to this background script.
BackgroundPage.prototype.handleNewContentScriptConnection = function(port) {
  port.onMessage.addListener(
    this.handleMessageFromContentScript.bind(this, port));

  var bp = this;
  port.onDisconnect.addListener(function() {
    var pId = portId(port);
    var instanceIds = bp.instanceIds[pId] || [];
    instanceIds.forEach(function(instanceId) {
      bp.handleBrowsprCleanup(port, {body: {instanceId: instanceId}});
    });
  });
};

// Clean up an instance, and tell Nacl to clean it up as well.
BackgroundPage.prototype.handleBrowsprCleanup = function(port, msg) {
  function sendCleanupFinishedMessage() {
    safePostMessage(port, {type: 'browsprCleanupFinished'});
  }

  if (!this.naclPluginIsActive()) {
    // If the plugin isn't started, no need to clean it up.
    sendCleanupFinishedMessage();
    return;
  }

  var instanceId = msg.body.instanceId;

  if (!this.ports[instanceId]) {
    return console.error('Got cleanup message from instance ' + instanceId +
        ' with no associated port.');
  }

  if (this.ports[instanceId] !== port) {
    return console.error('Got cleanup message for instance ' + instanceId +
        ' that does not match port.');
  }

  var bp = this;
  var now = Date.now();
  this.nacl.cleanupInstance(instanceId, function() {
    var end = Date.now();
    console.log('Cleaned up instance: ' + instanceId + ' in '
                + (end - now) + ' ms');<commit_msg>TBR: Fix jshint violation.<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var _ = require('lodash');
var debug = require('debug')('background:index');
var domready = require('domready');

var AuthHandler = require('./auth-handler');
var extensionErrors = require('../../../src/browser/extension-errors');
var getOrigin = require('./util').getOrigin;
var Nacl = require('./nacl');


domready(function() {
  // Start!
  var bp = new BackgroundPage();
  chrome.runtime.onConnect.addListener(
    bp.handleNewContentScriptConnection.bind(bp));

  // Set bp on the window so it will be accessable from options page.
  window.bp = bp;
  // Expose the state object so options page and background can share it and
  // stay in sync.
  bp.state = require('../state');
});

function BackgroundPage() {
  if (!(this instanceof BackgroundPage)) {
    return new BackgroundPage();
  }

  // Map that stores instanceId -> port so messages can be routed back to the
  // port they came from.
  this.ports = {};

  // Map that stores portId -> instanceId so browspr can do cleanup on the
  // instanceId when the port closes.
  this.instanceIds = {};

  debug('background script loaded');
}

// Start listening to messages from the Nacl plugin.
BackgroundPage.prototype.registerNaclListeners = function() {
  this.nacl.on('message', this.handleMessageFromNacl.bind(this));
  this.nacl.on('crash', this.handleNaclCrash.bind(this));
};

// Handle messages coming from Nacl by send them to the associated port.
BackgroundPage.prototype.handleMessageFromNacl = function(msg) {
  var instanceId = msg.instanceId;
  var port = this.ports[instanceId];
  if (!port) {
    console.error('Message received not matching instance id: ', instanceId);
    return;
  }
  port.postMessage(msg);
};


// Handle messages coming from a content script.
BackgroundPage.prototype.handleMessageFromContentScript = function(port, msg) {
  if (!this.naclPluginIsActive()) {
    // Start the plugin if it is not started.
    this.startNaclPlugin();
  }

  // Wrap in process.nextTick so chrome stack traces can use sourceMap.
  var bp = this;
  process.nextTick(function() {
    debug('background received message from content script.', msg);

    // Dispatch on the type of the message.
    switch (msg.type) {
      case 'browsprMsg':
        return bp.handleBrowsprMessage(port, msg);
      case 'browsprCleanup':
        return bp.handleBrowsprCleanup(port, msg);
      case 'createInstance':
        return bp.handleCreateInstance(port, msg);
      case 'auth':
        return bp.authHandler.handleAuthMessage(port);
      case 'assocAccount:finish':
        return bp.authHandler.handleFinishAuth(port, msg);
      case 'intentionallyPanic': // Only for tests.
        return bp._triggerIntentionalPanic();
      default:
        console.error('unknown message.', msg);
    }
  });
};

// Trigger a panic in the plug-in (only for tests).
BackgroundPage.prototype._triggerIntentionalPanic = function() {
  if (process.env.ALLOW_INTENTIONAL_CRASH) {
      var panicMsg = {
        type: 'intentionallyPanic',
        instanceId: 0,
        origin: '',
        body: ''
      };
      this.nacl.sendMessage(panicMsg);
    }
};

// Handle a content script connecting to this background script.
BackgroundPage.prototype.handleNewContentScriptConnection = function(port) {
  port.onMessage.addListener(
    this.handleMessageFromContentScript.bind(this, port));

  var bp = this;
  port.onDisconnect.addListener(function() {
    var pId = portId(port);
    var instanceIds = bp.instanceIds[pId] || [];
    instanceIds.forEach(function(instanceId) {
      bp.handleBrowsprCleanup(port, {body: {instanceId: instanceId}});
    });
  });
};

// Clean up an instance, and tell Nacl to clean it up as well.
BackgroundPage.prototype.handleBrowsprCleanup = function(port, msg) {
  function sendCleanupFinishedMessage() {
    safePostMessage(port, {type: 'browsprCleanupFinished'});
  }

  if (!this.naclPluginIsActive()) {
    // If the plugin isn't started, no need to clean it up.
    sendCleanupFinishedMessage();
    return;
  }

  var instanceId = msg.body.instanceId;

  if (!this.ports[instanceId]) {
    return console.error('Got cleanup message from instance ' + instanceId +
        ' with no associated port.');
  }

  if (this.ports[instanceId] !== port) {
    return console.error('Got cleanup message for instance ' + instanceId +
        ' that does not match port.');
  }

  var bp = this;
  var now = Date.now();
  this.nacl.cleanupInstance(instanceId, function() {
    var end = Date.now();
    console.log('Cleaned up instance: ' + instanceId + ' in ' +
                (end - now) + ' ms');
{'fraction_non_alphanumeric': 0.12245324417511232, 'fraction_numerical': 0.0010448229025180231, 'mean_word_length': 3.380778032036613, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '4019806', 'n_tokens_mistral': 2842, 'n_tokens_neox': 2749, 'n_words': 812}