src/Debug/js_src/sidebar.js
import $ from 'jquery'
import { addTest as addFilterTest, addPreFilter } from './filter.js'
var config
var options
var methods // method filters
var initialized = false
var methodLabels = {
alert: '<i class="fa fa-fw fa-lg fa-bullhorn"></i>Alerts',
error: '<i class="fa fa-fw fa-lg fa-times-circle"></i>Error',
warn: '<i class="fa fa-fw fa-lg fa-warning"></i>Warning',
info: '<i class="fa fa-fw fa-lg fa-info-circle"></i>Info',
other: '<i class="fa fa-fw fa-lg fa-sticky-note-o"></i>Other'
}
var sidebarHtml = '' +
'<div class="debug-sidebar show no-transition">' +
'<div class="sidebar-toggle">' +
'<div class="collapse">' +
'<i class="fa fa-caret-left"></i>' +
'<i class="fa fa-ellipsis-v"></i>' +
'<i class="fa fa-caret-left"></i>' +
'</div>' +
'<div class="expand">' +
'<i class="fa fa-caret-right"></i>' +
'<i class="fa fa-ellipsis-v"></i>' +
'<i class="fa fa-caret-right"></i>' +
'</div>' +
'</div>' +
'<div class="sidebar-content">' +
'<ul class="list-unstyled debug-filters">' +
'<li class="php-errors">' +
'<span><i class="fa fa-fw fa-lg fa-code"></i>PHP Errors</span>' +
'<ul class="list-unstyled">' +
'</ul>' +
'</li>' +
'<li class="channels">' +
'<span><i class="fa fa-fw fa-lg fa-list-ul"></i>Channels</span>' +
'<ul class="list-unstyled">' +
'</ul>' +
'</li>' +
'</ul>' +
'<button class="expand-all" style="display:none;"><i class="fa fa-lg fa-plus"></i> Exp All Groups</button>' +
'</div>' +
'</div>'
export function init ($root) {
config = $root.data('config') || $('body').data('config')
options = $root.find('> .tab-panes > .tab-primary').data('options') || {}
if (options.sidebar) {
addMarkup($root)
}
if (config.get('persistDrawer') && !config.get('openSidebar')) {
close($root)
}
$root.on('click', '.close[data-dismiss=alert]', onClickCloseAlert)
$root.on('click', '.sidebar-toggle', onClickSidebarToggle)
$root.on('change', '.debug-sidebar input[type=checkbox]', onChangeSidebarInput)
if (initialized) {
return
}
addPreFilter(preFilter)
addFilterTest(filterTest)
initialized = true
}
function onChangeSidebarInput (e) {
var $input = $(this)
var $toggle = $input.closest('.toggle')
var $nested = $toggle.next('ul').find('.toggle')
var isActive = $input.is(':checked')
var $errorSummary = $('.m_alert.error-summary.have-fatal')
$toggle.toggleClass('active', isActive)
$nested.toggleClass('active', isActive)
if ($input.val() === 'fatal') {
$errorSummary.find('.error-fatal').toggleClass('filter-hidden', !isActive)
$errorSummary.toggleClass('filter-hidden', $errorSummary.children().not('.filter-hidden').length === 0)
}
}
function onClickCloseAlert (e) {
// setTimeout -> new thread -> executed after event bubbled
var $debug = $(e.delegateTarget)
setTimeout(function () {
if ($debug.find('.tab-primary > .tab-body > .m_alert').length === 0) {
$debug.find('.debug-sidebar input[data-toggle=method][value=alert]').parent().addClass('disabled')
}
})
}
function onClickSidebarToggle () {
var $debug = $(this).closest('.debug')
var isVis = $debug.find('.debug-sidebar').is('.show')
if (!isVis) {
open($debug)
} else {
close($debug)
}
}
function filterTest ($node) {
var matches = $node[0].className.match(/\bm_(\S+)\b/)
var method = matches ? matches[1] : null
if (!options.sidebar) {
return true
}
if (method === 'group' && $node.find('> .group-body')[0].className.match(/level-(error|info|warn)/)) {
method = $node.find('> .group-body')[0].className.match(/level-(error|info|warn)/)[1]
$node.toggleClass('filter-hidden-body', methods.indexOf(method) < 0)
}
if (['alert', 'error', 'warn', 'info'].indexOf(method) > -1) {
return methods.indexOf(method) > -1
}
return methods.indexOf('other') > -1
}
function preFilter ($root) {
var $sidebar = $root.find('.tab-pane.active .debug-sidebar')
methods = []
if ($sidebar.length === 0) {
// sidebar not built yet
methods = Object.keys(methodLabels)
}
$sidebar.find('input[data-toggle=method]:checked').each(function () {
methods.push($(this).val())
})
}
export function addMarkup ($node) {
var $sidebar = $(sidebarHtml)
var $expAll = $node.find('.tab-panes > .tab-primary > .tab-body > .expand-all')
$node.find('.tab-panes > .tab-primary > .tab-body').before($sidebar)
updateErrorSummary($node)
phpErrorToggles($node)
moveChannelToggles($node)
addMethodToggles($node)
if ($expAll.length) {
$expAll.remove()
$sidebar.find('.expand-all').show()
}
setTimeout(function () {
$sidebar.removeClass('no-transition')
}, 500)
}
export function close ($node) {
$node.find('.debug-sidebar')
.removeClass('show')
.attr('style', '')
.trigger('close.debug.sidebar')
config.set('openSidebar', false)
}
export function open ($node) {
$node.find('.debug-sidebar')
.addClass('show')
.trigger('open.debug.sidebar')
config.set('openSidebar', true)
}
/**
* @param $node debugroot
*/
function addMethodToggles ($node) {
var channelNameRoot = $node.data('channelNameRoot')
var $filters = $node.find('.debug-filters')
var $entries = $node.find('.tab-primary').find('> .tab-body > .m_alert, .group-body > *')
var val
var haveEntry
for (val in methodLabels) {
haveEntry = val === 'other'
? $entries.not('.m_alert, .m_error, .m_warn, .m_info').length > 0
: $entries.filter('.m_' + val).not('[data-channel="' + channelNameRoot + '.phpError"]').length > 0
$filters.append(
$('<li />').append(
$('<label class="toggle active" />').toggleClass('disabled', !haveEntry).append(
$('<input />', {
type: 'checkbox',
checked: true,
'data-toggle': 'method',
value: val
})
).append(
$('<span>').append(methodLabels[val])
)
)
)
}
}
/**
* grab the .tab-panes toggles and move them to sidebar
*/
function moveChannelToggles ($node) {
var $togglesSrc = $node.find('.tab-panes .channels > ul > li')
var $togglesDest = $node.find('.debug-sidebar .channels ul')
$togglesDest.append($togglesSrc)
if ($togglesDest.children().length === 0) {
$togglesDest.parent().hide()
}
$node.find('> .tab-panes > .tab-primary > .tab-body > .channels').remove()
}
/**
* Build php error toggles
*/
function phpErrorToggles ($node) {
var $togglesUl = $node.find('.debug-sidebar .php-errors ul')
var categories = ['fatal', 'error', 'warning', 'deprecated', 'notice', 'strict']
$.each(categories, function (i, category) {
var count = category === 'fatal'
? $node.find('.m_alert.error-summary.have-fatal').length
: $node.find('.error-' + category).filter('.m_error,.m_warn').length
if (count === 0) {
return
}
$togglesUl.append(
$('<li>').append(
$('<label class="toggle active">').html(
'<input type="checkbox" checked data-toggle="error" data-count="' + count + '" value="' + category + '" />' +
category + ' <span class="badge">' + count + '</span>'
)
)
)
})
if ($togglesUl.children().length === 0) {
$togglesUl.parent().hide()
}
}
function updateErrorSummary ($node) {
var $errorSummary = $node.closest('.debug').find('.m_alert.error-summary')
var $inConsole = $errorSummary.find('.in-console')
$inConsole.prev().remove()
$inConsole.remove()
if ($errorSummary.children().length === 0) {
$errorSummary.remove()
}
}