!!! %html %head %title Snuffle: = summary.class_name %link{href: "http://cdn.datatables.net/1.10.0/css/jquery.dataTables.css", rel: "stylesheet"} %script{language: "javascript", src: "http://code.jquery.com/jquery-1.11.0.min.js", type: "text/javascript"} %script{language: "javascript", src: "http://code.jquery.com/jquery-migrate-1.2.1.min.js", type: "text/javascript"} %script{language: "javascript", src: "http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.0/highlight.min.js", type: "text/javascript"} :css #{Rouge::Theme.find('thankful_eyes').render(scope: '.highlight')} a:link, a:visited { color: #fff } body { line-height: 1.5em; background: #49525a; color: #fff; font-family: arial, sans-serif; font-size: 14px; padding: 2em; } div.column { float: left; width: 45%; } div.file_listing { padding: .1em; border-radius: 5px; background: #000; width: 100%; border: 1px solid #000;} div.file_meta { padding: 1em; border-radius: 5px; background: #440013; width: 98%; border: .5em solid #000;} h1 { color:#fff; font-size: 1.25em; margin-top: .25em; } h2 { color:#fff; font-size: .75em; margin-top: -1em; } h3 { color:#fff; font-size: 1.1em;margin-top: 1em; } h3.highlighted { background: rgba(170, 161, 57, .6); border-radius: 100px; padding: .25em; padding-left: 1em; color: #000;} h3.highlighted-method { background: rgba(153, 51, 80, .6); border-radius: 100px; padding-left: 1em; } li { margin-bottom: 1em;} pre { line-height: 1.75em;} pre.lineno { margin-top: -1.4em !important;} span.highlighted { padding-left: 1em; display: inline-block; position: absolute; left: 0px; padding-right: 90%} table { width: 100%; box-shadow: 0 5px 0 rgba(0,0,0,.8); border-spacing: 0; border: 5px solid #000; border-radius: 5px; border-collapse: collapse; min-width: 50%; } td { text-align: left; padding: .5em; padding-left: 1.25em !important;} tfoot { background: #000; border-top: 10px solid #000; font-family: courier; margin-top: 4em; font-size: .75em; } th { background: #000; text-align: left; padding: .5em; } tr.even { background: rgba(128, 128, 128, 0.5) !important;} tr.even:hover, tr.odd:hover { background: rgba(128, 128, 128, 0.75) !important;} tr.faint td { opacity: 0.5; font-style: italic; } tr.header { background-color: #222; } tr.header th:first-child { border-radius: 5px 0 0 0; } tr.header th:last-child { border-radius: 0 5px 0 0; } tr.header th:only-child { border-radius: 5px 5px 0 0; } tr.odd { background: rgba(128, 128, 128, 0.25) !important} .btn.float-right { float: right; margin-top: -4em;} .center { text-align: center; } .clear { clear: both; } .highlighted { background: rgba(170, 161, 57, .6); border-radius: 100px; } .highlighted-method { background: rgba(153, 51, 80, .6); padding: .25em; border-radius: 100px; color: #fff; } .indented {margin-left: 1em; } .summary {padding: 1em; border-radius: 5px; background: rgb(41, 80, 109); width: 98%; border: .5em solid #000;} .btn { -webkit-border-radius: 28; -moz-border-radius: 28; border: none; border-radius: 28px; color: #ffffff; background: #7d99af; padding: 10px 20px 10px 20px; text-decoration: none; } .btn:hover { background: #4c708c; border: none; text-decoration: none; } .file_meta %h1 = summary.class_name %h2 = summary.path_to_file %input.btn.float-right{onclick: "history.back(-1)", type: "button", value: "Back"} %br.clear %div.summary %div.column %h3.indented.highlighted Data Clumps: - if summary.cohorts.count == 0 %em.indented None - else %ul.indented - summary.cohorts.group_by{|c| c.values.sort }.each do |values, cohorts| - if cohorts.count > 0 %li = values.map{|c| ".#{c}" }.join(", ") %br (line = ":#{cohorts.map(&:line_numbers).join(', :')}" ) %div.column %h3.indented.highlighted-method Possible Latent Objects: - if summary.latent_objects.count == 0 %em.indented None - else %ul.indented - summary.latent_objects.each do |latent_object| %li = latent_object.object_candidate.titleize %br ( = ".#{latent_object.source_methods.join(', .')}" ) %br.clear %br.clear .file_listing = source_lines %br %input.btn{onclick: "history.back(-1)", type: "button", value: "Back"} %p.center %em Analyzed on = date at = time by %a{href: "https://gitlab.com/coraline/snuffle", target: "_new"} Snuffle :javascript /* * jQuery Highlight plugin * * Based on highlight v3 by Johann Burkard * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html * * Copyright (c) 2009 Bartek Szopka * * Licensed under MIT license. * */ jQuery.extend({ highlight: function (node, re, nodeName, className) { if (node.nodeType === 3) { var match = node.data.match(re); if (match) { var highlight = document.createElement(nodeName || 'span'); highlight.className = className || 'highlight'; var wordNode = node.splitText(match.index); wordNode.splitText(match[0].length); var wordClone = wordNode.cloneNode(true); highlight.appendChild(wordClone); wordNode.parentNode.replaceChild(highlight, wordNode); return 1; //skip added node in parent } } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children !/(script|style)/i.test(node.tagName) && // ignore script and style nodes !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted for (var i = 0; i < node.childNodes.length; i++) { i += jQuery.highlight(node.childNodes[i], re, nodeName, className); } } return 0; } }); jQuery.fn.unhighlight = function (options) { var settings = { className: 'highlight', element: 'span' }; jQuery.extend(settings, options); return this.find(settings.element + "." + settings.className).each(function () { var parent = this.parentNode; parent.replaceChild(this.firstChild, this); parent.normalize(); }).end(); }; jQuery.fn.highlight = function (words, options) { var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false }; jQuery.extend(settings, options); if (words.constructor === String) { words = [words]; } words = jQuery.grep(words, function(word, i){ return word != ''; }); words = jQuery.map(words, function(word, i) { return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); }); if (words.length == 0) { return this; }; var flag = settings.caseSensitive ? "" : "i"; var pattern = "(" + words.join("|") + ")"; if (settings.wordsOnly) { pattern = "\\b" + pattern + "\\b"; } var re = new RegExp(pattern, flag); return this.each(function () { jQuery.highlight(this, re, settings.element, settings.className); }); }; var line_numbers = #{summary.cohorts.map(&:line_numbers).flatten}; var method_names = #{summary.latent_objects.map(&:object_candidate).flatten}; $('pre.lineno').html($('pre.lineno').html().split(/\s+/).map(function(val){ if (line_numbers.indexOf(parseInt(val)) > -1) { return "" + val + "\n" } else { return "" + val + "\n"};})); $('.nf').highlight(method_names, { className: 'highlighted-method'});