forked from adamschwartz/chrome-inspector-detector
/
chrome.inspector-detector.js
142 lines (118 loc) · 5.12 KB
/
chrome.inspector-detector.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
(function(){
if (!window.chrome || !window.console) {
return ((window.console && console.log) || alert)('Chrome Inspector Helpers only supported in Google Chrome.');
}
window.chrome.inspector = window.chrome.inspector || {};
// As a side effect when running console.profile() to check if the
// inspector is open, WebKit prints a message to the console log. This
// clutters the log, but a workaround is to open a collapsed group (see
// https://developer.mozilla.org/en-US/docs/DOM/console#Using_groups_in_the_console
// ) that the messages are collected into.
//
// However, with this approach, we still would like console messages from
// external code to appear. The trick we use below is to keep track of
// whether there is a collapsed group currently open, and decorate the
// builtin console loging methods (log, info, warn, etc) as well as group,
// groupCollapsed and groupEnd to close the group if this is the case.
var logMethods = [ 'info', 'warn', 'log', 'debug' , 'error' ];
var origGroupEnd = console.groupEnd;
var groupActive = false;
logMethods.forEach(function(method) {
var orig = console[method];
console[method] = function() {
if(groupActive) {
origGroupEnd.apply(console);
groupActive = false;
}
return orig.apply(console, arguments);
};
});
var origGroupCollapsed = console.groupCollapsed;
var groupMethods = ['group', 'groupCollapsed'];
groupMethods.forEach(function(method) {
var orig = console[method];
console[method] = function() {
if (groupActive) {
origGroupEnd.apply(console);
groupActive = false;
}
orig.apply(console);
};
});
console.groupEnd = function() {
if(groupActive) {
origGroupEnd.apply(console);
groupActive = false;
}
origGroupEnd.apply(console);
};
window.chrome.inspector.tests = {
open: {
profile: function(){
// Try running a profile to see if it's open
// http://stackoverflow.com/a/15567735/131898
var existingProfiles = console.profiles.length;
if (!groupActive) {
groupActive = true;
origGroupCollapsed.apply(console)
}
console.profile('Inspector detector');
console.profileEnd();
if (console.profiles.length > existingProfiles) {
return true;
}
return false;
}
},
docked: {
height: function(){
var zoom = document.width / (document.body.clientWidth + parseInt(getComputedStyle(document.body)['margin-left'], 10) + parseInt(getComputedStyle(document.body)['margin-left'], 10));
// Try detecting by comparing the inner and outer window sizes
if (window.outerHeight > 1 + Math.ceil((zoom * window.innerHeight) + window.chrome.inspector._windowHeightOffset) ||
window.outerWidth > 1 + Math.ceil(zoom * window.innerWidth)) {
return true;
}
return false;
}
}
};
// Account for the height of the omnibar and bookmarks bar
// Can be overridden by setting window.chrome.inspector._windowHeightOffset yourself
// http://stackoverflow.com/a/7530254/131898
//
// This always uses the profile test right now, but should be configurable in the future.
if (window.chrome.inspector._windowHeightOffset === undefined)
window.chrome.inspector._windowHeightOffset = (window.chrome.inspector.tests.open.profile() ? 200 : window.outerHeight - window.innerHeight);
var getTests = function (spec){
var tests = {}, testType, testName, test;
for (testType in spec) {
// The tests can be specified as keys in the `window.chrome.inspector.tests[testType]` object,
// or as functions. Specify false (or don't include the key) to not run that
// class of test.
testName = spec[testType];
if (typeof testName == 'string')
test = window.chrome.inspector.tests[testType][testName];
else if (typeof testName == 'function')
test = testName;
else
continue;
tests[testType] = test;
}
return tests;
};
window.chrome.inspector.detector = function (options) {
var state, tests;
options = options || window.chrome.inspector.options || {};
// `options.tests` should be an object mapping a state to be looked for to
// a specific test to execute to test for it.
options.tests = options.tests || {
open: 'profile',
docked: 'height'
};
tests = getTests(options.tests);
state = {};
state.open = tests.open && tests.open();
state.docked = state.open && tests.docked && tests.docked();
return state;
};
})();