|
|
@ -27,9 +27,11 @@ using v8::HandleScope; |
|
|
|
using v8::Integer; |
|
|
|
using v8::Isolate; |
|
|
|
using v8::Local; |
|
|
|
using v8::MaybeLocal; |
|
|
|
using v8::Null; |
|
|
|
using v8::Object; |
|
|
|
using v8::String; |
|
|
|
using v8::TryCatch; |
|
|
|
using v8::Undefined; |
|
|
|
using v8::Value; |
|
|
|
|
|
|
@ -1226,6 +1228,29 @@ namespace url { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static inline void SetArgs(Environment* env, |
|
|
|
Local<Value> argv[], |
|
|
|
const struct url_data* url) { |
|
|
|
Isolate* isolate = env->isolate(); |
|
|
|
argv[ARG_FLAGS] = Integer::NewFromUnsigned(isolate, url->flags); |
|
|
|
if (url->flags & URL_FLAGS_HAS_SCHEME) |
|
|
|
argv[ARG_PROTOCOL] = OneByteString(isolate, url->scheme.c_str()); |
|
|
|
if (url->flags & URL_FLAGS_HAS_USERNAME) |
|
|
|
argv[ARG_USERNAME] = UTF8STRING(isolate, url->username); |
|
|
|
if (url->flags & URL_FLAGS_HAS_PASSWORD) |
|
|
|
argv[ARG_PASSWORD] = UTF8STRING(isolate, url->password); |
|
|
|
if (url->flags & URL_FLAGS_HAS_HOST) |
|
|
|
argv[ARG_HOST] = UTF8STRING(isolate, url->host); |
|
|
|
if (url->flags & URL_FLAGS_HAS_QUERY) |
|
|
|
argv[ARG_QUERY] = UTF8STRING(isolate, url->query); |
|
|
|
if (url->flags & URL_FLAGS_HAS_FRAGMENT) |
|
|
|
argv[ARG_FRAGMENT] = UTF8STRING(isolate, url->fragment); |
|
|
|
if (url->port > -1) |
|
|
|
argv[ARG_PORT] = Integer::New(isolate, url->port); |
|
|
|
if (url->flags & URL_FLAGS_HAS_PATH) |
|
|
|
argv[ARG_PATH] = Copy(env, url->path); |
|
|
|
} |
|
|
|
|
|
|
|
static void Parse(Environment* env, |
|
|
|
Local<Value> recv, |
|
|
|
const char* input, |
|
|
@ -1267,23 +1292,7 @@ namespace url { |
|
|
|
undef, |
|
|
|
undef, |
|
|
|
}; |
|
|
|
argv[ARG_FLAGS] = Integer::NewFromUnsigned(isolate, url.flags); |
|
|
|
if (url.flags & URL_FLAGS_HAS_SCHEME) |
|
|
|
argv[ARG_PROTOCOL] = OneByteString(isolate, url.scheme.c_str()); |
|
|
|
if (url.flags & URL_FLAGS_HAS_USERNAME) |
|
|
|
argv[ARG_USERNAME] = UTF8STRING(isolate, url.username); |
|
|
|
if (url.flags & URL_FLAGS_HAS_PASSWORD) |
|
|
|
argv[ARG_PASSWORD] = UTF8STRING(isolate, url.password); |
|
|
|
if (url.flags & URL_FLAGS_HAS_HOST) |
|
|
|
argv[ARG_HOST] = UTF8STRING(isolate, url.host); |
|
|
|
if (url.flags & URL_FLAGS_HAS_QUERY) |
|
|
|
argv[ARG_QUERY] = UTF8STRING(isolate, url.query); |
|
|
|
if (url.flags & URL_FLAGS_HAS_FRAGMENT) |
|
|
|
argv[ARG_FRAGMENT] = UTF8STRING(isolate, url.fragment); |
|
|
|
if (url.port > -1) |
|
|
|
argv[ARG_PORT] = Integer::New(isolate, url.port); |
|
|
|
if (url.flags & URL_FLAGS_HAS_PATH) |
|
|
|
argv[ARG_PATH] = Copy(env, url.path); |
|
|
|
SetArgs(env, argv, &url); |
|
|
|
(void)cb->Call(context, recv, arraysize(argv), argv); |
|
|
|
} else if (error_cb->IsFunction()) { |
|
|
|
Local<Value> argv[2] = { undef, undef }; |
|
|
@ -1418,6 +1427,58 @@ namespace url { |
|
|
|
v8::NewStringType::kNormal).ToLocalChecked()); |
|
|
|
} |
|
|
|
|
|
|
|
// This function works by calling out to a JS function that creates and
|
|
|
|
// returns the JS URL object. Be mindful of the JS<->Native boundary
|
|
|
|
// crossing that is required.
|
|
|
|
const Local<Value> URL::ToObject(Environment* env) const { |
|
|
|
Isolate* isolate = env->isolate(); |
|
|
|
Local<Context> context = env->context(); |
|
|
|
HandleScope handle_scope(isolate); |
|
|
|
Context::Scope context_scope(context); |
|
|
|
|
|
|
|
const Local<Value> undef = Undefined(isolate); |
|
|
|
|
|
|
|
if (context_.flags & URL_FLAGS_FAILED) |
|
|
|
return Local<Value>(); |
|
|
|
|
|
|
|
Local<Value> argv[9] = { |
|
|
|
undef, |
|
|
|
undef, |
|
|
|
undef, |
|
|
|
undef, |
|
|
|
undef, |
|
|
|
undef, |
|
|
|
undef, |
|
|
|
undef, |
|
|
|
undef, |
|
|
|
}; |
|
|
|
SetArgs(env, argv, &context_); |
|
|
|
|
|
|
|
TryCatch try_catch(isolate); |
|
|
|
|
|
|
|
// The SetURLConstructor method must have been called already to
|
|
|
|
// set the constructor function used below. SetURLConstructor is
|
|
|
|
// called automatically when the internal/url.js module is loaded
|
|
|
|
// during the internal/bootstrap_node.js processing.
|
|
|
|
MaybeLocal<Value> ret = |
|
|
|
env->url_constructor_function() |
|
|
|
->Call(env->context(), undef, 9, argv); |
|
|
|
|
|
|
|
if (ret.IsEmpty()) { |
|
|
|
ClearFatalExceptionHandlers(env); |
|
|
|
FatalException(isolate, try_catch); |
|
|
|
} |
|
|
|
|
|
|
|
return ret.ToLocalChecked(); |
|
|
|
} |
|
|
|
|
|
|
|
static void SetURLConstructor(const FunctionCallbackInfo<Value>& args) { |
|
|
|
Environment* env = Environment::GetCurrent(args); |
|
|
|
CHECK_EQ(args.Length(), 1); |
|
|
|
CHECK(args[0]->IsFunction()); |
|
|
|
env->set_url_constructor_function(args[0].As<Function>()); |
|
|
|
} |
|
|
|
|
|
|
|
static void Init(Local<Object> target, |
|
|
|
Local<Value> unused, |
|
|
|
Local<Context> context, |
|
|
@ -1428,6 +1489,7 @@ namespace url { |
|
|
|
env->SetMethod(target, "toUSVString", ToUSVString); |
|
|
|
env->SetMethod(target, "domainToASCII", DomainToASCII); |
|
|
|
env->SetMethod(target, "domainToUnicode", DomainToUnicode); |
|
|
|
env->SetMethod(target, "setURLConstructor", SetURLConstructor); |
|
|
|
|
|
|
|
#define XX(name, _) NODE_DEFINE_CONSTANT(target, name); |
|
|
|
FLAGS(XX) |
|
|
|