Skip to content

Commit 088e12d

Browse files
committed
adding initial javascript
1 parent 02867dd commit 088e12d

File tree

2 files changed

+517
-0
lines changed

2 files changed

+517
-0
lines changed

stacktrace.js

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
// Domain Public by Eric Wendelin http://eriwen.com/ (2008)
2+
// Luke Smith http://lucassmith.name/ (2008)
3+
// Loic Dachary <[email protected]> (2008)
4+
// Johan Euphrosine <[email protected]> (2008)
5+
//
6+
// Information and discussions
7+
// http://jspoker.pokersource.info/skin/test-printstacktrace.html
8+
// http://eriwen.com/javascript/js-stack-trace/
9+
// http://pastie.org/253058
10+
// http://browsershots.org/http://jspoker.pokersource.info/skin/test-printstacktrace.html
11+
//
12+
13+
//
14+
// guessFunctionNameFromLines comes from firebug
15+
//
16+
// Software License Agreement (BSD License)
17+
//
18+
// Copyright (c) 2007, Parakey Inc.
19+
// All rights reserved.
20+
//
21+
// Redistribution and use of this software in source and binary forms, with or without modification,
22+
// are permitted provided that the following conditions are met:
23+
//
24+
// * Redistributions of source code must retain the above
25+
// copyright notice, this list of conditions and the
26+
// following disclaimer.
27+
//
28+
// * Redistributions in binary form must reproduce the above
29+
// copyright notice, this list of conditions and the
30+
// following disclaimer in the documentation and/or other
31+
// materials provided with the distribution.
32+
//
33+
// * Neither the name of Parakey Inc. nor the names of its
34+
// contributors may be used to endorse or promote products
35+
// derived from this software without specific prior
36+
// written permission of Parakey Inc.
37+
//
38+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39+
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
40+
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41+
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
44+
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45+
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46+
47+
48+
function printStackTrace(options) {
49+
if (options && options.guess) {
50+
var p = new printStackTrace.implementation();
51+
var result = p.run();
52+
return p.guessFunctions(result);
53+
}
54+
return (new printStackTrace.implementation()).run();
55+
}
56+
57+
printStackTrace.implementation = function() {};
58+
59+
printStackTrace.implementation.prototype = {
60+
run: function() {
61+
mode = this.mode();
62+
if(mode != 'other') {
63+
try {(0)();} catch (e) {
64+
return this[mode](e);
65+
}
66+
} else {
67+
return this.other(arguments.callee);
68+
}
69+
},
70+
71+
mode: function() {
72+
var mode;
73+
try {(0)();} catch (e) {
74+
mode = e.stack ? 'firefox' : window.opera ? 'opera' : 'other';
75+
}
76+
return mode;
77+
},
78+
79+
firefox: function(e) {
80+
return e.stack.replace(/^.*?\n/,'').
81+
replace(/(?:\n@:0)?\s+$/m,'').
82+
replace(/^\(/gm,'{anonymous}(').
83+
split("\n");
84+
},
85+
86+
opera: function(e) {
87+
var lines = e.message.split("\n"),
88+
ANON = '{anonymous}',
89+
lineRE = /Line\s+(\d+).*?script\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i,
90+
i,j,len;
91+
92+
for (i=4,j=0,len=lines.length; i<len; i+=2) {
93+
if (lineRE.test(lines[i])) {
94+
lines[j++] = (RegExp.$3 ?
95+
RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 :
96+
ANON + '()@' + RegExp.$2 + ':' + RegExp.$1) +
97+
' -- ' + lines[i+1].replace(/^\s+/,'');
98+
}
99+
}
100+
101+
lines.splice(j,lines.length-j);
102+
return lines;
103+
},
104+
105+
other: function(curr) {
106+
var ANON = "{anonymous}",
107+
fnRE = /function\s*([\w\-$]+)?\s*\(/i,
108+
stack = [],j=0,
109+
fn,args;
110+
111+
while (curr) {
112+
fn = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON;
113+
args = Array.prototype.slice.call(curr['arguments']);
114+
stack[j++] = fn + '(' + printStackTrace.implementation.prototype.stringifyArguments(args) + ')';
115+
curr = curr.caller;
116+
}
117+
118+
return stack;
119+
},
120+
121+
stringifyArguments: function(args) {
122+
for (var i = 0; i < args.length; ++i) {
123+
var argument = args[i];
124+
if (typeof argument == 'object') {
125+
args[i] = '#object';
126+
} else if (typeof argument == 'function') {
127+
args[i] = '#function';
128+
} else if (typeof argument == 'string') {
129+
args[i] = '"'+argument+'"';
130+
}
131+
}
132+
return args.join(',');
133+
},
134+
135+
sourceCache : {},
136+
137+
ajax: function(url) {
138+
return jQuery.ajax({
139+
url: url,
140+
async: false
141+
}).responseText;
142+
},
143+
144+
getSource: function(url) {
145+
var self = this;
146+
if (!(url in self.sourceCache)) {
147+
self.sourceCache[url] = self.ajax(url).split("\n");
148+
}
149+
return self.sourceCache[url];
150+
},
151+
152+
guessFunctions: function(stack) {
153+
for (var i = 0; i < stack.length; ++i) {
154+
var reStack = /{anonymous}\(.*\)@(.*):(\d+)/;
155+
var frame = stack[i];
156+
var m = reStack.exec(frame);
157+
if (m) {
158+
var file = m[1];
159+
var lineno = m[2];
160+
if (file && lineno) {
161+
var functionName = this.guessFunctionName(file, lineno);
162+
stack[i] = frame.replace('{anonymous}', functionName);
163+
}
164+
}
165+
}
166+
return stack;
167+
},
168+
169+
guessFunctionName: function(url, lineNo) {
170+
var source;
171+
try {
172+
source = this.getSource(url);
173+
} catch (e) {
174+
return 'getSource failed with url: ' + url + ', exception: ' + e.toString();
175+
}
176+
return this.guessFunctionNameFromLines(lineNo, source);
177+
},
178+
179+
guessFunctionNameFromLines: function(lineNo, source) {
180+
var reFunctionArgNames = /function ([^(]*)\(([^)]*)\)/;
181+
var reGuessFunction = /['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*(function|eval|new Function)/;
182+
// Walk backwards from the first line in the function until we find the line which
183+
// matches the pattern above, which is the function definition
184+
var line = "";
185+
var maxLines = 10;
186+
for (var i = 0; i < maxLines; ++i) {
187+
line = source[lineNo-i] + line;
188+
if (line !== undefined) {
189+
var m = reGuessFunction.exec(line);
190+
if (m) {
191+
return m[1];
192+
} else {
193+
m = reFunctionArgNames.exec(line);
194+
}
195+
if (m && m[1]) {
196+
return m[1];
197+
}
198+
}
199+
}
200+
return "(?)";
201+
}
202+
};

0 commit comments

Comments
 (0)