<commit_before>import domUtils from 'src/helpers/domUtils';

const targetClassName = 'code-line';
/**
 * Return an array of code lines element found inside a document object
 * @param {HTMLDocument} scrollDocument - default to window's document
 */
function getCodeLines(scrollDocument = document) {
  const codeLines = scrollDocument.getElementsByClassName(targetClassName);
  const codeLinesArray = [];
  for (let i = 0; i < codeLines.length; i += 1) {
    codeLinesArray[i] = codeLines[i];
  }
  return codeLinesArray;
}

function getLines(element) {
  return {
    lineStart: parseInt(element.dataset.lineStart, 10),
    lineEnd: parseInt(element.dataset.lineEnd, 10)
  };
}

function isWithinLines(lineInfo, scrollPosition) {
  return (lineInfo.lineStart <= scrollPosition && scrollPosition <= lineInfo.lineEnd);
}

/**
 * Return a function for checking if an elemnet is within the specified scrollPosition
 * @param {number} scrollPosition
 * @return {function}
 */
function isElementWithinScrollPosition(scrollPosition) {
  return element => isWithinLines(getLines(element), scrollPosition);
}

function searchElement(scrollDocument = document) {
  const x = scrollDocument.defaultView.innerWidth/2;
  const yLimit = scrollDocument.defaultView.innerHeight * 0.25; // Search only the top 25% of the window
  const interval = 10;

  for (let i = 0; i < interval; i += 1) {
    const searchX = x;
    const searchY = (yLimit / interval);

    const theElement = scrollDocument.elementFromPoint(searchX, searchY);

    if (theElement) {
      const endNode = scrollDocument.body;

      let searchNode = theElement;
      let foundNode = null;
      do {
        if (domUtils.hasClass(searchNode, targetClassName)) {
          foundNode = searchNode;
          return foundNode;
        }
        searchNode = searchNode.parentNode;
      } while (searchNode !== endNode && searchNode != null);
    }
  }
  return null;
}

export default {
  getElementInScrollPosition(scrollPosition, scrollDocument = document) {
    return getCodeLines(scrollDocument).find(isElementWithinScrollPosition(scrollPosition));
  },

  getScrollPositionByDocument(scrollDocument = document) {
    const element = searchElement(scrollDocument);
    return (element) ? getLines(element).lineStart : null;
  }
};

<commit_msg>Update search algorithm to scan every pixel from the top<commit_after>import domUtils from 'src/helpers/domUtils';

const targetClassName = 'code-line';
/**
 * Return an array of code lines element found inside a document object
 * @param {HTMLDocument} scrollDocument - default to window's document
 */
function getCodeLines(scrollDocument = document) {
  const codeLines = scrollDocument.getElementsByClassName(targetClassName);
  const codeLinesArray = [];
  for (let i = 0; i < codeLines.length; i += 1) {
    codeLinesArray[i] = codeLines[i];
  }
  return codeLinesArray;
}

function getLines(element) {
  return {
    lineStart: parseInt(element.dataset.lineStart, 10),
    lineEnd: parseInt(element.dataset.lineEnd, 10)
  };
}

function isWithinLines(lineInfo, scrollPosition) {
  return (lineInfo.lineStart <= scrollPosition && scrollPosition <= lineInfo.lineEnd);
}

/**
 * Return a function for checking if an elemnet is within the specified scrollPosition
 * @param {number} scrollPosition
 * @return {function}
 */
function isElementWithinScrollPosition(scrollPosition) {
  return element => isWithinLines(getLines(element), scrollPosition);
}

function searchElement(scrollDocument = document) {
  const x = scrollDocument.defaultView.innerWidth/2;
  const yLimit = scrollDocument.defaultView.innerHeight * 0.25; // Search only the top 25% of the window

  for (let i = 0; i < yLimit; i += 1) {
    const searchX = x;
    const searchY = i;

    const theElement = scrollDocument.elementFromPoint(searchX, searchY);

    if (theElement) {
      const endNode = scrollDocument.body;

      let searchNode = theElement;
      let foundNode = null;
      do {
        if (domUtils.hasClass(searchNode, targetClassName)) {
          foundNode = searchNode;
          return foundNode;
        }
        searchNode = searchNode.parentNode;
      } while (searchNode !== endNode && searchNode != null);
    }
  }
  return null;
}

export default {
  getElementInScrollPosition(scrollPosition, scrollDocument = document) {
    return getCodeLines(scrollDocument).find(isElementWithinScrollPosition(scrollPosition));
  },

  getScrollPositionByDocument(scrollDocument = document) {
    const element = searchElement(scrollDocument);
    return (element) ? getLines(element).lineStart : null;
  }
};


{'fraction_non_alphanumeric': 0.10130151843817788, 'fraction_numerical': 0.006507592190889371, 'mean_word_length': 4.072607260726072, 'pattern_counts': {'":': 0, '<': 11, '<?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': '1214798', 'n_tokens_mistral': 1316, 'n_tokens_neox': 1274, 'n_words': 347}