src/Debug/js_src/enhanceEntries.js
import $ from 'jquery'
import * as enhanceArray from './enhanceArray.js'
import * as enhanceObject from './enhanceObject.js'
import * as enhanceSubscribers from './enhanceSubscribers.js'
import * as tableSort from './tableSort.js'
import * as fileLinks from './FileLinks.js'
var config
var toExpandQueue = []
var processingQueue = false
export function init ($root) {
config = $root.data('config').get()
enhanceArray.init($root)
enhanceObject.init($root)
enhanceSubscribers.init($root, enhanceValue, enhanceObject)
fileLinks.init($root)
}
/**
* Enhance log entries inside .group-body
*/
export function enhanceEntries ($node) {
// console.log('enhanceEntries', $node[0])
var $parent = $node.parent()
var show = !$parent.hasClass('m_group') || $parent.hasClass('expanded')
// temporarily hide when enhancing... minimize redraws
$node.hide()
$node.children().each(function () {
enhanceEntry($(this))
})
if (show) {
$node.show().trigger('expanded.debug.group')
}
processExpandQueue()
if ($node.parent().hasClass('m_group') === false) {
// only add .enhanced to root .group-body
$node.addClass('enhanced')
}
}
/**
* Enhance a single log entry
* we don't enhance strings by default (add showmore).. needs to be visible to calc height
*/
export function enhanceEntry ($entry) {
// console.log('enhanceEntry', $entry[0])
if ($entry.hasClass('enhanced')) {
return
} else if ($entry.hasClass('m_group')) {
enhanceGroup($entry)
} else if ($entry.hasClass('filter-hidden')) {
return
} else if ($entry.is('.m_table, .m_trace')) {
enhanceEntryTabular($entry)
} else {
enhanceEntryDefault($entry)
}
$entry.addClass('enhanced')
$entry.trigger('enhanced.debug')
}
export function enhanceValue (node, $entry) {
var $node = $(node)
if ($node.is('.t_array')) {
enhanceArray.enhance($node)
} else if ($node.is('.t_object')) {
enhanceObject.enhance($node)
} else if ($node.is('table')) {
tableSort.makeSortable($node)
} else if ($node.is('.t_string')) {
fileLinks.create($entry, $node)
} else if ($node.is('.string-encoded.tabs-container')) {
// console.warn('enhanceStringEncoded', $node)
enhanceValue($node.find('> .tab-pane.active > *'), $entry)
}
}
/**
* add font-awesome icons
*/
function addIcons ($node) {
var $caption
var $icon = determineIcon($node)
var isNested = false
addIconsMisc($node)
if (!$icon) {
return
}
if ($node.hasClass('m_group')) {
// custom icon.. add to .group-label
$node = $node.find('> .group-header .group-label').eq(0)
} else if ($node.find('> table').length) {
// table... we'll prepend icon to caption
isNested = $node.parent('.no-indent').length > 0
$caption = $node.find('> table > caption')
if ($caption.length === 0 && isNested === false) {
// add caption
$caption = $('<caption>')
$node.find('> table').prepend($caption)
}
$node = $caption
}
if ($node.find('> i:first-child').hasClass($icon.attr('class'))) {
// already have icon
return
}
$node.prepend($icon)
}
function addIconsMisc ($node) {
var $icon
var $node2
var selector
for (selector in config.iconsMisc) {
$node2 = $node.find(selector)
if ($node2.length === 0) {
continue
}
$icon = $(config.iconsMisc[selector])
if ($node2.find('> i:first-child').hasClass($icon.attr('class'))) {
// already have icon
$icon = null
continue
}
$node2.prepend($icon)
$icon = null
}
}
function determineIcon ($node) {
var $icon
var $node2
if ($node.data('icon')) {
return $node.data('icon').match('<')
? $($node.data('icon'))
: $('<i>').addClass($node.data('icon'))
}
if ($node.hasClass('m_group')) {
return $icon // undefined / groupIcon will be added separately
}
$node2 = $node.hasClass('group-header')
? $node.parent()
: $node
return determineIconFromConfig($node2)
}
function determineIconFromConfig ($node) {
var $icon
var selector
for (selector in config.iconsMethods) {
if ($node.is(selector)) {
$icon = $(config.iconsMethods[selector])
break
}
}
return $icon
}
function enhanceEntryDefault ($entry) {
// regular log-type entry
var title
if ($entry.data('file')) {
if (!$entry.attr('title')) {
title = $entry.data('file') + ': line ' + $entry.data('line')
if ($entry.data('evalline')) {
title += ' (eval\'d line ' + $entry.data('evalline') + ')'
}
$entry.attr('title', title)
}
fileLinks.create($entry)
}
addIcons($entry)
$entry.children().each(function () {
enhanceValue(this, $entry)
})
}
function enhanceEntryTabular ($entry) {
fileLinks.create($entry)
addIcons($entry)
if ($entry.hasClass('m_table')) {
$entry.find('> table > tbody > tr > td').each(function () {
enhanceValue(this, $entry)
})
}
// table may have a expand collapse row that's initially expanded
// trigger expanded event (so, trace context args are enhanced, etc)
$entry.find('tbody > tr.expanded').next().trigger('expanded.debug.next')
tableSort.makeSortable($entry.find('> table'))
}
function enhanceGroup ($group) {
// console.log('enhanceGroup', $group[0])
var $toggle = $group.find('> .group-header')
var $target = $toggle.next()
addIcons($group) // custom data-icon
addIcons($toggle) // expand/collapse
$toggle.attr('data-toggle', 'group')
$toggle.find('.t_array, .t_object').each(function () {
$(this).data('expand', false)
enhanceValue(this, $group)
})
$.each(['level-error', 'level-info', 'level-warn'], function (i, classname) {
var $toggleIcon
if ($group.hasClass(classname)) {
$toggleIcon = $toggle.children('i').eq(0)
$toggle.wrapInner('<span class="' + classname + '"></span>')
$toggle.prepend($toggleIcon) // move icon
}
})
if (
$group.hasClass('expanded') ||
$target.find('.m_error, .m_warn').not('.filter-hidden').not('[data-uncollapse=false]').length
) {
toExpandQueue.push($toggle)
return
}
$toggle.debugEnhance('collapse', true)
}
function processExpandQueue () {
if (processingQueue) {
return
}
processingQueue = true
while (toExpandQueue.length) {
toExpandQueue.shift().debugEnhance('expand')
}
processingQueue = false
}