qtools_profiler-8.x-1.x-dev/modules/qtools_cache_profiler/js/cache-profiler-preview.js
modules/qtools_cache_profiler/js/cache-profiler-preview.js
/**
* @file
* Behaviours for cache profiler.
*/
var qToolsCacheProfiler = {
'reports': []
};
(function ($) {
var observer = qToolsProfilerPreviewObserver;
/**
* Calculate complexity (reusability).
*/
qToolsCacheProfiler.calculateComplexity = function ($element, scales, ignoredContexts) {
var contexts = $element.data('renderviz-contexts').split(' ');
var complexity = 1;
var matches = [];
for (var i = 0; i < contexts.length; i++) {
var context = contexts[i];
if (ignoredContexts.indexOf(context) === -1) {
for (var j = 0; j < scales.length; j++) {
var scale = scales[j];
var rex = new RegExp(scale[0]);
if (context.match(rex)) {
complexity = complexity * scale[1];
// Only track scales that affect complexity.
matches.push(context + ':' + scale[1]);
// Only one scale can be applied per context.
break;
}
}
}
}
// Save matches in the element.
$element.attr('data-qtools-cache-profiler-complexity-matches', matches.join(' '));
$element.attr('data-qtools-cache-profiler-complexity-value', complexity);
// Result is capped at 4 and is lx(100).
return Math.max(1, Math.min(4, Math.round(Math.log(complexity) / Math.log(100))));
};
/**
* Main behavior.
*/
qToolsCacheProfiler.handleProfilerReportSelected = function (context, settings) {
$('body').once('qtools-cache-profiler').each(function () {
qToolsCacheProfiler.reports = settings.qtools_profiler.reports;
// Subscribe to observer.
observer.subscribe({
'onSelectReport': function (data) {
var report = qToolsCacheProfiler.reports[data.report];
if (report && report[0] === '#qtools_cache_profiler_render_cache') {
$('html').addClass('qtools-cache-profiler-enabled');
}
else{
$('html').removeClass('qtools-cache-profiler-enabled');
}
}
});
});
};
/**
* Show details about moseover item.
*/
qToolsCacheProfiler.showRenderedItemDetails = function ($element) {
var select = true;
if ($element.hasClass('qtools-cache-profiler-inspect')) {
select = false;
}
// Clean up old classes.
$('.qtools-cache-profiler-inspect').removeClass('qtools-cache-profiler-inspect');
$('.qtools-cache-profiler-inspect-inner').removeClass('qtools-cache-profiler-inspect-inner');
// Mark element.
if (select) {
$element.addClass('qtools-cache-profiler-inspect');
$element.find('*').addClass('qtools-cache-profiler-inspect-inner');
}
// Update log.
var matches = $element.data('qtools-cache-profiler-complexity-matches');
var report_content = {
'cid': $element.data('renderviz-qtools-cache-profiler-cid'),
'complexity': $element.attr('data-qtools-cache-profiler-complexity-value'),
'contexts': matches ? matches.split(' ') : []
};
qToolsProfilerPreviewObserver.setReportContent('#qtools_cache_profiler_render_cache', report_content);
};
/**
* Add new command to populate render cache for request.
*/
Drupal.AjaxCommands.prototype.qtoolsCacheProfilerRenderCacheStats = function (ajax, response, status) {
if (status === 'success') {
var $scope = $('html').eq(0);
// Apply cacheability display classes to all inner elements.
$scope.addClass('qtools-cache-profiler-cacheable');
var ignoredContexts = ['url.path', 'request_format', 'route', 'url.query_args:_wrapper_format'];
qToolsCacheProfiler.setCacheComplexity($scope, 'n', response.stats, ignoredContexts);
}
};
/**
* Set cache complexity on all children.
*/
qToolsCacheProfiler.setCacheComplexity = function ($element, complexity, cacheOps, ignoredContexts) {
// Get cid of the current block, if not empty
// calculate new complexity of this element.
if ($element.data('renderviz-qtools-cache-profiler-cacheable')) {
$element.addClass('qtools-cache-profiler-cacheable');
if ($element.data('renderviz-qtools-cache-profiler-lazy')) {
$element.addClass('qtools-cache-profiler-lazy');
}
var cache_miss = 0;
var cache_write = 1;
var cache_hit = 2;
// Get cache op for this element.
var cid = $element.data('renderviz-qtools-cache-profiler-cid');
var max_age = parseInt($element.data('renderviz-max-age'));
// If no cid op is always miss.
var op = cache_miss;
if (!cid) {
op = cache_miss;
}
else if (cacheOps[cid]) {
// If we have stats for this cid use it
op = cacheOps[cid];
}
else {
// If max_age > 0 this was taken form cache, otherwise was built (cache miss).
op = (max_age === 0) ? cache_miss : cache_hit;
}
// If op == cache_hit this piece was fetched from cache or supposed to be fetched from cache.
if (op === cache_hit) {
complexity = qToolsCacheProfiler.calculateComplexity($element, drupalSettings.qtools_profiler.contexts_scales, ignoredContexts);
}
else {
// Cache write.
complexity = (op === cache_write ? 0 : 'n');
}
// Show details on mouse right click.
if (cacheOps[cid]) {
$element.once('qtools-cache-profiler-details').contextmenu(function() {
qToolsCacheProfiler.showRenderedItemDetails($element);
});
}
}
// Set complexity and update children.
var complexityClass = 'qtools-cache-profiler-complexity-' + complexity;
$element.addClass(complexityClass);
// Don't colorize messages.
if ($element.prop('tagName') !== 'UL' || !$element.hasClass('messages__list')) {
$element.children().each(function () {
qToolsCacheProfiler.setCacheComplexity($(this), complexity, cacheOps, []);
});
}
};
/**
* Register behavior.
*/
Drupal.behaviors.qToolsCacheProfiler = {
attach: function (context, settings) {
qToolsCacheProfiler.handleProfilerReportSelected(context, settings);
}
};
}(jQuery));
