<commit_before>/* jshint node: true */
'use strict';

var bufferedchannel = require('rtc-bufferedchannel');
var point = require('point');
var EventEmitter = require('events').EventEmitter;
var throttle = require('cog/throttle');
var eventCodes = [
  'over',
  'start',
  'move',
  'end'
];

/**
  # rtc-sharedcursor

  The `rtc-sharedcursor` module makes it simple to share and touch
  mouse events for a target element across the wire one or more
  peers across a data channel connection.

  ## Example Usage

  <<< examples/simple.js

  Running the example in a few different windows, should display 
  something similar to what is shown below:

  ![Screenshot](https://raw.github.com/rtc-io/rtc-sharedcursor/master/screenshot.png)

**/

module.exports = function(qc, opts) {
  // create the cursor event emitter
  var emitter = new EventEmitter();
  var channels = [];
  var peers = [];
  var currentTarget;
  var targetX = 0;
  var targetY = 0;
  var targetWidth = 0;
  var targetHeight = 0;
  var MAXVAL = Math.pow(2, 16) - 1;

  function updateTargetBounds() {
    var rect = currentTarget && currentTarget.getBoundingClientRect();

    targetX = rect ? rect.left : 0;
    targetY = rect ? rect.top : 0;
    targetWidth = rect ? rect.width : 0;
    targetHeight = rect ? rect.height : 0;
  }

  function handleNewChannel(dc, id) {
    var channel = bufferedchannel(dc, { retry: false });

    channels.push(channel);
    peers.push(id);

    channel.on('data', function(payload) {
      emitter.emit(
        'data',
        id,
        eventCodes[payload[0]],
        (payload[1] / MAXVAL * targetWidth) | 0,
        (payload[2] / MAXVAL * targetHeight) | 0
      );
    });
  }

  function removeCursor(id) {
  }

  // listen for window resize events
  window.addEventListener('resize', updateTargetBounds);

  // bind the attach function to the emitter
  emitter.attach = function(target) {
    var stop;

    // detatch from the previous target
    emitter.detach();

    // update the current target
    currentTarget = target;

    // get the current target size
    updateTargetBounds();

    // listen for pointer events on the target
    stop = point(target, { over: true })(function(args) {
      var code;
      var relX;
      var relY;

      if (! args) {
        return;
      }

      code = eventCodes.indexOf(args[2].type);
      if (code >= 0) {
        // calculate the relative x and y
        relX = (((args[0] - targetX) / targetWidth) * MAXVAL) | 0;
        relY = (((args[1] - targetY) / targetHeight) * MAXVAL) | 0;

        channels.forEach(function(dc) {
          // send the mouse data payload<commit_msg>Always update target bounds to ensure correct relative position is used<commit_after>/* jshint node: true */
'use strict';

var bufferedchannel = require('rtc-bufferedchannel');
var point = require('point');
var EventEmitter = require('events').EventEmitter;
var throttle = require('cog/throttle');
var eventCodes = [
  'over',
  'start',
  'move',
  'end'
];

/**
  # rtc-sharedcursor

  The `rtc-sharedcursor` module makes it simple to share and touch
  mouse events for a target element across the wire one or more
  peers across a data channel connection.

  ## Example Usage

  <<< examples/simple.js

  Running the example in a few different windows, should display 
  something similar to what is shown below:

  ![Screenshot](https://raw.github.com/rtc-io/rtc-sharedcursor/master/screenshot.png)

**/

module.exports = function(qc, opts) {
  // create the cursor event emitter
  var emitter = new EventEmitter();
  var channels = [];
  var peers = [];
  var currentTarget;
  var targetX = 0;
  var targetY = 0;
  var targetWidth = 0;
  var targetHeight = 0;
  var MAXVAL = Math.pow(2, 16) - 1;

  function updateTargetBounds() {
    var rect = currentTarget && currentTarget.getBoundingClientRect();

    targetX = rect ? rect.left : 0;
    targetY = rect ? rect.top : 0;
    targetWidth = rect ? rect.width : 0;
    targetHeight = rect ? rect.height : 0;
  }

  function handleNewChannel(dc, id) {
    var channel = bufferedchannel(dc, { retry: false });

    channels.push(channel);
    peers.push(id);

    channel.on('data', function(payload) {
      emitter.emit(
        'data',
        id,
        eventCodes[payload[0]],
        (payload[1] / MAXVAL * targetWidth) | 0,
        (payload[2] / MAXVAL * targetHeight) | 0
      );
    });
  }

  function removeCursor(id) {
  }

  // bind the attach function to the emitter
  emitter.attach = function(target) {
    var stop;

    // detatch from the previous target
    emitter.detach();

    // update the current target
    currentTarget = target;

    // listen for pointer events on the target
    stop = point(target, { over: true })(function(args) {
      var code;
      var relX;
      var relY;

      if (! args) {
        return;
      }

      code = eventCodes.indexOf(args[2].type);
      if (code >= 0) {
        // update the target bounds :(
        updateTargetBounds();

        // calculate the relative x and y
        relX = (((args[0] - targetX) / targetWidth) * MAXVAL) | 0;
        relY = (((args[1] - targetY) / targetHeight) * MAXVAL) | 0;

        channels.forEach(function(dc) {
          // send the mouse data payload
{'fraction_non_alphanumeric': 0.12278697886921759, 'fraction_numerical': 0.00875690081857986, 'mean_word_length': 2.7026074700493306, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 2, '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': '2687438', 'n_tokens_mistral': 1659, 'n_tokens_neox': 1572, 'n_words': 487}