mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Merge pull request #1498 from lightpanda-io/fast_properties
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / demo-scripts (push) Has been cancelled
e2e-test / cdp-and-hyperfine-bench (push) Has been cancelled
e2e-test / perf-fmt (push) Has been cancelled
e2e-test / browser fetch (push) Has been cancelled
zig-test / zig test using v8 in debug mode (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
Convert more comptime-getters to fast getters
This commit is contained in:
2
.github/actions/install/action.yml
vendored
2
.github/actions/install/action.yml
vendored
@@ -13,7 +13,7 @@ inputs:
|
|||||||
zig-v8:
|
zig-v8:
|
||||||
description: 'zig v8 version to install'
|
description: 'zig v8 version to install'
|
||||||
required: false
|
required: false
|
||||||
default: 'v0.2.7'
|
default: 'v0.2.8'
|
||||||
v8:
|
v8:
|
||||||
description: 'v8 version to install'
|
description: 'v8 version to install'
|
||||||
required: false
|
required: false
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ FROM debian:stable-slim
|
|||||||
ARG MINISIG=0.12
|
ARG MINISIG=0.12
|
||||||
ARG ZIG_MINISIG=RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U
|
ARG ZIG_MINISIG=RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U
|
||||||
ARG V8=14.0.365.4
|
ARG V8=14.0.365.4
|
||||||
ARG ZIG_V8=v0.2.7
|
ARG ZIG_V8=v0.2.8
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
RUN apt-get update -yq && \
|
RUN apt-get update -yq && \
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
.minimum_zig_version = "0.15.2",
|
.minimum_zig_version = "0.15.2",
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
.v8 = .{
|
.v8 = .{
|
||||||
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/refs/tags/0.2.7.tar.gz",
|
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/refs/tags/v0.2.8.tar.gz",
|
||||||
.hash = "v8-0.0.0-xddH62VUBADeNHR3Go37RmFrODPARC-f5vjxkpJtxQsZ",
|
.hash = "v8-0.0.0-xddH63lfBADJ7UE2zAJ8nJIBnxoSiimXSaX6Q_M_7DS3",
|
||||||
},
|
},
|
||||||
//.v8 = .{ .path = "../zig-v8-fork" },
|
//.v8 = .{ .path = "../zig-v8-fork" },
|
||||||
.@"boringssl-zig" = .{
|
.@"boringssl-zig" = .{
|
||||||
|
|||||||
@@ -455,7 +455,7 @@ fn attachClass(comptime JsApi: type, isolate: *v8.Isolate, template: *v8.Functio
|
|||||||
switch (definition) {
|
switch (definition) {
|
||||||
bridge.Accessor => {
|
bridge.Accessor => {
|
||||||
const js_name = v8.v8__String__NewFromUtf8(isolate, name.ptr, v8.kNormal, @intCast(name.len));
|
const js_name = v8.v8__String__NewFromUtf8(isolate, name.ptr, v8.kNormal, @intCast(name.len));
|
||||||
const getter_callback = @constCast(v8.v8__FunctionTemplate__New__DEFAULT2(isolate, value.getter).?);
|
const getter_callback = @constCast(v8.v8__FunctionTemplate__New__Config(isolate, &.{ .callback = value.getter }).?);
|
||||||
if (value.setter == null) {
|
if (value.setter == null) {
|
||||||
if (value.static) {
|
if (value.static) {
|
||||||
v8.v8__Template__SetAccessorProperty__DEFAULT(@ptrCast(template), js_name, getter_callback);
|
v8.v8__Template__SetAccessorProperty__DEFAULT(@ptrCast(template), js_name, getter_callback);
|
||||||
@@ -466,12 +466,12 @@ fn attachClass(comptime JsApi: type, isolate: *v8.Isolate, template: *v8.Functio
|
|||||||
if (comptime IS_DEBUG) {
|
if (comptime IS_DEBUG) {
|
||||||
std.debug.assert(value.static == false);
|
std.debug.assert(value.static == false);
|
||||||
}
|
}
|
||||||
const setter_callback = @constCast(v8.v8__FunctionTemplate__New__DEFAULT2(isolate, value.setter.?).?);
|
const setter_callback = @constCast(v8.v8__FunctionTemplate__New__Config(isolate, &.{ .callback = value.setter.? }).?);
|
||||||
v8.v8__ObjectTemplate__SetAccessorProperty__DEFAULT2(target, js_name, getter_callback, setter_callback);
|
v8.v8__ObjectTemplate__SetAccessorProperty__DEFAULT2(target, js_name, getter_callback, setter_callback);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bridge.Function => {
|
bridge.Function => {
|
||||||
const function_template = @constCast(v8.v8__FunctionTemplate__New__DEFAULT2(isolate, value.func).?);
|
const function_template = @constCast(v8.v8__FunctionTemplate__New__Config(isolate, &.{ .callback = value.func, .length = value.arity }).?);
|
||||||
const js_name = v8.v8__String__NewFromUtf8(isolate, name.ptr, v8.kNormal, @intCast(name.len));
|
const js_name = v8.v8__String__NewFromUtf8(isolate, name.ptr, v8.kNormal, @intCast(name.len));
|
||||||
if (value.static) {
|
if (value.static) {
|
||||||
v8.v8__Template__Set(@ptrCast(template), js_name, @ptrCast(function_template), v8.None);
|
v8.v8__Template__Set(@ptrCast(template), js_name, @ptrCast(function_template), v8.None);
|
||||||
@@ -509,7 +509,7 @@ fn attachClass(comptime JsApi: type, isolate: *v8.Isolate, template: *v8.Functio
|
|||||||
has_named_index_getter = true;
|
has_named_index_getter = true;
|
||||||
},
|
},
|
||||||
bridge.Iterator => {
|
bridge.Iterator => {
|
||||||
const function_template = @constCast(v8.v8__FunctionTemplate__New__DEFAULT2(isolate, value.func).?);
|
const function_template = @constCast(v8.v8__FunctionTemplate__New__Config(isolate, &.{ .callback = value.func }).?);
|
||||||
const js_name = if (value.async)
|
const js_name = if (value.async)
|
||||||
v8.v8__Symbol__GetAsyncIterator(isolate)
|
v8.v8__Symbol__GetAsyncIterator(isolate)
|
||||||
else
|
else
|
||||||
@@ -518,7 +518,8 @@ fn attachClass(comptime JsApi: type, isolate: *v8.Isolate, template: *v8.Functio
|
|||||||
},
|
},
|
||||||
bridge.Property => {
|
bridge.Property => {
|
||||||
const js_value = switch (value.value) {
|
const js_value = switch (value.value) {
|
||||||
inline .bool, .int => |v| js.simpleZigValueToJs(.{ .handle = isolate }, v, true, false),
|
.null => js.simpleZigValueToJs(.{ .handle = isolate }, null, true, false),
|
||||||
|
inline .bool, .int, .float, .string => |v| js.simpleZigValueToJs(.{ .handle = isolate }, v, true, false),
|
||||||
};
|
};
|
||||||
const js_name = v8.v8__String__NewFromUtf8(isolate, name.ptr, v8.kNormal, @intCast(name.len));
|
const js_name = v8.v8__String__NewFromUtf8(isolate, name.ptr, v8.kNormal, @intCast(name.len));
|
||||||
|
|
||||||
@@ -527,7 +528,11 @@ fn attachClass(comptime JsApi: type, isolate: *v8.Isolate, template: *v8.Functio
|
|||||||
// is like an Accessor, but because the value is known at
|
// is like an Accessor, but because the value is known at
|
||||||
// compile time, we skip _a lot_ of code and quickly return
|
// compile time, we skip _a lot_ of code and quickly return
|
||||||
// the hard-coded value
|
// the hard-coded value
|
||||||
const getter_callback = @constCast(v8.v8__FunctionTemplate__New__DEFAULT3(isolate, bridge.Property.getter, js_value));
|
const getter_callback = @constCast(v8.v8__FunctionTemplate__New__Config(isolate, &.{
|
||||||
|
.callback = bridge.Property.getter,
|
||||||
|
.data = js_value,
|
||||||
|
.side_effect_type = v8.kSideEffectType_HasSideEffectToReceiver,
|
||||||
|
}));
|
||||||
v8.v8__ObjectTemplate__SetAccessorProperty__DEFAULT(target, js_name, getter_callback);
|
v8.v8__ObjectTemplate__SetAccessorProperty__DEFAULT(target, js_name, getter_callback);
|
||||||
} else {
|
} else {
|
||||||
// apply it both to the type itself
|
// apply it both to the type itself
|
||||||
|
|||||||
@@ -63,12 +63,23 @@ pub fn Builder(comptime T: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn property(value: anytype, opts: Property.Opts) Property {
|
pub fn property(value: anytype, opts: Property.Opts) Property {
|
||||||
// If you add strings to this, they might need to be internalized!
|
switch (@typeInfo(@TypeOf(value))) {
|
||||||
return switch (@typeInfo(@TypeOf(value))) {
|
.bool => return Property.init(.{ .bool = value }, opts),
|
||||||
.bool => Property.init(.{ .bool = value }, opts),
|
.null => return Property.init(.null, opts),
|
||||||
.comptime_int, .int => Property.init(.{ .int = value }, opts),
|
.comptime_int, .int => return Property.init(.{ .int = value }, opts),
|
||||||
else => @compileError("Property for " ++ @typeName(@TypeOf(value)) ++ " hasn't been defined yet"),
|
.comptime_float, .float => return Property.init(.{ .float = value }, opts),
|
||||||
};
|
.pointer => |ptr| switch (ptr.size) {
|
||||||
|
.one => {
|
||||||
|
const one_info = @typeInfo(ptr.child);
|
||||||
|
if (one_info == .array and one_info.array.child == u8) {
|
||||||
|
return Property.init(.{ .string = value }, opts);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
@compileError("Property for " ++ @typeName(@TypeOf(value)) ++ " hasn't been defined yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
const PrototypeChainEntry = @import("TaggedOpaque.zig").PrototypeChainEntry;
|
const PrototypeChainEntry = @import("TaggedOpaque.zig").PrototypeChainEntry;
|
||||||
@@ -150,6 +161,7 @@ pub const Constructor = struct {
|
|||||||
|
|
||||||
pub const Function = struct {
|
pub const Function = struct {
|
||||||
static: bool,
|
static: bool,
|
||||||
|
arity: usize,
|
||||||
func: *const fn (?*const v8.FunctionCallbackInfo) callconv(.c) void,
|
func: *const fn (?*const v8.FunctionCallbackInfo) callconv(.c) void,
|
||||||
|
|
||||||
const Opts = struct {
|
const Opts = struct {
|
||||||
@@ -162,6 +174,7 @@ pub const Function = struct {
|
|||||||
fn init(comptime T: type, comptime func: anytype, comptime opts: Opts) Function {
|
fn init(comptime T: type, comptime func: anytype, comptime opts: Opts) Function {
|
||||||
return .{
|
return .{
|
||||||
.static = opts.static,
|
.static = opts.static,
|
||||||
|
.arity = getArity(@TypeOf(func)),
|
||||||
.func = struct {
|
.func = struct {
|
||||||
fn wrap(handle: ?*const v8.FunctionCallbackInfo) callconv(.c) void {
|
fn wrap(handle: ?*const v8.FunctionCallbackInfo) callconv(.c) void {
|
||||||
const v8_isolate = v8.v8__FunctionCallbackInfo__GetIsolate(handle).?;
|
const v8_isolate = v8.v8__FunctionCallbackInfo__GetIsolate(handle).?;
|
||||||
@@ -186,6 +199,22 @@ pub const Function = struct {
|
|||||||
}.wrap,
|
}.wrap,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getArity(comptime T: type) usize {
|
||||||
|
var count: usize = 0;
|
||||||
|
var params = @typeInfo(T).@"fn".params;
|
||||||
|
for (params[1..]) |p| { // start at 1, skip self
|
||||||
|
const PT = p.type.?;
|
||||||
|
if (PT == *Page or PT == *const Page) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (@typeInfo(PT) == .optional) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Accessor = struct {
|
pub const Accessor = struct {
|
||||||
@@ -403,10 +432,12 @@ pub const Property = struct {
|
|||||||
value: Value,
|
value: Value,
|
||||||
template: bool,
|
template: bool,
|
||||||
|
|
||||||
// If you add strings to this, they might need to be internalized!
|
|
||||||
const Value = union(enum) {
|
const Value = union(enum) {
|
||||||
|
null,
|
||||||
int: i64,
|
int: i64,
|
||||||
|
float: f64,
|
||||||
bool: bool,
|
bool: bool,
|
||||||
|
string: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Opts = struct {
|
const Opts = struct {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
<body></body>
|
<body></body>
|
||||||
<script src="../testing.js"></script>
|
<script src="../testing.js"></script>
|
||||||
<script id=createElement>
|
<script id=createElement>
|
||||||
|
testing.expectEqual(1, document.createElement.length);
|
||||||
|
|
||||||
const div1 = document.createElement('div');
|
const div1 = document.createElement('div');
|
||||||
testing.expectEqual(true, div1 instanceof HTMLDivElement);
|
testing.expectEqual(true, div1 instanceof HTMLDivElement);
|
||||||
testing.expectEqual("DIV", div1.tagName);
|
testing.expectEqual("DIV", div1.tagName);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
<main>Main content</main>
|
<main>Main content</main>
|
||||||
|
|
||||||
<script id=byId name="test1">
|
<script id=byId name="test1">
|
||||||
|
testing.expectEqual(1, document.querySelector.length);
|
||||||
testing.expectError("SyntaxError: Syntax Error", () => document.querySelector(''));
|
testing.expectError("SyntaxError: Syntax Error", () => document.querySelector(''));
|
||||||
testing.withError((err) => {
|
testing.withError((err) => {
|
||||||
testing.expectEqual(12, err.code);
|
testing.expectEqual(12, err.code);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<script id=setTimeout>
|
<script id=setTimeout>
|
||||||
|
testing.expectEqual(1, window.setTimeout.length);
|
||||||
let wst2 = 1;
|
let wst2 = 1;
|
||||||
window.setTimeout((a, b) => {
|
window.setTimeout((a, b) => {
|
||||||
wst2 = a + b;
|
wst2 = a + b;
|
||||||
|
|||||||
@@ -103,18 +103,6 @@ pub fn getContentType(self: *const Document) []const u8 {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getCharacterSet(_: *const Document) []const u8 {
|
|
||||||
return "UTF-8";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getCompatMode(_: *const Document) []const u8 {
|
|
||||||
return "CSS1Compat";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getReferrer(_: *const Document) []const u8 {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getDomain(_: *const Document, page: *const Page) []const u8 {
|
pub fn getDomain(_: *const Document, page: *const Page) []const u8 {
|
||||||
return URL.getHostname(page.url);
|
return URL.getHostname(page.url);
|
||||||
}
|
}
|
||||||
@@ -951,11 +939,6 @@ pub const JsApi = struct {
|
|||||||
pub const activeElement = bridge.accessor(Document.getActiveElement, null, .{});
|
pub const activeElement = bridge.accessor(Document.getActiveElement, null, .{});
|
||||||
pub const styleSheets = bridge.accessor(Document.getStyleSheets, null, .{});
|
pub const styleSheets = bridge.accessor(Document.getStyleSheets, null, .{});
|
||||||
pub const contentType = bridge.accessor(Document.getContentType, null, .{});
|
pub const contentType = bridge.accessor(Document.getContentType, null, .{});
|
||||||
pub const characterSet = bridge.accessor(Document.getCharacterSet, null, .{});
|
|
||||||
pub const charset = bridge.accessor(Document.getCharacterSet, null, .{});
|
|
||||||
pub const inputEncoding = bridge.accessor(Document.getCharacterSet, null, .{});
|
|
||||||
pub const compatMode = bridge.accessor(Document.getCompatMode, null, .{});
|
|
||||||
pub const referrer = bridge.accessor(Document.getReferrer, null, .{});
|
|
||||||
pub const domain = bridge.accessor(Document.getDomain, null, .{});
|
pub const domain = bridge.accessor(Document.getDomain, null, .{});
|
||||||
pub const createElement = bridge.function(Document.createElement, .{ .dom_exception = true });
|
pub const createElement = bridge.function(Document.createElement, .{ .dom_exception = true });
|
||||||
pub const createElementNS = bridge.function(Document.createElementNS, .{ .dom_exception = true });
|
pub const createElementNS = bridge.function(Document.createElementNS, .{ .dom_exception = true });
|
||||||
@@ -1004,14 +987,19 @@ pub const JsApi = struct {
|
|||||||
pub const adoptedStyleSheets = bridge.accessor(Document.getAdoptedStyleSheets, Document.setAdoptedStyleSheets, .{});
|
pub const adoptedStyleSheets = bridge.accessor(Document.getAdoptedStyleSheets, Document.setAdoptedStyleSheets, .{});
|
||||||
pub const hidden = bridge.accessor(Document.getHidden, null, .{});
|
pub const hidden = bridge.accessor(Document.getHidden, null, .{});
|
||||||
pub const visibilityState = bridge.accessor(Document.getVisibilityState, null, .{});
|
pub const visibilityState = bridge.accessor(Document.getVisibilityState, null, .{});
|
||||||
pub const prerendering = bridge.property(false, .{ .template = false });
|
|
||||||
|
|
||||||
pub const defaultView = bridge.accessor(struct {
|
pub const defaultView = bridge.accessor(struct {
|
||||||
fn defaultView(_: *const Document, page: *Page) *@import("Window.zig") {
|
fn defaultView(_: *const Document, page: *Page) *@import("Window.zig") {
|
||||||
return page.window;
|
return page.window;
|
||||||
}
|
}
|
||||||
}.defaultView, null, .{ .cache = "defaultView" });
|
}.defaultView, null, .{ .cache = "defaultView" });
|
||||||
pub const hasFocus = bridge.function(Document.hasFocus, .{});
|
pub const hasFocus = bridge.function(Document.hasFocus, .{});
|
||||||
|
|
||||||
|
pub const prerendering = bridge.property(false, .{ .template = false });
|
||||||
|
pub const characterSet = bridge.property("UTF-8", .{ .template = false });
|
||||||
|
pub const charset = bridge.property("UTF-8", .{ .template = false });
|
||||||
|
pub const inputEncoding = bridge.property("UTF-8", .{ .template = false });
|
||||||
|
pub const compatMode = bridge.property("CSS1Compat", .{ .template = false });
|
||||||
|
pub const referrer = bridge.property("", .{ .template = false });
|
||||||
};
|
};
|
||||||
|
|
||||||
const testing = @import("../../testing.zig");
|
const testing = @import("../../testing.zig");
|
||||||
|
|||||||
@@ -24,10 +24,6 @@ pub fn init() IdleDeadline {
|
|||||||
return .{};
|
return .{};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDidTimeout(_: *const IdleDeadline) bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn timeRemaining(_: *const IdleDeadline) f64 {
|
pub fn timeRemaining(_: *const IdleDeadline) f64 {
|
||||||
// Return a fixed 50ms.
|
// Return a fixed 50ms.
|
||||||
// This allows idle callbacks to perform work without complex
|
// This allows idle callbacks to perform work without complex
|
||||||
@@ -47,5 +43,5 @@ pub const JsApi = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const timeRemaining = bridge.function(IdleDeadline.timeRemaining, .{});
|
pub const timeRemaining = bridge.function(IdleDeadline.timeRemaining, .{});
|
||||||
pub const didTimeout = bridge.accessor(IdleDeadline.getDidTimeout, null, .{});
|
pub const didTimeout = bridge.property(false, .{ .template = false });
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,16 +32,8 @@ pub fn getUserAgent(_: *const Navigator, page: *Page) []const u8 {
|
|||||||
return page._session.browser.app.config.http_headers.user_agent;
|
return page._session.browser.app.config.http_headers.user_agent;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getAppName(_: *const Navigator) []const u8 {
|
pub fn getLanguages(_: *const Navigator) [1][]const u8 {
|
||||||
return "Netscape";
|
return .{"en-US"};
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getAppCodeName(_: *const Navigator) []const u8 {
|
|
||||||
return "Netscape";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getAppVersion(_: *const Navigator) []const u8 {
|
|
||||||
return "1.0";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getPlatform(_: *const Navigator) []const u8 {
|
pub fn getPlatform(_: *const Navigator) []const u8 {
|
||||||
@@ -54,62 +46,15 @@ pub fn getPlatform(_: *const Navigator) []const u8 {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getLanguage(_: *const Navigator) []const u8 {
|
|
||||||
return "en-US";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getLanguages(_: *const Navigator) [1][]const u8 {
|
|
||||||
return .{"en-US"};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getOnLine(_: *const Navigator) bool {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getCookieEnabled(_: *const Navigator) bool {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getHardwareConcurrency(_: *const Navigator) u32 {
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getMaxTouchPoints(_: *const Navigator) u32 {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the vendor name
|
|
||||||
pub fn getVendor(_: *const Navigator) []const u8 {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the product name (typically "Gecko" for compatibility)
|
|
||||||
pub fn getProduct(_: *const Navigator) []const u8 {
|
|
||||||
return "Gecko";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns whether Java is enabled (always false)
|
/// Returns whether Java is enabled (always false)
|
||||||
pub fn javaEnabled(_: *const Navigator) bool {
|
pub fn javaEnabled(_: *const Navigator) bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether the browser is controlled by automation (always false)
|
|
||||||
pub fn getWebdriver(_: *const Navigator) bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getPlugins(self: *Navigator) *PluginArray {
|
pub fn getPlugins(self: *Navigator) *PluginArray {
|
||||||
return &self._plugins;
|
return &self._plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDoNotTrack(_: *const Navigator) ?[]const u8 {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getGlobalPrivacyControl(_: *const Navigator) bool {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn registerProtocolHandler(_: *const Navigator, scheme: []const u8, url: [:0]const u8, page: *const Page) !void {
|
pub fn registerProtocolHandler(_: *const Navigator, scheme: []const u8, url: [:0]const u8, page: *const Page) !void {
|
||||||
try validateProtocolHandlerScheme(scheme);
|
try validateProtocolHandlerScheme(scheme);
|
||||||
try validateProtocolHandlerURL(url, page);
|
try validateProtocolHandlerURL(url, page);
|
||||||
@@ -190,22 +135,22 @@ pub const JsApi = struct {
|
|||||||
|
|
||||||
// Read-only properties
|
// Read-only properties
|
||||||
pub const userAgent = bridge.accessor(Navigator.getUserAgent, null, .{});
|
pub const userAgent = bridge.accessor(Navigator.getUserAgent, null, .{});
|
||||||
pub const appName = bridge.accessor(Navigator.getAppName, null, .{});
|
pub const appName = bridge.property("Netscape", .{ .template = false });
|
||||||
pub const appCodeName = bridge.accessor(Navigator.getAppCodeName, null, .{});
|
pub const appCodeName = bridge.property("Netscape", .{ .template = false });
|
||||||
pub const appVersion = bridge.accessor(Navigator.getAppVersion, null, .{});
|
pub const appVersion = bridge.property("1.0", .{ .template = false });
|
||||||
pub const platform = bridge.accessor(Navigator.getPlatform, null, .{});
|
pub const platform = bridge.accessor(Navigator.getPlatform, null, .{});
|
||||||
pub const language = bridge.accessor(Navigator.getLanguage, null, .{});
|
pub const language = bridge.property("en-US", .{ .template = false });
|
||||||
pub const languages = bridge.accessor(Navigator.getLanguages, null, .{});
|
pub const languages = bridge.accessor(Navigator.getLanguages, null, .{});
|
||||||
pub const onLine = bridge.accessor(Navigator.getOnLine, null, .{});
|
pub const onLine = bridge.property(true, .{ .template = false });
|
||||||
pub const cookieEnabled = bridge.accessor(Navigator.getCookieEnabled, null, .{});
|
pub const cookieEnabled = bridge.property(true, .{ .template = false });
|
||||||
pub const hardwareConcurrency = bridge.accessor(Navigator.getHardwareConcurrency, null, .{});
|
pub const hardwareConcurrency = bridge.property(4, .{ .template = false });
|
||||||
pub const maxTouchPoints = bridge.accessor(Navigator.getMaxTouchPoints, null, .{});
|
pub const maxTouchPoints = bridge.property(0, .{ .template = false });
|
||||||
pub const vendor = bridge.accessor(Navigator.getVendor, null, .{});
|
pub const vendor = bridge.property("", .{ .template = false });
|
||||||
pub const product = bridge.accessor(Navigator.getProduct, null, .{});
|
pub const product = bridge.property("Gecko", .{ .template = false });
|
||||||
pub const webdriver = bridge.accessor(Navigator.getWebdriver, null, .{});
|
pub const webdriver = bridge.property(false, .{ .template = false });
|
||||||
pub const plugins = bridge.accessor(Navigator.getPlugins, null, .{});
|
pub const plugins = bridge.accessor(Navigator.getPlugins, null, .{});
|
||||||
pub const doNotTrack = bridge.accessor(Navigator.getDoNotTrack, null, .{});
|
pub const doNotTrack = bridge.property(null, .{ .template = false });
|
||||||
pub const globalPrivacyControl = bridge.accessor(Navigator.getGlobalPrivacyControl, null, .{});
|
pub const globalPrivacyControl = bridge.property(true, .{ .template = false });
|
||||||
pub const registerProtocolHandler = bridge.function(Navigator.registerProtocolHandler, .{ .dom_exception = true });
|
pub const registerProtocolHandler = bridge.function(Navigator.registerProtocolHandler, .{ .dom_exception = true });
|
||||||
pub const unregisterProtocolHandler = bridge.function(Navigator.unregisterProtocolHandler, .{ .dom_exception = true });
|
pub const unregisterProtocolHandler = bridge.function(Navigator.unregisterProtocolHandler, .{ .dom_exception = true });
|
||||||
|
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ const PluginArray = @This();
|
|||||||
|
|
||||||
_pad: bool = false,
|
_pad: bool = false,
|
||||||
|
|
||||||
pub fn getLength(_: *const PluginArray) u32 {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pub fn refresh(_: *const PluginArray) void {}
|
pub fn refresh(_: *const PluginArray) void {}
|
||||||
pub fn getAtIndex(_: *const PluginArray, index: usize) ?*Plugin {
|
pub fn getAtIndex(_: *const PluginArray, index: usize) ?*Plugin {
|
||||||
_ = index;
|
_ = index;
|
||||||
@@ -64,7 +61,7 @@ pub const JsApi = struct {
|
|||||||
pub const empty_with_no_proto = true;
|
pub const empty_with_no_proto = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const length = bridge.accessor(PluginArray.getLength, null, .{});
|
pub const length = bridge.property(0, .{ .template = false });
|
||||||
pub const refresh = bridge.function(PluginArray.refresh, .{});
|
pub const refresh = bridge.function(PluginArray.refresh, .{});
|
||||||
pub const @"[int]" = bridge.indexed(PluginArray.getAtIndex, .{ .null_as_undefined = true });
|
pub const @"[int]" = bridge.indexed(PluginArray.getAtIndex, .{ .null_as_undefined = true });
|
||||||
pub const @"[str]" = bridge.namedIndexed(PluginArray.getByName, null, null, .{ .null_as_undefined = true });
|
pub const @"[str]" = bridge.namedIndexed(PluginArray.getByName, null, null, .{ .null_as_undefined = true });
|
||||||
|
|||||||
@@ -43,30 +43,6 @@ pub fn asEventTarget(self: *Screen) *EventTarget {
|
|||||||
return self._proto;
|
return self._proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getWidth(_: *const Screen) u32 {
|
|
||||||
return 1920;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getHeight(_: *const Screen) u32 {
|
|
||||||
return 1080;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getAvailWidth(_: *const Screen) u32 {
|
|
||||||
return 1920;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getAvailHeight(_: *const Screen) u32 {
|
|
||||||
return 1040; // 40px reserved for taskbar/dock
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getColorDepth(_: *const Screen) u32 {
|
|
||||||
return 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getPixelDepth(_: *const Screen) u32 {
|
|
||||||
return 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getOrientation(self: *Screen, page: *Page) !*Orientation {
|
pub fn getOrientation(self: *Screen, page: *Page) !*Orientation {
|
||||||
if (self._orientation) |orientation| {
|
if (self._orientation) |orientation| {
|
||||||
return orientation;
|
return orientation;
|
||||||
@@ -85,12 +61,12 @@ pub const JsApi = struct {
|
|||||||
pub var class_id: bridge.ClassId = undefined;
|
pub var class_id: bridge.ClassId = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const width = bridge.accessor(Screen.getWidth, null, .{});
|
pub const width = bridge.property(1920, .{ .template = false });
|
||||||
pub const height = bridge.accessor(Screen.getHeight, null, .{});
|
pub const height = bridge.property(1080, .{ .template = false });
|
||||||
pub const availWidth = bridge.accessor(Screen.getAvailWidth, null, .{});
|
pub const availWidth = bridge.property(1920, .{ .template = false });
|
||||||
pub const availHeight = bridge.accessor(Screen.getAvailHeight, null, .{});
|
pub const availHeight = bridge.property(1040, .{ .template = false });
|
||||||
pub const colorDepth = bridge.accessor(Screen.getColorDepth, null, .{});
|
pub const colorDepth = bridge.property(24, .{ .template = false });
|
||||||
pub const pixelDepth = bridge.accessor(Screen.getPixelDepth, null, .{});
|
pub const pixelDepth = bridge.property(24, .{ .template = false });
|
||||||
pub const orientation = bridge.accessor(Screen.getOrientation, null, .{});
|
pub const orientation = bridge.accessor(Screen.getOrientation, null, .{});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -107,14 +83,6 @@ pub const Orientation = struct {
|
|||||||
return self._proto;
|
return self._proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getAngle(_: *const Orientation) u32 {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getType(_: *const Orientation) []const u8 {
|
|
||||||
return "landscape-primary";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const JsApi = struct {
|
pub const JsApi = struct {
|
||||||
pub const bridge = js.Bridge(Orientation);
|
pub const bridge = js.Bridge(Orientation);
|
||||||
|
|
||||||
@@ -124,7 +92,7 @@ pub const Orientation = struct {
|
|||||||
pub var class_id: bridge.ClassId = undefined;
|
pub var class_id: bridge.ClassId = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const angle = bridge.accessor(Orientation.getAngle, null, .{});
|
pub const angle = bridge.property(0, .{ .template = false });
|
||||||
pub const @"type" = bridge.accessor(Orientation.getType, null, .{});
|
pub const @"type" = bridge.property("landscape-primary", .{ .template = false });
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -341,14 +341,6 @@ pub fn getComputedStyle(_: *const Window, element: *Element, pseudo_element: ?[]
|
|||||||
return CSSStyleProperties.init(element, true, page);
|
return CSSStyleProperties.init(element, true, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getIsSecureContext(_: *const Window) bool {
|
|
||||||
// Return false since we don't have secure-context-only APIs implemented
|
|
||||||
// (webcam, geolocation, clipboard, etc.)
|
|
||||||
// This is safer and could help avoid processing errors by hinting at
|
|
||||||
// sites not to try to access those features
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn postMessage(self: *Window, message: js.Value.Global, target_origin: ?[]const u8, page: *Page) !void {
|
pub fn postMessage(self: *Window, message: js.Value.Global, target_origin: ?[]const u8, page: *Page) !void {
|
||||||
// For now, we ignore targetOrigin checking and just dispatch the message
|
// For now, we ignore targetOrigin checking and just dispatch the message
|
||||||
// In a full implementation, we would validate the origin
|
// In a full implementation, we would validate the origin
|
||||||
@@ -405,14 +397,6 @@ pub fn getFramesLength(self: *const Window) u32 {
|
|||||||
return ln;
|
return ln;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getInnerWidth(_: *const Window) u32 {
|
|
||||||
return 1920;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getInnerHeight(_: *const Window) u32 {
|
|
||||||
return 1080;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getScrollX(self: *const Window) u32 {
|
pub fn getScrollX(self: *const Window) u32 {
|
||||||
return self._scroll_pos.x;
|
return self._scroll_pos.x;
|
||||||
}
|
}
|
||||||
@@ -421,12 +405,6 @@ pub fn getScrollY(self: *const Window) u32 {
|
|||||||
return self._scroll_pos.y;
|
return self._scroll_pos.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getOpener(_: *const Window) ?*Window {
|
|
||||||
// This should return a window-like object in specific conditions. Would be
|
|
||||||
// pretty complicated to properly support I think.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ScrollToOpts = union(enum) {
|
const ScrollToOpts = union(enum) {
|
||||||
x: i32,
|
x: i32,
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
@@ -743,19 +721,28 @@ pub const JsApi = struct {
|
|||||||
pub const reportError = bridge.function(Window.reportError, .{});
|
pub const reportError = bridge.function(Window.reportError, .{});
|
||||||
pub const getComputedStyle = bridge.function(Window.getComputedStyle, .{});
|
pub const getComputedStyle = bridge.function(Window.getComputedStyle, .{});
|
||||||
pub const getSelection = bridge.function(Window.getSelection, .{});
|
pub const getSelection = bridge.function(Window.getSelection, .{});
|
||||||
pub const isSecureContext = bridge.accessor(Window.getIsSecureContext, null, .{});
|
|
||||||
pub const frames = bridge.accessor(Window.getWindow, null, .{ .cache = "frames" });
|
pub const frames = bridge.accessor(Window.getWindow, null, .{ .cache = "frames" });
|
||||||
pub const index = bridge.indexed(Window.getFrame, .{ .null_as_undefined = true });
|
pub const index = bridge.indexed(Window.getFrame, .{ .null_as_undefined = true });
|
||||||
pub const length = bridge.accessor(Window.getFramesLength, null, .{ .cache = "length" });
|
pub const length = bridge.accessor(Window.getFramesLength, null, .{ .cache = "length" });
|
||||||
pub const innerWidth = bridge.accessor(Window.getInnerWidth, null, .{ .cache = "innerWidth" });
|
|
||||||
pub const innerHeight = bridge.accessor(Window.getInnerHeight, null, .{ .cache = "innerHeight" });
|
|
||||||
pub const scrollX = bridge.accessor(Window.getScrollX, null, .{ .cache = "scrollX" });
|
pub const scrollX = bridge.accessor(Window.getScrollX, null, .{ .cache = "scrollX" });
|
||||||
pub const scrollY = bridge.accessor(Window.getScrollY, null, .{ .cache = "scrollY" });
|
pub const scrollY = bridge.accessor(Window.getScrollY, null, .{ .cache = "scrollY" });
|
||||||
pub const pageXOffset = bridge.accessor(Window.getScrollX, null, .{ .cache = "pageXOffset" });
|
pub const pageXOffset = bridge.accessor(Window.getScrollX, null, .{ .cache = "pageXOffset" });
|
||||||
pub const pageYOffset = bridge.accessor(Window.getScrollY, null, .{ .cache = "pageYOffset" });
|
pub const pageYOffset = bridge.accessor(Window.getScrollY, null, .{ .cache = "pageYOffset" });
|
||||||
pub const scrollTo = bridge.function(Window.scrollTo, .{});
|
pub const scrollTo = bridge.function(Window.scrollTo, .{});
|
||||||
pub const scroll = bridge.function(Window.scrollTo, .{});
|
pub const scroll = bridge.function(Window.scrollTo, .{});
|
||||||
pub const opener = bridge.accessor(Window.getOpener, null, .{});
|
|
||||||
|
// Return false since we don't have secure-context-only APIs implemented
|
||||||
|
// (webcam, geolocation, clipboard, etc.)
|
||||||
|
// This is safer and could help avoid processing errors by hinting at
|
||||||
|
// sites not to try to access those features
|
||||||
|
pub const isSecureContext = bridge.property(false, .{ .template = false });
|
||||||
|
|
||||||
|
pub const innerWidth = bridge.property(1920, .{ .template = false });
|
||||||
|
pub const innerHeight = bridge.property(1080, .{ .template = false });
|
||||||
|
// This should return a window-like object in specific conditions. Would be
|
||||||
|
// pretty complicated to properly support I think.
|
||||||
|
pub const opener = bridge.property(null, .{ .template = false });
|
||||||
};
|
};
|
||||||
|
|
||||||
const testing = @import("../../testing.zig");
|
const testing = @import("../../testing.zig");
|
||||||
|
|||||||
@@ -36,14 +36,6 @@ pub fn cancel(_: *Animation) void {}
|
|||||||
pub fn finish(_: *Animation) void {}
|
pub fn finish(_: *Animation) void {}
|
||||||
pub fn reverse(_: *Animation) void {}
|
pub fn reverse(_: *Animation) void {}
|
||||||
|
|
||||||
pub fn getPlayState(_: *const Animation) []const u8 {
|
|
||||||
return "finished";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getPending(_: *const Animation) bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getFinished(self: *Animation, page: *Page) !js.Promise {
|
pub fn getFinished(self: *Animation, page: *Page) !js.Promise {
|
||||||
if (self._finished_resolver == null) {
|
if (self._finished_resolver == null) {
|
||||||
const resolver = page.js.local.?.createPromiseResolver();
|
const resolver = page.js.local.?.createPromiseResolver();
|
||||||
@@ -94,8 +86,8 @@ pub const JsApi = struct {
|
|||||||
pub const cancel = bridge.function(Animation.cancel, .{});
|
pub const cancel = bridge.function(Animation.cancel, .{});
|
||||||
pub const finish = bridge.function(Animation.finish, .{});
|
pub const finish = bridge.function(Animation.finish, .{});
|
||||||
pub const reverse = bridge.function(Animation.reverse, .{});
|
pub const reverse = bridge.function(Animation.reverse, .{});
|
||||||
pub const playState = bridge.accessor(Animation.getPlayState, null, .{});
|
pub const playState = bridge.property("finished", .{ .template = false });
|
||||||
pub const pending = bridge.accessor(Animation.getPending, null, .{});
|
pub const pending = bridge.property(false, .{ .template = false });
|
||||||
pub const finished = bridge.accessor(Animation.getFinished, null, .{});
|
pub const finished = bridge.accessor(Animation.getFinished, null, .{});
|
||||||
pub const ready = bridge.accessor(Animation.getReady, null, .{});
|
pub const ready = bridge.accessor(Animation.getReady, null, .{});
|
||||||
pub const effect = bridge.accessor(Animation.getEffect, Animation.setEffect, .{});
|
pub const effect = bridge.accessor(Animation.getEffect, Animation.setEffect, .{});
|
||||||
|
|||||||
@@ -65,10 +65,6 @@ pub fn deinit(self: *TextDecoder, _: bool) void {
|
|||||||
self._page.releaseArena(self._arena);
|
self._page.releaseArena(self._arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getEncoding(_: *const TextDecoder) []const u8 {
|
|
||||||
return "utf-8";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getIgnoreBOM(self: *const TextDecoder) bool {
|
pub fn getIgnoreBOM(self: *const TextDecoder) bool {
|
||||||
return self._ignore_bom;
|
return self._ignore_bom;
|
||||||
}
|
}
|
||||||
@@ -120,7 +116,7 @@ pub const JsApi = struct {
|
|||||||
|
|
||||||
pub const constructor = bridge.constructor(TextDecoder.init, .{});
|
pub const constructor = bridge.constructor(TextDecoder.init, .{});
|
||||||
pub const decode = bridge.function(TextDecoder.decode, .{});
|
pub const decode = bridge.function(TextDecoder.decode, .{});
|
||||||
pub const encoding = bridge.accessor(TextDecoder.getEncoding, null, .{});
|
pub const encoding = bridge.property("utf-8", .{ .template = false });
|
||||||
pub const fatal = bridge.accessor(TextDecoder.getFatal, null, .{});
|
pub const fatal = bridge.accessor(TextDecoder.getFatal, null, .{});
|
||||||
pub const ignoreBOM = bridge.accessor(TextDecoder.getIgnoreBOM, null, .{});
|
pub const ignoreBOM = bridge.accessor(TextDecoder.getIgnoreBOM, null, .{});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,10 +26,6 @@ pub fn init() TextEncoder {
|
|||||||
return .{};
|
return .{};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getEncoding(_: *const TextEncoder) []const u8 {
|
|
||||||
return "utf-8";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn encode(_: *const TextEncoder, v: []const u8) !js.TypedArray(u8) {
|
pub fn encode(_: *const TextEncoder, v: []const u8) !js.TypedArray(u8) {
|
||||||
if (!std.unicode.utf8ValidateSlice(v)) {
|
if (!std.unicode.utf8ValidateSlice(v)) {
|
||||||
return error.InvalidUtf8;
|
return error.InvalidUtf8;
|
||||||
@@ -50,7 +46,7 @@ pub const JsApi = struct {
|
|||||||
|
|
||||||
pub const constructor = bridge.constructor(TextEncoder.init, .{});
|
pub const constructor = bridge.constructor(TextEncoder.init, .{});
|
||||||
pub const encode = bridge.function(TextEncoder.encode, .{ .as_typed_array = true });
|
pub const encode = bridge.function(TextEncoder.encode, .{ .as_typed_array = true });
|
||||||
pub const encoding = bridge.accessor(TextEncoder.getEncoding, null, .{});
|
pub const encoding = bridge.property("utf-8", .{ .template = false });
|
||||||
};
|
};
|
||||||
|
|
||||||
const testing = @import("../../../testing.zig");
|
const testing = @import("../../../testing.zig");
|
||||||
|
|||||||
@@ -139,14 +139,6 @@ pub fn getMetaKey(self: *const MouseEvent) bool {
|
|||||||
return self._meta_key;
|
return self._meta_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getOffsetX(_: *const MouseEvent) f64 {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getOffsetY(_: *const MouseEvent) f64 {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getPageX(self: *const MouseEvent) f64 {
|
pub fn getPageX(self: *const MouseEvent) f64 {
|
||||||
// this should be clientX + window.scrollX
|
// this should be clientX + window.scrollX
|
||||||
return self._client_x;
|
return self._client_x;
|
||||||
@@ -189,8 +181,8 @@ pub const JsApi = struct {
|
|||||||
pub const clientY = bridge.accessor(getClientY, null, .{});
|
pub const clientY = bridge.accessor(getClientY, null, .{});
|
||||||
pub const ctrlKey = bridge.accessor(getCtrlKey, null, .{});
|
pub const ctrlKey = bridge.accessor(getCtrlKey, null, .{});
|
||||||
pub const metaKey = bridge.accessor(getMetaKey, null, .{});
|
pub const metaKey = bridge.accessor(getMetaKey, null, .{});
|
||||||
pub const offsetX = bridge.accessor(getOffsetX, null, .{});
|
pub const offsetX = bridge.property(0.0, .{ .template = false });
|
||||||
pub const offsetY = bridge.accessor(getOffsetY, null, .{});
|
pub const offsetY = bridge.property(0.0, .{ .template = false });
|
||||||
pub const pageX = bridge.accessor(getPageX, null, .{});
|
pub const pageX = bridge.accessor(getPageX, null, .{});
|
||||||
pub const pageY = bridge.accessor(getPageY, null, .{});
|
pub const pageY = bridge.accessor(getPageY, null, .{});
|
||||||
pub const relatedTarget = bridge.accessor(getRelatedTarget, null, .{});
|
pub const relatedTarget = bridge.accessor(getRelatedTarget, null, .{});
|
||||||
|
|||||||
Reference in New Issue
Block a user