<commit_before>'use strict'; // eslint-disable-line
const beautify = require('js-beautify').html_beautify;
const objectAssign = require('object-assign');

/**
* Gets the window object from a given element or document
*
* @private
* @param {!HTMLDocument|HTMLElement} element The element to get the window object for
* @return {Window|null} the window object for the given element
*/
function getWindowForElement(element) {
  const e = element.documentElement || element;
  const doc = e.ownerDocument;
  return doc.defaultView;
}

const PLACEHOLDER = '…';

const DEFAULT_OPTIONS = {
  beautify: false,
  maxLength: 0,
  placeholder: PLACEHOLDER,
};

/**
* Checks whether this is a valid element for providing context
*
* @private
* @param {!HTMLDocument|HTMLElement} element The element to check for validity
* @return {boolean} Whether this is a valid element to provide context for
*/
function isValidElement(element) {
  return element && (element.documentElement /* document */ || element.ownerDocument /* any other element */);
}

module.exports = (e, opts) => {
  if (!isValidElement(e)) {
    throw new Error(`Element '${e}' is not a valid DOM element`);
  }

  const options = objectAssign({}, DEFAULT_OPTIONS, opts || {});
  options.placeholder = '' + options.placeholder;

  let element = e;
  const window = getWindowForElement(e);
  if (e instanceof window.HTMLDocument) {
    element = e.documentElement;
  }

  const outer = options.beautify ? beautify(element.outerHTML) : element.outerHTML;
  const outerLength = outer.length;
  const fitsComplete = options.maxLength - outerLength >= 0;
  if (options.maxLength && options.maxLength > 0 && !fitsComplete) {
    // we only have space for shortened markup
    let remainingChars = options.maxLength;

    const inner = options.beautify ? beautify(element.innerHTML) : element.innerHTML;
    const outerTagWithoutInner = outer.replace(inner, options.placeholder);

    let leftBoundary = 0;
    let rightBoundary = 0;
    if (outerTagWithoutInner.length <= options.maxLength) {
      // can we fit the whole outermost tag in whole? If yes, then let's do so...
      const outerPieces = outer.split(inner);
      leftBoundary = outerPieces.shift().length;
      rightBoundary = -outerPieces.pop().length;
      // subtract the space we need for opening and closing outer tag
      remainingChars -= leftBoundary + Math.abs(rightBoundary);
    }
    // we need X chars for the placeholder
    remainingChars -= options.placeholder.length;

    const remainingCharsLeft = Math.ceil(remainingChars / 2); // in case of uneven split, favor beginning with 1 character
    const remainingCharsRight = remainingChars - remainingCharsLeft;
    leftBoundary += remainingCharsLeft;<commit_msg>fix: guard against some special cases<commit_after>'use strict'; // eslint-disable-line
const beautify = require('js-beautify').html_beautify;
const objectAssign = require('object-assign');

/**
* Gets the window object from a given element or document
*
* @private
* @param {!HTMLDocument|HTMLElement} element The element to get the window object for
* @return {Window|null} the window object for the given element
*/
function getWindowForElement(element) {
  const e = element.documentElement || element;
  const doc = e.ownerDocument;
  return doc.defaultView;
}

const PLACEHOLDER = '…';

const DEFAULT_OPTIONS = {
  beautify: false,
  maxLength: 0,
  placeholder: PLACEHOLDER,
};

/**
* Checks whether this is a valid element for providing context
*
* @private
* @param {!HTMLDocument|HTMLElement} element The element to check for validity
* @return {boolean} Whether this is a valid element to provide context for
*/
function isValidElement(element) {
  return element && (element.documentElement /* document */ || element.ownerDocument /* any other element */);
}

module.exports = (e, opts) => {
  if (!isValidElement(e)) {
    throw new Error(`Element '${e}' is not a valid DOM element`);
  }

  const options = objectAssign({}, DEFAULT_OPTIONS, opts || {});
  options.placeholder = '' + options.placeholder;

  let element = e;
  const window = getWindowForElement(e);
  if (e instanceof window.HTMLDocument) {
    element = e.documentElement;
  }

  if (!element.outerHTML) {
    // SVG elements for example
    return null;
  }

  const outer = options.beautify ? beautify(element.outerHTML) : element.outerHTML;
  const outerLength = outer.length;
  const fitsComplete = options.maxLength - outerLength >= 0;
  if (options.maxLength && options.maxLength > 0 && !fitsComplete) {
    // we only have space for shortened markup
    let remainingChars = options.maxLength;

    const inner = options.beautify ? beautify(element.innerHTML) : element.innerHTML;
    const outerTagWithoutInner = outer.replace(inner, options.placeholder);

    let leftBoundary = 0;
    let rightBoundary = 0;
    if (outerTagWithoutInner.length <= options.maxLength && outer.indexOf(inner) !== -1) {
      // can we fit the whole outermost tag in whole? If yes, then let's do so...
      const outerPieces = outer.split(inner);
      leftBoundary = outerPieces.shift().length;
      rightBoundary = -outerPieces.pop().length;
      // subtract the space we need for opening and closing outer tag
      remainingChars -= leftBoundary + Math.abs(rightBoundary);
    }
    // we need X chars for the placeholder
    remainingChars -= options.placeholder.length;

    const remainingCharsLeft = Math.ceil(remainingChars / 2); // in case of uneven split, favor beginning with 1 character
    const remainingCharsRight = remainingChars - remainingCharsLeft;
    leftBoundary += remainingCharsLeft;
{'fraction_non_alphanumeric': 0.10684444444444445, 'fraction_numerical': 0.0026666666666666666, 'mean_word_length': 3.956828193832599, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, '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': '5779196', 'n_tokens_mistral': 1616, 'n_tokens_neox': 1567, 'n_words': 512}