Skip to content

Commit

Permalink
feat(WinterCG): URL & URLSearchParams (#1801)
Browse files Browse the repository at this point in the history
  • Loading branch information
triniwiz authored Mar 28, 2024
1 parent f43f591 commit 4f3a0d7
Show file tree
Hide file tree
Showing 13 changed files with 24,190 additions and 1 deletion.
4 changes: 3 additions & 1 deletion test-app/app/src/main/assets/app/mainpage.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ require("./tests/testPackagePrivate");
require("./tests/kotlin/properties/testPropertiesSupport.js");
require('./tests/testNativeTimers');
require("./tests/testPostFrameCallback");
require("./tests/console/logTests.js");
require("./tests/console/logTests.js");
require('./tests/testURLImpl.js');
require('./tests/testURLSearchParamsImpl.js');
31 changes: 31 additions & 0 deletions test-app/app/src/main/assets/app/tests/testURLImpl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
describe("Test URL ", function () {

it("Test invalid URL parsing", function(){
var exceptionCaught = false;
try {
const url = new URL('');
}catch(e){
exceptionCaught = true;
}
expect(exceptionCaught).toBe(true);
});

it("Test valid URL parsing", function(){
var exceptionCaught = false;
try {
const url = new URL('https://google.com');
}catch(e){
exceptionCaught = true;
}
expect(exceptionCaught).toBe(false);
});


it("Test URL fields", function(){
var exceptionCaught = false;
const url = new URL('https://google.com');
expect(url.protocol).toBe('https:');
expect(url.hostname).toBe('google.com');
});

});
64 changes: 64 additions & 0 deletions test-app/app/src/main/assets/app/tests/testURLSearchParamsImpl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
describe("Test URLSearchParams ", function () {
const fooBar = "foo=1&bar=2";
it("Test URLSearchParams keys", function(){
const params = new URLSearchParams(fooBar);
const keys = params.keys();
expect(keys[0]).toBe("foo");
expect(keys[1]).toBe("bar");
});

it("Test URLSearchParams values", function(){
const params = new URLSearchParams(fooBar);
const values = params.values();
expect(values[0]).toBe("1");
expect(values[1]).toBe("2");
});


it("Test URLSearchParams entries", function(){
const params = new URLSearchParams(fooBar);
const entries = params.entries();
expect(entries[0][0]).toBe("foo");
expect(entries[0][1]).toBe("1");

expect(entries[1][0]).toBe("bar");
expect(entries[1][1]).toBe("2");

});


it("Test URLSearchParams size", function(){
const params = new URLSearchParams(fooBar);
expect(params.size).toBe(2);
});

it("Test URLSearchParams append", function(){
const params = new URLSearchParams(fooBar);
params.append("first", "Osei");
expect(params.get("first")).toBe("Osei");
});


it("Test URLSearchParams delete", function(){
const params = new URLSearchParams(fooBar);
params.append("first", "Osei");
params.delete("first");
expect(params.get("first")).toBe(undefined);
});


it("Test URLSearchParams has", function(){
const params = new URLSearchParams(fooBar);
expect(params.has("foo")).toBe(true);
});

it("Test URLSearchParams changes propagates to URL parent", function(){
const toBe = 'https://github.com/triniwiz?first=Osei';
const url = new URL('https://github.com/triniwiz');
const params = url.searchParams;
console.log(params);
params.set('first', 'Osei');
expect(url.toString()).toBe(toBe);
});

});
4 changes: 4 additions & 0 deletions test-app/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ include_directories(
src/main/cpp
src/main/cpp/include
src/main/cpp/v8_inspector
src/main/cpp/ada
)

if (OPTIMIZED_BUILD OR OPTIMIZED_WITH_INSPECTOR_BUILD)
Expand Down Expand Up @@ -137,6 +138,9 @@ add_library(
src/main/cpp/conversions/objects/JSToJavaObjectsConverter.cpp
src/main/cpp/conversions/arrays/JSToJavaArraysConverter.cpp
src/main/cpp/conversions/primitives/JSToJavaPrimitivesConverter.cpp
src/main/cpp/ada/ada.cpp
src/main/cpp/URLImpl.cpp
src/main/cpp/URLSearchParamsImpl.cpp

# V8 inspector source files will be included only in Release mode
${INSPECTOR_SOURCES}
Expand Down
73 changes: 73 additions & 0 deletions test-app/runtime/src/main/cpp/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include <thread>
#include "File.h"
#include "ModuleBinding.h"
#include "URLImpl.h"
#include "URLSearchParamsImpl.h"

#ifdef APPLICATION_IN_DEBUG
// #include "NetworkDomainCallbackHandlers.h"
Expand Down Expand Up @@ -519,6 +521,9 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, const string& native
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__runOnMainThread"), FunctionTemplate::New(isolate, CallbackHandlers::RunOnMainThreadCallback));
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__postFrameCallback"), FunctionTemplate::New(isolate, CallbackHandlers::PostFrameCallback));
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__removeFrameCallback"), FunctionTemplate::New(isolate, CallbackHandlers::RemoveFrameCallback));
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "URL"), URLImpl::GetCtor(isolate));
globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "URLSearchParams"), URLSearchParamsImpl::GetCtor(isolate));

/*
* Attach `Worker` object constructor only to the main thread (isolate)'s global object
* Workers should not be created from within other Workers, for now
Expand Down Expand Up @@ -586,10 +591,78 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, const string& native

Local<Context> context = Context::New(isolate, nullptr, globalTemplate);

auto blob_methods = R"js(
const BLOB_STORE = new Map();
URL.createObjectURL = function (object, options = null) {
try {
if (object instanceof Blob || object instanceof File) {
const id = java.util.UUID.randomUUID().toString();
const ret = `blob:nativescript/${id}`;
BLOB_STORE.set(ret, {
blob: object,
type: object?.type,
ext: options?.ext,
});
return ret;
}
} catch (error) {
return null;
}
return null;
};
URL.revokeObjectURL = function (url) {
BLOB_STORE.delete(url);
};
const InternalAccessor = class {};
InternalAccessor.getData = function (url) {
return BLOB_STORE.get(url);
};
URL.InternalAccessor = InternalAccessor;
Object.defineProperty(URL.prototype, 'searchParams', {
get() {
if (this._searchParams == null) {
this._searchParams = new URLSearchParams(this.search);
Object.defineProperty(this._searchParams, '_url', {
enumerable: false,
writable: false,
value: this,
});
this._searchParams._append = this._searchParams.append;
this._searchParams.append = function (name, value) {
this._append(name, value);
this._url.search = this.toString();
};
this._searchParams._delete = this._searchParams.delete;
this._searchParams.delete = function (name) {
this._delete(name);
this._url.search = this.toString();
};
this._searchParams._set = this._searchParams.set;
this._searchParams.set = function (name, value) {
this._set(name, value);
this._url.search = this.toString();
};
this._searchParams._sort = this._searchParams.sort;
this._searchParams.sort = function () {
this._sort();
this._url.search = this.toString();
};
}
return this._searchParams;
},
});
)js";


auto global = context->Global();

v8::Context::Scope contextScope{context};

v8::Local<v8::Script> script;
v8::Script::Compile(context, ArgConverter::ConvertToV8String(isolate, blob_methods)).ToLocal(&script);

v8::Local<v8::Value> out;
script->Run(context).ToLocal(&out);
m_objectManager->Init(isolate);

m_module.Init(isolate, callingDir);
Expand Down
Loading

0 comments on commit 4f3a0d7

Please sign in to comment.