diff --git a/.jshintrc b/.jshintrc index 6a123502afdb..79444bf25963 100644 --- a/.jshintrc +++ b/.jshintrc @@ -3,8 +3,8 @@ "globalstrict": true, "browser": true, "predef": [ - "TraceKit", "console", - "_slice" + "module", + "require" ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 7767a8479802..7457f947e92d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 2.0.0 + +* CHANGE: Default HTTP transport changed from `Image` GET to `XMLHttpRequest` POST (w/ CORS) + ## 1.3.0 * CHANGE: `console` plugin will now send all arguments as an `extra` value. See: https://github.com/getsentry/raven-js/pull/398 * CHANGE: Bump to v7 of the Sentry API spec. This now requires a Sentry 7.7.0+ https://github.com/getsentry/raven-js/pull/403 diff --git a/Gruntfile.js b/Gruntfile.js index 54c18d450e4b..c90a75eabb55 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,15 +1,11 @@ +var proxyquire = require('proxyquireify'); + module.exports = function(grunt) { "use strict"; var _ = require('lodash'); var path = require('path'); - - var coreFiles = [ - 'template/_header.js', - 'vendor/**/*.js', - 'src/**/*.js', - 'template/_footer.js' - ]; + var through = require('through2'); var excludedPlugins = [ 'react-native' @@ -26,6 +22,21 @@ module.exports = function(grunt) { return path; }); + // custom browserify transformer to re-write plugins to + // self-register with Raven via addPlugin + function AddPluginBrowserifyTransformer() { + return function (file) { + return through(function (buf, enc, next) { + buf = buf.toString('utf8'); + if (/plugins/.test(file)) { + buf += "\nrequire('../src/singleton').addPlugin(module.exports);"; + } + this.push(buf); + next(); + }); + }; + } + // Taken from http://dzone.com/snippets/calculate-all-combinations var combine = function (a) { var fn = function (n, src, got, all) { @@ -65,7 +76,7 @@ module.exports = function(grunt) { key.sort(); var dest = path.join('build/', key.join(','), '/raven.js'); - dict[dest] = coreFiles.concat(comb); + dict[dest] = ['src/singleton.js'].concat(comb); return dict; }, {}); @@ -75,18 +86,35 @@ module.exports = function(grunt) { aws: grunt.file.exists('aws.json') ? grunt.file.readJSON('aws.json'): {}, clean: ['build'], - concat: { + + browserify: { options: { - separator: '\n', - banner: grunt.file.read('template/_copyright.js'), - process: true + browserifyOptions: { + banner: grunt.file.read('template/_copyright.js'), + standalone: 'Raven' // umd + } }, core: { - src: coreFiles.concat(plugins), + src: 'src/singleton.js', dest: 'build/raven.js' }, - all: { - files: pluginConcatFiles + plugins: { + files: pluginConcatFiles, + options: { + transform: [ + [ new AddPluginBrowserifyTransformer() ] + ] + } + }, + test: { + src: 'test/**/*.test.js', + dest: 'build/raven.test.js', + options: { + browserifyOptions: { + debug: true // source maps + }, + plugin: [proxyquire.plugin] + } } }, @@ -100,7 +128,13 @@ module.exports = function(grunt) { sourceMappingURL: function (dest) { return path.basename(dest, '.js') + '.map'; }, - preserveComments: 'some' + preserveComments: 'some', + compress: { + dead_code: true, + global_defs: { + "TEST": false + } + } }, dist: { src: ['build/**/*.js'], @@ -251,13 +285,13 @@ module.exports = function(grunt) { // Grunt contrib tasks grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-connect'); grunt.loadNpmTasks('grunt-contrib-copy'); // 3rd party Grunt tasks + grunt.loadNpmTasks('grunt-browserify'); grunt.loadNpmTasks('grunt-mocha'); grunt.loadNpmTasks('grunt-release'); grunt.loadNpmTasks('grunt-s3'); @@ -266,15 +300,16 @@ module.exports = function(grunt) { // Build tasks grunt.registerTask('_prep', ['clean', 'gitinfo', 'version']); - grunt.registerTask('concat.core', ['_prep', 'concat:core']); - grunt.registerTask('concat.all', ['_prep', 'concat:all']); - grunt.registerTask('build.core', ['concat.core', 'uglify', 'fixSourceMaps', 'sri:dist']); - grunt.registerTask('build.all', ['concat.all', 'uglify', 'fixSourceMaps', 'sri:dist', 'sri:build']); + grunt.registerTask('browserify.core', ['_prep', 'browserify:core']); + grunt.registerTask('browserify.plugins', ['_prep', 'browserify:plugins']); + grunt.registerTask('build.test', ['_prep', 'browserify:test']); + grunt.registerTask('build.core', ['browserify.core', 'uglify', 'fixSourceMaps', 'sri:dist']); + grunt.registerTask('build.all', ['browserify.plugins', 'uglify', 'fixSourceMaps', 'sri:dist', 'sri:build']); grunt.registerTask('build', ['build.all']); grunt.registerTask('dist', ['build.core', 'copy:dist']); // Test task - grunt.registerTask('test', ['jshint', 'mocha']); + grunt.registerTask('test', ['jshint', 'browserify.core', 'browserify:test', 'mocha']); // Webserver tasks grunt.registerTask('run:test', ['connect:test']); diff --git a/bower.json b/bower.json index e077f27aacac..1b3c78b24d44 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "raven-js", - "version": "1.3.0", + "version": "2.0.0-rc1", "dependencies": {}, "main": "dist/raven.js", "ignore": [ diff --git a/dist/raven.js b/dist/raven.js index 78c47292a7b5..88ef067fdf68 100644 --- a/dist/raven.js +++ b/dist/raven.js @@ -1,4 +1,4 @@ -/*! Raven.js 1.3.0 (768fdca) | github.com/getsentry/raven-js */ +/*! Raven.js 2.0.0-rc1 (4de0c94) | github.com/getsentry/raven-js */ /* * Includes TraceKit @@ -1067,6 +1067,7 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { return computeStackTrace; }()); +/*global XDomainRequest:false*/ 'use strict'; // First, check for JSON support @@ -1110,7 +1111,7 @@ for (var method in originalConsole) { * @this {Raven} */ var Raven = { - VERSION: '1.3.0', + VERSION: '2.0.0-rc1', debug: false, @@ -1174,7 +1175,9 @@ var Raven = { (uri.port ? ':' + uri.port : '') + '/' + path + 'api/' + globalProject + '/store/'; - if (uri.protocol) { + // can safely use protocol relative (//) if target host is + // app.getsentry.com; otherwise use protocol from DSN + if (uri.protocol && uri.host !== 'app.getsentry.com') { globalServer = uri.protocol + ':' + globalServer; } @@ -1909,7 +1912,7 @@ function send(data) { }); } -function makeRequest(opts) { +function makeImageRequest(opts) { // Tack on sentry_data to auth options, which get urlencoded opts.auth.sentry_data = JSON.stringify(opts.data); @@ -1925,6 +1928,47 @@ function makeRequest(opts) { img.src = src; } +function makeXhrRequest(opts) { + var request; + + function handler() { + if (request.status === 200) { + if (opts.onSuccess) { + opts.onSuccess(); + } + } else if (opts.onError) { + opts.onError(); + } + } + + request = new XMLHttpRequest(); + if ('withCredentials' in request) { + request.onreadystatechange = function () { + if (request.readyState !== 4) { + return; + } + handler(); + }; + } else { + request = new XDomainRequest(); + // onreadystatechange not supported by XDomainRequest + request.onload = handler; + } + + // NOTE: auth is intentionally sent as part of query string (NOT as custom + // HTTP header) so as to avoid preflight CORS requests + request.open('POST', opts.url + '?' + urlencode(opts.auth)); + request.send(JSON.stringify(opts.data)); +} + +function makeRequest(opts) { + var hasCORS = + 'withCredentials' in new XMLHttpRequest() || + typeof XDomainRequest !== 'undefined'; + + return (hasCORS ? makeXhrRequest : makeImageRequest)(opts); +} + // Note: this is shitty, but I can't figure out how to get // sinon to stub document.createElement without breaking everything // so this wrapper is just so I can stub it for tests. diff --git a/dist/raven.min.js b/dist/raven.min.js index 4f800102b4d4..f34ac5ddb468 100644 --- a/dist/raven.min.js +++ b/dist/raven.min.js @@ -1,3 +1,3 @@ -/*! Raven.js 1.3.0 (768fdca) | github.com/getsentry/raven-js */ -!function(a,b){"use strict";function c(){return"undefined"==typeof document?"":document.location.href}function d(a,b){var c,d;if(R){b=b||{},a="raven"+a.substr(0,1).toUpperCase()+a.substr(1),document.createEvent?(c=document.createEvent("HTMLEvents"),c.initEvent(a,!0,!0)):(c=document.createEventObject(),c.eventType=a);for(d in b)m(b,d)&&(c[d]=b[d]);if(document.createEvent)document.dispatchEvent(c);else try{document.fireEvent("on"+c.eventType.toLowerCase(),c)}catch(e){}}}function e(a){this.name="RavenConfigError",this.message=a}function f(a){var b=ba.exec(a),c={},d=7;try{for(;d--;)c[aa[d]]=b[d]||""}catch(f){throw new e("Invalid DSN: "+a)}if(c.pass)throw new e("Do not specify your private key in the DSN!");return c}function g(a){return void 0===a}function h(a){return"function"==typeof a}function i(a){return"[object String]"===V.toString.call(a)}function j(a){return"object"==typeof a&&null!==a}function k(a){for(var b in a)return!1;return!0}function l(a){return j(a)&&"[object Error]"===V.toString.call(a)||a instanceof Error}function m(a,b){return V.hasOwnProperty.call(a,b)}function n(a,b){var c,d;if(g(a.length))for(c in a)m(a,c)&&b.call(null,c,a[c]);else if(d=a.length)for(c=0;d>c;c++)b.call(null,c,a[c])}function o(a,b){var c=[];a.stack&&a.stack.length&&n(a.stack,function(a,b){var d=p(b);d&&c.push(d)}),d("handle",{stackInfo:a,options:b}),r(a.name,a.message,a.url,a.lineno,c,b)}function p(a){if(a.url){var b,c={filename:a.url,lineno:a.line,colno:a.column,"function":a.func||"?"},d=q(a);if(d){var e=["pre_context","context_line","post_context"];for(b=3;b--;)c[e[b]]=d[b]}return c.in_app=!(T.includePaths.test&&!T.includePaths.test(c.filename)||/(Raven|TraceKit)\./.test(c["function"])||/raven\.(min\.)?js$/.test(c.filename)),c}}function q(a){if(a.context&&T.fetchContext){for(var b=a.context,c=~~(b.length/2),d=b.length,e=!1;d--;)if(b[d].length>300){e=!0;break}if(e){if(g(a.column))return;return[[],b[c].substr(a.column,50),[]]}return[b.slice(0,c),b[c],b.slice(c+1)]}}function r(a,b,c,d,e,f){var g,h;T.ignoreErrors.test&&T.ignoreErrors.test(b)||(b+="",h=a+": "+b,e&&e.length?(c=e[0].filename||c,e.reverse(),g={frames:e}):c&&(g={frames:[{filename:c,lineno:d,in_app:!0}]}),T.ignoreUrls.test&&T.ignoreUrls.test(c)||(!T.whitelistUrls.test||T.whitelistUrls.test(c))&&x(s({exception:{values:[{type:a,value:b,stacktrace:g}]},culprit:c,message:h},f)))}function s(a,b){return b?(n(b,function(b,c){a[b]=c}),a):a}function t(a,b){return a.length<=b?a:a.substr(0,b)+"…"}function u(a){var b=T.maxMessageLength;if(a.message=t(a.message,b),a.exception){var c=a.exception.values[0];c.value=t(c.value,b)}return a}function v(){return+new Date}function w(){if(R&&document.location&&document.location.href){var a={headers:{"User-Agent":navigator.userAgent}};return a.url=document.location.href,document.referrer&&(a.headers.Referer=document.referrer),a}}function x(a){var b={project:O,logger:T.logger,platform:"javascript"},c=w();c&&(b.request=c),a=s(b,a),a.tags=s(s({},S.tags),a.tags),a.extra=s(s({},S.extra),a.extra),a.extra["session:duration"]=v()-Z,k(a.tags)&&delete a.tags,S.user&&(a.user=S.user),T.release&&(a.release=T.release),T.serverName&&(a.server_name=T.serverName),h(T.dataCallback)&&(a=T.dataCallback(a)||a),a&&!k(a)&&(!h(T.shouldSendCallback)||T.shouldSendCallback(a))&&(L=a.event_id||(a.event_id=C()),a=u(a),D("debug","Raven about to send:",a),A()&&(T.transport||y)({url:M,auth:{sentry_version:"7",sentry_client:"raven-js/"+_.VERSION,sentry_key:N},data:a,options:T,onSuccess:function(){d("success",{data:a,src:M})},onError:function(){d("failure",{data:a,src:M})}}))}function y(a){a.auth.sentry_data=JSON.stringify(a.data);var b=z(),c=a.url+"?"+F(a.auth),d=a.options.crossOrigin;(d||""===d)&&(b.crossOrigin=d),b.onload=a.onSuccess,b.onerror=b.onabort=a.onError,b.src=c}function z(){return document.createElement("img")}function A(){return Q?M?!0:(ca||D("error","Error: Raven has not been configured."),ca=!0,!1):!1}function B(a){for(var b,c=[],d=0,e=a.length;e>d;d++)b=a[d],i(b)?c.push(b.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")):b&&b.source&&c.push(b.source);return new RegExp(c.join("|"),"i")}function C(){var b=a.crypto||a.msCrypto;if(!g(b)&&b.getRandomValues){var c=new Uint16Array(8);b.getRandomValues(c),c[3]=4095&c[3]|16384,c[4]=16383&c[4]|32768;var d=function(a){for(var b=a.toString(16);b.length<4;)b="0"+b;return b};return d(c[0])+d(c[1])+d(c[2])+d(c[3])+d(c[4])+d(c[5])+d(c[6])+d(c[7])}return"xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"==a?b:3&b|8;return c.toString(16)})}function D(a){X[a]&&_.debug&&X[a].apply(W,I.call(arguments,1))}function E(){var b=a.RavenConfig;b&&_.config(b.dsn,b.config).install()}function F(a){var b=[];return n(a,function(a,c){b.push(encodeURIComponent(a)+"="+encodeURIComponent(c))}),b.join("&")}function G(a,b){g(b)?delete S[a]:S[a]=s(S[a]||{},b)}var H={remoteFetching:!1,collectWindowErrors:!0,linesOfContext:7,debug:!1},I=[].slice,J="?";H.report=function(){function d(a){i(),p.push(a)}function e(a){for(var b=p.length-1;b>=0;--b)p[b]===a&&p.splice(b,1)}function f(){j(),p=[]}function g(a,b){var c=null;if(!b||H.collectWindowErrors){for(var d in p)if(m(p,d))try{p[d].apply(null,[a].concat(I.call(arguments,2)))}catch(e){c=e}if(c)throw c}}function h(a,b,d,e,f){var h=null;if(s)H.computeStackTrace.augmentStackTraceWithInitialElement(s,b,d,a),k();else if(f)h=H.computeStackTrace(f),g(h,!0);else{var i={url:b,line:d,column:e};i.func=H.computeStackTrace.guessFunctionName(i.url,i.line),i.context=H.computeStackTrace.gatherContext(i.url,i.line),h={message:a,url:c(),stack:[i]},g(h,!0)}return n?n.apply(this,arguments):!1}function i(){o||(n=a.onerror,a.onerror=h,o=!0)}function j(){o&&(a.onerror=n,o=!1,n=b)}function k(){var a=s,b=q;q=null,s=null,r=null,g.apply(null,[a,!1].concat(b))}function l(b,c){var d=I.call(arguments,1);if(s){if(r===b)return;k()}var e=H.computeStackTrace(b);if(s=e,r=b,q=d,a.setTimeout(function(){r===b&&k()},e.incomplete?2e3:0),c!==!1)throw b}var n,o,p=[],q=null,r=null,s=null;return l.subscribe=d,l.unsubscribe=e,l.uninstall=f,l}(),H.computeStackTrace=function(){function b(b){if(!H.remoteFetching)return"";try{var c=function(){try{return new a.XMLHttpRequest}catch(b){return new a.ActiveXObject("Microsoft.XMLHTTP")}},d=c();return d.open("GET",b,!1),d.send(""),d.responseText}catch(e){return""}}function d(a){if(!i(a))return[];if(!m(u,a)){var c="",d="";try{d=document.domain}catch(e){}-1!==a.indexOf(d)&&(c=b(a)),u[a]=c?c.split("\n"):[]}return u[a]}function e(a,b){var c,e=/function ([^(]*)\(([^)]*)\)/,f=/['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/,h="",i=10,j=d(a);if(!j.length)return J;for(var k=0;i>k;++k)if(h=j[b-k]+h,!g(h)){if(c=f.exec(h))return c[1];if(c=e.exec(h))return c[1]}return J}function f(a,b){var c=d(a);if(!c.length)return null;var e=[],f=Math.floor(H.linesOfContext/2),h=f+H.linesOfContext%2,i=Math.max(0,b-f-1),j=Math.min(c.length,b+h-1);b-=1;for(var k=i;j>k;++k)g(c[k])||e.push(c[k]);return e.length>0?e:null}function h(a){return a.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g,"\\$&")}function j(a){return h(a).replace("<","(?:<|<)").replace(">","(?:>|>)").replace("&","(?:&|&)").replace('"','(?:"|")').replace(/\s+/g,"\\s+")}function k(a,b){for(var c,e,f=0,g=b.length;g>f;++f)if((c=d(b[f])).length&&(c=c.join("\n"),e=a.exec(c)))return{url:b[f],line:c.substring(0,e.index).split("\n").length,column:e.index-c.lastIndexOf("\n",e.index)-1};return null}function l(a,b,c){var e,f=d(b),g=new RegExp("\\b"+h(a)+"\\b");return c-=1,f&&f.length>c&&(e=g.exec(f[c]))?e.index:null}function n(b){if("undefined"!=typeof document){for(var c,d,e,f,g=[a.location.href],i=document.getElementsByTagName("script"),l=""+b,m=/^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,n=/^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,o=0;o):(\d+)(?::(\d+))?\)?\s*$/i,i=/^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i,j=/^\s*at (?:((?:\[object object\])?.+) )?\(?((?:ms-appx|http|https):.*?):(\d+)(?::(\d+))?\)?\s*$/i,k=a.stack.split("\n"),m=[],n=/^(.*) is undefined$/.exec(a.message),o=0,p=k.length;p>o;++o){if(b=i.exec(k[o]))d={url:b[3],func:b[1]||J,args:b[2]?b[2].split(","):"",line:+b[4],column:b[5]?+b[5]:null};else if(b=h.exec(k[o]))d={url:b[2],func:b[1]||J,line:+b[3],column:b[4]?+b[4]:null};else{if(!(b=j.exec(k[o])))continue;d={url:b[2],func:b[1]||J,line:+b[3],column:b[4]?+b[4]:null}}!d.func&&d.line&&(d.func=e(d.url,d.line)),d.line&&(d.context=f(d.url,d.line)),m.push(d)}return m.length?(m[0].line&&!m[0].column&&n?m[0].column=l(n[1],m[0].url,m[0].line):m[0].column||g(a.columnNumber)||(m[0].column=a.columnNumber+1),{name:a.name,message:a.message,url:c(),stack:m}):null}}function p(a){var b=a.stacktrace;if(!g(a.stacktrace)&&a.stacktrace){for(var d,h=/ line (\d+), column (\d+) in (?:]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i,i=b.split("\n"),j=[],k=0,l=i.length;l>k;k+=2)if(d=h.exec(i[k])){var m={line:+d[1],column:+d[2],func:d[3]||d[4],args:d[5]?d[5].split(","):[],url:d[6]};if(!m.func&&m.line&&(m.func=e(m.url,m.line)),m.line)try{m.context=f(m.url,m.line)}catch(n){}m.context||(m.context=[i[k+1]]),j.push(m)}return j.length?{name:a.name,message:a.message,url:c(),stack:j}:null}}function q(b){var g=b.message.split("\n");if(g.length<4)return null;var h,i,l,n,o=/^\s*Line (\d+) of linked script ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,p=/^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,q=/^\s*Line (\d+) of function script\s*$/i,r=[],s=document.getElementsByTagName("script"),t=[];for(i in s)m(s,i)&&!s[i].src&&t.push(s[i]);for(i=2,l=g.length;l>i;i+=2){var u=null;if(h=o.exec(g[i]))u={url:h[2],func:h[3],line:+h[1]};else if(h=p.exec(g[i])){u={url:h[3],func:h[4]};var v=+h[1],w=t[h[2]-1];if(w&&(n=d(u.url))){n=n.join("\n");var x=n.indexOf(w.innerText);x>=0&&(u.line=v+n.substring(0,x).split("\n").length)}}else if(h=q.exec(g[i])){var y=a.location.href.replace(/#.*$/,""),z=h[1],A=new RegExp(j(g[i+1]));n=k(A,[y]),u={url:y,line:n?n.line:z,func:""}}if(u){u.func||(u.func=e(u.url,u.line));var B=f(u.url,u.line),C=B?B[Math.floor(B.length/2)]:null;B&&C.replace(/^\s*/,"")===g[i+1].replace(/^\s*/,"")?u.context=B:u.context=[g[i+1]],r.push(u)}}return r.length?{name:b.name,message:g[0],url:c(),stack:r}:null}function r(a,b,c,d){var g={url:b,line:c};if(g.url&&g.line){a.incomplete=!1,g.func||(g.func=e(g.url,g.line)),g.context||(g.context=f(g.url,g.line));var h=/ '([^']+)' /.exec(d);if(h&&(g.column=l(h[1],g.url,g.line)),a.stack.length>0&&a.stack[0].url===g.url){if(a.stack[0].line===g.line)return!1;if(!a.stack[0].line&&a.stack[0].func===g.func)return a.stack[0].line=g.line,a.stack[0].context=g.context,!1}return a.stack.unshift(g),a.partial=!0,!0}return a.incomplete=!0,!1}function s(a,b){for(var d,f,g,h=/function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,i=[],j={},k=!1,m=s.caller;m&&!k;m=m.caller)if(m!==t&&m!==H.report){if(f={url:null,func:J,line:null,column:null},m.name?f.func=m.name:(d=h.exec(m.toString()))&&(f.func=d[1]),"undefined"==typeof f.func)try{f.func=d.input.substring(0,d.input.indexOf("{"))}catch(o){}if(g=n(m)){f.url=g.url,f.line=g.line,f.func===J&&(f.func=e(f.url,f.line));var p=/ '([^']+)' /.exec(a.message||a.description);p&&(f.column=l(p[1],g.url,g.line))}j[""+m]?k=!0:j[""+m]=!0,i.push(f)}b&&i.splice(0,b);var q={name:a.name,message:a.message,url:c(),stack:i};return r(q,a.sourceURL||a.fileName,a.line||a.lineNumber,a.message||a.description),q}function t(a,b){var d=null;b=null==b?0:+b;try{if(d=p(a))return d}catch(e){if(H.debug)throw e}try{if(d=o(a))return d}catch(e){if(H.debug)throw e}try{if(d=q(a))return d}catch(e){if(H.debug)throw e}try{if(d=s(a,b+1))return d}catch(e){if(H.debug)throw e}return{name:a.name,message:a.message,url:c()}}var u={};return t.augmentStackTraceWithInitialElement=r,t.computeStackTraceFromStackProp=o,t.guessFunctionName=e,t.gatherContext=f,t}();var K,L,M,N,O,P=a.Raven,Q=!("object"!=typeof JSON||!JSON.stringify),R="undefined"!=typeof document,S={},T={logger:"javascript",ignoreErrors:[],ignoreUrls:[],whitelistUrls:[],includePaths:[],crossOrigin:"anonymous",collectWindowErrors:!0,maxMessageLength:100},U=!1,V=Object.prototype,W=a.console||{},X={},Y=[],Z=v();for(var $ in W)X[$]=W[$];var _={VERSION:"1.3.0",debug:!1,noConflict:function(){return a.Raven=P,_},config:function(a,b){if(M)return D("error","Error: Raven has already been configured"),_;if(!a)return _;var c=f(a),d=c.path.lastIndexOf("/"),e=c.path.substr(1,d);return b&&n(b,function(a,b){"tags"==a||"extra"==a?S[a]=b:T[a]=b}),T.ignoreErrors.push(/^Script error\.?$/),T.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/),T.ignoreErrors=B(T.ignoreErrors),T.ignoreUrls=T.ignoreUrls.length?B(T.ignoreUrls):!1,T.whitelistUrls=T.whitelistUrls.length?B(T.whitelistUrls):!1,T.includePaths=B(T.includePaths),N=c.user,O=c.path.substr(d+1),M="//"+c.host+(c.port?":"+c.port:"")+"/"+e+"api/"+O+"/store/",c.protocol&&(M=c.protocol+":"+M),T.fetchContext&&(H.remoteFetching=!0),T.linesOfContext&&(H.linesOfContext=T.linesOfContext),H.collectWindowErrors=!!T.collectWindowErrors,_},install:function(){return A()&&!U&&(H.report.subscribe(o),n(Y,function(a,b){b()}),U=!0),_},context:function(a,c,d){return h(a)&&(d=c||[],c=a,a=b),_.wrap(a,c).apply(this,d)},wrap:function(a,c){function d(){for(var b=[],d=arguments.length,e=!a||a&&a.deep!==!1;d--;)b[d]=e?_.wrap(a,arguments[d]):arguments[d];try{return c.apply(this,b)}catch(f){throw _.captureException(f,a),f}}if(g(c)&&!h(a))return a;if(h(a)&&(c=a,a=b),!h(c))return c;if(c.__raven__)return c;for(var e in c)m(c,e)&&(d[e]=c[e]);return d.prototype=c.prototype,d.__raven__=!0,d.__inner__=c,d},uninstall:function(){return H.report.uninstall(),U=!1,_},captureException:function(a,b){if(!l(a))return _.captureMessage(a,b);K=a;try{var c=H.computeStackTrace(a);o(c,b)}catch(d){if(a!==d)throw d}return _},captureMessage:function(a,b){return T.ignoreErrors.test&&T.ignoreErrors.test(a)?void 0:(x(s({message:a+""},b)),_)},addPlugin:function(a){return Y.push(a),U&&a(),_},setUserContext:function(a){return S.user=a,_},setExtraContext:function(a){return G("extra",a),_},setTagsContext:function(a){return G("tags",a),_},clearContext:function(){return S={},_},getContext:function(){return JSON.parse(JSON.stringify(S))},setRelease:function(a){return T.release=a,_},setDataCallback:function(a){return T.dataCallback=a,_},setShouldSendCallback:function(a){return T.shouldSendCallback=a,_},setTransport:function(a){return T.transport=a,_},lastException:function(){return K},lastEventId:function(){return L},isSetup:function(){return A()}};_.setUser=_.setUserContext,_.setReleaseContext=_.setRelease;var aa="source protocol user pass host port path".split(" "),ba=/^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/;e.prototype=new Error,e.prototype.constructor=e;var ca;E(),a.Raven=_,"function"==typeof define&&define.amd?define("raven",[],function(){return _}):"object"==typeof module?module.exports=_:"object"==typeof exports&&(exports=_)}("undefined"!=typeof window?window:this); +/*! Raven.js 2.0.0-rc1 (4de0c94) | github.com/getsentry/raven-js */ +!function(a,b){"use strict";function c(){return"undefined"==typeof document?"":document.location.href}function d(a,b){var c,d;if(T){b=b||{},a="raven"+a.substr(0,1).toUpperCase()+a.substr(1),document.createEvent?(c=document.createEvent("HTMLEvents"),c.initEvent(a,!0,!0)):(c=document.createEventObject(),c.eventType=a);for(d in b)m(b,d)&&(c[d]=b[d]);if(document.createEvent)document.dispatchEvent(c);else try{document.fireEvent("on"+c.eventType.toLowerCase(),c)}catch(e){}}}function e(a){this.name="RavenConfigError",this.message=a}function f(a){var b=da.exec(a),c={},d=7;try{for(;d--;)c[ca[d]]=b[d]||""}catch(f){throw new e("Invalid DSN: "+a)}if(c.pass)throw new e("Do not specify your private key in the DSN!");return c}function g(a){return void 0===a}function h(a){return"function"==typeof a}function i(a){return"[object String]"===X.toString.call(a)}function j(a){return"object"==typeof a&&null!==a}function k(a){for(var b in a)return!1;return!0}function l(a){return j(a)&&"[object Error]"===X.toString.call(a)||a instanceof Error}function m(a,b){return X.hasOwnProperty.call(a,b)}function n(a,b){var c,d;if(g(a.length))for(c in a)m(a,c)&&b.call(null,c,a[c]);else if(d=a.length)for(c=0;d>c;c++)b.call(null,c,a[c])}function o(a,b){var c=[];a.stack&&a.stack.length&&n(a.stack,function(a,b){var d=p(b);d&&c.push(d)}),d("handle",{stackInfo:a,options:b}),r(a.name,a.message,a.url,a.lineno,c,b)}function p(a){if(a.url){var b,c={filename:a.url,lineno:a.line,colno:a.column,"function":a.func||"?"},d=q(a);if(d){var e=["pre_context","context_line","post_context"];for(b=3;b--;)c[e[b]]=d[b]}return c.in_app=!(V.includePaths.test&&!V.includePaths.test(c.filename)||/(Raven|TraceKit)\./.test(c["function"])||/raven\.(min\.)?js$/.test(c.filename)),c}}function q(a){if(a.context&&V.fetchContext){for(var b=a.context,c=~~(b.length/2),d=b.length,e=!1;d--;)if(b[d].length>300){e=!0;break}if(e){if(g(a.column))return;return[[],b[c].substr(a.column,50),[]]}return[b.slice(0,c),b[c],b.slice(c+1)]}}function r(a,b,c,d,e,f){var g,h;V.ignoreErrors.test&&V.ignoreErrors.test(b)||(b+="",h=a+": "+b,e&&e.length?(c=e[0].filename||c,e.reverse(),g={frames:e}):c&&(g={frames:[{filename:c,lineno:d,in_app:!0}]}),V.ignoreUrls.test&&V.ignoreUrls.test(c)||(!V.whitelistUrls.test||V.whitelistUrls.test(c))&&x(s({exception:{values:[{type:a,value:b,stacktrace:g}]},culprit:c,message:h},f)))}function s(a,b){return b?(n(b,function(b,c){a[b]=c}),a):a}function t(a,b){return a.length<=b?a:a.substr(0,b)+"…"}function u(a){var b=V.maxMessageLength;if(a.message=t(a.message,b),a.exception){var c=a.exception.values[0];c.value=t(c.value,b)}return a}function v(){return+new Date}function w(){if(T&&document.location&&document.location.href){var a={headers:{"User-Agent":navigator.userAgent}};return a.url=document.location.href,document.referrer&&(a.headers.Referer=document.referrer),a}}function x(a){var b={project:Q,logger:V.logger,platform:"javascript"},c=w();c&&(b.request=c),a=s(b,a),a.tags=s(s({},U.tags),a.tags),a.extra=s(s({},U.extra),a.extra),a.extra["session:duration"]=v()-_,k(a.tags)&&delete a.tags,U.user&&(a.user=U.user),V.release&&(a.release=V.release),V.serverName&&(a.server_name=V.serverName),h(V.dataCallback)&&(a=V.dataCallback(a)||a),a&&!k(a)&&(!h(V.shouldSendCallback)||V.shouldSendCallback(a))&&(N=a.event_id||(a.event_id=E()),a=u(a),F("debug","Raven about to send:",a),C()&&(V.transport||A)({url:O,auth:{sentry_version:"7",sentry_client:"raven-js/"+ba.VERSION,sentry_key:P},data:a,options:V,onSuccess:function(){d("success",{data:a,src:O})},onError:function(){d("failure",{data:a,src:O})}}))}function y(a){a.auth.sentry_data=JSON.stringify(a.data);var b=B(),c=a.url+"?"+H(a.auth),d=a.options.crossOrigin;(d||""===d)&&(b.crossOrigin=d),b.onload=a.onSuccess,b.onerror=b.onabort=a.onError,b.src=c}function z(a){function b(){200===c.status?a.onSuccess&&a.onSuccess():a.onError&&a.onError()}var c;c=new XMLHttpRequest,"withCredentials"in c?c.onreadystatechange=function(){4===c.readyState&&b()}:(c=new XDomainRequest,c.onload=b),c.open("POST",a.url+"?"+H(a.auth)),c.send(JSON.stringify(a.data))}function A(a){var b="withCredentials"in new XMLHttpRequest||"undefined"!=typeof XDomainRequest;return(b?z:y)(a)}function B(){return document.createElement("img")}function C(){return S?O?!0:(ea||F("error","Error: Raven has not been configured."),ea=!0,!1):!1}function D(a){for(var b,c=[],d=0,e=a.length;e>d;d++)b=a[d],i(b)?c.push(b.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")):b&&b.source&&c.push(b.source);return new RegExp(c.join("|"),"i")}function E(){var b=a.crypto||a.msCrypto;if(!g(b)&&b.getRandomValues){var c=new Uint16Array(8);b.getRandomValues(c),c[3]=4095&c[3]|16384,c[4]=16383&c[4]|32768;var d=function(a){for(var b=a.toString(16);b.length<4;)b="0"+b;return b};return d(c[0])+d(c[1])+d(c[2])+d(c[3])+d(c[4])+d(c[5])+d(c[6])+d(c[7])}return"xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"==a?b:3&b|8;return c.toString(16)})}function F(a){Z[a]&&ba.debug&&Z[a].apply(Y,K.call(arguments,1))}function G(){var b=a.RavenConfig;b&&ba.config(b.dsn,b.config).install()}function H(a){var b=[];return n(a,function(a,c){b.push(encodeURIComponent(a)+"="+encodeURIComponent(c))}),b.join("&")}function I(a,b){g(b)?delete U[a]:U[a]=s(U[a]||{},b)}var J={remoteFetching:!1,collectWindowErrors:!0,linesOfContext:7,debug:!1},K=[].slice,L="?";J.report=function(){function d(a){i(),p.push(a)}function e(a){for(var b=p.length-1;b>=0;--b)p[b]===a&&p.splice(b,1)}function f(){j(),p=[]}function g(a,b){var c=null;if(!b||J.collectWindowErrors){for(var d in p)if(m(p,d))try{p[d].apply(null,[a].concat(K.call(arguments,2)))}catch(e){c=e}if(c)throw c}}function h(a,b,d,e,f){var h=null;if(s)J.computeStackTrace.augmentStackTraceWithInitialElement(s,b,d,a),k();else if(f)h=J.computeStackTrace(f),g(h,!0);else{var i={url:b,line:d,column:e};i.func=J.computeStackTrace.guessFunctionName(i.url,i.line),i.context=J.computeStackTrace.gatherContext(i.url,i.line),h={message:a,url:c(),stack:[i]},g(h,!0)}return n?n.apply(this,arguments):!1}function i(){o||(n=a.onerror,a.onerror=h,o=!0)}function j(){o&&(a.onerror=n,o=!1,n=b)}function k(){var a=s,b=q;q=null,s=null,r=null,g.apply(null,[a,!1].concat(b))}function l(b,c){var d=K.call(arguments,1);if(s){if(r===b)return;k()}var e=J.computeStackTrace(b);if(s=e,r=b,q=d,a.setTimeout(function(){r===b&&k()},e.incomplete?2e3:0),c!==!1)throw b}var n,o,p=[],q=null,r=null,s=null;return l.subscribe=d,l.unsubscribe=e,l.uninstall=f,l}(),J.computeStackTrace=function(){function b(b){if(!J.remoteFetching)return"";try{var c=function(){try{return new a.XMLHttpRequest}catch(b){return new a.ActiveXObject("Microsoft.XMLHTTP")}},d=c();return d.open("GET",b,!1),d.send(""),d.responseText}catch(e){return""}}function d(a){if(!i(a))return[];if(!m(u,a)){var c="",d="";try{d=document.domain}catch(e){}-1!==a.indexOf(d)&&(c=b(a)),u[a]=c?c.split("\n"):[]}return u[a]}function e(a,b){var c,e=/function ([^(]*)\(([^)]*)\)/,f=/['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/,h="",i=10,j=d(a);if(!j.length)return L;for(var k=0;i>k;++k)if(h=j[b-k]+h,!g(h)){if(c=f.exec(h))return c[1];if(c=e.exec(h))return c[1]}return L}function f(a,b){var c=d(a);if(!c.length)return null;var e=[],f=Math.floor(J.linesOfContext/2),h=f+J.linesOfContext%2,i=Math.max(0,b-f-1),j=Math.min(c.length,b+h-1);b-=1;for(var k=i;j>k;++k)g(c[k])||e.push(c[k]);return e.length>0?e:null}function h(a){return a.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g,"\\$&")}function j(a){return h(a).replace("<","(?:<|<)").replace(">","(?:>|>)").replace("&","(?:&|&)").replace('"','(?:"|")').replace(/\s+/g,"\\s+")}function k(a,b){for(var c,e,f=0,g=b.length;g>f;++f)if((c=d(b[f])).length&&(c=c.join("\n"),e=a.exec(c)))return{url:b[f],line:c.substring(0,e.index).split("\n").length,column:e.index-c.lastIndexOf("\n",e.index)-1};return null}function l(a,b,c){var e,f=d(b),g=new RegExp("\\b"+h(a)+"\\b");return c-=1,f&&f.length>c&&(e=g.exec(f[c]))?e.index:null}function n(b){if("undefined"!=typeof document){for(var c,d,e,f,g=[a.location.href],i=document.getElementsByTagName("script"),l=""+b,m=/^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,n=/^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,o=0;o):(\d+)(?::(\d+))?\)?\s*$/i,i=/^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i,j=/^\s*at (?:((?:\[object object\])?.+) )?\(?((?:ms-appx|http|https):.*?):(\d+)(?::(\d+))?\)?\s*$/i,k=a.stack.split("\n"),m=[],n=/^(.*) is undefined$/.exec(a.message),o=0,p=k.length;p>o;++o){if(b=i.exec(k[o]))d={url:b[3],func:b[1]||L,args:b[2]?b[2].split(","):"",line:+b[4],column:b[5]?+b[5]:null};else if(b=h.exec(k[o]))d={url:b[2],func:b[1]||L,line:+b[3],column:b[4]?+b[4]:null};else{if(!(b=j.exec(k[o])))continue;d={url:b[2],func:b[1]||L,line:+b[3],column:b[4]?+b[4]:null}}!d.func&&d.line&&(d.func=e(d.url,d.line)),d.line&&(d.context=f(d.url,d.line)),m.push(d)}return m.length?(m[0].line&&!m[0].column&&n?m[0].column=l(n[1],m[0].url,m[0].line):m[0].column||g(a.columnNumber)||(m[0].column=a.columnNumber+1),{name:a.name,message:a.message,url:c(),stack:m}):null}}function p(a){var b=a.stacktrace;if(!g(a.stacktrace)&&a.stacktrace){for(var d,h=/ line (\d+), column (\d+) in (?:]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i,i=b.split("\n"),j=[],k=0,l=i.length;l>k;k+=2)if(d=h.exec(i[k])){var m={line:+d[1],column:+d[2],func:d[3]||d[4],args:d[5]?d[5].split(","):[],url:d[6]};if(!m.func&&m.line&&(m.func=e(m.url,m.line)),m.line)try{m.context=f(m.url,m.line)}catch(n){}m.context||(m.context=[i[k+1]]),j.push(m)}return j.length?{name:a.name,message:a.message,url:c(),stack:j}:null}}function q(b){var g=b.message.split("\n");if(g.length<4)return null;var h,i,l,n,o=/^\s*Line (\d+) of linked script ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,p=/^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,q=/^\s*Line (\d+) of function script\s*$/i,r=[],s=document.getElementsByTagName("script"),t=[];for(i in s)m(s,i)&&!s[i].src&&t.push(s[i]);for(i=2,l=g.length;l>i;i+=2){var u=null;if(h=o.exec(g[i]))u={url:h[2],func:h[3],line:+h[1]};else if(h=p.exec(g[i])){u={url:h[3],func:h[4]};var v=+h[1],w=t[h[2]-1];if(w&&(n=d(u.url))){n=n.join("\n");var x=n.indexOf(w.innerText);x>=0&&(u.line=v+n.substring(0,x).split("\n").length)}}else if(h=q.exec(g[i])){var y=a.location.href.replace(/#.*$/,""),z=h[1],A=new RegExp(j(g[i+1]));n=k(A,[y]),u={url:y,line:n?n.line:z,func:""}}if(u){u.func||(u.func=e(u.url,u.line));var B=f(u.url,u.line),C=B?B[Math.floor(B.length/2)]:null;B&&C.replace(/^\s*/,"")===g[i+1].replace(/^\s*/,"")?u.context=B:u.context=[g[i+1]],r.push(u)}}return r.length?{name:b.name,message:g[0],url:c(),stack:r}:null}function r(a,b,c,d){var g={url:b,line:c};if(g.url&&g.line){a.incomplete=!1,g.func||(g.func=e(g.url,g.line)),g.context||(g.context=f(g.url,g.line));var h=/ '([^']+)' /.exec(d);if(h&&(g.column=l(h[1],g.url,g.line)),a.stack.length>0&&a.stack[0].url===g.url){if(a.stack[0].line===g.line)return!1;if(!a.stack[0].line&&a.stack[0].func===g.func)return a.stack[0].line=g.line,a.stack[0].context=g.context,!1}return a.stack.unshift(g),a.partial=!0,!0}return a.incomplete=!0,!1}function s(a,b){for(var d,f,g,h=/function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,i=[],j={},k=!1,m=s.caller;m&&!k;m=m.caller)if(m!==t&&m!==J.report){if(f={url:null,func:L,line:null,column:null},m.name?f.func=m.name:(d=h.exec(m.toString()))&&(f.func=d[1]),"undefined"==typeof f.func)try{f.func=d.input.substring(0,d.input.indexOf("{"))}catch(o){}if(g=n(m)){f.url=g.url,f.line=g.line,f.func===L&&(f.func=e(f.url,f.line));var p=/ '([^']+)' /.exec(a.message||a.description);p&&(f.column=l(p[1],g.url,g.line))}j[""+m]?k=!0:j[""+m]=!0,i.push(f)}b&&i.splice(0,b);var q={name:a.name,message:a.message,url:c(),stack:i};return r(q,a.sourceURL||a.fileName,a.line||a.lineNumber,a.message||a.description),q}function t(a,b){var d=null;b=null==b?0:+b;try{if(d=p(a))return d}catch(e){if(J.debug)throw e}try{if(d=o(a))return d}catch(e){if(J.debug)throw e}try{if(d=q(a))return d}catch(e){if(J.debug)throw e}try{if(d=s(a,b+1))return d}catch(e){if(J.debug)throw e}return{name:a.name,message:a.message,url:c()}}var u={};return t.augmentStackTraceWithInitialElement=r,t.computeStackTraceFromStackProp=o,t.guessFunctionName=e,t.gatherContext=f,t}();var M,N,O,P,Q,R=a.Raven,S=!("object"!=typeof JSON||!JSON.stringify),T="undefined"!=typeof document,U={},V={logger:"javascript",ignoreErrors:[],ignoreUrls:[],whitelistUrls:[],includePaths:[],crossOrigin:"anonymous",collectWindowErrors:!0,maxMessageLength:100},W=!1,X=Object.prototype,Y=a.console||{},Z={},$=[],_=v();for(var aa in Y)Z[aa]=Y[aa];var ba={VERSION:"2.0.0-rc1",debug:!1,noConflict:function(){return a.Raven=R,ba},config:function(a,b){if(O)return F("error","Error: Raven has already been configured"),ba;if(!a)return ba;var c=f(a),d=c.path.lastIndexOf("/"),e=c.path.substr(1,d);return b&&n(b,function(a,b){"tags"==a||"extra"==a?U[a]=b:V[a]=b}),V.ignoreErrors.push(/^Script error\.?$/),V.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/),V.ignoreErrors=D(V.ignoreErrors),V.ignoreUrls=V.ignoreUrls.length?D(V.ignoreUrls):!1,V.whitelistUrls=V.whitelistUrls.length?D(V.whitelistUrls):!1,V.includePaths=D(V.includePaths),P=c.user,Q=c.path.substr(d+1),O="//"+c.host+(c.port?":"+c.port:"")+"/"+e+"api/"+Q+"/store/",c.protocol&&"app.getsentry.com"!==c.host&&(O=c.protocol+":"+O),V.fetchContext&&(J.remoteFetching=!0),V.linesOfContext&&(J.linesOfContext=V.linesOfContext),J.collectWindowErrors=!!V.collectWindowErrors,ba},install:function(){return C()&&!W&&(J.report.subscribe(o),n($,function(a,b){b()}),W=!0),ba},context:function(a,c,d){return h(a)&&(d=c||[],c=a,a=b),ba.wrap(a,c).apply(this,d)},wrap:function(a,c){function d(){for(var b=[],d=arguments.length,e=!a||a&&a.deep!==!1;d--;)b[d]=e?ba.wrap(a,arguments[d]):arguments[d];try{return c.apply(this,b)}catch(f){throw ba.captureException(f,a),f}}if(g(c)&&!h(a))return a;if(h(a)&&(c=a,a=b),!h(c))return c;if(c.__raven__)return c;for(var e in c)m(c,e)&&(d[e]=c[e]);return d.prototype=c.prototype,d.__raven__=!0,d.__inner__=c,d},uninstall:function(){return J.report.uninstall(),W=!1,ba},captureException:function(a,b){if(!l(a))return ba.captureMessage(a,b);M=a;try{var c=J.computeStackTrace(a);o(c,b)}catch(d){if(a!==d)throw d}return ba},captureMessage:function(a,b){return V.ignoreErrors.test&&V.ignoreErrors.test(a)?void 0:(x(s({message:a+""},b)),ba)},addPlugin:function(a){return $.push(a),W&&a(),ba},setUserContext:function(a){return U.user=a,ba},setExtraContext:function(a){return I("extra",a),ba},setTagsContext:function(a){return I("tags",a),ba},clearContext:function(){return U={},ba},getContext:function(){return JSON.parse(JSON.stringify(U))},setRelease:function(a){return V.release=a,ba},setDataCallback:function(a){return V.dataCallback=a,ba},setShouldSendCallback:function(a){return V.shouldSendCallback=a,ba},setTransport:function(a){return V.transport=a,ba},lastException:function(){return M},lastEventId:function(){return N},isSetup:function(){return C()}};ba.setUser=ba.setUserContext,ba.setReleaseContext=ba.setRelease;var ca="source protocol user pass host port path".split(" "),da=/^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/;e.prototype=new Error,e.prototype.constructor=e;var ea;G(),a.Raven=ba,"function"==typeof define&&define.amd?define("raven",[],function(){return ba}):"object"==typeof module?module.exports=ba:"object"==typeof exports&&(exports=ba)}("undefined"!=typeof window?window:this); //# sourceMappingURL=raven.min.map \ No newline at end of file diff --git a/dist/raven.min.map b/dist/raven.min.map index 96e148df5907..a39dbf3ce15a 100644 --- a/dist/raven.min.map +++ b/dist/raven.min.map @@ -1 +1 @@ -{"version":3,"file":"raven.min.js","sources":["raven.js"],"names":["window","undefined","getLocationHref","document","location","href","triggerEvent","eventType","options","evt","key","hasDocument","substr","toUpperCase","createEvent","initEvent","createEventObject","hasKey","dispatchEvent","fireEvent","toLowerCase","e","RavenConfigError","message","this","name","parseDSN","str","m","dsnPattern","exec","dsn","i","dsnKeys","pass","isUndefined","what","isFunction","isString","objectPrototype","toString","call","isObject","isEmptyObject","k","isError","Error","object","hasOwnProperty","each","obj","callback","j","length","handleStackInfo","stackInfo","frames","stack","frame","normalizeFrame","push","processException","url","lineno","normalized","filename","line","colno","column","function","func","context","extractContextFromFrame","keys","in_app","globalOptions","includePaths","test","fetchContext","pivot","isMinified","slice","type","fileurl","stacktrace","fullMessage","ignoreErrors","reverse","ignoreUrls","whitelistUrls","send","objectMerge","exception","values","value","culprit","obj1","obj2","truncate","max","trimPacket","data","maxMessageLength","now","Date","getHttpData","httpData","headers","User-Agent","navigator","userAgent","referrer","Referer","baseData","project","globalProject","logger","platform","request","tags","globalContext","extra","startTime","user","release","serverName","server_name","dataCallback","shouldSendCallback","lastEventId","event_id","uuid4","logDebug","isSetup","transport","makeRequest","globalServer","auth","sentry_version","sentry_client","Raven","VERSION","sentry_key","globalKey","onSuccess","src","onError","opts","sentry_data","JSON","stringify","img","newImage","urlencode","crossOrigin","onload","onerror","onabort","createElement","hasJSON","ravenNotConfiguredError","joinRegExp","patterns","pattern","sources","len","replace","source","RegExp","join","crypto","msCrypto","getRandomValues","arr","Uint16Array","pad","num","v","c","r","Math","random","level","originalConsoleMethods","debug","apply","originalConsole","_slice","arguments","afterLoad","RavenConfig","config","install","o","pairs","encodeURIComponent","mergeContext","TraceKit","remoteFetching","collectWindowErrors","linesOfContext","UNKNOWN_FUNCTION","report","subscribe","handler","installGlobalHandler","handlers","unsubscribe","splice","unsubscribeAll","uninstallGlobalHandler","notifyHandlers","isWindowError","concat","inner","traceKitWindowOnError","lineNo","colNo","ex","lastExceptionStack","computeStackTrace","augmentStackTraceWithInitialElement","processLastException","guessFunctionName","gatherContext","_oldOnerrorHandler","_onErrorHandlerInstalled","_lastExceptionStack","_lastArgs","lastArgs","lastException","rethrow","args","setTimeout","incomplete","uninstall","loadSource","getXHR","XMLHttpRequest","ActiveXObject","open","responseText","getSource","sourceCache","domain","indexOf","split","reFunctionArgNames","reGuessFunction","maxLines","linesBefore","floor","linesAfter","start","end","min","escapeRegExp","text","escapeCodeAsRegExpForMatchingInsideHTML","body","findSourceInUrls","re","urls","substring","index","lastIndexOf","findSourceInLine","fragment","findSourceByFunctionBody","parts","result","scripts","getElementsByTagName","code","codeRE","eventRE","script","event","computeStackTraceFromStackProp","element","chrome","gecko","winjs","lines","reference","columnNumber","computeStackTraceFromStacktraceProp","testRE","exc","computeStackTraceFromOperaMultiLineMessage","lineRE1","lineRE2","lineRE3","inlineScriptBlocks","item","relativeLine","pos","innerText","midline","initial","unshift","partial","computeStackTraceByWalkingCallerChain","depth","functionName","funcs","recursion","curr","caller","input","description","sourceURL","fileName","lineNumber","lastCapturedException","_Raven","isRavenInstalled","Object","prototype","console","plugins","method","noConflict","uri","lastSlash","path","host","port","protocol","_","plugin","wrap","wrapped","deep","captureException","__raven__","property","__inner__","captureMessage","ex1","msg","addPlugin","setUserContext","setExtraContext","setTagsContext","clearContext","getContext","parse","setRelease","setDataCallback","setShouldSendCallback","setTransport","setUser","setReleaseContext","constructor","define","amd","module","exports"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"raven.min.js","sources":["raven.js"],"names":["window","undefined","getLocationHref","document","location","href","triggerEvent","eventType","options","evt","key","hasDocument","substr","toUpperCase","createEvent","initEvent","createEventObject","hasKey","dispatchEvent","fireEvent","toLowerCase","e","RavenConfigError","message","this","name","parseDSN","str","m","dsnPattern","exec","dsn","i","dsnKeys","pass","isUndefined","what","isFunction","isString","objectPrototype","toString","call","isObject","isEmptyObject","k","isError","Error","object","hasOwnProperty","each","obj","callback","j","length","handleStackInfo","stackInfo","frames","stack","frame","normalizeFrame","push","processException","url","lineno","normalized","filename","line","colno","column","function","func","context","extractContextFromFrame","keys","in_app","globalOptions","includePaths","test","fetchContext","pivot","isMinified","slice","type","fileurl","stacktrace","fullMessage","ignoreErrors","reverse","ignoreUrls","whitelistUrls","send","objectMerge","exception","values","value","culprit","obj1","obj2","truncate","max","trimPacket","data","maxMessageLength","now","Date","getHttpData","httpData","headers","User-Agent","navigator","userAgent","referrer","Referer","baseData","project","globalProject","logger","platform","request","tags","globalContext","extra","startTime","user","release","serverName","server_name","dataCallback","shouldSendCallback","lastEventId","event_id","uuid4","logDebug","isSetup","transport","makeRequest","globalServer","auth","sentry_version","sentry_client","Raven","VERSION","sentry_key","globalKey","onSuccess","src","onError","makeImageRequest","opts","sentry_data","JSON","stringify","img","newImage","urlencode","crossOrigin","onload","onerror","onabort","makeXhrRequest","handler","status","XMLHttpRequest","onreadystatechange","readyState","XDomainRequest","open","hasCORS","createElement","hasJSON","ravenNotConfiguredError","joinRegExp","patterns","pattern","sources","len","replace","source","RegExp","join","crypto","msCrypto","getRandomValues","arr","Uint16Array","pad","num","v","c","r","Math","random","level","originalConsoleMethods","debug","apply","originalConsole","_slice","arguments","afterLoad","RavenConfig","config","install","o","pairs","encodeURIComponent","mergeContext","TraceKit","remoteFetching","collectWindowErrors","linesOfContext","UNKNOWN_FUNCTION","report","subscribe","installGlobalHandler","handlers","unsubscribe","splice","unsubscribeAll","uninstallGlobalHandler","notifyHandlers","isWindowError","concat","inner","traceKitWindowOnError","lineNo","colNo","ex","lastExceptionStack","computeStackTrace","augmentStackTraceWithInitialElement","processLastException","guessFunctionName","gatherContext","_oldOnerrorHandler","_onErrorHandlerInstalled","_lastExceptionStack","_lastArgs","lastArgs","lastException","rethrow","args","setTimeout","incomplete","uninstall","loadSource","getXHR","ActiveXObject","responseText","getSource","sourceCache","domain","indexOf","split","reFunctionArgNames","reGuessFunction","maxLines","linesBefore","floor","linesAfter","start","end","min","escapeRegExp","text","escapeCodeAsRegExpForMatchingInsideHTML","body","findSourceInUrls","re","urls","substring","index","lastIndexOf","findSourceInLine","fragment","findSourceByFunctionBody","parts","result","scripts","getElementsByTagName","code","codeRE","eventRE","script","event","computeStackTraceFromStackProp","element","chrome","gecko","winjs","lines","reference","columnNumber","computeStackTraceFromStacktraceProp","testRE","exc","computeStackTraceFromOperaMultiLineMessage","lineRE1","lineRE2","lineRE3","inlineScriptBlocks","item","relativeLine","pos","innerText","midline","initial","unshift","partial","computeStackTraceByWalkingCallerChain","depth","functionName","funcs","recursion","curr","caller","input","description","sourceURL","fileName","lineNumber","lastCapturedException","_Raven","isRavenInstalled","Object","prototype","console","plugins","method","noConflict","uri","lastSlash","path","host","port","protocol","_","plugin","wrap","wrapped","deep","captureException","__raven__","property","__inner__","captureMessage","ex1","msg","addPlugin","setUserContext","setExtraContext","setTagsContext","clearContext","getContext","parse","setRelease","setDataCallback","setShouldSendCallback","setTransport","setUser","setReleaseContext","constructor","define","amd","module","exports"],"mappings":"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"} \ No newline at end of file diff --git a/dist/sri.json b/dist/sri.json index 9f191a50a1f9..8dfbcd881790 100644 --- a/dist/sri.json +++ b/dist/sri.json @@ -1,20 +1,20 @@ { "@dist/raven.js": { "hashes": { - "sha256": "5UE4fab406RSte0iFIx9VVy0L7JRxE9kGErS7lDIWkk=", - "sha512": "0srxulL0vd6Ydesh7zWvsdiYPgZYXPHIvuJBA07d10bcin20FURPxGQwk57o4iM2yY/JjSDYOVhas7hhHs5e1Q==" + "sha256": "Zkhgh2p6T82np/UXEwH1kZ4fZEDWmG8xT1UlHr4Tmbw=", + "sha512": "yJAc3bpE733agfFrrPpngIGNL/FIj2/eXSGYKlfSunuTP154SUzVgEdAIwQJWu6+j6Y2pWlRw4kQAQ6oM8TMKg==" }, "type": null, - "integrity": "sha256-5UE4fab406RSte0iFIx9VVy0L7JRxE9kGErS7lDIWkk= sha512-0srxulL0vd6Ydesh7zWvsdiYPgZYXPHIvuJBA07d10bcin20FURPxGQwk57o4iM2yY/JjSDYOVhas7hhHs5e1Q==", + "integrity": "sha256-Zkhgh2p6T82np/UXEwH1kZ4fZEDWmG8xT1UlHr4Tmbw= sha512-yJAc3bpE733agfFrrPpngIGNL/FIj2/eXSGYKlfSunuTP154SUzVgEdAIwQJWu6+j6Y2pWlRw4kQAQ6oM8TMKg==", "path": "dist/raven.js" }, "@dist/raven.min.js": { "hashes": { - "sha256": "aL/V92cKCaVImsInedZ+GWsqlMT9a1vzIQEa5gpYiPc=", - "sha512": "kbzPX17iHEbbs6sBh6TPlkZv8sf2IRGElHAnvXVpktSaKx6JF8TlTDfKP1IF3FP1EdafBrkjY778lWcmUifODQ==" + "sha256": "MhFwOXgkBzPqNA8nau0NIugp5f+ScSrGmJQ87XOrPJE=", + "sha512": "g9daZLbslcitp9sYD3i4zBlabtv0EGkZZNSMlUP1kfhafSnIaQI4FuMvZBCkF7rx9FfieVJg9ZVoTUwMynhHYA==" }, "type": null, - "integrity": "sha256-aL/V92cKCaVImsInedZ+GWsqlMT9a1vzIQEa5gpYiPc= sha512-kbzPX17iHEbbs6sBh6TPlkZv8sf2IRGElHAnvXVpktSaKx6JF8TlTDfKP1IF3FP1EdafBrkjY778lWcmUifODQ==", + "integrity": "sha256-MhFwOXgkBzPqNA8nau0NIugp5f+ScSrGmJQ87XOrPJE= sha512-g9daZLbslcitp9sYD3i4zBlabtv0EGkZZNSMlUP1kfhafSnIaQI4FuMvZBCkF7rx9FfieVJg9ZVoTUwMynhHYA==", "path": "dist/raven.min.js" } } \ No newline at end of file diff --git a/package.json b/package.json index 9ccf2f1ce263..fb9e4976fb6e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "raven-js", - "version": "1.3.0", + "version": "2.0.0-rc1", "license": "BSD-2-Clause", "homepage": "https://getsentry.com", "scripts": { @@ -11,10 +11,11 @@ "type": "git", "url": "git://github.com/getsentry/raven-js.git" }, - "main": "dist/raven.js", + "main": "src/singleton.js", "devDependencies": { "chai": "~1.8.1", "grunt": "^0.4.5", + "grunt-browserify": "^4.0.1", "grunt-cli": "~0.1.9", "grunt-contrib-clean": "~0.4.0", "grunt-contrib-concat": "~0.3.0", @@ -29,7 +30,9 @@ "grunt-sri": "mattrobenolt/grunt-sri#pretty", "jquery": "^2.1.4", "lodash": "~2.4.0", - "sinon": "~1.7.3" + "proxyquireify": "^3.0.0", + "sinon": "~1.7.3", + "through2": "^2.0.0" }, "keywords": [ "exceptions", diff --git a/plugins/angular.js b/plugins/angular.js index dd929f5cddeb..4b4cff987554 100644 --- a/plugins/angular.js +++ b/plugins/angular.js @@ -3,60 +3,58 @@ * * Provides an $exceptionHandler for Angular.js */ -;(function(window) { 'use strict'; -var angular = window.angular, - Raven = window.Raven; +// See https://github.com/angular/angular.js/blob/v1.4.7/src/minErr.js +var angularPattern = /^\[((?:[$a-zA-Z0-9]+:)?(?:[$a-zA-Z0-9]+))\] (.+?)\n(\S+)$/; -// quit if angular isn't on the page -if (!(angular && Raven)) return; +function angularPlugin(Raven, angular) { + /*jshint validthis:true*/ + angular = angular || window.angular; -function RavenProvider() { - this.$get = ['$window', function($window, $log) { - return $window.Raven; - }]; -} + if (!angular) return; -function ExceptionHandlerProvider($provide) { - $provide.decorator('$exceptionHandler', - ['Raven', '$delegate', exceptionHandler]); -} + function RavenProvider() { + this.$get = ['$window', function($window) { + return Raven; + }]; + } -function exceptionHandler(Raven, $delegate) { - return function (ex, cause) { - Raven.captureException(ex, { - extra: { cause: cause } - }); - $delegate(ex, cause); - }; -} + function ExceptionHandlerProvider($provide) { + $provide.decorator('$exceptionHandler', + ['Raven', '$delegate', exceptionHandler]); + } -// See https://github.com/angular/angular.js/blob/v1.4.7/src/minErr.js -var angularPattern = /^\[((?:[$a-zA-Z0-9]+:)?(?:[$a-zA-Z0-9]+))\] (.+?)\n(\S+)$/; + function exceptionHandler(Raven, $delegate) { + return function (ex, cause) { + Raven.captureException(ex, { + extra: { cause: cause } + }); + $delegate(ex, cause); + }; + } -Raven.addPlugin(function () { angular.module('ngRaven', []) .provider('Raven', RavenProvider) .config(['$provide', ExceptionHandlerProvider]); -}); - -Raven.setDataCallback(function(data) { - // We only care about mutating an exception - var exception = data.exception; - if (exception) { - exception = exception.values[0]; - var matches = angularPattern.exec(exception.value); - - if (matches) { - // This type now becomes something like: $rootScope:inprog - exception.type = matches[1]; - exception.value = matches[2]; - data.message = exception.type + ': ' + exception.value; - // auto set a new tag specifically for the angular error url - data.extra.angularDocs = matches[3].substr(0, 250); + + Raven.setDataCallback(function(data) { + // We only care about mutating an exception + var exception = data.exception; + if (exception) { + exception = exception.values[0]; + var matches = angularPattern.exec(exception.value); + + if (matches) { + // This type now becomes something like: $rootScope:inprog + exception.type = matches[1]; + exception.value = matches[2]; + data.message = exception.type + ': ' + exception.value; + // auto set a new tag specifically for the angular error url + data.extra.angularDocs = matches[3].substr(0, 250); + } } - } -}); + }); +} -}(typeof window !== 'undefined' ? window : this)); +module.exports = angularPlugin; diff --git a/plugins/backbone.js b/plugins/backbone.js index 6e6b64c2b034..6c777688b1f5 100644 --- a/plugins/backbone.js +++ b/plugins/backbone.js @@ -3,57 +3,54 @@ * * Patches Backbone.Events callbacks. */ -;(function(window) { 'use strict'; -if (window.Raven) Raven.addPlugin(function backbonePlugin() { +function backbonePlugin(Raven, Backbone) { + Backbone = Backbone || window.Backbone; -var Backbone = window.Backbone; + // quit if Backbone isn't on the page + if (!Backbone) return; -// quit if Backbone isn't on the page -if (!Backbone) return; - -function makeBackboneEventsOn(oldOn) { - return function BackboneEventsOn(name, callback, context) { - var wrapCallback = function (cb) { - if (Object.prototype.toString.call(cb) === '[object Function]') { - var _callback = cb._callback || cb; - cb = Raven.wrap(cb); - cb._callback = _callback; - } - return cb; - }; - if (Object.prototype.toString.call(name) === '[object Object]') { - // Handle event maps. - for (var key in name) { - if (name.hasOwnProperty(key)) { - name[key] = wrapCallback(name[key]); + function makeBackboneEventsOn(oldOn) { + return function BackboneEventsOn(name, callback, context) { + var wrapCallback = function (cb) { + if (Object.prototype.toString.call(cb) === '[object Function]') { + var _callback = cb._callback || cb; + cb = Raven.wrap(cb); + cb._callback = _callback; } + return cb; + }; + if (Object.prototype.toString.call(name) === '[object Object]') { + // Handle event maps. + for (var key in name) { + if (name.hasOwnProperty(key)) { + name[key] = wrapCallback(name[key]); + } + } + } else { + callback = wrapCallback(callback); } - } else { - callback = wrapCallback(callback); - } - return oldOn.call(this, name, callback, context); - }; -} - -// We're too late to catch all of these by simply patching Backbone.Events.on -var affectedObjects = [ - Backbone.Events, - Backbone, - Backbone.Model.prototype, - Backbone.Collection.prototype, - Backbone.View.prototype, - Backbone.Router.prototype, - Backbone.History.prototype -], i = 0, l = affectedObjects.length; - -for (; i < l; i++) { - var affected = affectedObjects[i]; - affected.on = makeBackboneEventsOn(affected.on); - affected.bind = affected.on; + return oldOn.call(this, name, callback, context); + }; + } + + // We're too late to catch all of these by simply patching Backbone.Events.on + var affectedObjects = [ + Backbone.Events, + Backbone, + Backbone.Model.prototype, + Backbone.Collection.prototype, + Backbone.View.prototype, + Backbone.Router.prototype, + Backbone.History.prototype + ], i = 0, l = affectedObjects.length; + + for (; i < l; i++) { + var affected = affectedObjects[i]; + affected.on = makeBackboneEventsOn(affected.on); + affected.bind = affected.on; + } } -}); - -}(typeof window !== 'undefined' ? window : this)); +module.exports = backbonePlugin; diff --git a/plugins/console.js b/plugins/console.js index c3e098a72e4e..3f2b14a4966f 100644 --- a/plugins/console.js +++ b/plugins/console.js @@ -4,49 +4,41 @@ * Monkey patches console.* calls into Sentry messages with * their appropriate log levels. (Experimental) */ -;(function(window) { 'use strict'; -if (window.Raven) Raven.addPlugin(function ConsolePlugin() { - -var console = window.console || {}; - -var originalConsole = console, - logLevels = ['debug', 'info', 'warn', 'error'], - level = logLevels.pop(); - -var logForGivenLevel = function(level) { - var originalConsoleLevel = console[level]; - - // warning level is the only level that doesn't map up - // correctly with what Sentry expects. - if (level === 'warn') level = 'warning'; - return function () { - var args = [].slice.call(arguments); - Raven.captureMessage('' + args[0], {level: level, logger: 'console', extra: { 'arguments': args }}); - - // this fails for some browsers. :( - if (originalConsoleLevel) { - // IE9 doesn't allow calling apply on console functions directly - // See: https://stackoverflow.com/questions/5472938/does-ie9-support-console-log-and-is-it-a-real-function#answer-5473193 - Function.prototype.bind - .call(originalConsoleLevel, originalConsole) - .apply(originalConsole, args); - } +function consolePlugin(Raven, console) { + console = console || window.console || {}; + + var originalConsole = console, + logLevels = ['debug', 'info', 'warn', 'error'], + level = logLevels.pop(); + + var logForGivenLevel = function(level) { + var originalConsoleLevel = console[level]; + + // warning level is the only level that doesn't map up + // correctly with what Sentry expects. + if (level === 'warn') level = 'warning'; + return function () { + var args = [].slice.call(arguments); + Raven.captureMessage('' + args[0], {level: level, logger: 'console', extra: { 'arguments': args }}); + + // this fails for some browsers. :( + if (originalConsoleLevel) { + // IE9 doesn't allow calling apply on console functions directly + // See: https://stackoverflow.com/questions/5472938/does-ie9-support-console-log-and-is-it-a-real-function#answer-5473193 + Function.prototype.bind + .call(originalConsoleLevel, originalConsole) + .apply(originalConsole, args); + } + }; }; -}; -while(level) { - console[level] = logForGivenLevel(level); - level = logLevels.pop(); + while(level) { + console[level] = logForGivenLevel(level); + level = logLevels.pop(); + } } -// export -window.console = console; - -// End of plugin factory -}); - -// console would require `window`, so we don't allow it to be optional -}(window)); +module.exports = consolePlugin; diff --git a/plugins/ember.js b/plugins/ember.js index 3d669fad9d6a..fd58c590f262 100644 --- a/plugins/ember.js +++ b/plugins/ember.js @@ -3,32 +3,29 @@ * * Patches event handler callbacks and ajax callbacks. */ -;(function(window) { 'use strict'; -if (window.Raven) Raven.addPlugin(function EmberPlugin() { +function emberPlugin(Raven, Ember) { + /*jshint validthis:true*/ + Ember = Ember || window.Ember; -var Ember = window.Ember; + // quit if Ember isn't on the page + if (!Ember) return; -// quit if Ember isn't on the page -if (!Ember) return; + var _oldOnError = Ember.onerror; + Ember.onerror = function EmberOnError(error) { + Raven.captureException(error); + if (typeof _oldOnError === 'function') { + _oldOnError.call(this, error); + } + }; + Ember.RSVP.on('error', function (reason) { + if (reason instanceof Error) { + Raven.captureException(reason, {extra: {context: 'Unhandled Promise error detected'}}); + } else { + Raven.captureMessage('Unhandled Promise error detected', {extra: {reason: reason}}); + } + }); +} -var _oldOnError = Ember.onerror; -Ember.onerror = function EmberOnError(error) { - Raven.captureException(error); - if (typeof _oldOnError === 'function') { - _oldOnError.call(this, error); - } -}; -Ember.RSVP.on('error', function (reason) { - if (reason instanceof Error) { - Raven.captureException(reason, {extra: {context: 'Unhandled Promise error detected'}}); - } else { - Raven.captureMessage('Unhandled Promise error detected', {extra: {reason: reason}}); - } -}); - -// End of plugin factory -}); - -}(typeof window !== 'undefined' ? window : this)); +module.exports = emberPlugin; diff --git a/plugins/jquery.js b/plugins/jquery.js index 63203f5329c6..34fa47566d7c 100644 --- a/plugins/jquery.js +++ b/plugins/jquery.js @@ -3,106 +3,103 @@ * * Patches event handler callbacks and ajax callbacks. */ -;(function(window) { 'use strict'; -if (window.Raven) Raven.addPlugin(function jQueryPlugin() { - -var $ = window.jQuery; - -// quit if jQuery isn't on the page -if (!$) return; - -var _oldEventAdd = $.event.add; -$.event.add = function ravenEventAdd(elem, types, handler, data, selector) { - var _handler; - - if (handler && handler.handler) { - _handler = handler.handler; - handler.handler = Raven.wrap(handler.handler); - } else { - _handler = handler; - handler = Raven.wrap(handler); - } - - // If the handler we are attaching doesn’t have the same guid as - // the original, it will never be removed when someone tries to - // unbind the original function later. Technically as a result of - // this our guids are no longer globally unique, but whatever, that - // never hurt anybody RIGHT?! - if (_handler.guid) { - handler.guid = _handler.guid; - } else { - handler.guid = _handler.guid = $.guid++; - } - - return _oldEventAdd.call(this, elem, types, handler, data, selector); -}; - -var _oldReady = $.fn.ready; -$.fn.ready = function ravenjQueryReadyWrapper(fn) { - return _oldReady.call(this, Raven.wrap(fn)); -}; - -var _oldAjax = $.ajax; -$.ajax = function ravenAjaxWrapper(url, options) { - var keys = ['complete', 'error', 'success'], key; - - // Taken from https://github.com/jquery/jquery/blob/eee2eaf1d7a189d99106423a4206c224ebd5b848/src/ajax.js#L311-L318 - // If url is an object, simulate pre-1.5 signature - if (typeof url === 'object') { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - /*jshint -W084*/ - while (key = keys.pop()) { - if ($.isFunction(options[key])) { - options[key] = Raven.wrap(options[key]); +function jQueryPlugin(Raven, jQuery) { + /*jshint validthis:true*/ + var $ = jQuery || window.jQuery; + + // quit if jQuery isn't on the page + if (!$) return; + + var _oldEventAdd = $.event.add; + $.event.add = function ravenEventAdd(elem, types, handler, data, selector) { + var _handler; + + if (handler && handler.handler) { + _handler = handler.handler; + handler.handler = Raven.wrap(handler.handler); + } else { + _handler = handler; + handler = Raven.wrap(handler); } - } - /*jshint +W084*/ - - try { - var jqXHR = _oldAjax.call(this, url, options); - // jqXHR.complete is not a regular deferred callback - if ($.isFunction(jqXHR.complete)) - jqXHR.complete = Raven.wrap(jqXHR.complete); - return jqXHR; - } catch (e) { - Raven.captureException(e); - throw e; - } -}; - -var _oldDeferred = $.Deferred; -$.Deferred = function ravenDeferredWrapper(func) { - return !_oldDeferred ? null : _oldDeferred(function beforeStartWrapper(deferred) { - var methods = ['resolve', 'reject', 'notify', 'resolveWith', 'rejectWith', 'notifyWith'], method; - - // since jQuery 1.9, deferred[resolve | reject | notify] are calling internally - // deferred[resolveWith | rejectWith | notifyWith] but we need to wrap them as well - // to support all previous versions. + + // If the handler we are attaching doesn’t have the same guid as + // the original, it will never be removed when someone tries to + // unbind the original function later. Technically as a result of + // this our guids are no longer globally unique, but whatever, that + // never hurt anybody RIGHT?! + if (_handler.guid) { + handler.guid = _handler.guid; + } else { + handler.guid = _handler.guid = $.guid++; + } + + return _oldEventAdd.call(this, elem, types, handler, data, selector); + }; + + var _oldReady = $.fn.ready; + $.fn.ready = function ravenjQueryReadyWrapper(fn) { + return _oldReady.call(this, Raven.wrap(fn)); + }; + + var _oldAjax = $.ajax; + $.ajax = function ravenAjaxWrapper(url, options) { + var keys = ['complete', 'error', 'success'], key; + + // Taken from https://github.com/jquery/jquery/blob/eee2eaf1d7a189d99106423a4206c224ebd5b848/src/ajax.js#L311-L318 + // If url is an object, simulate pre-1.5 signature + if (typeof url === 'object') { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; /*jshint -W084*/ - while (method = methods.pop()) { - if ($.isFunction(deferred[method])) { - deferred[method] = Raven.wrap(deferred[method]); + while (key = keys.pop()) { + if ($.isFunction(options[key])) { + options[key] = Raven.wrap(options[key]); } } /*jshint +W084*/ - // Call given func if any - if (func) { - func.call(deferred, deferred); + try { + var jqXHR = _oldAjax.call(this, url, options); + // jqXHR.complete is not a regular deferred callback + if ($.isFunction(jqXHR.complete)) + jqXHR.complete = Raven.wrap(jqXHR.complete); + return jqXHR; + } catch (e) { + Raven.captureException(e); + throw e; } - }); -}; + }; + + var _oldDeferred = $.Deferred; + $.Deferred = function ravenDeferredWrapper(func) { + return !_oldDeferred ? null : _oldDeferred(function beforeStartWrapper(deferred) { + var methods = ['resolve', 'reject', 'notify', 'resolveWith', 'rejectWith', 'notifyWith'], method; + + // since jQuery 1.9, deferred[resolve | reject | notify] are calling internally + // deferred[resolveWith | rejectWith | notifyWith] but we need to wrap them as well + // to support all previous versions. + + /*jshint -W084*/ + while (method = methods.pop()) { + if ($.isFunction(deferred[method])) { + deferred[method] = Raven.wrap(deferred[method]); + } + } + /*jshint +W084*/ -// End of plugin factory -}); + // Call given func if any + if (func) { + func.call(deferred, deferred); + } + }); + }; +} -}(typeof window !== 'undefined' ? window : this)); +module.exports = jQueryPlugin; diff --git a/plugins/native.js b/plugins/native.js index bf8b7e6d9b83..d78cb505d12f 100644 --- a/plugins/native.js +++ b/plugins/native.js @@ -4,35 +4,31 @@ * Extends support for global error handling for asynchronous browser * functions. Adopted from Closure Library's errorhandler.js. */ -;(function(window) { 'use strict'; -if (window.Raven) Raven.addPlugin(function nativePlugin() { - -var _helper = function _helper(fnName) { - var originalFn = window[fnName]; - window[fnName] = function ravenAsyncExtension() { - // Make a copy of the arguments - var args = [].slice.call(arguments); - var originalCallback = args[0]; - if (typeof (originalCallback) === 'function') { - args[0] = Raven.wrap(originalCallback); - } - // IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it - // also supports only two arguments and doesn't care what this is, so we - // can just call the original function directly. - if (originalFn.apply) { - return originalFn.apply(this, args); - } else { - return originalFn(args[0], args[1]); - } +function nativePlugin(Raven) { + var _helper = function _helper(fnName) { + var originalFn = window[fnName]; + window[fnName] = function ravenAsyncExtension() { + // Make a copy of the arguments + var args = [].slice.call(arguments); + var originalCallback = args[0]; + if (typeof (originalCallback) === 'function') { + args[0] = Raven.wrap(originalCallback); + } + // IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it + // also supports only two arguments and doesn't care what this is, so we + // can just call the original function directly. + if (originalFn.apply) { + return originalFn.apply(this, args); + } else { + return originalFn(args[0], args[1]); + } + }; }; -}; - -_helper('setTimeout'); -_helper('setInterval'); -// End of plugin factory -}); + _helper('setTimeout'); + _helper('setInterval'); +} -}(typeof window !== 'undefined' ? window : this)); +module.exports = nativePlugin; diff --git a/plugins/react-native.js b/plugins/react-native.js index 80ff300c9eea..1ce887f97eb3 100644 --- a/plugins/react-native.js +++ b/plugins/react-native.js @@ -7,19 +7,16 @@ * var Raven = require('raven-js'); * require('raven-js/plugins/react-native')(Raven); */ +'use strict'; var DEVICE_PATH_RE = /^\/var\/mobile\/Containers\/Bundle\/Application\/[^\/]+\/[^\.]+\.app/; function normalizeUrl(url) { - "use strict"; - return url .replace(/^file\:\/\//, '') .replace(DEVICE_PATH_RE, ''); } -module.exports = function (Raven) { - "use strict"; - +function reactNativePlugin(Raven) { function urlencode(obj) { var pairs = []; for (var key in obj) { @@ -73,4 +70,6 @@ module.exports = function (Raven) { }); ErrorUtils.setGlobalHandler(Raven.captureException); -}; +} + +module.exports = reactNativePlugin; diff --git a/plugins/require.js b/plugins/require.js index 768a935b2ff5..71eddb284ba2 100644 --- a/plugins/require.js +++ b/plugins/require.js @@ -1,19 +1,16 @@ +/*global define*/ /** * require.js plugin * * Automatically wrap define/require callbacks. (Experimental) */ -;(function(window) { 'use strict'; -if (window.Raven) Raven.addPlugin(function RequirePlugin() { - -if (typeof define === 'function' && define.amd) { - window.define = Raven.wrap({deep: false}, define); - window.require = Raven.wrap({deep: false}, require); +function requirePlugin(Raven) { + if (typeof define === 'function' && define.amd) { + window.define = Raven.wrap({deep: false}, define); + window.require = Raven.wrap({deep: false}, require); + } } -// End of plugin factory -}); - -}(window)); +module.exports = requirePlugin; diff --git a/src/configError.js b/src/configError.js new file mode 100644 index 000000000000..bb48808f0b77 --- /dev/null +++ b/src/configError.js @@ -0,0 +1,10 @@ +'use strict'; + +function RavenConfigError(message) { + this.name = 'RavenConfigError'; + this.message = message; +} +RavenConfigError.prototype = new Error(); +RavenConfigError.prototype.constructor = RavenConfigError; + +module.exports = RavenConfigError; diff --git a/src/raven.js b/src/raven.js index 77964b91b732..52c1d054196c 100644 --- a/src/raven.js +++ b/src/raven.js @@ -1,19 +1,43 @@ +/*global XDomainRequest:false*/ 'use strict'; +var TraceKit = require('../vendor/TraceKit/tracekit'); +var RavenConfigError = require('./configError'); +var utils = require('./utils'); + +var isFunction = utils.isFunction; +var isUndefined = utils.isUndefined; +var isError = utils.isError; +var isEmptyObject = utils.isEmptyObject; +var hasKey = utils.hasKey; +var joinRegExp = utils.joinRegExp; +var each = utils.each; +var objectMerge = utils.objectMerge; +var truncate = utils.truncate; +var urlencode = utils.urlencode; +var uuid4 = utils.uuid4; + +var dsnKeys = 'source protocol user pass host port path'.split(' '), + dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/; + +function now() { + return +new Date(); +} + // First, check for JSON support // If there is no JSON, we no-op the core features of Raven // since JSON is required to encode the payload -var _Raven = window.Raven, - hasJSON = !!(typeof JSON === 'object' && JSON.stringify), +function Raven() { + this._hasJSON = !!(typeof JSON === 'object' && JSON.stringify); // Raven can run in contexts where there's no document (react-native) - hasDocument = typeof document !== 'undefined', - lastCapturedException, - lastEventId, - globalServer, - globalKey, - globalProject, - globalContext = {}, - globalOptions = { + this._hasDocument = typeof document !== 'undefined'; + this._lastCapturedException = null; + this._lastEventId = null; + this._globalServer = null; + this._globalKey = null; + this._globalProject = null; + this._globalContext = {}; + this._globalOptions = { logger: 'javascript', ignoreErrors: [], ignoreUrls: [], @@ -22,39 +46,30 @@ var _Raven = window.Raven, crossOrigin: 'anonymous', collectWindowErrors: true, maxMessageLength: 100 - }, - isRavenInstalled = false, - objectPrototype = Object.prototype, + }; + this._isRavenInstalled = false; // capture references to window.console *and* all its methods first // before the console plugin has a chance to monkey patch - originalConsole = window.console || {}, - originalConsoleMethods = {}, - plugins = [], - startTime = now(); + this._originalConsole = window.console || {}; + this._originalConsoleMethods = {}; + this._plugins = []; + this._startTime = now(); -for (var method in originalConsole) { - originalConsoleMethods[method] = originalConsole[method]; + for (var method in this._originalConsole) { + this._originalConsoleMethods[method] = this._originalConsole[method]; + } } + /* * The core Raven singleton * * @this {Raven} */ -var Raven = { + +Raven.prototype = { VERSION: '<%= pkg.version %>', - debug: false, - - /* - * Allow multiple versions of Raven to be installed. - * Strip Raven from the global context and returns the instance. - * - * @return {Raven} - */ - noConflict: function() { - window.Raven = _Raven; - return Raven; - }, + debug: true, /* * Configure Raven with a DSN and extra options @@ -64,13 +79,15 @@ var Raven = { * @return {Raven} */ config: function(dsn, options) { - if (globalServer) { - logDebug('error', 'Error: Raven has already been configured'); - return Raven; + var self = this; + + if (this._globalServer) { + this._logDebug('error', 'Error: Raven has already been configured'); + return this; } - if (!dsn) return Raven; + if (!dsn) return this; - var uri = parseDSN(dsn), + var uri = this._parseDSN(dsn), lastSlash = uri.path.lastIndexOf('/'), path = uri.path.substr(1, lastSlash); @@ -79,48 +96,48 @@ var Raven = { each(options, function(key, value){ // tags and extra are special and need to be put into context if (key == 'tags' || key == 'extra') { - globalContext[key] = value; + self._globalContext[key] = value; } else { - globalOptions[key] = value; + self._globalOptions[key] = value; } }); } // "Script error." is hard coded into browsers for errors that it can't read. // this is the result of a script being pulled in from an external domain and CORS. - globalOptions.ignoreErrors.push(/^Script error\.?$/); - globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/); + this._globalOptions.ignoreErrors.push(/^Script error\.?$/); + this._globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/); // join regexp rules into one big rule - globalOptions.ignoreErrors = joinRegExp(globalOptions.ignoreErrors); - globalOptions.ignoreUrls = globalOptions.ignoreUrls.length ? joinRegExp(globalOptions.ignoreUrls) : false; - globalOptions.whitelistUrls = globalOptions.whitelistUrls.length ? joinRegExp(globalOptions.whitelistUrls) : false; - globalOptions.includePaths = joinRegExp(globalOptions.includePaths); + this._globalOptions.ignoreErrors = joinRegExp(this._globalOptions.ignoreErrors); + this._globalOptions.ignoreUrls = this._globalOptions.ignoreUrls.length ? joinRegExp(this._globalOptions.ignoreUrls) : false; + this._globalOptions.whitelistUrls = this._globalOptions.whitelistUrls.length ? joinRegExp(this._globalOptions.whitelistUrls) : false; + this._globalOptions.includePaths = joinRegExp(this._globalOptions.includePaths); - globalKey = uri.user; - globalProject = uri.path.substr(lastSlash + 1); + this._globalKey = uri.user; + this._globalProject = uri.path.substr(lastSlash + 1); // assemble the endpoint from the uri pieces - globalServer = '//' + uri.host + + this._globalServer = '//' + uri.host + (uri.port ? ':' + uri.port : '') + - '/' + path + 'api/' + globalProject + '/store/'; + '/' + path + 'api/' + this._globalProject + '/store/'; - if (uri.protocol) { - globalServer = uri.protocol + ':' + globalServer; + if (uri.protocol && uri.host !== 'app.getsentry.com') { + this._globalServer = uri.protocol + ':' + this._globalServer; } - if (globalOptions.fetchContext) { + if (this._globalOptions.fetchContext) { TraceKit.remoteFetching = true; } - if (globalOptions.linesOfContext) { - TraceKit.linesOfContext = globalOptions.linesOfContext; + if (this._globalOptions.linesOfContext) { + TraceKit.linesOfContext = this._globalOptions.linesOfContext; } - TraceKit.collectWindowErrors = !!globalOptions.collectWindowErrors; + TraceKit.collectWindowErrors = !!this._globalOptions.collectWindowErrors; // return for chaining - return Raven; + return this; }, /* @@ -132,18 +149,20 @@ var Raven = { * @return {Raven} */ install: function() { - if (isSetup() && !isRavenInstalled) { - TraceKit.report.subscribe(handleStackInfo); + var self = this; + if (this.isSetup() && !this._isRavenInstalled) { + TraceKit.report.subscribe(function () { + // maintain 'self' + self._handleStackInfo.apply(self, arguments); + }); // Install all of the plugins - each(plugins, function(_, plugin) { - plugin(); - }); + this._drainPlugins(); - isRavenInstalled = true; + this._isRavenInstalled = true; } - return Raven; + return this; }, /* @@ -161,7 +180,7 @@ var Raven = { options = undefined; } - return Raven.wrap(options, func).apply(this, args); + return this.wrap(options, func).apply(this, args); }, /* @@ -172,6 +191,8 @@ var Raven = { * @return {function} The newly wrapped functions with a context */ wrap: function(options, func) { + var self = this; + // 1 argument has been passed, and it's not a function // so just return it if (isUndefined(func) && !isFunction(options)) { @@ -201,13 +222,13 @@ var Raven = { // Recursively wrap all of a function's arguments that are // functions themselves. - while(i--) args[i] = deep ? Raven.wrap(options, arguments[i]) : arguments[i]; + while(i--) args[i] = deep ? self.wrap(options, arguments[i]) : arguments[i]; try { /*jshint -W040*/ return func.apply(this, args); } catch(e) { - Raven.captureException(e, options); + self.captureException(e, options); throw e; } } @@ -235,9 +256,9 @@ var Raven = { */ uninstall: function() { TraceKit.report.uninstall(); - isRavenInstalled = false; + this._isRavenInstalled = false; - return Raven; + return this; }, /* @@ -249,10 +270,10 @@ var Raven = { */ captureException: function(ex, options) { // If not an Error is passed through, recall as a message instead - if (!isError(ex)) return Raven.captureMessage(ex, options); + if (!isError(ex)) return this.captureMessage(ex, options); // Store the raw exception object for potential debugging and introspection - lastCapturedException = ex; + this._lastCapturedException = ex; // TraceKit.report will re-raise any exception passed to it, // which means you have to wrap it in try/catch. Instead, we @@ -261,14 +282,14 @@ var Raven = { // report on. try { var stack = TraceKit.computeStackTrace(ex); - handleStackInfo(stack, options); + this._handleStackInfo(stack, options); } catch(ex1) { if(ex !== ex1) { throw ex1; } } - return Raven; + return this; }, /* @@ -282,24 +303,29 @@ var Raven = { // config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an // early call; we'll error on the side of logging anything called before configuration since it's // probably something you should see: - if (!!globalOptions.ignoreErrors.test && globalOptions.ignoreErrors.test(msg)) { + if (!!this._globalOptions.ignoreErrors.test && this._globalOptions.ignoreErrors.test(msg)) { return; } // Fire away! - send( + this._send( objectMerge({ message: msg + '' // Make sure it's actually a string }, options) ); - return Raven; + return this; }, - addPlugin: function(plugin) { - plugins.push(plugin); - if (isRavenInstalled) plugin(); - return Raven; + addPlugin: function(plugin /*arg1, arg2, ... argN*/) { + var pluginArgs = Array.prototype.slice.call(arguments, 1); + + this._plugins.push([plugin, pluginArgs]); + if (this._isRavenInstalled) { + this._drainPlugins(); + } + + return this; }, /* @@ -310,9 +336,9 @@ var Raven = { */ setUserContext: function(user) { // Intentionally do not merge here since that's an unexpected behavior. - globalContext.user = user; + this._globalContext.user = user; - return Raven; + return this; }, /* @@ -322,9 +348,9 @@ var Raven = { * @return {Raven} */ setExtraContext: function(extra) { - mergeContext('extra', extra); + this._mergeContext('extra', extra); - return Raven; + return this; }, /* @@ -334,9 +360,9 @@ var Raven = { * @return {Raven} */ setTagsContext: function(tags) { - mergeContext('tags', tags); + this._mergeContext('tags', tags); - return Raven; + return this; }, /* @@ -345,9 +371,9 @@ var Raven = { * @return {Raven} */ clearContext: function() { - globalContext = {}; + this._globalContext = {}; - return Raven; + return this; }, /* @@ -357,7 +383,7 @@ var Raven = { */ getContext: function() { // lol javascript - return JSON.parse(JSON.stringify(globalContext)); + return JSON.parse(JSON.stringify(this._globalContext)); }, /* @@ -367,9 +393,9 @@ var Raven = { * @return {Raven} */ setRelease: function(release) { - globalOptions.release = release; + this._globalOptions.release = release; - return Raven; + return this; }, /* @@ -380,9 +406,9 @@ var Raven = { * @return {Raven} */ setDataCallback: function(callback) { - globalOptions.dataCallback = callback; + this._globalOptions.dataCallback = callback; - return Raven; + return this; }, /* @@ -393,9 +419,9 @@ var Raven = { * @return {Raven} */ setShouldSendCallback: function(callback) { - globalOptions.shouldSendCallback = callback; + this._globalOptions.shouldSendCallback = callback; - return Raven; + return this; }, /** @@ -408,9 +434,9 @@ var Raven = { * @return {Raven} */ setTransport: function(transport) { - globalOptions.transport = transport; + this._globalOptions.transport = transport; - return Raven; + return this; }, /* @@ -419,7 +445,7 @@ var Raven = { * @return {error} */ lastException: function() { - return lastCapturedException; + return this._lastCapturedException; }, /* @@ -428,7 +454,7 @@ var Raven = { * @return {string} */ lastEventId: function() { - return lastEventId; + return this._lastEventId; }, /* @@ -437,530 +463,442 @@ var Raven = { * @return {boolean} */ isSetup: function() { - return isSetup(); - } -}; - -// Deprecations -Raven.setUser = Raven.setUserContext; -Raven.setReleaseContext = Raven.setRelease; - -function triggerEvent(eventType, options) { - // NOTE: `event` is a native browser thing, so let's avoid conflicting wiht it - var evt, key; - - if (!hasDocument) - return; + if (!this._hasJSON) return false; // needs JSON support + if (!this._globalServer) { + if (!this.ravenNotConfiguredError) + this._logDebug('error', 'Error: Raven has not been configured.'); + this.ravenNotConfiguredError = true; + return false; + } + return true; + }, - options = options || {}; + afterLoad: function () { + // TODO: remove window dependence? - eventType = 'raven' + eventType.substr(0,1).toUpperCase() + eventType.substr(1); + // Attempt to initialize Raven on load + var RavenConfig = window.RavenConfig; + if (RavenConfig) { + this.config(RavenConfig.dsn, RavenConfig.config).install(); + } + }, - if (document.createEvent) { - evt = document.createEvent('HTMLEvents'); - evt.initEvent(eventType, true, true); - } else { - evt = document.createEventObject(); - evt.eventType = eventType; - } + /**** Private functions ****/ + _triggerEvent: function(eventType, options) { + // NOTE: `event` is a native browser thing, so let's avoid conflicting wiht it + var evt, key; - for (key in options) if (hasKey(options, key)) { - evt[key] = options[key]; - } + if (!this._hasDocument) + return; - if (document.createEvent) { - // IE9 if standards - document.dispatchEvent(evt); - } else { - // IE8 regardless of Quirks or Standards - // IE9 if quirks - try { - document.fireEvent('on' + evt.eventType.toLowerCase(), evt); - } catch(e) {} - } -} + options = options || {}; -var dsnKeys = 'source protocol user pass host port path'.split(' '), - dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/; + eventType = 'raven' + eventType.substr(0,1).toUpperCase() + eventType.substr(1); -function RavenConfigError(message) { - this.name = 'RavenConfigError'; - this.message = message; -} -RavenConfigError.prototype = new Error(); -RavenConfigError.prototype.constructor = RavenConfigError; - -/**** Private functions ****/ -function parseDSN(str) { - var m = dsnPattern.exec(str), - dsn = {}, - i = 7; - - try { - while (i--) dsn[dsnKeys[i]] = m[i] || ''; - } catch(e) { - throw new RavenConfigError('Invalid DSN: ' + str); - } - - if (dsn.pass) - throw new RavenConfigError('Do not specify your private key in the DSN!'); - - return dsn; -} + if (document.createEvent) { + evt = document.createEvent('HTMLEvents'); + evt.initEvent(eventType, true, true); + } else { + evt = document.createEventObject(); + evt.eventType = eventType; + } -function isUndefined(what) { - return what === void 0; -} + for (key in options) if (hasKey(options, key)) { + evt[key] = options[key]; + } -function isFunction(what) { - return typeof what === 'function'; -} + if (document.createEvent) { + // IE9 if standards + document.dispatchEvent(evt); + } else { + // IE8 regardless of Quirks or Standards + // IE9 if quirks + try { + document.fireEvent('on' + evt.eventType.toLowerCase(), evt); + } catch(e) {} + } + }, -function isString(what) { - return objectPrototype.toString.call(what) === '[object String]'; -} + /** + * Install any queued plugins + */ + _drainPlugins: function() { + var self = this; + + // FIX ME TODO + each(this._plugins, function(_, plugin) { + var installer = plugin[0]; + var args = plugin[1]; + installer.apply(self, [self].concat(args)); + }); + }, -function isObject(what) { - return typeof what === 'object' && what !== null; -} + _parseDSN: function(str) { + var m = dsnPattern.exec(str), + dsn = {}, + i = 7; -function isEmptyObject(what) { - for (var k in what) return false; - return true; -} + try { + while (i--) dsn[dsnKeys[i]] = m[i] || ''; + } catch(e) { + throw new RavenConfigError('Invalid DSN: ' + str); + } -// Sorta yanked from https://github.com/joyent/node/blob/aa3b4b4/lib/util.js#L560 -// with some tiny modifications -function isError(what) { - return isObject(what) && - objectPrototype.toString.call(what) === '[object Error]' || - what instanceof Error; -} + if (dsn.pass) + throw new RavenConfigError('Do not specify your private key in the DSN!'); -/** - * hasKey, a better form of hasOwnProperty - * Example: hasKey(MainHostObject, property) === true/false - * - * @param {Object} host object to check property - * @param {string} key to check - */ -function hasKey(object, key) { - return objectPrototype.hasOwnProperty.call(object, key); -} + return dsn; + }, -function each(obj, callback) { - var i, j; + _handleStackInfo: function(stackInfo, options) { + var self = this; + var frames = []; - if (isUndefined(obj.length)) { - for (i in obj) { - if (hasKey(obj, i)) { - callback.call(null, i, obj[i]); - } - } - } else { - j = obj.length; - if (j) { - for (i = 0; i < j; i++) { - callback.call(null, i, obj[i]); - } + if (stackInfo.stack && stackInfo.stack.length) { + each(stackInfo.stack, function(i, stack) { + var frame = self._normalizeFrame(stack); + if (frame) { + frames.push(frame); + } + }); } - } -} - -function handleStackInfo(stackInfo, options) { - var frames = []; - if (stackInfo.stack && stackInfo.stack.length) { - each(stackInfo.stack, function(i, stack) { - var frame = normalizeFrame(stack); - if (frame) { - frames.push(frame); - } + this._triggerEvent('handle', { + stackInfo: stackInfo, + options: options }); - } - triggerEvent('handle', { - stackInfo: stackInfo, - options: options - }); - - processException( - stackInfo.name, - stackInfo.message, - stackInfo.url, - stackInfo.lineno, - frames, - options - ); -} - -function normalizeFrame(frame) { - if (!frame.url) return; - - // normalize the frames data - var normalized = { - filename: frame.url, - lineno: frame.line, - colno: frame.column, - 'function': frame.func || '?' - }, context = extractContextFromFrame(frame), i; - - if (context) { - var keys = ['pre_context', 'context_line', 'post_context']; - i = 3; - while (i--) normalized[keys[i]] = context[i]; - } - - normalized.in_app = !( // determine if an exception came from outside of our app - // first we check the global includePaths list. - (!!globalOptions.includePaths.test && !globalOptions.includePaths.test(normalized.filename)) || - // Now we check for fun, if the function name is Raven or TraceKit - /(Raven|TraceKit)\./.test(normalized['function']) || - // finally, we do a last ditch effort and check for raven.min.js - /raven\.(min\.)?js$/.test(normalized.filename) - ); + this._processException( + stackInfo.name, + stackInfo.message, + stackInfo.url, + stackInfo.lineno, + frames, + options + ); + }, - return normalized; -} + _normalizeFrame: function(frame) { + if (!frame.url) return; + + // normalize the frames data + var normalized = { + filename: frame.url, + lineno: frame.line, + colno: frame.column, + 'function': frame.func || '?' + }, context = this._extractContextFromFrame(frame), i; + + if (context) { + var keys = ['pre_context', 'context_line', 'post_context']; + i = 3; + while (i--) normalized[keys[i]] = context[i]; + } -function extractContextFromFrame(frame) { - // immediately check if we should even attempt to parse a context - if (!frame.context || !globalOptions.fetchContext) return; + normalized.in_app = !( // determine if an exception came from outside of our app + // first we check the global includePaths list. + (!!this._globalOptions.includePaths.test && !this._globalOptions.includePaths.test(normalized.filename)) || + // Now we check for fun, if the function name is Raven or TraceKit + /(Raven|TraceKit)\./.test(normalized['function']) || + // finally, we do a last ditch effort and check for raven.min.js + /raven\.(min\.)?js$/.test(normalized.filename) + ); - var context = frame.context, - pivot = ~~(context.length / 2), - i = context.length, isMinified = false; + return normalized; + }, - while (i--) { - // We're making a guess to see if the source is minified or not. - // To do that, we make the assumption if *any* of the lines passed - // in are greater than 300 characters long, we bail. - // Sentry will see that there isn't a context - if (context[i].length > 300) { - isMinified = true; - break; + _extractContextFromFrame: function(frame) { + // immediately check if we should even attempt to parse a context + if (!frame.context || !this._globalOptions.fetchContext) return; + + var context = frame.context, + pivot = ~~(context.length / 2), + i = context.length, isMinified = false; + + while (i--) { + // We're making a guess to see if the source is minified or not. + // To do that, we make the assumption if *any* of the lines passed + // in are greater than 300 characters long, we bail. + // Sentry will see that there isn't a context + if (context[i].length > 300) { + isMinified = true; + break; + } } - } - if (isMinified) { - // The source is minified and we don't know which column. Fuck it. - if (isUndefined(frame.column)) return; + if (isMinified) { + // The source is minified and we don't know which column. Fuck it. + if (isUndefined(frame.column)) return; + + // If the source is minified and has a frame column + // we take a chunk of the offending line to hopefully shed some light + return [ + [], // no pre_context + context[pivot].substr(frame.column, 50), // grab 50 characters, starting at the offending column + [] // no post_context + ]; + } - // If the source is minified and has a frame column - // we take a chunk of the offending line to hopefully shed some light return [ - [], // no pre_context - context[pivot].substr(frame.column, 50), // grab 50 characters, starting at the offending column - [] // no post_context + context.slice(0, pivot), // pre_context + context[pivot], // context_line + context.slice(pivot + 1) // post_context ]; - } - - return [ - context.slice(0, pivot), // pre_context - context[pivot], // context_line - context.slice(pivot + 1) // post_context - ]; -} - -function processException(type, message, fileurl, lineno, frames, options) { - var stacktrace, i, fullMessage; - - if (!!globalOptions.ignoreErrors.test && globalOptions.ignoreErrors.test(message)) return; - - message += ''; - fullMessage = type + ': ' + message; - - if (frames && frames.length) { - fileurl = frames[0].filename || fileurl; - // Sentry expects frames oldest to newest - // and JS sends them as newest to oldest - frames.reverse(); - stacktrace = {frames: frames}; - } else if (fileurl) { - stacktrace = { - frames: [{ - filename: fileurl, - lineno: lineno, - in_app: true - }] - }; - } + }, - if (!!globalOptions.ignoreUrls.test && globalOptions.ignoreUrls.test(fileurl)) return; - if (!!globalOptions.whitelistUrls.test && !globalOptions.whitelistUrls.test(fileurl)) return; - - // Fire away! - send( - objectMerge({ - // sentry.interfaces.Exception - exception: { - values: [{ - type: type, - value: message, - stacktrace: stacktrace + _processException: function(type, message, fileurl, lineno, frames, options) { + var stacktrace, i, fullMessage; + + if (!!this._globalOptions.ignoreErrors.test && this._globalOptions.ignoreErrors.test(message)) return; + + message += ''; + message = truncate(message, this._globalOptions.maxMessageLength); + + fullMessage = type + ': ' + message; + fullMessage = truncate(fullMessage, this._globalOptions.maxMessageLength); + + if (frames && frames.length) { + fileurl = frames[0].filename || fileurl; + // Sentry expects frames oldest to newest + // and JS sends them as newest to oldest + frames.reverse(); + stacktrace = {frames: frames}; + } else if (fileurl) { + stacktrace = { + frames: [{ + filename: fileurl, + lineno: lineno, + in_app: true }] - }, - culprit: fileurl, - message: fullMessage - }, options) - ); -} + }; + } -function objectMerge(obj1, obj2) { - if (!obj2) { - return obj1; - } - each(obj2, function(key, value){ - obj1[key] = value; - }); - return obj1; -} + if (!!this._globalOptions.ignoreUrls.test && this._globalOptions.ignoreUrls.test(fileurl)) return; + if (!!this._globalOptions.whitelistUrls.test && !this._globalOptions.whitelistUrls.test(fileurl)) return; -function truncate(str, max) { - return str.length <= max ? str : str.substr(0, max) + '\u2026'; -} + // Fire away! + this._send( + objectMerge({ + // sentry.interfaces.Exception + exception: { + values: [{ + type: type, + value: message, + stacktrace: stacktrace + }] + }, + culprit: fileurl, + message: fullMessage + }, options) + ); + }, -function trimPacket(data) { - // For now, we only want to truncate the two different messages - // but this could/should be expanded to just trim everything - var max = globalOptions.maxMessageLength; - data.message = truncate(data.message, max); - if (data.exception) { - var exception = data.exception.values[0]; - exception.value = truncate(exception.value, max); - } + _trimPacket: function(data) { + // For now, we only want to truncate the two different messages + // but this could/should be expanded to just trim everything + var max = this._globalOptions.maxMessageLength; + data.message = truncate(data.message, max); + if (data.exception) { + var exception = data.exception.values[0]; + exception.value = truncate(exception.value, max); + } - return data; -} + return data; + }, -function now() { - return +new Date(); -} + _getHttpData: function() { + if (!this._hasDocument || !document.location || !document.location.href) { + return; + } -function getHttpData() { - if (!hasDocument || !document.location || !document.location.href) { - return; - } + var httpData = { + headers: { + 'User-Agent': navigator.userAgent + } + }; - var httpData = { - headers: { - 'User-Agent': navigator.userAgent + httpData.url = document.location.href; + + if (document.referrer) { + httpData.headers.Referer = document.referrer; } - }; - httpData.url = document.location.href; + return httpData; + }, - if (document.referrer) { - httpData.headers.Referer = document.referrer; - } - return httpData; -} + _send: function(data) { + var self = this; -function send(data) { - var baseData = { - project: globalProject, - logger: globalOptions.logger, - platform: 'javascript' - }, httpData = getHttpData(); + var globalOptions = this._globalOptions; - if (httpData) { - baseData.request = httpData; - } + var baseData = { + project: this._globalProject, + logger: globalOptions.logger, + platform: 'javascript' + }, httpData = this._getHttpData(); - data = objectMerge(baseData, data); + if (httpData) { + baseData.request = httpData; + } - // Merge in the tags and extra separately since objectMerge doesn't handle a deep merge - data.tags = objectMerge(objectMerge({}, globalContext.tags), data.tags); - data.extra = objectMerge(objectMerge({}, globalContext.extra), data.extra); + data = objectMerge(baseData, data); - // Send along our own collected metadata with extra - data.extra['session:duration'] = now() - startTime; + // Merge in the tags and extra separately since objectMerge doesn't handle a deep merge + data.tags = objectMerge(objectMerge({}, this._globalContext.tags), data.tags); + data.extra = objectMerge(objectMerge({}, this._globalContext.extra), data.extra); - // If there are no tags/extra, strip the key from the payload alltogther. - if (isEmptyObject(data.tags)) delete data.tags; + // Send along our own collected metadata with extra + data.extra['session:duration'] = now() - this._startTime; - if (globalContext.user) { - // sentry.interfaces.User - data.user = globalContext.user; - } + // If there are no tags/extra, strip the key from the payload alltogther. + if (isEmptyObject(data.tags)) delete data.tags; - // Include the release if it's defined in globalOptions - if (globalOptions.release) data.release = globalOptions.release; - // Include server_name if it's defined in globalOptions - if (globalOptions.serverName) data.server_name = globalOptions.serverName; + if (this._globalContext.user) { + // sentry.interfaces.User + data.user = this._globalContext.user; + } - if (isFunction(globalOptions.dataCallback)) { - data = globalOptions.dataCallback(data) || data; - } + // Include the release if it's defined in globalOptions + if (globalOptions.release) data.release = globalOptions.release; + // Include server_name if it's defined in globalOptions + if (globalOptions.serverName) data.server_name = globalOptions.serverName; - // Why?????????? - if (!data || isEmptyObject(data)) { - return; - } + // Include the release if it's defined in globalOptions + if (globalOptions.release) data.release = globalOptions.release; - // Check if the request should be filtered or not - if (isFunction(globalOptions.shouldSendCallback) && !globalOptions.shouldSendCallback(data)) { - return; - } + if (isFunction(globalOptions.dataCallback)) { + data = globalOptions.dataCallback(data) || data; + } - // Send along an event_id if not explicitly passed. - // This event_id can be used to reference the error within Sentry itself. - // Set lastEventId after we know the error should actually be sent - lastEventId = data.event_id || (data.event_id = uuid4()); - - // Try and clean up the packet before sending by truncating long values - data = trimPacket(data); - - logDebug('debug', 'Raven about to send:', data); - - if (!isSetup()) return; - - (globalOptions.transport || makeRequest)({ - url: globalServer, - auth: { - sentry_version: '7', - sentry_client: 'raven-js/' + Raven.VERSION, - sentry_key: globalKey - }, - data: data, - options: globalOptions, - onSuccess: function success() { - triggerEvent('success', { - data: data, - src: globalServer - }); - }, - onError: function failure() { - triggerEvent('failure', { - data: data, - src: globalServer - }); + // Why?????????? + if (!data || isEmptyObject(data)) { + return; } - }); -} -function makeRequest(opts) { - // Tack on sentry_data to auth options, which get urlencoded - opts.auth.sentry_data = JSON.stringify(opts.data); + // Check if the request should be filtered or not + if (isFunction(globalOptions.shouldSendCallback) && !globalOptions.shouldSendCallback(data)) { + return; + } - var img = newImage(), - src = opts.url + '?' + urlencode(opts.auth), - crossOrigin = opts.options.crossOrigin; + // Send along an event_id if not explicitly passed. + // This event_id can be used to reference the error within Sentry itself. + // Set lastEventId after we know the error should actually be sent + this._lastEventId = data.event_id || (data.event_id = uuid4()); - if (crossOrigin || crossOrigin === '') { - img.crossOrigin = crossOrigin; - } - img.onload = opts.onSuccess; - img.onerror = img.onabort = opts.onError; - img.src = src; -} + // Try and clean up the packet before sending by truncating long values + data = this._trimPacket(data); -// Note: this is shitty, but I can't figure out how to get -// sinon to stub document.createElement without breaking everything -// so this wrapper is just so I can stub it for tests. -function newImage() { - return document.createElement('img'); -} + this._logDebug('debug', 'Raven about to send:', data); -var ravenNotConfiguredError; + if (!this.isSetup()) return; -function isSetup() { - if (!hasJSON) return false; // needs JSON support - if (!globalServer) { - if (!ravenNotConfiguredError) - logDebug('error', 'Error: Raven has not been configured.'); - ravenNotConfiguredError = true; - return false; - } - return true; -} + (globalOptions.transport || this._makeRequest).call(this, { + url: this._globalServer, + auth: { + sentry_version: '7', + sentry_client: 'raven-js/' + this.VERSION, + sentry_key: this._globalKey + }, + data: data, + options: globalOptions, + onSuccess: function success() { + self._triggerEvent('success', { + data: data, + src: self._globalServer + }); + }, + onError: function failure() { + self._triggerEvent('failure', { + data: data, + src: self._globalServer + }); + } + }); + }, -function joinRegExp(patterns) { - // Combine an array of regular expressions and strings into one large regexp - // Be mad. - var sources = [], - i = 0, len = patterns.length, - pattern; - - for (; i < len; i++) { - pattern = patterns[i]; - if (isString(pattern)) { - // If it's a string, we need to escape it - // Taken from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions - sources.push(pattern.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1")); - } else if (pattern && pattern.source) { - // If it's a regexp already, we want to extract the source - sources.push(pattern.source); - } - // Intentionally skip other cases - } - return new RegExp(sources.join('|'), 'i'); -} + _makeImageRequest: function(opts) { + // Tack on sentry_data to auth options, which get urlencoded + opts.auth.sentry_data = JSON.stringify(opts.data); -function uuid4() { - var crypto = window.crypto || window.msCrypto; + var img = this._newImage(), + src = opts.url + '?' + urlencode(opts.auth), + crossOrigin = opts.options.crossOrigin; - if (!isUndefined(crypto) && crypto.getRandomValues) { - // Use window.crypto API if available - var arr = new Uint16Array(8); - crypto.getRandomValues(arr); + if (crossOrigin || crossOrigin === '') { + img.crossOrigin = crossOrigin; + } + img.onload = opts.onSuccess; + img.onerror = img.onabort = opts.onError; + img.src = src; + }, - // set 4 in byte 7 - arr[3] = arr[3] & 0xFFF | 0x4000; - // set 2 most significant bits of byte 9 to '10' - arr[4] = arr[4] & 0x3FFF | 0x8000; + _makeXhrRequest: function(opts) { + var request; - var pad = function(num) { - var v = num.toString(16); - while (v.length < 4) { - v = '0' + v; + function handler() { + if (request.status === 200) { + if (opts.onSuccess) { + opts.onSuccess(); + } + } else if (opts.onError) { + opts.onError(); } - return v; - }; + } - return (pad(arr[0]) + pad(arr[1]) + pad(arr[2]) + pad(arr[3]) + pad(arr[4]) + - pad(arr[5]) + pad(arr[6]) + pad(arr[7])); - } else { - // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 - return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r = Math.random()*16|0, - v = c == 'x' ? r : (r&0x3|0x8); - return v.toString(16); - }); - } -} + request = new XMLHttpRequest(); + if ('withCredentials' in request) { + request.onreadystatechange = function () { + if (request.readyState !== 4) { + return; + } + handler(); + }; + } else { + request = new XDomainRequest(); + // onreadystatechange not supported by XDomainRequest + request.onload = handler; + } -function logDebug(level) { - if (originalConsoleMethods[level] && Raven.debug) { - // _slice is coming from vendor/TraceKit/tracekit.js - // so it's accessible globally - originalConsoleMethods[level].apply(originalConsole, _slice.call(arguments, 1)); - } -} + // NOTE: auth is intentionally sent as part of query string (NOT as custom + // HTTP header) so as to avoid preflight CORS requests + request.open('POST', opts.url + '?' + urlencode(opts.auth)); + request.setRequestHeader("Content-type", "application/json"); + request.send(JSON.stringify(opts.data)); + }, -function afterLoad() { - // Attempt to initialize Raven on load - var RavenConfig = window.RavenConfig; - if (RavenConfig) { - Raven.config(RavenConfig.dsn, RavenConfig.config).install(); - } -} + _makeRequest: function(opts) { + var hasCORS = + 'withCredentials' in new XMLHttpRequest() || + typeof XDomainRequest !== 'undefined'; -function urlencode(o) { - var pairs = []; - each(o, function(key, value) { - pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value)); - }); - return pairs.join('&'); -} + return (hasCORS ? this._makeXhrRequest : this._makeImageRequest)(opts); + }, + + // Note: this is shitty, but I can't figure out how to get + // sinon to stub document.createElement without breaking everything + // so this wrapper is just so I can stub it for tests. + _newImage: function() { + return document.createElement('img'); + }, + + _logDebug: function(level) { + if (this._originalConsoleMethods[level] && this.debug) { + this._originalConsoleMethods[level].apply(this._originalConsole, [].slice.call(arguments, 1)); + } + }, -function mergeContext(key, context) { - if (isUndefined(context)) { - delete globalContext[key]; - } else { - globalContext[key] = objectMerge(globalContext[key] || {}, context); + _mergeContext: function(key, context) { + if (isUndefined(context)) { + delete this._globalContext[key]; + } else { + this._globalContext[key] = objectMerge(this._globalContext[key] || {}, context); + } } -} +}; + +// Deprecations +Raven.prototype.setUser = Raven.prototype.setUserContext; +Raven.prototype.setReleaseContext = Raven.prototype.setRelease; -afterLoad(); +module.exports = Raven; diff --git a/src/singleton.js b/src/singleton.js new file mode 100644 index 000000000000..48cee938b016 --- /dev/null +++ b/src/singleton.js @@ -0,0 +1,28 @@ +/** + * Enforces a single instance of the Raven client, and the + * main entry point for Raven. If you are a consumer of the + * Raven library, you SHOULD load this file (vs raven.js). + **/ + +'use strict'; + +var RavenConstructor = require('./raven'); + +var _Raven = window.Raven; + +var Raven = new RavenConstructor(); + +/* + * Allow multiple versions of Raven to be installed. + * Strip Raven from the global context and returns the instance. + * + * @return {Raven} + */ +Raven.noConflict = function () { + window.Raven = _Raven; + return Raven; +}; + +Raven.afterLoad(); + +module.exports = Raven; diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 000000000000..21da2fcad3cc --- /dev/null +++ b/src/utils.js @@ -0,0 +1,155 @@ +'use strict'; + +var objectPrototype = Object.prototype; + +function isUndefined(what) { + return what === void 0; +} + +function isFunction(what) { + return typeof what === 'function'; +} + +function isString(what) { + return objectPrototype.toString.call(what) === '[object String]'; +} + +function isObject(what) { + return typeof what === 'object' && what !== null; +} + +function isEmptyObject(what) { + for (var k in what) return false; + return true; +} + +// Sorta yanked from https://github.com/joyent/node/blob/aa3b4b4/lib/util.js#L560 +// with some tiny modifications +function isError(what) { + return isObject(what) && + objectPrototype.toString.call(what) === '[object Error]' || + what instanceof Error; +} + +function each(obj, callback) { + var i, j; + + if (isUndefined(obj.length)) { + for (i in obj) { + if (hasKey(obj, i)) { + callback.call(null, i, obj[i]); + } + } + } else { + j = obj.length; + if (j) { + for (i = 0; i < j; i++) { + callback.call(null, i, obj[i]); + } + } + } +} + +function objectMerge(obj1, obj2) { + if (!obj2) { + return obj1; + } + each(obj2, function(key, value){ + obj1[key] = value; + }); + return obj1; +} + +function truncate(str, max) { + return str.length <= max ? str : str.substr(0, max) + '\u2026'; +} + +/** + * hasKey, a better form of hasOwnProperty + * Example: hasKey(MainHostObject, property) === true/false + * + * @param {Object} host object to check property + * @param {string} key to check + */ +function hasKey(object, key) { + return objectPrototype.hasOwnProperty.call(object, key); +} + +function joinRegExp(patterns) { + // Combine an array of regular expressions and strings into one large regexp + // Be mad. + var sources = [], + i = 0, len = patterns.length, + pattern; + + for (; i < len; i++) { + pattern = patterns[i]; + if (isString(pattern)) { + // If it's a string, we need to escape it + // Taken from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions + sources.push(pattern.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1")); + } else if (pattern && pattern.source) { + // If it's a regexp already, we want to extract the source + sources.push(pattern.source); + } + // Intentionally skip other cases + } + return new RegExp(sources.join('|'), 'i'); +} + +function urlencode(o) { + var pairs = []; + each(o, function(key, value) { + pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value)); + }); + return pairs.join('&'); +} + +function uuid4() { + var crypto = window.crypto || window.msCrypto; + + if (!isUndefined(crypto) && crypto.getRandomValues) { + // Use window.crypto API if available + var arr = new Uint16Array(8); + crypto.getRandomValues(arr); + + // set 4 in byte 7 + arr[3] = arr[3] & 0xFFF | 0x4000; + // set 2 most significant bits of byte 9 to '10' + arr[4] = arr[4] & 0x3FFF | 0x8000; + + var pad = function(num) { + var v = num.toString(16); + while (v.length < 4) { + v = '0' + v; + } + return v; + }; + + return (pad(arr[0]) + pad(arr[1]) + pad(arr[2]) + pad(arr[3]) + pad(arr[4]) + + pad(arr[5]) + pad(arr[6]) + pad(arr[7])); + } else { + // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 + return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random()*16|0, + v = c == 'x' ? r : (r&0x3|0x8); + return v.toString(16); + }); + } +} + +module.exports = { + isUndefined: isUndefined, + isFunction: isFunction, + isString: isString, + isObject: isObject, + isEmptyObject: isEmptyObject, + isError: isError, + each: each, + objectMerge: objectMerge, + truncate: truncate, + hasKey: hasKey, + joinRegExp: joinRegExp, + urlencode: urlencode, + uuid4: uuid4 +}; diff --git a/template/_footer.js b/template/_footer.js deleted file mode 100644 index b6583ef31388..000000000000 --- a/template/_footer.js +++ /dev/null @@ -1,19 +0,0 @@ -// This is being exposed no matter what because there are too many weird -// usecases for how people use Raven. If this is really a problem, I'm sorry. -window.Raven = Raven; - -// Expose Raven to the world -if (typeof define === 'function' && define.amd) { - // AMD - define('raven', [], function() { - return Raven; - }); -} else if (typeof module === 'object') { - // browserify - module.exports = Raven; -} else if (typeof exports === 'object') { - // CommonJS - exports = Raven; -} - -})(typeof window !== 'undefined' ? window : this); diff --git a/template/_header.js b/template/_header.js deleted file mode 100644 index 27595a61a2db..000000000000 --- a/template/_header.js +++ /dev/null @@ -1,2 +0,0 @@ -;(function(window, undefined){ -'use strict'; diff --git a/test/index.html b/test/index.html index d988e2313b9c..74d2a67dc6f6 100644 --- a/test/index.html +++ b/test/index.html @@ -19,6 +19,7 @@ - - - - - - - +