<commit_before>/**
 * @module DateTimeMenuItem
 * @description This module exports the DateTimeMenuItem class
 */

'use strict'

var $ = window.jQuery

var dateformat = require('dateformat')

var days = { 'Monday': 'Lundi', 'Tuesday': 'Mardi', 'Wednesday': 'Mercredi', 'Thursday': 'Jeudi', 'Friday': 'Vendredi', 'Saturday': 'Samedi', 'Sunday': 'Dimanche' }

var months = { 'January': 'Janvier', 'February': 'Février', 'March': 'Mars', 'April': 'Avril', 'May': 'Mai', 'June': 'Juin', 'July': 'Juillet', 'August': 'Août', 'September': 'Septembre', 'October': 'Octobre', 'November': 'November', 'December': 'Decembre' }

module.exports = DateTimeMenuItem

/**
 * This class instances permit to manage the plugin menu items
 * @class
 * @param {string} mask
 * @param {tinymce.Editor} editor The tinymce instance
 */
function DateTimeMenuItem (mask, editor) {
  this.mask = mask
  this.editor = editor
  this.text = this.format()
  this.title = mask
  this.setId()
}

/**
 * Set an menu item element to its object instance
 * @method
 * @param {DOMElement} element The element to set to its object instance (as a jquery set of one element)
 * @returns {undefined}
 */
DateTimeMenuItem.prototype.setElement = function ($element) {
  var that = this
  this.node = $element[0]
  $element.click(function () {
    var selectedNode = that.editor.selection.getNode()
    var dateNode = $('<span contenteditable="false" data-dynamicdate="' + that.mask + '">' + that.format() + '</span>')
    $(selectedNode).append(dateNode)
    console.log('selectedNode', selectedNode)
  })
}

/**
 * Shared prefix for all menu item element's id
 * @constant
 * @static
 */
DateTimeMenuItem.PREFIX_ID = 'dynamicdate-'

/**
 * Computes and encodes the id for the menu item element, then set it in the id property
 * @method
 * @returns {undefined}
 */
DateTimeMenuItem.prototype.setId = function () {
  var id = (DateTimeMenuItem.PREFIX_ID + this.mask)
    .replace(/ /gi, '-space-')
    .replace(/\//gi, '-slash-')
    .replace(/:/gi, '-dots-')
    .replace(/,/gi, '-comma-')
    .replace(/'/gi, '-singlequote-')
  this.id = id
}

/**
 * Formats and translate in french a new date against the date mask set to the instance
 * @method
 * @returns {string} the mask-formated now-date, in french
 */
DateTimeMenuItem.prototype.format = function () {
  var now = new Date()
  var formatted = dateformat(now, this.mask)
  // replace english days by french days
  for (var enDay in days) {
    var frDay = days[enDay]
    formatted = formatted.replace(enDay, frDay)
  }
  // replace english months by french ones
  for (var enMonth in months) {
    var frMonth = months[enMonth]
    formatted = formatted.replace(enMonth, frMonth)
  }
  return formatted
}<commit_msg>finalize the  DateTimeMenuItem#setElement() method<commit_after>/**
 * @module DateTimeMenuItem
 * @description This module exports the DateTimeMenuItem class
 */

'use strict'

var $ = window.jQuery

var dateformat = require('dateformat')

var days = { 'Monday': 'Lundi', 'Tuesday': 'Mardi', 'Wednesday': 'Mercredi', 'Thursday': 'Jeudi', 'Friday': 'Vendredi', 'Saturday': 'Samedi', 'Sunday': 'Dimanche' }

var months = { 'January': 'Janvier', 'February': 'Février', 'March': 'Mars', 'April': 'Avril', 'May': 'Mai', 'June': 'Juin', 'July': 'Juillet', 'August': 'Août', 'September': 'Septembre', 'October': 'Octobre', 'November': 'November', 'December': 'Decembre' }

module.exports = DateTimeMenuItem

/**
 * This class instances permit to manage the plugin menu items
 * @class
 * @param {string} mask
 * @param {tinymce.Editor} editor The tinymce instance
 */
function DateTimeMenuItem (mask, editor) {
  this.mask = mask
  this.editor = editor
  this.text = this.format()
  this.title = mask
  this.setId()
}

/**
 * Set an menu item element to its object instance
 * @method
 * @param {DOMElement} element The element to set to its object instance (as a jquery set of one element)
 * @returns {undefined}
 */
DateTimeMenuItem.prototype.setElement = function ($element) {
  var that = this
  this.node = $element[0]
  $element.click(function () {
    var selectedNode = that.editor.selection.getNode()
    // search the closest font family and size
    var closestFontConfig = getClosestNodeWithFontConfig(selectedNode, 'Calibri', '12pt', that.editor)

    $('<span>' + that.format() + '</span>')
      .attr('contenteditable', false)
      .attr('data-dynamicdate', that.mask)
      .css(closestFontConfig)
      .appendTo(selectedNode)
  })
}

/**
 * Shared prefix for all menu item element's id
 * @constant
 * @static
 */
DateTimeMenuItem.PREFIX_ID = 'dynamicdate-'

/**
 * Computes and encodes the id for the menu item element, then set it in the id property
 * @method
 * @returns {undefined}
 */
DateTimeMenuItem.prototype.setId = function () {
  var id = (DateTimeMenuItem.PREFIX_ID + this.mask)
    .replace(/ /gi, '-space-')
    .replace(/\//gi, '-slash-')
    .replace(/:/gi, '-dots-')
    .replace(/,/gi, '-comma-')
    .replace(/'/gi, '-singlequote-')
  this.id = id
}

/**
 * Formats and translate in french a new date against the date mask set to the instance
 * @method
 * @returns {string} the mask-formated now-date, in french
 */
DateTimeMenuItem.prototype.format = function () {
  var now = new Date()
  var formatted = dateformat(now, this.mask)
  // replace english days by french days
  for (var enDay in days) {
    var frDay = days[enDay]
    formatted = formatted.replace(enDay, frDay)
  }
  // replace english months by french ones
  for (var enMonth in months) {
    var frMonth = months[enMonth]
    formatted = formatted.replace(enMonth, frMonth)
  }
  return formatted
}

/**
 * @typedef FontConfig
 * @type object
 * @property {string} fontFamily The font-family name
 * @property {string} fontSize The font-size with unit (ex: "12pt")
 */

/**
 * Search the closest span element for wich font size and family is defined. Begins with previous, then next, and finally search through the ancestors and their children
 * @function
 * @param {DOMNode} the node from wich the search starts
 * @returns {null|FontConfig}
 */
function getClosestNodeWithFontConfig (node, defaultFamily, defaultSize, editor) {
  var $node = $(node)
  var $currentNode
  var found, $found

  // is node ok itself ?
  $currentNode = $node.filter(fontConfigFilter)
  if ($currentNode.length) {
    $found = $currentNode
  } else {
    var $allNodes = $('*', editor.getDoc())
    var nodePosition = $allNodes.index(node)

    var $allSpans = $('span', editor.getDoc()).filter(fontConfigFilter)
    var allSpanPositions = $allSpans.map(function (i, el) {
      return $allNodes.index(el)
    })

    var lowerPositions = []
    var greaterPositions = []
    $.each(allSpanPositions, function (i, documentPosition) {
      if (documentPosition < nodePosition) {
        lowerPositions.push(documentPosition)
      } else if (documentPosition > nodePosition) {
        greaterPositions.push(documentPosition)
      }
    })

    var prevIndex = Math.max.apply(null, lowerPositions)
    var nextIndex = Math.min.apply(null, greaterPositions)

    if (!isNaN(prevIndex) && isFinite(prevIndex)) {
      found = $allNodes[prevIndex]
    } else if (!isNaN(nextIndex) && isFinite(nextIndex)) {
      found = $allNodes[nextIndex]
    }
    if (found) {
      $found = $(found)
    }
  }

  if ($found) {
    return getConfigFromElement($found)
  } else {
    return {
      fontFamily: defaultFamily,
      fontSize: defaultSize
    }
  }
}

/**
 * A jquery filter to filter span elements having fontFamily and fontSize defined
 * @function
 * @returns {boolean} true|false
 */
function fontConfigFilter () {
  return (this.style.fontFamily && this.style.fontSize)
}

/**
 * A handy function to return a FontConfig type object from the element styles values
 * @function
 * @param {jQuery} $element A jQuery object from the element to lookup the font style rules
 * @returns {FontConfig} the resulting fontConfig object
 */
function getConfigFromElement ($element) {
  return {
    fontFamily: $element[0].style.fontFamily,
    fontSize: $element[0].style.fontSize
  }
}
{'fraction_non_alphanumeric': 0.1408641975308642, 'fraction_numerical': 0.0009876543209876543, 'mean_word_length': 3.7429742388758784, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, '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': '340428', 'n_tokens_mistral': 2566, 'n_tokens_neox': 2481, 'n_words': 765}