<commit_before>
/**
 * The Firefeed object is the primary conduit to the data feed. It provides
 * functions to login a user, log them out, and most importantly, to register
 * callbacks for events like receiving a new message, or a new suggested user
 * to follow. This object knows nothing about the UI, see firefeed-ui.js for
 * how this object is used to make sure the UI is updated as events come in.
 *
 * @param    {string}    baseURL     The Firebase URL.
 * @param    {boolean}   newContext  Whether a new Firebase context is used.
 *                                   (Useful for testing only)
 * @return   {Firefeed}
 */
function Firefeed(baseURL, newContext) {
  var self = this;
  this._name = null;
  this._userid = null;
  this._firebase = null;
  this._mainUser = null;
  this._fullName = null;
  this._searchHandler = null;
  this._currentSearch = null;

  // Every time we call firebaseRef.on, we need to remember to call .off,
  // when requested by the caller via unload(). We'll store our handlers
  // here so we can clear them later.
  this._handlers = [];

  if (!baseURL || typeof baseURL != "string") {
    throw new Error("Invalid baseURL provided");
  }
  this._firebase = new Firebase(
    baseURL, newContext || false ? new Firebase.Context() : null
  );

  this._authHandlers = [];
  this._firebaseAuthClient = new FirebaseSimpleLogin(this._firebase, function(error, user) {
    self._onLoginStateChange(error, user);
  });
}
Firefeed.prototype = {
  _validateCallback: function(cb, notInit) {
    if (!cb || typeof cb != "function") {
      throw new Error("Invalid onComplete callback provided");
    }
    if (!notInit) {
      if (!this._userid || !this._firebase) {
        throw new Error("Method called without a preceding login() call");
      }
    }
  },
  _validateString: function(str, name) {
    if (!str || typeof str != "string") {
      throw new Error("Invalid " + name + " provided");
    }
  },
  _getParameterByName: function(name) {
    var expr = "[?&]" + name + "=([^&]*)";
    var match = RegExp().exec(window.location.search);
    return match && decodeURIComponent(match[1].replace(/\+/g, " "));
  },
  _getPicURL: function(id, large) {
    return "https://graph.facebook.com/" + (id || this._userid) +
           "/picture/?type=" + (large ? "large" : "square") +
           "&return_ssl_resources=1";
  },
  _onNewSparkForFeed: function(feed, onComplete, onOverflow) {
    var self = this;

    // We listen for new children on the feed.
    var handler = feed.on("child_added", function(snap) {
      // When a new spark is added, fetch the content from the master spark
      // list since feeds only contain references in the form of spark IDs.
      var sparkID = snap.name();
      var sparkRef = self._firebase.child("sparks").child(sparkID);
      var handler = sparkRef.on("value", function(sparkSnap) {
        var ret = sparkSnap.val();
        if (ret !== null) {
          ret.pic = self._getPicURL(ret.author);
          onComplete(sparkSnap.name(), ret);
        }
      });
      self._handlers.push({
        ref: sparkRef, handler: handler, eventType: "value"
      });
    });
    self._handlers.push({
      ref: feed, handler: handler, eventType: "child_added"
    });

    // Also listen for child_removed so we can call onOverflow appropriately.
    handler = feed.on("child_removed", function(snap) {
      onOverflow(snap.name());
    });
    self._handlers.push({
      ref: feed, handler: handler, eventType: "child_removed"
    });
  },
  _onLoginStateChange: function(error, user) {
    var self = this;
    if (error) {
      // An error occurred while authenticating the user.
      this.handleLogout();
    } else if (user) {
      // The user is successfully logged in.
      this.onLogin(user);
    } else {
      // No existing session found - the user is logged out.
      this.onLogout();
    }
  }
};

/**
 * Attach a callback method to be invoked whenever the authentication state
 * of the user changes. If an error occurs during authentication, the error
 * object will be non-null. If a user is successfully authenticated, the error
 * object will be null, and the user object will be non-null. If a user is
 * simply logged-out, both the error and user objects will be null.
 */
Firefeed.prototype.onLoginStateChange = function(onLoginStateChange) {
  var self = this;
  self._validateCallback(onLoginStateChange, true);
  this._authHandlers.push(onLoginStateChange);

  // Immediate invoke the function once with current user information
  setTimeout(function() {
    onLoginStateChange(null, this._user);
  }, 0);
}

/**
 * Login a user using Firebase Simple Login, using the specified authentication
 * provider. Pass the optional 'rememberMe' argument to the FirebaseSimpleLogin
 * in order to create a long-lasting session. If the user is successfully
 * authenticated, then the previously-configured callback will be invoked with
 * a null error and a user object.
 *
 * @param    {string}    provider    The authentication provider to use.
 */
Firefeed.prototype.login = function(provider) {<commit_msg>Fix double rendering of recent sparks on homepage<commit_after>
/**
 * The Firefeed object is the primary conduit to the data feed. It provides
 * functions to login a user, log them out, and most importantly, to register
 * callbacks for events like receiving a new message, or a new suggested user
 * to follow. This object knows nothing about the UI, see firefeed-ui.js for
 * how this object is used to make sure the UI is updated as events come in.
 *
 * @param    {string}    baseURL     The Firebase URL.
 * @param    {boolean}   newContext  Whether a new Firebase context is used.
 *                                   (Useful for testing only)
 * @return   {Firefeed}
 */
function Firefeed(baseURL, newContext) {
  var self = this;
  this._name = null;
  this._userid = null;
  this._firebase = null;
  this._mainUser = null;
  this._fullName = null;
  this._searchHandler = null;
  this._currentSearch = null;

  // Every time we call firebaseRef.on, we need to remember to call .off,
  // when requested by the caller via unload(). We'll store our handlers
  // here so we can clear them later.
  this._handlers = [];

  if (!baseURL || typeof baseURL != "string") {
    throw new Error("Invalid baseURL provided");
  }
  this._firebase = new Firebase(
    baseURL, newContext || false ? new Firebase.Context() : null
  );

  this._authHandlers = [];
  this._firebaseAuthClient = new FirebaseSimpleLogin(this._firebase, function(error, user) {
    self._onLoginStateChange(error, user);
  });
}
Firefeed.prototype = {
  _validateCallback: function(cb, notInit) {
    if (!cb || typeof cb != "function") {
      throw new Error("Invalid onComplete callback provided");
    }
    if (!notInit) {
      if (!this._userid || !this._firebase) {
        throw new Error("Method called without a preceding login() call");
      }
    }
  },
  _validateString: function(str, name) {
    if (!str || typeof str != "string") {
      throw new Error("Invalid " + name + " provided");
    }
  },
  _getParameterByName: function(name) {
    var expr = "[?&]" + name + "=([^&]*)";
    var match = RegExp().exec(window.location.search);
    return match && decodeURIComponent(match[1].replace(/\+/g, " "));
  },
  _getPicURL: function(id, large) {
    return "https://graph.facebook.com/" + (id || this._userid) +
           "/picture/?type=" + (large ? "large" : "square") +
           "&return_ssl_resources=1";
  },
  _onNewSparkForFeed: function(feed, onComplete, onOverflow) {
    var self = this;

    // We listen for new children on the feed.
    var handler = feed.on("child_added", function(snap) {
      // When a new spark is added, fetch the content from the master spark
      // list since feeds only contain references in the form of spark IDs.
      var sparkID = snap.name();
      var sparkRef = self._firebase.child("sparks").child(sparkID);
      var handler = sparkRef.on("value", function(sparkSnap) {
        var ret = sparkSnap.val();
        if (ret !== null) {
          ret.pic = self._getPicURL(ret.author);
          onComplete(sparkSnap.name(), ret);
        }
      });
      self._handlers.push({
        ref: sparkRef, handler: handler, eventType: "value"
      });
    });
    self._handlers.push({
      ref: feed, handler: handler, eventType: "child_added"
    });

    // Also listen for child_removed so we can call onOverflow appropriately.
    handler = feed.on("child_removed", function(snap) {
      onOverflow(snap.name());
    });
    self._handlers.push({
      ref: feed, handler: handler, eventType: "child_removed"
    });
  },
  _onLoginStateChange: function(error, user) {
    var self = this;
    if (error) {
      // An error occurred while authenticating the user.
      this.handleLogout();
    } else if (user) {
      // The user is successfully logged in.
      this.onLogin(user);
    } else {
      // No existing session found - the user is logged out.
      this.onLogout();
    }
  }
};

/**
 * Attach a callback method to be invoked whenever the authentication state
 * of the user changes. If an error occurs during authentication, the error
 * object will be non-null. If a user is successfully authenticated, the error
 * object will be null, and the user object will be non-null. If a user is
 * simply logged-out, both the error and user objects will be null.
 */
Firefeed.prototype.onLoginStateChange = function(onLoginStateChange) {
  var self = this;
  self._validateCallback(onLoginStateChange, true);
  this._authHandlers.push(onLoginStateChange);
};

/**
 * Login a user using Firebase Simple Login, using the specified authentication
 * provider. Pass the optional 'rememberMe' argument to the FirebaseSimpleLogin
 * in order to create a long-lasting session. If the user is successfully
 * authenticated, then the previously-configured callback will be invoked with
 * a null error and a user object.
 *
 * @param    {string}    provider    The authentication provider to use.
 */
Firefeed.prototype.login = function(provider) {
{'fraction_non_alphanumeric': 0.11450608128151883, 'fraction_numerical': 0.0004944131316127757, 'mean_word_length': 3.0039588281868568, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3349399', 'n_tokens_mistral': 2930, 'n_tokens_neox': 2887, 'n_words': 1012}