Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

v8-debug

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

v8-debug - npm Package Compare versions

Comparing version
0.5.4
to
0.6.0
+35
src/InjectedScriptHost.h
#ifndef X_INJECTED_SCRIPT_HOST_
#define X_INJECTED_SCRIPT_HOST_
#include <nan.h>
namespace nodex {
class InjectedScriptHost {
public:
static void Initialize(v8::Handle<v8::Object> target);
static NAN_METHOD(Eval);
static NAN_METHOD(EvaluateWithExceptionDetails);
static NAN_METHOD(SetNonEnumProperty);
static NAN_METHOD(Subtype);
static NAN_METHOD(InternalConstructorName);
static NAN_METHOD(FunctionDetailsWithoutScopes);
static NAN_METHOD(CallFunction);
/*
static v8::Local<v8::Value> New(const v8::CpuProfile* node);
static Nan::Persistent<v8::Array> profiles;
*/
private:
static v8::Handle<v8::Object> createExceptionDetails(v8::Handle<v8::Message> message);
static v8::Local<v8::String> functionDisplayName(v8::Handle<v8::Function> function);
/*
static NAN_METHOD(Delete);
static void Initialize();
static Nan::Persistent<v8::ObjectTemplate> profile_template_;
static uint32_t uid_counter;
*/
};
} //namespace nodex
#endif // X_INJECTED_SCRIPT_HOST_
#ifndef X_DEBUG_TOOLS_
#define X_DEBUG_TOOLS_
#define CHK(VALUE) \
VALUE.ToLocalChecked()
#define RETURN(VALUE) { \
info.GetReturnValue().Set(VALUE); \
return; \
}
#define SET(TARGET, NAME, VALUE) \
Nan::Set(TARGET, CHK(Nan::New(NAME)), VALUE)
#define RUNSCRIPT(EXPRESSION, RESULT) while (true) { \
Nan::MaybeLocal<Nan::BoundScript> script = Nan::CompileScript(EXPRESSION);\
if (tryCatch.HasCaught()) break; \
RESULT = Nan::RunScript(CHK(script)); \
break; \
}
#define MAYBE_RETHROW() \
if (tryCatch.HasCaught()) { \
tryCatch.ReThrow(); \
return; \
}
#endif // X_DEBUG_TOOLS_
var expect = require('chai').expect;
var binary = require('node-pre-gyp');
var path = require('path');
var binding_path = binary.find(path.resolve(path.join(__dirname,'../package.json')));
var NODE_NEXT = require('../tools/NODE_NEXT.js');
if (!NODE_NEXT) return;
describe('binding', function() {
var binding = require(binding_path);
it('source was builded and can be accessed from script', function() {
expect(binding.InjectedScriptHost).to.be.instanceof(Object);
});
describe('InjectedScriptHost', function() {
var host = binding.InjectedScriptHost;
describe('function `subtype`', function() {
checksTypeValid(new Array(), 'array');
checksTypeValid(new Date(), 'date');
checksTypeValid(new RegExp(), 'regexp');
checksTypeValid(new Error(), 'error');
checksTypeValid(new String(), undefined);
function checksTypeValid(value, type) {
it('checks ' + type + ' subtype', function() {
expect(host.subtype(value)).to.equal(type);
});
}
it('should throw on wrong arguments', function() {
expect(host.subtype).to.throw();
});
});
describe('function `setNonEnumProperty`', function() {
it('should set non enumerable property to object', function() {
var object = {
'visibleProp': '1'
};
host.setNonEnumProperty(object, 'hiddenProp', 'value');
var keys = Object.keys(object);
expect(keys).to.deep.equal(['visibleProp']);
expect(object.hiddenProp).to.equal('value');
});
throwsOnArgs([]);
throwsOnArgs([{}, 'a']);
throwsOnArgs([{}, null, 'b']);
throwsOnArgs([null, {}, 'b']);
function throwsOnArgs(argvList) {
it('should throw on wrong arguments ' + JSON.stringify(argvList), function() {
expect(host.setNonEnumProperty.bind.apply(
host.setNonEnumProperty, [host].concat(argvList))).to.throw();
});
}
it('should not throw on valid arguments', function() {
expect(host.setNonEnumProperty.bind(host, {}, 'a', null)).to.not.throw();
expect(host.setNonEnumProperty.bind(host, {}, 'a', 'b')).to.not.throw();
});
});
describe('function `internalConstructorName`', function() {
checksNameValid(new Number(), 'Number');
checksNameValid(new Object(), 'Object');
function checksNameValid(value, name) {
it('checks new ' + name + '() constructor name', function() {
expect(host.internalConstructorName(value)).to.equal(name);
});
}
throwsOnArgs([]);
throwsOnArgs([1]);
throwsOnArgs([null]);
function throwsOnArgs(argvList) {
it('should throw on wrong arguments ' + JSON.stringify(argvList), function() {
expect(host.internalConstructorName.bind.apply(
host.internalConstructorName, [host].concat(argvList))).to.throw();
});
}
});
describe('function `functionDetailsWithoutScopes`', function() {
it('should return valid details', function() {
function example() {}
var details = host.functionDetailsWithoutScopes(example);
expect(details).to.include.keys(['location', 'functionName']);
expect(details.location).to.include.keys(['lineNumber', 'columnNumber', 'scriptId']);
});
throwsOnArgs([]);
throwsOnArgs([null]);
function throwsOnArgs(argvList) {
it('should throw on wrong arguments ' + JSON.stringify(argvList), function() {
expect(host.functionDetailsWithoutScopes.bind.apply(
host.functionDetailsWithoutScopes, [host].concat(argvList))).to.throw();
});
}
});
describe('function `eval`', function() {
it('should evaluate expression', function() {
expect(host.eval("[1]")).to.deep.equal([1]);
});
it('should throw on wrong arguments', function() {
expect(host.eval).to.throw();
});
it('should throw on wrong expression', function() {
expect(host.eval.bind(null, "[1")).to.throw(SyntaxError);
});
});
describe('function `evaluateWithExceptionDetails`', function() {
it('should evaluate expression', function() {
expect(host.evaluateWithExceptionDetails("[1]")).to.deep.equal({
result: [1],
exceptionDetails: undefined
});
});
it('should throw on wrong arguments', function() {
expect(host.evaluateWithExceptionDetails).to.throw();
});
});
describe('function `callFunction`', function() {
it('should call function without args', function(done) {
host.callFunction(done, this);
});
it('should call function with args', function(done) {
host.callFunction(function(arg) {
expect(arg).to.equal(1);
done();
}, this, [1]);
});
it('should throw on wrong arguments', function() {
expect(host.callFunction.bind(null, null, null, [1])).to.throw();
expect(host.callFunction.bind(null, null, null, 1)).to.throw();
});
it('should rethrow ReferenceError', function() {
expect(host.callFunction.bind(null, function() {
'use strict';
if (error_here) return;
}, this)).to.throw(ReferenceError);
});
});
});
});
return module.exports = process.versions.modules > 45;
+3
-2
{
"name": "v8-debug",
"version": "0.5.4",
"version": "0.6.0",
"description": "v8 debugger extending API",

@@ -40,6 +40,7 @@ "homepage": "http://github.com/node-inspector/v8-debug",

"scripts": {
"preinstall": " ",
"preinstall": "node -e 'process.exit(0)'",
"install": "node-pre-gyp install --fallback-to-build",
"rebuild": "node-pre-gyp rebuild",
"test": "mocha --debug"
}
}
+10
-295

@@ -0,65 +1,29 @@

#include <v8-debug.h>
#include <nan.h>
#include <v8-debug.h>
#include "tools.h"
#if (NODE_NEXT)
#include "InjectedScriptHost.h"
#endif
using v8::Isolate;
using v8::Handle;
using v8::Local;
using v8::Value;
using v8::Number;
using v8::Integer;
using v8::String;
using v8::Script;
using v8::Object;
using v8::Array;
using v8::Message;
using v8::Context;
using v8::Function;
using v8::FunctionTemplate;
using Nan::To;
using Nan::New;
using Nan::Get;
using Nan::Set;
using Nan::ForceSet;
using Nan::SetMethod;
using Nan::HandleScope;
using Nan::EscapableHandleScope;
using Nan::Undefined;
using Nan::TryCatch;
using Nan::ThrowError;
using Nan::ThrowTypeError;
using Nan::CompileScript;
using Nan::RunScript;
using Nan::MaybeLocal;
using Nan::EmptyString;
using Nan::BoundScript;
using Nan::Utf8String;
namespace nodex {
#define CHK(VALUE) \
VALUE.ToLocalChecked()
#define RETURN(VALUE) { \
info.GetReturnValue().Set(VALUE); \
return; \
}
#define SET(TARGET, NAME, VALUE) \
Set(TARGET, CHK(New(NAME)), VALUE)
#define RUNSCRIPT(EXPRESSION, RESULT) while (true) { \
MaybeLocal<BoundScript> script = CompileScript(EXPRESSION); \
if (tryCatch.HasCaught()) break; \
RESULT = Nan::RunScript(CHK(script)); \
break; \
}
#define MAYBE_RETHROW() \
if (tryCatch.HasCaught()) { \
tryCatch.ReThrow(); \
return; \
}
class Debug {

@@ -73,3 +37,3 @@ public:

Handle<Function> fn = Handle<Function>::Cast(info[0]);
Local<Function> fn = Local<Function>::Cast(info[0]);
v8::Debug::Call(fn);

@@ -82,3 +46,3 @@

String::Value command(info[0]);
#if (NODE_MODULE_VERSION > 0x000B)
#if (NODE_MODULE_VERSION > 11)
Isolate* debug_isolate = v8::Debug::GetDebugContext()->GetIsolate();

@@ -99,3 +63,2 @@ v8::HandleScope debug_scope(debug_isolate);

Local<Context> debug_context = v8::Debug::GetDebugContext();

@@ -126,242 +89,2 @@ #if (NODE_MODULE_VERSION > 45)

static Handle<Object> createExceptionDetails(Handle<Message> message) {
EscapableHandleScope scope;
Local<Object> exceptionDetails = New<Object>();
SET(exceptionDetails, "text", message->Get());
#if (NODE_MODULE_VERSION > 0x000E)
SET(exceptionDetails, "url", message->GetScriptOrigin().ResourceName());
SET(exceptionDetails, "scriptId", New<Integer>((int32_t)message->GetScriptOrigin().ScriptID()->Value()));
#else
SET(exceptionDetails, "url", message->GetScriptResourceName());
#endif
SET(exceptionDetails, "line", New<Integer>(message->GetLineNumber()));
SET(exceptionDetails, "column", New<Number>(message->GetStartColumn()));
if (!message->GetStackTrace().IsEmpty())
SET(exceptionDetails, "stackTrace", message->GetStackTrace()->AsArray());
else
SET(exceptionDetails, "stackTrace", Undefined());
return scope.Escape(exceptionDetails);
};
static NAN_METHOD(EvaluateWithExceptionDetails) {
if (info.Length() < 1)
return ThrowError("One argument expected.");
Local<Object> wrappedResult = New<Object>();
Local<String> expression = CHK(To<String>(info[0]));
if (expression.IsEmpty())
return ThrowTypeError("The argument must be a string.");
TryCatch tryCatch;
MaybeLocal<Value> result;
RUNSCRIPT(expression, result);
if (tryCatch.HasCaught()) {
SET(wrappedResult, "result", tryCatch.Exception());
SET(wrappedResult, "exceptionDetails", createExceptionDetails(tryCatch.Message()));
} else {
SET(wrappedResult, "result", CHK(result));
SET(wrappedResult, "exceptionDetails", Undefined());
}
RETURN(wrappedResult);
};
static NAN_METHOD(SetNonEnumProperty) {
if (info.Length() < 3)
return ThrowError("Three arguments expected.");
if (!info[0]->IsObject())
return ThrowTypeError("Argument 0 must be an object.");
if (!info[1]->IsString())
return ThrowTypeError("Argument 1 must be a string.");
Local<Object> object = CHK(To<Object>(info[0]));
ForceSet(object, info[1], info[2], v8::DontEnum);
RETURN(Undefined());
};
static NAN_METHOD(Subtype) {
if (info.Length() < 1)
return ThrowError("One argument expected.");
Handle<Value> value = info[0];
if (value->IsArray())
RETURN(CHK(New("array")));
#if (NODE_MODULE_VERSION > 0x000B)
if (value->IsTypedArray())
RETURN(CHK(New("array")));
#endif
if (value->IsDate())
RETURN(CHK(New("date")));
if (value->IsRegExp())
RETURN(CHK(New("regexp")));
if (value->IsNativeError())
RETURN(CHK(New("error")));
#if (NODE_MODULE_VERSION > 0x000E)
if (value->IsArgumentsObject())
RETURN(CHK(New("array")));
if (value->IsMap() || value->IsWeakMap())
RETURN(CHK(New("map")));
if (value->IsSet() || value->IsWeakSet())
RETURN(CHK(New("set")));
if (value->IsMapIterator() || value->IsSetIterator())
RETURN(CHK(New("iterator")));
#endif
RETURN(Undefined());
};
static Local<String> functionDisplayName(Handle<Function> function) {
EscapableHandleScope scope;
Local<String> value;
#if (NODE_MODULE_VERSION > 0x000B)
value = CHK(To<String>(function->GetDisplayName()));
if (value->Length())
return scope.Escape(value);
value = CHK(To<String>(function->GetName()));
if (value->Length())
return scope.Escape(value);
value = CHK(To<String>(function->GetInferredName()));
if (value->Length())
return scope.Escape(value);
#else
value = function->GetName()->ToString();
if (value->Length())
return scope.Escape(value);
value = function->GetInferredName()->ToString();
if (value->Length())
return scope.Escape(value);
#endif
return scope.Escape(EmptyString());
};
static NAN_METHOD(InternalConstructorName) {
if (info.Length() < 1)
return ThrowError("One argument expected.");
if (!info[0]->IsObject())
return ThrowTypeError("The argument must be an object.");
Local<Object> object = CHK(To<Object>(info[0]));
Local<String> result = object->GetConstructorName();
const char* result_type;
if (result.IsEmpty() || result->IsNull() || result->IsUndefined())
result_type = "";
else
result_type = *Utf8String(info[0]);
if (!result.IsEmpty() && strcmp(result_type, "Object") == 0) {
Local<String> constructorSymbol = CHK(New("constructor"));
if (object->HasRealNamedProperty(constructorSymbol) && !object->HasRealNamedCallbackProperty(constructorSymbol)) {
TryCatch tryCatch;
Local<Value> constructor = object->GetRealNamedProperty(constructorSymbol);
if (!constructor.IsEmpty() && constructor->IsFunction()) {
Local<String> constructorName = functionDisplayName(Handle<Function>::Cast(constructor));
if (!constructorName.IsEmpty() && !tryCatch.HasCaught())
result = constructorName;
}
}
if (strcmp(result_type, "Object") == 0 && object->IsFunction())
result = CHK(New("Function"));
}
RETURN(result);
}
static NAN_METHOD(FunctionDetailsWithoutScopes) {
if (info.Length() < 1)
return ThrowError("One argument expected.");
if (!info[0]->IsFunction())
return ThrowTypeError("The argument must be a function.");
Handle<Function> function = Handle<Function>::Cast(info[0]);
int32_t lineNumber = function->GetScriptLineNumber();
int32_t columnNumber = function->GetScriptColumnNumber();
Local<Object> location = New<Object>();
SET(location, "lineNumber", New(lineNumber));
SET(location, "columnNumber", New(columnNumber));
#if (NODE_MODULE_VERSION > 0x000B)
SET(location, "scriptId", CHK(To<String>(New(function->ScriptId()))));
#else
SET(location, "scriptId", CHK(To<String>(New(function->GetScriptId()->ToInt32()->Value()))));
#endif
Local<Object> result = New<Object>();
SET(result, "location", location);
Handle<String> name = functionDisplayName(function);
SET(result, "functionName", name.IsEmpty() ? EmptyString() : name);
RETURN(result);
}
static NAN_METHOD(CallFunction) {
if (info.Length() < 2 || info.Length() > 3)
return ThrowError("Two or three arguments expected.");
if (!info[0]->IsFunction())
return ThrowTypeError("Argument 0 must be a function.");
Handle<Function> function = Handle<Function>::Cast(info[0]);
#if (NODE_MODULE_VERSION > 0x000B)
Handle<Value> receiver = info[1];
#else
Handle<Object> receiver = CHK(To<Object>(info[1]));
#endif
TryCatch tryCatch;
MaybeLocal<Value> result;
if (info.Length() < 3 || info[2]->IsUndefined()) {
result = function->Call(receiver, 0, NULL);
MAYBE_RETHROW();
RETURN(CHK(result));
}
if (!info[2]->IsArray())
return ThrowTypeError("Argument 2 must be an array.");
Handle<Array> arguments = Handle<Array>::Cast(info[2]);
int argc = arguments->Length();
Handle<Value> *argv = new Handle<Value>[argc];
for (int i = 0; i < argc; ++i)
argv[i] = CHK(Get(arguments, i));
result = function->Call(receiver, argc, argv);
delete [] argv;
MAYBE_RETHROW();
RETURN(CHK(result));
};
static NAN_METHOD(Eval) {
if (info.Length() < 1)
return ThrowError("One argument expected.");
Local<String> expression = info[0]->ToString();
if (expression.IsEmpty())
return ThrowTypeError("The argument must be a string.");
TryCatch tryCatch;
MaybeLocal<Value> result;
RUNSCRIPT(expression, result);
MAYBE_RETHROW();
RETURN(CHK(result));
};
private:

@@ -373,13 +96,6 @@ Debug() {}

NAN_MODULE_INIT(Initialize) {
HandleScope scope;
#if (NODE_NEXT)
InjectedScriptHost::Initialize(target);
#endif
Local<Object> InjectedScriptHost = New<Object>();
SetMethod(InjectedScriptHost, "eval", Debug::Eval);
SetMethod(InjectedScriptHost, "evaluateWithExceptionDetails", Debug::EvaluateWithExceptionDetails);
SetMethod(InjectedScriptHost, "setNonEnumProperty", Debug::SetNonEnumProperty);
SetMethod(InjectedScriptHost, "subtype", Debug::Subtype);
SetMethod(InjectedScriptHost, "internalConstructorName", Debug::InternalConstructorName);
SetMethod(InjectedScriptHost, "functionDetailsWithoutScopes", Debug::FunctionDetailsWithoutScopes);
SetMethod(InjectedScriptHost, "callFunction", Debug::CallFunction);
SetMethod(target, "call", Debug::Call);

@@ -389,3 +105,2 @@ SetMethod(target, "sendCommand", Debug::SendCommand);

SetMethod(target, "allowNatives", Debug::AllowNatives);
SET(target, "InjectedScriptHost", InjectedScriptHost);
}

@@ -392,0 +107,0 @@

@@ -29,147 +29,2 @@ var expect = require('chai').expect;

});
describe('InjectedScriptHost', function() {
var host = binding.InjectedScriptHost;
describe('function `subtype`', function() {
checksTypeValid(new Array(), 'array');
checksTypeValid(new Date(), 'date');
checksTypeValid(new RegExp(), 'regexp');
checksTypeValid(new Error(), 'error');
checksTypeValid(new String(), undefined);
function checksTypeValid(value, type) {
it('checks ' + type + ' subtype', function() {
expect(host.subtype(value)).to.equal(type);
});
}
it('should throw on wrong arguments', function() {
expect(host.subtype).to.throw();
});
});
describe('function `setNonEnumProperty`', function() {
it('should set non enumerable property to object', function() {
var object = {
'visibleProp': '1'
};
host.setNonEnumProperty(object, 'hiddenProp', 'value');
var keys = Object.keys(object);
expect(keys).to.deep.equal(['visibleProp']);
expect(object.hiddenProp).to.equal('value');
});
throwsOnArgs([]);
throwsOnArgs([{}, 'a']);
throwsOnArgs([{}, null, 'b']);
throwsOnArgs([null, {}, 'b']);
function throwsOnArgs(argvList) {
it('should throw on wrong arguments ' + JSON.stringify(argvList), function() {
expect(host.setNonEnumProperty.bind.apply(
host.setNonEnumProperty, [host].concat(argvList))).to.throw();
});
}
it('should not throw on valid arguments', function() {
expect(host.setNonEnumProperty.bind(host, {}, 'a', null)).to.not.throw();
expect(host.setNonEnumProperty.bind(host, {}, 'a', 'b')).to.not.throw();
});
});
describe('function `internalConstructorName`', function() {
checksNameValid(new Number(), 'Number');
checksNameValid(new Object(), 'Object');
function checksNameValid(value, name) {
it('checks new ' + name + '() constructor name', function() {
expect(host.internalConstructorName(value)).to.equal(name);
});
}
throwsOnArgs([]);
throwsOnArgs([1]);
throwsOnArgs([null]);
function throwsOnArgs(argvList) {
it('should throw on wrong arguments ' + JSON.stringify(argvList), function() {
expect(host.internalConstructorName.bind.apply(
host.internalConstructorName, [host].concat(argvList))).to.throw();
});
}
});
describe('function `functionDetailsWithoutScopes`', function() {
it('should return valid details', function() {
function example() {}
var details = host.functionDetailsWithoutScopes(example);
expect(details).to.include.keys(['location', 'functionName']);
expect(details.location).to.include.keys(['lineNumber', 'columnNumber', 'scriptId']);
});
throwsOnArgs([]);
throwsOnArgs([null]);
function throwsOnArgs(argvList) {
it('should throw on wrong arguments ' + JSON.stringify(argvList), function() {
expect(host.functionDetailsWithoutScopes.bind.apply(
host.functionDetailsWithoutScopes, [host].concat(argvList))).to.throw();
});
}
});
describe('function `eval`', function() {
it('should evaluate expression', function() {
expect(host.eval("[1]")).to.deep.equal([1]);
});
it('should throw on wrong arguments', function() {
expect(host.eval).to.throw();
});
it('should throw on wrong expression', function() {
expect(host.eval.bind(null, "[1")).to.throw(SyntaxError);
});
});
describe('function `evaluateWithExceptionDetails`', function() {
it('should evaluate expression', function() {
expect(host.evaluateWithExceptionDetails("[1]")).to.deep.equal({
result: [1],
exceptionDetails: undefined
});
});
it('should throw on wrong arguments', function() {
expect(host.evaluateWithExceptionDetails).to.throw();
});
});
describe('function `callFunction`', function() {
it('should call function without args', function(done) {
host.callFunction(done, this);
});
it('should call function with args', function(done) {
host.callFunction(function(arg) {
expect(arg).to.equal(1);
done();
}, this, [1]);
});
it('should throw on wrong arguments', function() {
expect(host.callFunction.bind(null, null, null, [1])).to.throw();
expect(host.callFunction.bind(null, null, null, 1)).to.throw();
});
it('should rethrow ReferenceError', function() {
expect(host.callFunction.bind(null, function() {
'use strict';
if (error_here) return;
}, this)).to.throw(ReferenceError);
});
});
});
});
var expect = require('chai').expect,
v8debug = require('../');
var NODE_NEXT = require('../tools/NODE_NEXT');
var _debugger = require('child_process').spawn('node', ['./test/helpers/debugger.js']);

@@ -35,13 +37,19 @@

it('enableWebkitProtocol should enable Webkit protocol', function() {
v8debug.enableWebkitProtocol();
expect(v8debug.enableWebkitProtocol.bind(v8debug)).to.not.throw();
});
if (NODE_NEXT) {
it('enableWebkitProtocol should enable Webkit protocol', function() {
v8debug.enableWebkitProtocol();
expect(v8debug.enableWebkitProtocol.bind(v8debug)).to.not.throw();
});
it('if enabled registerAgentCommand should register command', function(done) {
expect(v8debug.registerAgentCommand.bind(v8debug, 'command', [], function() {
done();
})).to.not.throw();
v8debug.sendCommand('command');
});
it('if enabled registerAgentCommand should register command', function(done) {
expect(v8debug.registerAgentCommand.bind(v8debug, 'command', [], function() {
done();
})).to.not.throw();
v8debug.sendCommand('command');
});
} else {
it('enableWebkitProtocol should throw error', function() {
expect(v8debug.enableWebkitProtocol).to.throw();
});
}
});

@@ -48,0 +56,0 @@

@@ -10,2 +10,4 @@ var binary = require('node-pre-gyp');

var NODE_NEXT = require('./tools/NODE_NEXT');
// Don't cache debugger module

@@ -218,2 +220,6 @@ delete require.cache[module.id];

V8Debug.prototype.enableWebkitProtocol = function() {
if (!NODE_NEXT) {
throw new Error('WebKit protocol is not supported on target node version (' + process.version + ')');
}
if (this._webkitProtocolEnabled) return;

@@ -220,0 +226,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display