<commit_before>/* See license.txt for terms of usage */

define(function(require, exports/*, module*/) {

"use strict";

// Dependencies
const React = require("react");

// Firebug SDK
const { Reps } = require("reps/reps");
const { Str } = require("reps/core/string");
const { TreeView } = require("reps/tree-view");

// Shortcuts
const { div, span } = React.DOM;

/**
 * @template This template represents a list of frames displayed
 * inside the frame bubble content.
 */
var FrameList = React.createClass({
/** @lends FrameList */

  displayName: "FrameList",

  getInitialState: function() {
    return { data: [] };
  },

  componentWillUpdate: function() {
    var node = this.getDOMNode();
    this.shouldScrollBottom = node.scrollTop +
      node.offsetHeight === node.scrollHeight;
  },

  componentDidUpdate: function() {
    if (this.shouldScrollBottom) {
      var node = this.getDOMNode();
      node.scrollTop = node.scrollHeight;
    }
  },

  render: function() {
    var output = [];
    var frames = this.props.frames.frames;
    var summary = this.props.frames.summary;
    var removedFrames = this.props.removedFrames;

    if (removedFrames > 0) {
      output.push(PacketsLimit({
        removedPackets: removedPackets
      }));
    }

    for (var i in frames) {
      var frame = frames[i];

      output.push(Frame({
        key: frame.id,
        frame: frame,
        actions: this.props.actions,
        selection: this.props.selection,
        showInlineDetails: this.props.showInlineDetails
      }));
    }

    return (
      div({className: "frameList"},
        div({}, output)
      )
    );
  }
});

/**
 * @template TODO docs
 */
var Frame = React.createFactory(React.createClass({
/** @lends Frame */

  displayName: "Frame",

  /**
   * Packet needs to be re-rendered only if the selection or
   * 'show inline details' option changes. This is an optimization
   * the makes the packet-list rendering a lot faster.
   */
  shouldComponentUpdate: function(nextProps, nextState) {
/*    var { contextMenu: prevContextMenu } = this.state || {};
    var { contextMenu: nextContextMenu } = nextState || {};

    return (this.props.selected != nextProps.selected ||
      this.props.showInlineDetails != nextProps.showInlineDetails ||
      prevContextMenu != nextContextMenu);*/
  },

  render: function() {
    var packet = this.props.frame;

    console.log("frame", packet);

    var data = packet.header ? packet.header : packet.maskBit;
    var type = packet.header ? "send" : "receive";
    var mode = "tiny";
    var classNames = ["frameBubble", type];
    var size = Str.formatSize(data.payload.length);

    var payload = Str.cropString(data.payload, 50);
    var size = Str.formatSize(data.payload.length);
    var time = new Date(data.timeStamp / 1000);
    var timeText = time.getHours() + ":" + time.getMinutes() +
      ":" + time.getSeconds() + "." + time.getMilliseconds();

    var previewData = {
      frame: packet
    };

    // Error packets have its own styling
    if (packet.error) {
      classNames.push("error");
    }

    // Selected packets are highlighted
    if (this.props.selection == packet) {
      classNames.push("selected");
    }

    // Inline preview component
    this.props.showInlineDetails = true;
    var preview = this.props.showInlineDetails ? TreeView(
      {data: previewData, mode: mode}) : null;

    var label = (type == "send") ?
      Locale.$STR("websocketmonitor.label.sent") :
      Locale.$STR("websocketmonitor.label.received");

    return (
      div({className: classNames.join(" "), onClick: this.onClick,
           onContextMenu: this.onContextMenu},
        div({className: "frameBox"},
          div({className: "frameContent"},
            div({className: "body"},
              span({className: "text"}, label),
              div({className: "preview"},
                preview
              ),
              div({},
                span({className: "info"}, timeText + ", " + size)
              )
            ),
            div({className: "boxArrow"})
          )
        )
      )
    );
  },

  // Event Handlers

  onClick: function(event) {
    var target = event.target;

    event.stopPropagation();
    event.preventDefault();

    // If a 'memberLabel' is clicked inside the inline preview
    // tree, let's process it by the tree, so expansion and
    // collapsing works. Otherwise just select the packet.
    if (!target.classList.contains("memberLabel")) {
      this.props.actions.selectPacket(this.props.data);
    }
  },
}));

// Exports from this module
exports.FrameList = FrameList;
});
<commit_msg>Fix selection in the frame-list<commit_after>/* See license.txt for terms of usage */

define(function(require, exports/*, module*/) {

"use strict";

// Dependencies
const React = require("react");

// Firebug SDK
const { Reps } = require("reps/reps");
const { Str } = require("reps/core/string");
const { TreeView } = require("reps/tree-view");

// WebSockets Monitor
const { selectFrame } = require("../actions/selection");

// Shortcuts
const { div, span } = React.DOM;

/**
 * @template This template represents a list of frames displayed
 * inside the frame bubble content.
 */
var FrameList = React.createClass({
/** @lends FrameList */

  displayName: "FrameList",

  getInitialState: function() {
    return { data: [] };
  },

  componentWillUpdate: function() {
    var node = this.getDOMNode();
    this.shouldScrollBottom = node.scrollTop +
      node.offsetHeight === node.scrollHeight;
  },

  componentDidUpdate: function() {
    if (this.shouldScrollBottom) {
      var node = this.getDOMNode();
      node.scrollTop = node.scrollHeight;
    }
  },

  render: function() {
    var output = [];
    var frames = this.props.frames.frames;
    var summary = this.props.frames.summary;
    var removedFrames = this.props.removedFrames;

    if (removedFrames > 0) {
      output.push(FramesLimit({
        removedframes: removedframes
      }));
    }

    for (var i in frames) {
      var frame = frames[i];

      output.push(FrameBubble({
        key: frame.id,
        frame: frame,
        selection: this.props.selection,
        dispatch: this.props.dispatch
      }));
    }

    return (
      div({className: "frameList"},
        div({}, output)
      )
    );
  }
});

/**
 * This template is responsible for rendering a frame with
 * related information. It looks like a chat message
 * bubble in standard chat UI applications.
 */
var FrameBubble = React.createFactory(React.createClass({
/** @lends FrameBubble */

  displayName: "FrameBubble",

  /**
   * Frames need to be re-rendered only if the selection option changes.
   * This is an optimization that makes the list rendering a lot faster.
   */
  shouldComponentUpdate: function(nextProps, nextState) {
    return (this.props.selection != nextProps.selection);
  },

  render: function() {
    var frame = this.props.frame;

    var data = frame.header ? frame.header : frame.maskBit;
    var type = frame.header ? "send" : "receive";
    var mode = "tiny";
    var classNames = ["frameBubble", type];
    var size = Str.formatSize(data.payload.length);

    var payload = Str.cropString(data.payload, 50);
    var size = Str.formatSize(data.payload.length);
    var time = new Date(data.timeStamp / 1000);
    var timeText = time.getHours() + ":" + time.getMinutes() +
      ":" + time.getSeconds() + "." + time.getMilliseconds();

    var previewData = {
      frame: frame
    };

    // Error frames have its own styling
    if (frame.error) {
      classNames.push("error");
    }

    // Selected frames are highlighted
    if (this.props.selection == frame) {
      classNames.push("selected");
    }

    // Inline preview component
    this.props.showInlineDetails = true;
    var preview = this.props.showInlineDetails ? TreeView(
      {data: previewData, mode: mode}) : null;

    var label = (type == "send") ?
      Locale.$STR("websocketmonitor.label.sent") :
      Locale.$STR("websocketmonitor.label.received");

    return (
      div({className: classNames.join(" "), onClick: this.onClick},
        div({className: "frameBox"},
          div({className: "frameContent"},
            div({className: "body"},
              span({className: "text"}, label),
              div({className: "preview"},
                preview
              ),
              div({},
                span({className: "info"}, timeText + ", " + size)
              )
            ),
            div({className: "boxArrow"})
          )
        )
      )
    );
  },

  // Event Handlers

  onClick: function(event) {
    var target = event.target;

    event.stopPropagation();
    event.preventDefault();

    // If a 'memberLabel' is clicked inside the inline preview
    // tree, let's process it by the tree, so expansion and
    // collapsing works. Otherwise just select the frame.
    if (!target.classList.contains("memberLabel")) {
      if (this.props.frame != this.props.selection) {
        this.props.dispatch(selectFrame(this.props.frame));
      }
    }
  },
}));

// Exports from this module
exports.FrameList = FrameList;
});

{'fraction_non_alphanumeric': 0.13904969961769525, 'fraction_numerical': 0.001529219006007646, 'mean_word_length': 2.577960140679953, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 5, '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': '97120', 'n_tokens_mistral': 2715, 'n_tokens_neox': 2631, 'n_words': 668}