Skip to content
139 changes: 139 additions & 0 deletions js/extra/rainbow-display-stats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
$(function() {

'use strict';

var labels = {
show: 'show usage counts',
hide: 'hide usage counts'
};

/**
* Rainbow.displayStats();
*
* Adds a new element before <pre> tag and displays usage counts.
*
* @param tag {String} optional - any element container of <pre> tag (applies to all <pre> tags if no param given)
* @param fullList {Boolean} optional - if true will expand the list of usages
*/
Rainbow.displayStatsOn = function(tag,fullList){

Rainbow.statsOn = tag || 'body';
Rainbow.statsFull = fullList;

getElementLink();

};

/********************
* PRIVATE METHODS
********************/

function getElementLink(){
var $link = $('<a>').attr('href','#').text(labels.show);

$link.on('click',createOrToggleList);

$(Rainbow.statsOn).find('pre').before($link);
}

function getElementStats($target){
var classes = getClasses($target.next()),
$stats = $('<div>').attr('class','rainbow-stats'),
$class = $('<span>').attr('class','rainbow-stats-class'),
$count = $('<span>').attr('class','rainbow-stats-count');

for(var c in classes){
if(classes.hasOwnProperty(c)){
$stats.append(
$('<div>')
.append($count.clone().text(classes[c].count))
.append($class.clone().text(classes[c].name)
.on('click',doHighlight)
)
);
}
}

$target.after($stats);

return $stats;
}

function getClasses($el){

var classes = {};

if(!$el || !$el.is || !$el.is('pre')) {
return null;
}

$el.find('span').each(function(i,e){

var clsStr = $(e).attr('class');

classes[clsStr] || (classes[clsStr]=0);
classes[clsStr]++;

if(Rainbow.statsFull === true){
var clsArr = clsStr.split(' ');
for(var c in clsArr){
if(clsArr.hasOwnProperty(c)){
classes[clsArr[c]] || (classes[clsArr[c]]=0);
classes[clsArr[c]]++;
}
}
}

});

var classesArray = [];
for(var cl in classes){
if(classes.hasOwnProperty(cl)){
classesArray.push({name:cl,count:classes[cl]});
}
}

return classesArray.sort(function(a,b){return a.name > b.name;});

}

/********************
* EVENT HANDLERS
********************/

function createOrToggleList(e){
e.preventDefault();

var $t = $(e.currentTarget),
$stats = $t.next('.rainbow-stats');

var action = $stats.length===0 ? 'create' : $stats.css('display')==='none' ? 'show' : 'hide';

switch(action){
case 'create':
$t.text(labels.hide);
getElementStats($t);
break;
case 'show':
$t.text(labels.hide);
$stats.show();
break;
case 'hide':
$t.text(labels.show);
$stats.hide();
break;
}
}

function doHighlight(e){
var $t = $(e.currentTarget),
cl = $t.text().split(' ');

$('.rainbow-stats-class').removeClass('rainbow-stats-selected');
$t.addClass('rainbow-stats-selected');

cl.unshift('');
Rainbow.doHighlight && Rainbow.doHighlight($t.closest('.rainbow-stats').next(),cl.join('.'));
}

});
49 changes: 49 additions & 0 deletions js/extra/rainbow-extensions.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* TOGGLE HIGHLIGHT
*
* rainbow-toggle-highlight.js
*/
pre .highlighted {
background-color: rgba(255, 255, 0, 0.2);
box-shadow: 0 0 2px 2px #ffff00;
}

/**
* TOGGLE INFO
*
* rainbow-toggle-info.js
*/
#rainbowOverlay {
background: #002b36;
border-radius: 4px;
bottom: 0;
color: #839496;
left: 0;
margin: 8px;
padding: 8px 16px;
position: fixed;
}

#rainbowOverlay strong {
color: #acb8b9;
}

/**
* DISPLAY STATS
*
* rainbow-display-stats.js
*/
.rainbow-stats-class {
cursor: pointer;
}

.rainbow-stats-count {
display: inline-block;
margin: 0 8px 0 0;
text-align: right;
width: 30px;
}

.rainbow-stats-selected {
font-weight: bold;
}
117 changes: 117 additions & 0 deletions js/extra/rainbow-toggle-highlight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
$(function() {

'use strict';

/**
* Rainbow.toggleHighlightOn(tag:String, toggle:Boolean);
*
* Toggle click event for highlight every Rainbow generated span tags.
*
* @param tag {String} any ancestor tag of the <pre> modified by Rainbow
* @param toggle {Boolean} optional
* @returns {Boolean} returns false if no tags were found
*/
Rainbow.toggleHighlightOn = function(tag, toggle){

if($(tag).length===0) {
return false;
}

typeof(toggle)!=='boolean' && (toggle = !$(tag).data('Rainbow.toggleHighlightState'));

if(!!toggle){
$(tag).on('click', 'pre', highlightClasses);
}else{
$(tag).off('click', 'pre', highlightClasses);
}

$(tag).data('Rainbow.toggleHighlightState', !toggle);

return true;
};

/**
* Rainbow.doHighlight($parent:jQuery, selector:String);
*
* Publicly exposed method for a single highlight.
*
* @param $parent {jQuery} the element that contains the <pre> tag
* @param selector {String} the selector to be highlighted
*/
Rainbow.doHighlight = function($parent,selector){
removeHighlight($parent);
addHighlight($parent,selector);
};

/**
* Rainbow.setHighlightClass(className:String);
*
* Call this method in order to customize the className for highlighted elements
*
* @param className {String} className for highlighted tags
*/
Rainbow.setHighlightClass = function(className){
if(typeof(className)==='string') {
Rainbow.toggleHighlightClass = className;
}
};

// sets default className
Rainbow.setHighlightClass('highlighted');

/********************
* PRIVATE METHODS
********************/

function highlightClasses(e){
e.stopPropagation();

if(!Rainbow.toggleHighlightClass || typeof(Rainbow.toggleHighlightClass)!=='string' || Rainbow.toggleHighlightClass.length===0){
return;
}

var $e = $(e.target),
$pre = $e.is('pre') ? $e : $e.closest('pre');

if(!$e.is('span')) {
removeHighlight($pre);
return;
}

if($e.parents('.' + Rainbow.toggleHighlightClass).length){
$e = $e.parents('.' + Rainbow.toggleHighlightClass).parents('span');
}else if($e.hasClass(Rainbow.toggleHighlightClass)){
$e = $e.parents('span');
}

removeHighlight($pre);

if($e.length){
var cl = $e.attr('class').split(' '),
classes = [''];

for(var c in cl){
if(cl.hasOwnProperty(c)){
classes.push(cl[c]);
}
}

addHighlight($pre,classes.join('.'));

console.log('highlight on: ',classes.join('.'));
}else {
console.log('highlight off');
}

Rainbow.refreshOverlay && Rainbow.refreshOverlay();
}

function addHighlight($parent,selector){
$parent.find(selector).addClass(Rainbow.toggleHighlightClass);
}

function removeHighlight($parent){
$parent.find('.'+Rainbow.toggleHighlightClass).removeClass(Rainbow.toggleHighlightClass);
}

});
Loading