rack-mini-profiler 0.1.26 → 0.1.31
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rack-mini-profiler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Ruby/CHANGELOG +28 -2
- data/Ruby/README.md +11 -0
- data/Ruby/lib/html/includes.js +82 -67
- data/Ruby/lib/html/includes.tmpl +2 -0
- data/Ruby/lib/mini_profiler/client_settings.rb +11 -11
- data/Ruby/lib/mini_profiler/config.rb +10 -9
- data/Ruby/lib/mini_profiler/context.rb +1 -1
- data/Ruby/lib/mini_profiler/gc_profiler_ruby_head.rb +40 -0
- data/Ruby/lib/mini_profiler/page_timer_struct.rb +4 -4
- data/Ruby/lib/mini_profiler/profiler.rb +98 -121
- data/Ruby/lib/mini_profiler/profiling_methods.rb +31 -11
- data/Ruby/lib/mini_profiler/request_timer_struct.rb +5 -5
- data/Ruby/lib/mini_profiler/sql_timer_struct.rb +1 -1
- data/Ruby/lib/mini_profiler/storage/abstract_store.rb +4 -3
- data/Ruby/lib/mini_profiler/storage/redis_store.rb +3 -3
- data/Ruby/lib/mini_profiler/version.rb +1 -1
- data/Ruby/lib/patches/sql_patches.rb +6 -1
- data/rack-mini-profiler.gemspec +2 -1
- metadata +6 -6
- data/Ruby/lib/html/flamegraph.html +0 -325
- data/Ruby/lib/mini_profiler/flame_graph.rb +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50a96f45043bb94f118971de9fe539a5af648d9c
|
4
|
+
data.tar.gz: 2deba7160023f7ae64ec39bdc456bcaf2c77fb45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4444d3a819342722b3e27d8de3d9cbf9687fa3d54f9d9f39214ccb405b05973cc68950687227f3ea7caa4d994f0d6f757b4f34122c24a95689f9563b97e844a2
|
7
|
+
data.tar.gz: 2a9bdaf1850ca648c2569994f680874ce79bd5351553ce4d1c802119923ac375cddf4ba9d67812a2d4db1e06562af5672a9318aff678a84eef5896a3897b3907
|
data/Ruby/CHANGELOG
CHANGED
@@ -131,5 +131,31 @@
|
|
131
131
|
* 1.26
|
132
132
|
* (minor) allow Rack::MiniProfilerRails.initialize!(Rails.application), for post config intialization
|
133
133
|
|
134
|
-
|
135
|
-
|
134
|
+
26-June-2013
|
135
|
+
* 1.27
|
136
|
+
* Disable global ajax handlers on MP requests @JP
|
137
|
+
* Add Rack::MiniProfiler.config.backtrace_threshold_ms
|
138
|
+
* jQuery 2.0 support
|
139
|
+
|
140
|
+
18-July-2013
|
141
|
+
* 1.28
|
142
|
+
* diagnostics in abstract storage was raising not implemented killing
|
143
|
+
?pp=env and others
|
144
|
+
* SOLR xml unescaped by mistake
|
145
|
+
|
146
|
+
20-August-2013
|
147
|
+
* 1.29
|
148
|
+
* Bugfix: SOLR patching had an incorrect monkey patch
|
149
|
+
* Implemented exception tracing using TracePoint see pp=trace-exceptions
|
150
|
+
|
151
|
+
30-August-2013
|
152
|
+
|
153
|
+
* 1.30
|
154
|
+
* Feature: Added Rack::MiniProfiler.counter_method(klass,name) for injecting counters
|
155
|
+
* Bug: Counters were not shifting the table correctly
|
156
|
+
|
157
|
+
3-September-2013
|
158
|
+
|
159
|
+
* Ripped out flamegraph so it can be isolated into a gem
|
160
|
+
* Flamegraph now has much increased fidelity
|
161
|
+
* Ripped out pp=sample it just was never really used
|
data/Ruby/README.md
CHANGED
@@ -111,8 +111,14 @@ You can set configuration options using the configuration accessor on Rack::Mini
|
|
111
111
|
```
|
112
112
|
# Have Mini Profiler show up on the right
|
113
113
|
Rack::MiniProfiler.config.position = 'right'
|
114
|
+
# Have Mini Profiler start in hidden mode - display with short cut (defaulted to 'Alt+P')
|
115
|
+
Rack::MiniProfiler.config.start_hidden = true
|
116
|
+
# Don't collect backtraces on SQL queries that take less than 5 ms to execute
|
117
|
+
# (necessary on Rubies earlier than 2.0)
|
118
|
+
Rack::MiniProfiler.config.backtrace_threshold_ms = 5
|
114
119
|
```
|
115
120
|
|
121
|
+
|
116
122
|
In a Rails app, this can be done conveniently in an initializer such as config/initializers/mini_profiler.rb.
|
117
123
|
|
118
124
|
## Rails 2.X support
|
@@ -145,6 +151,10 @@ if JSON.const_defined?(:Pure)
|
|
145
151
|
end
|
146
152
|
```
|
147
153
|
|
154
|
+
## Notes
|
155
|
+
|
156
|
+
- Be sure to require rack_mini_profiler last in your Gemfile, when it is required it will monkey patch pg and mysql gems to insert instrumentation. If included too early no SQL will show up.
|
157
|
+
|
148
158
|
## Available Options
|
149
159
|
|
150
160
|
* pre_authorize_cb - A lambda callback you can set to determine whether or not mini_profiler should be visible on a given request. Default in a Rails environment is only on in development mode. If in a Rack app, the default is always on.
|
@@ -154,6 +164,7 @@ end
|
|
154
164
|
* backtrace_filter - a regex you can use to filter out unwanted lines from the backtraces
|
155
165
|
* toggle_shortcut (default Alt+P) - a jquery.hotkeys.js-style keyboard shortcut, used to toggle the mini_profiler's visibility. See http://code.google.com/p/js-hotkeys/ for more info.
|
156
166
|
* start_hidden (default false) - Whether or not you want the mini_profiler to be visible when loading a page
|
167
|
+
* backtrace_threshold_ms (default zero) - Minimum SQL query elapsed time before a backtrace is recorded. Backtrace recording can take a couple of milliseconds on rubies earlier than 2.0, impacting performance for very small queries.
|
157
168
|
|
158
169
|
## Special query strings
|
159
170
|
|
data/Ruby/lib/html/includes.js
CHANGED
@@ -20,7 +20,7 @@ var MiniProfiler = (function () {
|
|
20
20
|
|
21
21
|
var getVersionedKey = function (keyPrefix) {
|
22
22
|
return keyPrefix + '-' + options.version;
|
23
|
-
}
|
23
|
+
};
|
24
24
|
|
25
25
|
var save = function (keyPrefix, value) {
|
26
26
|
if (!hasLocalStorage()) { return; }
|
@@ -81,7 +81,7 @@ var MiniProfiler = (function () {
|
|
81
81
|
}
|
82
82
|
mPt.flush();
|
83
83
|
}
|
84
|
-
|
84
|
+
|
85
85
|
if (id == options.currentId) {
|
86
86
|
|
87
87
|
clientPerformance = getClientPerformance();
|
@@ -91,7 +91,7 @@ var MiniProfiler = (function () {
|
|
91
91
|
var copy = { navigation: {}, timing: {} };
|
92
92
|
|
93
93
|
var timing = $.extend({}, clientPerformance.timing);
|
94
|
-
|
94
|
+
|
95
95
|
for (p in timing) {
|
96
96
|
if (timing.hasOwnProperty(p) && !$.isFunction(timing[p])) {
|
97
97
|
copy.timing[p] = timing[p];
|
@@ -102,9 +102,9 @@ var MiniProfiler = (function () {
|
|
102
102
|
}
|
103
103
|
clientPerformance = copy;
|
104
104
|
|
105
|
-
// hack to add chrome timings
|
105
|
+
// hack to add chrome timings
|
106
106
|
if (window.chrome && window.chrome.loadTimes) {
|
107
|
-
var chromeTimes = window.chrome.loadTimes();
|
107
|
+
var chromeTimes = window.chrome.loadTimes();
|
108
108
|
if (chromeTimes.firstPaintTime) {
|
109
109
|
clientPerformance.timing["First Paint Time"] = Math.round(chromeTimes.firstPaintTime * 1000);
|
110
110
|
}
|
@@ -126,6 +126,7 @@ var MiniProfiler = (function () {
|
|
126
126
|
url: options.path + 'results',
|
127
127
|
data: { id: id, clientPerformance: clientPerformance, clientProbes: clientProbes, popup: 1 },
|
128
128
|
dataType: 'json',
|
129
|
+
global: false,
|
129
130
|
type: 'POST',
|
130
131
|
success: function (json) {
|
131
132
|
fetchedIds.push(id);
|
@@ -244,7 +245,7 @@ var MiniProfiler = (function () {
|
|
244
245
|
popup.children().each(function () { childrenHeight += $(this).height(); });
|
245
246
|
|
246
247
|
popup.css({ 'padding-right': childrenHeight > popup.height() ? 40 : 10 });
|
247
|
-
}
|
248
|
+
};
|
248
249
|
|
249
250
|
var popupHide = function (button, popup) {
|
250
251
|
button.removeClass('profiler-button-active');
|
@@ -290,13 +291,13 @@ var MiniProfiler = (function () {
|
|
290
291
|
originalRgb = getRGB(cell.css('background-color')),
|
291
292
|
getColorDiff = function (fx, i) {
|
292
293
|
// adapted from John Resig's color plugin: http://plugins.jquery.com/project/color
|
293
|
-
return Math.max(Math.min(parseInt((fx.pos * (originalRgb[i] - highlightRgb[i])) + highlightRgb[i]), 255), 0);
|
294
|
+
return Math.max(Math.min(parseInt((fx.pos * (originalRgb[i] - highlightRgb[i])) + highlightRgb[i], 10), 255), 0);
|
294
295
|
};
|
295
296
|
|
296
297
|
// we need to animate some other property to piggy-back on the step function, so I choose you, opacity!
|
297
298
|
cell.css({ 'opacity': 1, 'background-color': highlightHex })
|
298
299
|
.animate({ 'opacity': 1 }, { duration: 2000, step: function (now, fx) {
|
299
|
-
fx.elem.style
|
300
|
+
fx.elem.style.backgroundColor = "rgb(" + [getColorDiff(fx, 0), getColorDiff(fx, 1), getColorDiff(fx, 2)].join(",") + ")";
|
300
301
|
}
|
301
302
|
});
|
302
303
|
});
|
@@ -460,7 +461,7 @@ var MiniProfiler = (function () {
|
|
460
461
|
|
461
462
|
if (jQuery && jQuery(document).ajaxStart)
|
462
463
|
jQuery(document).ajaxStart(function () { ajaxStartTime = new Date(); });
|
463
|
-
|
464
|
+
|
464
465
|
// fetch results after ASP Ajax calls
|
465
466
|
if (typeof (Sys) != 'undefined' && typeof (Sys.WebForms) != 'undefined' && typeof (Sys.WebForms.PageRequestManager) != 'undefined') {
|
466
467
|
// Get the instance of PageRequestManager.
|
@@ -480,7 +481,7 @@ var MiniProfiler = (function () {
|
|
480
481
|
});
|
481
482
|
}
|
482
483
|
|
483
|
-
// more Asp.Net callbacks
|
484
|
+
// more Asp.Net callbacks
|
484
485
|
if (typeof (WebForm_ExecuteCallback) == "function") {
|
485
486
|
WebForm_ExecuteCallback = (function (callbackObject) {
|
486
487
|
// Store original function
|
@@ -494,7 +495,7 @@ var MiniProfiler = (function () {
|
|
494
495
|
var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
|
495
496
|
fetchResults(ids);
|
496
497
|
}
|
497
|
-
}
|
498
|
+
};
|
498
499
|
|
499
500
|
})();
|
500
501
|
}
|
@@ -502,7 +503,12 @@ var MiniProfiler = (function () {
|
|
502
503
|
// also fetch results after ExtJS requests, in case it is being used
|
503
504
|
if (typeof (Ext) != 'undefined' && typeof (Ext.Ajax) != 'undefined' && typeof (Ext.Ajax.on) != 'undefined') {
|
504
505
|
// Ext.Ajax is a singleton, so we just have to attach to its 'requestcomplete' event
|
505
|
-
Ext.Ajax.on('requestcomplete', function(e, xhr, settings) {
|
506
|
+
Ext.Ajax.on('requestcomplete', function (e, xhr, settings) {
|
507
|
+
//iframed file uploads don't have headers
|
508
|
+
if (!xhr || !xhr.getResponseHeader) {
|
509
|
+
return;
|
510
|
+
}
|
511
|
+
|
506
512
|
var stringIds = xhr.getResponseHeader('X-MiniProfiler-Ids');
|
507
513
|
if (stringIds) {
|
508
514
|
var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
|
@@ -540,10 +546,10 @@ var MiniProfiler = (function () {
|
|
540
546
|
}
|
541
547
|
|
542
548
|
return this._onreadystatechange.apply(this, arguments);
|
543
|
-
}
|
549
|
+
};
|
544
550
|
|
545
551
|
return _send.apply(this, arguments);
|
546
|
-
}
|
552
|
+
};
|
547
553
|
}
|
548
554
|
|
549
555
|
// some elements want to be hidden on certain doc events
|
@@ -569,8 +575,9 @@ var MiniProfiler = (function () {
|
|
569
575
|
|
570
576
|
var toggleShortcut = script.getAttribute('data-toggle-shortcut');
|
571
577
|
|
572
|
-
if (script.getAttribute('data-max-traces'))
|
573
|
-
var maxTraces = parseInt(script.getAttribute('data-max-traces'));
|
578
|
+
if (script.getAttribute('data-max-traces')) {
|
579
|
+
var maxTraces = parseInt(script.getAttribute('data-max-traces'), 10);
|
580
|
+
}
|
574
581
|
|
575
582
|
if (script.getAttribute('data-trivial') === 'true') var trivial = true;
|
576
583
|
if (script.getAttribute('data-children') == 'true') var children = true;
|
@@ -591,7 +598,7 @@ var MiniProfiler = (function () {
|
|
591
598
|
authorized: authorized,
|
592
599
|
toggleShortcut: toggleShortcut,
|
593
600
|
startHidden: startHidden
|
594
|
-
}
|
601
|
+
};
|
595
602
|
})();
|
596
603
|
|
597
604
|
var doInit = function () {
|
@@ -599,7 +606,7 @@ var MiniProfiler = (function () {
|
|
599
606
|
container = $('.profiler-result-full');
|
600
607
|
if (container.length) {
|
601
608
|
if (window.location.href.indexOf("&trivial=1") > 0) {
|
602
|
-
options.showTrivial = true
|
609
|
+
options.showTrivial = true;
|
603
610
|
}
|
604
611
|
initFullView();
|
605
612
|
}
|
@@ -627,7 +634,7 @@ var MiniProfiler = (function () {
|
|
627
634
|
var finish = false;
|
628
635
|
var deferInit = function() {
|
629
636
|
if (finish) return;
|
630
|
-
if (window.performance && window.performance.timing && window.performance.timing.loadEventEnd
|
637
|
+
if (window.performance && window.performance.timing && window.performance.timing.loadEventEnd === 0 && wait < 10000) {
|
631
638
|
setTimeout(deferInit, 100);
|
632
639
|
wait += 100;
|
633
640
|
} else {
|
@@ -654,10 +661,15 @@ var MiniProfiler = (function () {
|
|
654
661
|
}
|
655
662
|
};
|
656
663
|
|
664
|
+
var major, minor;
|
657
665
|
if (typeof(jQuery) == 'function') {
|
658
666
|
var jQueryVersion = jQuery.fn.jquery.split('.');
|
667
|
+
major = parseInt(jQueryVersion[0], 10);
|
668
|
+
minor = parseInt(jQueryVersion[1], 10);
|
659
669
|
}
|
660
|
-
|
670
|
+
|
671
|
+
|
672
|
+
if (major === 2 || (major === 1 && minor >= 7)) {
|
661
673
|
MiniProfiler.jQuery = $ = jQuery;
|
662
674
|
$(deferInit);
|
663
675
|
} else {
|
@@ -709,7 +721,7 @@ var MiniProfiler = (function () {
|
|
709
721
|
getClientTimings: function (clientTimings) {
|
710
722
|
var list = [];
|
711
723
|
var t;
|
712
|
-
|
724
|
+
|
713
725
|
if (!clientTimings.Timings) return [];
|
714
726
|
|
715
727
|
for (var i = 0; i < clientTimings.Timings.length; i++) {
|
@@ -896,49 +908,52 @@ MiniProfiler.init();
|
|
896
908
|
!0:(f[a+e]=!0,f[a+d.hotkeys.shiftNums[e]]=!0,"shift+"===a&&(f[d.hotkeys.shiftNums[e]]=!0));c=0;for(e=j.length;c<e;c++)if(f[j[c]])return h.apply(this,arguments)}}}}d.hotkeys={version:"0.8",specialKeys:{8:"backspace",9:"tab",13:"return",16:"shift",17:"ctrl",18:"alt",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",
|
897
909
|
109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",191:"/",224:"meta"},shiftNums:{"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(","0":")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|"}};d.each(["keydown","keyup","keypress"],function(){d.event.special[this]={add:h}})})(jQuery);
|
898
910
|
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
g
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
null
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
"
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
["
|
925
|
-
|
926
|
-
|
927
|
-
cStyleComments:true}),["
|
928
|
-
u(x({keywords:"
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
"
|
933
|
-
document.
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
911
|
+
if (typeof prettyPrint === "undefined") {
|
912
|
+
|
913
|
+
// prettify.js
|
914
|
+
// http://code.google.com/p/google-code-prettify/
|
915
|
+
|
916
|
+
window.PR_SHOULD_USE_CONTINUATION=true;window.PR_TAB_WIDTH=8;window.PR_normalizedHtml=window.PR=window.prettyPrintOne=window.prettyPrint=void 0;window._pr_isIE6=function(){var y=navigator&&navigator.userAgent&&navigator.userAgent.match(/\bMSIE ([678])\./);y=y?+y[1]:false;window._pr_isIE6=function(){return y};return y};
|
917
|
+
(function(){function y(b){return b.replace(L,"&").replace(M,"<").replace(N,">")}function H(b,f,i){switch(b.nodeType){case 1:var o=b.tagName.toLowerCase();f.push("<",o);var l=b.attributes,n=l.length;if(n){if(i){for(var r=[],j=n;--j>=0;)r[j]=l[j];r.sort(function(q,m){return q.name<m.name?-1:q.name===m.name?0:1});l=r}for(j=0;j<n;++j){r=l[j];r.specified&&f.push(" ",r.name.toLowerCase(),'="',r.value.replace(L,"&").replace(M,"<").replace(N,">").replace(X,"""),'"')}}f.push(">");
|
918
|
+
for(l=b.firstChild;l;l=l.nextSibling)H(l,f,i);if(b.firstChild||!/^(?:br|link|img)$/.test(o))f.push("</",o,">");break;case 3:case 4:f.push(y(b.nodeValue));break}}function O(b){function f(c){if(c.charAt(0)!=="\\")return c.charCodeAt(0);switch(c.charAt(1)){case "b":return 8;case "t":return 9;case "n":return 10;case "v":return 11;case "f":return 12;case "r":return 13;case "u":case "x":return parseInt(c.substring(2),16)||c.charCodeAt(1);case "0":case "1":case "2":case "3":case "4":case "5":case "6":case "7":return parseInt(c.substring(1),
|
919
|
+
8);default:return c.charCodeAt(1)}}function i(c){if(c<32)return(c<16?"\\x0":"\\x")+c.toString(16);c=String.fromCharCode(c);if(c==="\\"||c==="-"||c==="["||c==="]")c="\\"+c;return c}function o(c){var d=c.substring(1,c.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));c=[];for(var a=[],k=d[0]==="^",e=k?1:0,h=d.length;e<h;++e){var g=d[e];switch(g){case "\\B":case "\\b":case "\\D":case "\\d":case "\\S":case "\\s":case "\\W":case "\\w":c.push(g);
|
920
|
+
continue}g=f(g);var s;if(e+2<h&&"-"===d[e+1]){s=f(d[e+2]);e+=2}else s=g;a.push([g,s]);if(!(s<65||g>122)){s<65||g>90||a.push([Math.max(65,g)|32,Math.min(s,90)|32]);s<97||g>122||a.push([Math.max(97,g)&-33,Math.min(s,122)&-33])}}a.sort(function(v,w){return v[0]-w[0]||w[1]-v[1]});d=[];g=[NaN,NaN];for(e=0;e<a.length;++e){h=a[e];if(h[0]<=g[1]+1)g[1]=Math.max(g[1],h[1]);else d.push(g=h)}a=["["];k&&a.push("^");a.push.apply(a,c);for(e=0;e<d.length;++e){h=d[e];a.push(i(h[0]));if(h[1]>h[0]){h[1]+1>h[0]&&a.push("-");
|
921
|
+
a.push(i(h[1]))}}a.push("]");return a.join("")}function l(c){for(var d=c.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g")),a=d.length,k=[],e=0,h=0;e<a;++e){var g=d[e];if(g==="(")++h;else if("\\"===g.charAt(0))if((g=+g.substring(1))&&g<=h)k[g]=-1}for(e=1;e<k.length;++e)if(-1===k[e])k[e]=++n;for(h=e=0;e<a;++e){g=d[e];if(g==="("){++h;if(k[h]===undefined)d[e]="(?:"}else if("\\"===
|
922
|
+
g.charAt(0))if((g=+g.substring(1))&&g<=h)d[e]="\\"+k[h]}for(h=e=0;e<a;++e)if("^"===d[e]&&"^"!==d[e+1])d[e]="";if(c.ignoreCase&&r)for(e=0;e<a;++e){g=d[e];c=g.charAt(0);if(g.length>=2&&c==="[")d[e]=o(g);else if(c!=="\\")d[e]=g.replace(/[a-zA-Z]/g,function(s){s=s.charCodeAt(0);return"["+String.fromCharCode(s&-33,s|32)+"]"})}return d.join("")}for(var n=0,r=false,j=false,q=0,m=b.length;q<m;++q){var t=b[q];if(t.ignoreCase)j=true;else if(/[a-z]/i.test(t.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,
|
923
|
+
""))){r=true;j=false;break}}var p=[];q=0;for(m=b.length;q<m;++q){t=b[q];if(t.global||t.multiline)throw Error(""+t);p.push("(?:"+l(t)+")")}return RegExp(p.join("|"),j?"gi":"g")}function Y(b){var f=0;return function(i){for(var o=null,l=0,n=0,r=i.length;n<r;++n)switch(i.charAt(n)){case "\t":o||(o=[]);o.push(i.substring(l,n));l=b-f%b;for(f+=l;l>=0;l-=16)o.push(" ".substring(0,l));l=n+1;break;case "\n":f=0;break;default:++f}if(!o)return i;o.push(i.substring(l));return o.join("")}}function I(b,
|
924
|
+
f,i,o){if(f){b={source:f,c:b};i(b);o.push.apply(o,b.d)}}function B(b,f){var i={},o;(function(){for(var r=b.concat(f),j=[],q={},m=0,t=r.length;m<t;++m){var p=r[m],c=p[3];if(c)for(var d=c.length;--d>=0;)i[c.charAt(d)]=p;p=p[1];c=""+p;if(!q.hasOwnProperty(c)){j.push(p);q[c]=null}}j.push(/[\0-\uffff]/);o=O(j)})();var l=f.length;function n(r){for(var j=r.c,q=[j,z],m=0,t=r.source.match(o)||[],p={},c=0,d=t.length;c<d;++c){var a=t[c],k=p[a],e=void 0,h;if(typeof k==="string")h=false;else{var g=i[a.charAt(0)];
|
925
|
+
if(g){e=a.match(g[1]);k=g[0]}else{for(h=0;h<l;++h){g=f[h];if(e=a.match(g[1])){k=g[0];break}}e||(k=z)}if((h=k.length>=5&&"lang-"===k.substring(0,5))&&!(e&&typeof e[1]==="string")){h=false;k=P}h||(p[a]=k)}g=m;m+=a.length;if(h){h=e[1];var s=a.indexOf(h),v=s+h.length;if(e[2]){v=a.length-e[2].length;s=v-h.length}k=k.substring(5);I(j+g,a.substring(0,s),n,q);I(j+g+s,h,Q(k,h),q);I(j+g+v,a.substring(v),n,q)}else q.push(j+g,k)}r.d=q}return n}function x(b){var f=[],i=[];if(b.tripleQuotedStrings)f.push([A,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
|
926
|
+
null,"'\""]);else b.multiLineStrings?f.push([A,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]):f.push([A,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"]);b.verbatimStrings&&i.push([A,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);if(b.hashComments)if(b.cStyleComments){f.push([C,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"]);i.push([A,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
|
927
|
+
null])}else f.push([C,/^#[^\r\n]*/,null,"#"]);if(b.cStyleComments){i.push([C,/^\/\/[^\r\n]*/,null]);i.push([C,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}b.regexLiterals&&i.push(["lang-regex",RegExp("^"+Z+"(/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/)")]);b=b.keywords.replace(/^\s+|\s+$/g,"");b.length&&i.push([R,RegExp("^(?:"+b.replace(/\s+/g,"|")+")\\b"),null]);f.push([z,/^\s+/,null," \r\n\t\u00a0"]);i.push([J,/^@[a-z_$][a-z_$@0-9]*/i,null],[S,/^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/,
|
928
|
+
null],[z,/^[a-z_$][a-z_$@0-9]*/i,null],[J,/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],[E,/^.[^\s\w\.$@\'\"\`\/\#]*/,null]);return B(f,i)}function $(b){function f(D){if(D>r){if(j&&j!==q){n.push("</span>");j=null}if(!j&&q){j=q;n.push('<span class="',j,'">')}var T=y(p(i.substring(r,D))).replace(e?d:c,"$1 ");e=k.test(T);n.push(T.replace(a,s));r=D}}var i=b.source,o=b.g,l=b.d,n=[],r=0,j=null,q=null,m=0,t=0,p=Y(window.PR_TAB_WIDTH),c=/([\r\n ]) /g,
|
929
|
+
d=/(^| ) /gm,a=/\r\n?|\n/g,k=/[ \r\n]$/,e=true,h=window._pr_isIE6();h=h?b.b.tagName==="PRE"?h===6?" \r\n":h===7?" <br>\r":" \r":" <br />":"<br />";var g=b.b.className.match(/\blinenums\b(?::(\d+))?/),s;if(g){for(var v=[],w=0;w<10;++w)v[w]=h+'</li><li class="L'+w+'">';var F=g[1]&&g[1].length?g[1]-1:0;n.push('<ol class="linenums"><li class="L',F%10,'"');F&&n.push(' value="',F+1,'"');n.push(">");s=function(){var D=v[++F%10];return j?"</span>"+D+'<span class="'+j+'">':D}}else s=h;
|
930
|
+
for(;;)if(m<o.length?t<l.length?o[m]<=l[t]:true:false){f(o[m]);if(j){n.push("</span>");j=null}n.push(o[m+1]);m+=2}else if(t<l.length){f(l[t]);q=l[t+1];t+=2}else break;f(i.length);j&&n.push("</span>");g&&n.push("</li></ol>");b.a=n.join("")}function u(b,f){for(var i=f.length;--i>=0;){var o=f[i];if(G.hasOwnProperty(o))"console"in window&&console.warn("cannot override language handler %s",o);else G[o]=b}}function Q(b,f){b&&G.hasOwnProperty(b)||(b=/^\s*</.test(f)?"default-markup":"default-code");return G[b]}
|
931
|
+
function U(b){var f=b.f,i=b.e;b.a=f;try{var o,l=f.match(aa);f=[];var n=0,r=[];if(l)for(var j=0,q=l.length;j<q;++j){var m=l[j];if(m.length>1&&m.charAt(0)==="<"){if(!ba.test(m))if(ca.test(m)){f.push(m.substring(9,m.length-3));n+=m.length-12}else if(da.test(m)){f.push("\n");++n}else if(m.indexOf(V)>=0&&m.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,' $1="$2$3$4"').match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/)){var t=m.match(W)[2],p=1,c;c=j+1;a:for(;c<q;++c){var d=l[c].match(W);if(d&&
|
932
|
+
d[2]===t)if(d[1]==="/"){if(--p===0)break a}else++p}if(c<q){r.push(n,l.slice(j,c+1).join(""));j=c}else r.push(n,m)}else r.push(n,m)}else{var a;p=m;var k=p.indexOf("&");if(k<0)a=p;else{for(--k;(k=p.indexOf("&#",k+1))>=0;){var e=p.indexOf(";",k);if(e>=0){var h=p.substring(k+3,e),g=10;if(h&&h.charAt(0)==="x"){h=h.substring(1);g=16}var s=parseInt(h,g);isNaN(s)||(p=p.substring(0,k)+String.fromCharCode(s)+p.substring(e+1))}}a=p.replace(ea,"<").replace(fa,">").replace(ga,"'").replace(ha,'"').replace(ia," ").replace(ja,
|
933
|
+
"&")}f.push(a);n+=a.length}}o={source:f.join(""),h:r};var v=o.source;b.source=v;b.c=0;b.g=o.h;Q(i,v)(b);$(b)}catch(w){if("console"in window)console.log(w&&w.stack?w.stack:w)}}var A="str",R="kwd",C="com",S="typ",J="lit",E="pun",z="pln",P="src",V="nocode",Z=function(){for(var b=["!","!=","!==","#","%","%=","&","&&","&&=","&=","(","*","*=","+=",",","-=","->","/","/=",":","::",";","<","<<","<<=","<=","=","==","===",">",">=",">>",">>=",">>>",">>>=","?","@","[","^","^=","^^","^^=","{","|","|=","||","||=",
|
934
|
+
"~","break","case","continue","delete","do","else","finally","instanceof","return","throw","try","typeof"],f="(?:^^|[+-]",i=0;i<b.length;++i)f+="|"+b[i].replace(/([^=<>:&a-z])/g,"\\$1");f+=")\\s*";return f}(),L=/&/g,M=/</g,N=/>/g,X=/\"/g,ea=/</g,fa=/>/g,ga=/'/g,ha=/"/g,ja=/&/g,ia=/ /g,ka=/[\r\n]/g,K=null,aa=RegExp("[^<]+|<!--[\\s\\S]*?--\>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>|</?[a-zA-Z](?:[^>\"']|'[^']*'|\"[^\"]*\")*>|<","g"),ba=/^<\!--/,ca=/^<!\[CDATA\[/,da=/^<br\b/i,W=/^<(\/?)([a-zA-Z][a-zA-Z0-9]*)/,
|
935
|
+
la=x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename using virtual wchar_t where break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof debugger eval export function get null set undefined var with Infinity NaN caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END break continue do else for if return while case done elif esac eval fi function in local set then until ",
|
936
|
+
hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true}),G={};u(la,["default-code"]);u(B([],[[z,/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],[C,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[E,/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup",
|
937
|
+
"htm","html","mxml","xhtml","xml","xsl"]);u(B([[z,/^[\s]+/,null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[E,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],
|
938
|
+
["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);u(B([],[["atv",/^[\s\S]+/]]),["uq.val"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename using virtual wchar_t where ",
|
939
|
+
hashComments:true,cStyleComments:true}),["c","cc","cpp","cxx","cyc","m"]);u(x({keywords:"null true false"}),["json"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params partial readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var ",
|
940
|
+
hashComments:true,cStyleComments:true,verbatimStrings:true}),["cs"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof abstract boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient ",
|
941
|
+
cStyleComments:true}),["java"]);u(x({keywords:"break continue do else for if return while case done elif esac eval fi function in local set then until ",hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);u(x({keywords:"break continue do else for if return while and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None ",hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);
|
942
|
+
u(x({keywords:"caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END ",hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);u(x({keywords:"break continue do else for if return while alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END ",hashComments:true,
|
943
|
+
multiLineStrings:true,regexLiterals:true}),["rb"]);u(x({keywords:"break continue do else for if return while auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile catch class delete false import new operator private protected public this throw true try typeof debugger eval export function get null set undefined var with Infinity NaN ",cStyleComments:true,regexLiterals:true}),["js"]);u(B([],[[A,/^[\s\S]+/]]),
|
944
|
+
["regex"]);window.PR_normalizedHtml=H;window.prettyPrintOne=function(b,f){var i={f:b,e:f};U(i);return i.a};window.prettyPrint=function(b){function f(){for(var t=window.PR_SHOULD_USE_CONTINUATION?j.now()+250:Infinity;q<o.length&&j.now()<t;q++){var p=o[q];if(p.className&&p.className.indexOf("prettyprint")>=0){var c=p.className.match(/\blang-(\w+)\b/);if(c)c=c[1];for(var d=false,a=p.parentNode;a;a=a.parentNode)if((a.tagName==="pre"||a.tagName==="code"||a.tagName==="xmp")&&a.className&&a.className.indexOf("prettyprint")>=
|
945
|
+
0){d=true;break}if(!d){a=p;if(null===K){d=document.createElement("PRE");d.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));K=!/</.test(d.innerHTML)}if(K){d=a.innerHTML;if("XMP"===a.tagName)d=y(d);else{a=a;if("PRE"===a.tagName)a=true;else if(ka.test(d)){var k="";if(a.currentStyle)k=a.currentStyle.whiteSpace;else if(window.getComputedStyle)k=window.getComputedStyle(a,null).whiteSpace;a=!k||k==="pre"}else a=true;a||(d=d.replace(/(<br\s*\/?>)[\r\n]+/g,"$1").replace(/(?:[\r\n]+[ \t]*)+/g,
|
946
|
+
" "))}d=d}else{d=[];for(a=a.firstChild;a;a=a.nextSibling)H(a,d);d=d.join("")}d=d.replace(/(?:\r\n?|\n)$/,"");m={f:d,e:c,b:p};U(m);if(p=m.a){c=m.b;if("XMP"===c.tagName){d=document.createElement("PRE");for(a=0;a<c.attributes.length;++a){k=c.attributes[a];if(k.specified)if(k.name.toLowerCase()==="class")d.className=k.value;else d.setAttribute(k.name,k.value)}d.innerHTML=p;c.parentNode.replaceChild(d,c)}else c.innerHTML=p}}}}if(q<o.length)setTimeout(f,250);else b&&b()}for(var i=[document.getElementsByTagName("pre"),
|
947
|
+
document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],o=[],l=0;l<i.length;++l)for(var n=0,r=i[l].length;n<r;++n)o.push(i[l][n]);i=null;var j=Date;j.now||(j={now:function(){return(new Date).getTime()}});var q=0,m;f()};window.PR={combinePrefixPatterns:O,createSimpleLexer:B,registerLangHandler:u,sourceDecorator:x,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:C,PR_DECLARATION:"dec",PR_KEYWORD:R,PR_LITERAL:J,PR_NOCODE:V,PR_PLAIN:z,PR_PUNCTUATION:E,PR_SOURCE:P,PR_STRING:A,
|
948
|
+
PR_TAG:"tag",PR_TYPE:S}})()
|
949
|
+
|
950
|
+
;
|
951
|
+
|
952
|
+
// lang-sql.js
|
953
|
+
// http://code.google.com/p/google-code-prettify/
|
954
|
+
|
955
|
+
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/,null,"\"'"]],[["com",/^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/],["kwd",/^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i,
|
956
|
+
null],["lit",/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],["pln",/^[a-z_][\w-]*/i],["pun",/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/]]),["sql"])
|
957
|
+
|
958
|
+
;
|
959
|
+
}
|
data/Ruby/lib/html/includes.tmpl
CHANGED
@@ -159,6 +159,8 @@
|
|
159
159
|
<td class="profiler-duration" title="aggregate duration of all queries in this step (excludes children)">
|
160
160
|
${MiniProfiler.formatDuration(timing.SqlTimingsDurationMilliseconds)}
|
161
161
|
</td>
|
162
|
+
{{else}}
|
163
|
+
<td colspan="2"></td>
|
162
164
|
{{/if}}
|
163
165
|
|
164
166
|
{{each page.CustomTimingNames}}
|
@@ -1,20 +1,20 @@
|
|
1
1
|
module Rack
|
2
2
|
class MiniProfiler
|
3
3
|
class ClientSettings
|
4
|
-
|
4
|
+
|
5
5
|
COOKIE_NAME = "__profilin"
|
6
6
|
|
7
7
|
BACKTRACE_DEFAULT = nil
|
8
|
-
BACKTRACE_FULL = 1
|
8
|
+
BACKTRACE_FULL = 1
|
9
9
|
BACKTRACE_NONE = 2
|
10
10
|
|
11
11
|
attr_accessor :disable_profiling
|
12
12
|
attr_accessor :backtrace_level
|
13
13
|
|
14
|
-
|
14
|
+
|
15
15
|
def initialize(env)
|
16
16
|
request = ::Rack::Request.new(env)
|
17
|
-
@cookie = request.cookies[COOKIE_NAME]
|
17
|
+
@cookie = request.cookies[COOKIE_NAME]
|
18
18
|
if @cookie
|
19
19
|
@cookie.split(",").map{|pair| pair.split("=")}.each do |k,v|
|
20
20
|
@orig_disable_profiling = @disable_profiling = (v=='t') if k == "dp"
|
@@ -22,7 +22,7 @@ module Rack
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
@backtrace_level = nil if !@backtrace_level.nil? && (@backtrace_level == 0 || @backtrace_level > BACKTRACE_NONE)
|
25
|
+
@backtrace_level = nil if !@backtrace_level.nil? && (@backtrace_level == 0 || @backtrace_level > BACKTRACE_NONE)
|
26
26
|
@orig_backtrace_level = @backtrace_level
|
27
27
|
|
28
28
|
end
|
@@ -30,7 +30,7 @@ module Rack
|
|
30
30
|
def write!(headers)
|
31
31
|
if @orig_disable_profiling != @disable_profiling || @orig_backtrace_level != @backtrace_level || @cookie.nil?
|
32
32
|
settings = {"p" => "t" }
|
33
|
-
settings["dp"] = "t" if @disable_profiling
|
33
|
+
settings["dp"] = "t" if @disable_profiling
|
34
34
|
settings["bt"] = @backtrace_level if @backtrace_level
|
35
35
|
settings_string = settings.map{|k,v| "#{k}=#{v}"}.join(",")
|
36
36
|
Rack::Utils.set_cookie_header!(headers, COOKIE_NAME, :value => settings_string, :path => '/')
|
@@ -45,19 +45,19 @@ module Rack
|
|
45
45
|
!@cookie.nil?
|
46
46
|
end
|
47
47
|
|
48
|
-
def disable_profiling?
|
48
|
+
def disable_profiling?
|
49
49
|
@disable_profiling
|
50
50
|
end
|
51
51
|
|
52
|
-
def backtrace_full?
|
52
|
+
def backtrace_full?
|
53
53
|
@backtrace_level == BACKTRACE_FULL
|
54
54
|
end
|
55
55
|
|
56
|
-
def backtrace_default?
|
56
|
+
def backtrace_default?
|
57
57
|
@backtrace_level == BACKTRACE_DEFAULT
|
58
58
|
end
|
59
|
-
|
60
|
-
def backtrace_none?
|
59
|
+
|
60
|
+
def backtrace_none?
|
61
61
|
@backtrace_level == BACKTRACE_NONE
|
62
62
|
end
|
63
63
|
end
|
@@ -7,15 +7,15 @@ module Rack
|
|
7
7
|
@attributes.concat vars
|
8
8
|
super(*vars)
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def self.attributes
|
12
12
|
@attributes
|
13
13
|
end
|
14
14
|
|
15
15
|
attr_accessor :auto_inject, :base_url_path, :pre_authorize_cb, :position,
|
16
|
-
:backtrace_remove, :backtrace_includes, :backtrace_ignores, :skip_schema_queries,
|
16
|
+
:backtrace_remove, :backtrace_includes, :backtrace_ignores, :skip_schema_queries,
|
17
17
|
:storage, :user_provider, :storage_instance, :storage_options, :skip_paths, :authorization_mode,
|
18
|
-
:toggle_shortcut, :start_hidden
|
18
|
+
:toggle_shortcut, :start_hidden, :backtrace_threshold_ms
|
19
19
|
|
20
20
|
# Deprecated options
|
21
21
|
attr_accessor :use_existing_jquery
|
@@ -24,10 +24,10 @@ module Rack
|
|
24
24
|
new.instance_eval {
|
25
25
|
@auto_inject = true # automatically inject on every html page
|
26
26
|
@base_url_path = "/mini-profiler-resources/"
|
27
|
-
|
27
|
+
|
28
28
|
# called prior to rack chain, to ensure we are allowed to profile
|
29
|
-
@pre_authorize_cb = lambda {|env| true}
|
30
|
-
|
29
|
+
@pre_authorize_cb = lambda {|env| true}
|
30
|
+
|
31
31
|
# called after rack chain, to ensure we are REALLY allowed to profile
|
32
32
|
@position = 'left' # Where it is displayed
|
33
33
|
@skip_schema_queries = false
|
@@ -36,16 +36,17 @@ module Rack
|
|
36
36
|
@authorization_mode = :allow_all
|
37
37
|
@toggle_shortcut = 'Alt+P'
|
38
38
|
@start_hidden = false
|
39
|
+
@backtrace_threshold_ms = 0
|
39
40
|
self
|
40
41
|
}
|
41
42
|
end
|
42
43
|
|
43
44
|
def merge!(config)
|
44
45
|
return unless config
|
45
|
-
if Hash === config
|
46
|
+
if Hash === config
|
46
47
|
config.each{|k,v| instance_variable_set "@#{k}",v}
|
47
|
-
else
|
48
|
-
self.class.attributes.each{ |k|
|
48
|
+
else
|
49
|
+
self.class.attributes.each{ |k|
|
49
50
|
v = config.send k
|
50
51
|
instance_variable_set "@#{k}", v if v
|
51
52
|
}
|