<commit_before>(function (Q, $) {
	/**
	 * @module Q-tools
	 */

	/**
	 * When you scroll and reach the end of a list, more has already been loaded.
	 * @class Q infinitescroll
	 * @constructor
	 * @param {Object} [options] Override various options for this tool
	 *  @param {Float} [options.future.threshold=0.8] Required. How much to scroll to load future elements.
	 *  @param {Boolean} [options.flipped=false] If true, seek for scrolling from bottom to top.
	 *  @param {Object} [options.onInvoke] Event fired when need load new elements.
	 * @return {Q.Tool}
	 */
	Q.Tool.define('Q/infinitescroll', function (options) {
		var tool = this;
		var state = tool.state;
		var $te = $(tool.element);

		Q.addStylesheet('{{Q}}/css/infinitescroll.css', { slotName: 'Q' });

		state.lastScrollHeight = $te[0].scrollHeight;

		$te.on('scroll', tool, function () {
			var scrolled;

			if (state.flipped) {
				scrolled = 1 - $te[0].scrollTop/$te[0].scrollHeight;
			} else {
				scrolled = ($te[0].scrollTop + $te[0].clientHeight)/$te[0].scrollHeight;
			}

			if (scrolled >= state.future.threshold && !state.waiting) {
				state.waiting = true;
				Q.handle(state.onInvoke, tool, [scrolled]);
			}
		});

		// watch for tool.element scrollHeight change
		Q.onLayout(tool.element).set(function () {
			if (state.lastScrollHeight < tool.element.scrollHeight) {
				// if flipped, scroll down to the value of scrollHeight diff
				if (state.flipped) {
					tool.element.scrollTop += tool.element.scrollHeight - state.lastScrollHeight;
				}

				state.waiting = false;
			}

			state.lastScrollHeight = tool.element.scrollHeight;
		}, tool);

		// listen for included tools rendered
		var includedTools = [];
		var pipeTimer = null;
		tool.element.forEachTool(function () {
			if (pipeTimer === true) {
				return;
			}

			if (this.state.onRender) {
				includedTools.push(this);
				clearTimeout(pipeTimer);
				pipeTimer = setTimeout(function () {
					pipeTimer = true; // mark that pipe called
					var pipeArray = includedTools.map(function (currTool) {
						return currTool.id;<commit_msg>Fixed infiniteScroll to not rely on Q.layout() call<commit_after>(function (Q, $) {
	/**
	 * @module Q-tools
	 */

	/**
	 * When you scroll and reach the end of a list, more has already been loaded.
	 * @class Q infinitescroll
	 * @constructor
	 * @param {Object} [options] Override various options for this tool
	 *  @param {Float} [options.future.threshold=0.8] Required. How much to scroll to load future elements.
	 *  @param {Boolean} [options.flipped=false] If true, seek for scrolling from bottom to top.
	 *  @param {Object} [options.onInvoke] Event fired when need load new elements.
	 * @return {Q.Tool}
	 */
	Q.Tool.define('Q/infinitescroll', function (options) {
		var tool = this;
		var state = tool.state;
		var $te = $(tool.element);

		Q.addStylesheet('{{Q}}/css/infinitescroll.css', { slotName: 'Q' });

		state.lastScrollHeight = $te[0].scrollHeight;

		$te.on('scroll', tool, function () {
			var scrolled;

			if (state.flipped) {
				scrolled = 1 - $te[0].scrollTop/$te[0].scrollHeight;
			} else {
				scrolled = ($te[0].scrollTop + $te[0].clientHeight)/$te[0].scrollHeight;
			}

			if (scrolled >= state.future.threshold && !state.waiting) {
				state.waiting = true;
				Q.handle(state.onInvoke, tool, [scrolled]);
			}
		});

		// watch for tool.element scrollHeight change
		var ival = setInterval(function () {
			if (state.lastScrollHeight < tool.element.scrollHeight) {
				// if flipped, scroll down to the value of scrollHeight diff
				if (state.flipped) {
					tool.element.scrollTop += tool.element.scrollHeight - state.lastScrollHeight;
				}
				state.waiting = false;
				clearInterval(ival);
			}
			state.lastScrollHeight = tool.element.scrollHeight;
		}, 300);

		// listen for included tools rendered
		var includedTools = [];
		var pipeTimer = null;
		tool.element.forEachTool(function () {
			if (pipeTimer === true) {
				return;
			}

			if (this.state.onRender) {
				includedTools.push(this);
				clearTimeout(pipeTimer);
				pipeTimer = setTimeout(function () {
					pipeTimer = true; // mark that pipe called
					var pipeArray = includedTools.map(function (currTool) {
						return currTool.id;
{'fraction_non_alphanumeric': 0.1388101983002833, 'fraction_numerical': 0.004957507082152974, 'mean_word_length': 3.305894308943089, 'pattern_counts': {'":': 0, '<': 5, '<?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': '1555906', 'n_tokens_mistral': 1567, 'n_tokens_neox': 1339, 'n_words': 349}