mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 07:03:29 +00:00
Merge pull request #786 from lightpanda-io/custom-elements
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / puppeteer-perf (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
zig-test / zig build dev (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
Some checks failed
e2e-test / zig build release (push) Has been cancelled
e2e-test / puppeteer-perf (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
zig-test / zig build dev (push) Has been cancelled
zig-test / browser fetch (push) Has been cancelled
zig-test / zig test (push) Has been cancelled
zig-test / perf-fmt (push) Has been cancelled
nightly build / build-linux-x86_64 (push) Has been cancelled
nightly build / build-linux-aarch64 (push) Has been cancelled
nightly build / build-macos-aarch64 (push) Has been cancelled
nightly build / build-macos-x86_64 (push) Has been cancelled
wpt / web platform tests json output (push) Has been cancelled
wpt / perf-fmt (push) Has been cancelled
add CustomElementRegistry
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
const log = @import("../../log.zig");
|
||||||
const parser = @import("../netsurf.zig");
|
const parser = @import("../netsurf.zig");
|
||||||
const Page = @import("../page.zig").Page;
|
const Page = @import("../page.zig").Page;
|
||||||
|
|
||||||
@@ -120,9 +121,28 @@ pub const Document = struct {
|
|||||||
return try Element.toInterface(e);
|
return try Element.toInterface(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _createElement(self: *parser.Document, tag_name: []const u8) !ElementUnion {
|
const CreateElementResult = union(enum) {
|
||||||
const e = try parser.documentCreateElement(self, tag_name);
|
element: ElementUnion,
|
||||||
return try Element.toInterface(e);
|
custom: Env.JsObject,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn _createElement(self: *parser.Document, tag_name: []const u8, page: *Page) !CreateElementResult {
|
||||||
|
const custom_element = page.window.custom_elements._get(tag_name) orelse {
|
||||||
|
const e = try parser.documentCreateElement(self, tag_name);
|
||||||
|
return .{ .element = try Element.toInterface(e) };
|
||||||
|
};
|
||||||
|
|
||||||
|
var result: Env.Function.Result = undefined;
|
||||||
|
const js_obj = custom_element.newInstance(&result) catch |err| {
|
||||||
|
log.fatal(.user_script, "newInstance error", .{
|
||||||
|
.err = result.exception,
|
||||||
|
.stack = result.stack,
|
||||||
|
.tag_name = tag_name,
|
||||||
|
.source = "createElement",
|
||||||
|
});
|
||||||
|
return err;
|
||||||
|
};
|
||||||
|
return .{ .custom = js_obj };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn _createElementNS(self: *parser.Document, ns: []const u8, tag_name: []const u8) !ElementUnion {
|
pub fn _createElementNS(self: *parser.Document, ns: []const u8, tag_name: []const u8) !ElementUnion {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ const WebApis = struct {
|
|||||||
@import("xhr/xhr.zig").Interfaces,
|
@import("xhr/xhr.zig").Interfaces,
|
||||||
@import("xhr/form_data.zig").Interfaces,
|
@import("xhr/form_data.zig").Interfaces,
|
||||||
@import("xmlserializer/xmlserializer.zig").Interfaces,
|
@import("xmlserializer/xmlserializer.zig").Interfaces,
|
||||||
|
@import("webcomponents/webcomponents.zig").Interfaces,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const log = @import("../../log.zig");
|
||||||
|
|
||||||
const parser = @import("../netsurf.zig");
|
const parser = @import("../netsurf.zig");
|
||||||
const generate = @import("../../runtime/generate.zig");
|
const generate = @import("../../runtime/generate.zig");
|
||||||
@@ -112,6 +113,10 @@ pub const HTMLElement = struct {
|
|||||||
pub const prototype = *Element;
|
pub const prototype = *Element;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_style(e: *parser.ElementHTML, page: *Page) !*CSSStyleDeclaration {
|
pub fn get_style(e: *parser.ElementHTML, page: *Page) !*CSSStyleDeclaration {
|
||||||
const state = try page.getOrCreateNodeState(@ptrCast(e));
|
const state = try page.getOrCreateNodeState(@ptrCast(e));
|
||||||
return &state.style;
|
return &state.style;
|
||||||
@@ -174,6 +179,10 @@ pub const HTMLMediaElement = struct {
|
|||||||
pub const Self = parser.MediaElement;
|
pub const Self = parser.MediaElement;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// HTML elements
|
// HTML elements
|
||||||
@@ -183,6 +192,10 @@ pub const HTMLUnknownElement = struct {
|
|||||||
pub const Self = parser.Unknown;
|
pub const Self = parser.Unknown;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/#the-a-element
|
// https://html.spec.whatwg.org/#the-a-element
|
||||||
@@ -191,6 +204,10 @@ pub const HTMLAnchorElement = struct {
|
|||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_target(self: *parser.Anchor) ![]const u8 {
|
pub fn get_target(self: *parser.Anchor) ![]const u8 {
|
||||||
return try parser.anchorGetTarget(self);
|
return try parser.anchorGetTarget(self);
|
||||||
}
|
}
|
||||||
@@ -428,144 +445,240 @@ pub const HTMLAppletElement = struct {
|
|||||||
pub const Self = parser.Applet;
|
pub const Self = parser.Applet;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLAreaElement = struct {
|
pub const HTMLAreaElement = struct {
|
||||||
pub const Self = parser.Area;
|
pub const Self = parser.Area;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLAudioElement = struct {
|
pub const HTMLAudioElement = struct {
|
||||||
pub const Self = parser.Audio;
|
pub const Self = parser.Audio;
|
||||||
pub const prototype = *HTMLMediaElement;
|
pub const prototype = *HTMLMediaElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLBRElement = struct {
|
pub const HTMLBRElement = struct {
|
||||||
pub const Self = parser.BR;
|
pub const Self = parser.BR;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLBaseElement = struct {
|
pub const HTMLBaseElement = struct {
|
||||||
pub const Self = parser.Base;
|
pub const Self = parser.Base;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLBodyElement = struct {
|
pub const HTMLBodyElement = struct {
|
||||||
pub const Self = parser.Body;
|
pub const Self = parser.Body;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLButtonElement = struct {
|
pub const HTMLButtonElement = struct {
|
||||||
pub const Self = parser.Button;
|
pub const Self = parser.Button;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLCanvasElement = struct {
|
pub const HTMLCanvasElement = struct {
|
||||||
pub const Self = parser.Canvas;
|
pub const Self = parser.Canvas;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLDListElement = struct {
|
pub const HTMLDListElement = struct {
|
||||||
pub const Self = parser.DList;
|
pub const Self = parser.DList;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLDataElement = struct {
|
pub const HTMLDataElement = struct {
|
||||||
pub const Self = parser.Data;
|
pub const Self = parser.Data;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLDataListElement = struct {
|
pub const HTMLDataListElement = struct {
|
||||||
pub const Self = parser.DataList;
|
pub const Self = parser.DataList;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLDialogElement = struct {
|
pub const HTMLDialogElement = struct {
|
||||||
pub const Self = parser.Dialog;
|
pub const Self = parser.Dialog;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLDirectoryElement = struct {
|
pub const HTMLDirectoryElement = struct {
|
||||||
pub const Self = parser.Directory;
|
pub const Self = parser.Directory;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLDivElement = struct {
|
pub const HTMLDivElement = struct {
|
||||||
pub const Self = parser.Div;
|
pub const Self = parser.Div;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLEmbedElement = struct {
|
pub const HTMLEmbedElement = struct {
|
||||||
pub const Self = parser.Embed;
|
pub const Self = parser.Embed;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLFieldSetElement = struct {
|
pub const HTMLFieldSetElement = struct {
|
||||||
pub const Self = parser.FieldSet;
|
pub const Self = parser.FieldSet;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLFontElement = struct {
|
pub const HTMLFontElement = struct {
|
||||||
pub const Self = parser.Font;
|
pub const Self = parser.Font;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLFrameElement = struct {
|
pub const HTMLFrameElement = struct {
|
||||||
pub const Self = parser.Frame;
|
pub const Self = parser.Frame;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLFrameSetElement = struct {
|
pub const HTMLFrameSetElement = struct {
|
||||||
pub const Self = parser.FrameSet;
|
pub const Self = parser.FrameSet;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLHRElement = struct {
|
pub const HTMLHRElement = struct {
|
||||||
pub const Self = parser.HR;
|
pub const Self = parser.HR;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLHeadElement = struct {
|
pub const HTMLHeadElement = struct {
|
||||||
pub const Self = parser.Head;
|
pub const Self = parser.Head;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLHeadingElement = struct {
|
pub const HTMLHeadingElement = struct {
|
||||||
pub const Self = parser.Heading;
|
pub const Self = parser.Heading;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLHtmlElement = struct {
|
pub const HTMLHtmlElement = struct {
|
||||||
pub const Self = parser.Html;
|
pub const Self = parser.Html;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLIFrameElement = struct {
|
pub const HTMLIFrameElement = struct {
|
||||||
pub const Self = parser.IFrame;
|
pub const Self = parser.IFrame;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLImageElement = struct {
|
pub const HTMLImageElement = struct {
|
||||||
@@ -573,6 +686,10 @@ pub const HTMLImageElement = struct {
|
|||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_alt(self: *parser.Image) ![]const u8 {
|
pub fn get_alt(self: *parser.Image) ![]const u8 {
|
||||||
return try parser.imageGetAlt(self);
|
return try parser.imageGetAlt(self);
|
||||||
}
|
}
|
||||||
@@ -613,6 +730,7 @@ pub const HTMLImageElement = struct {
|
|||||||
pub const Factory = struct {
|
pub const Factory = struct {
|
||||||
pub const js_name = "Image";
|
pub const js_name = "Image";
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
pub const js_legacy_factory = true;
|
pub const js_legacy_factory = true;
|
||||||
pub const prototype = *HTMLImageElement;
|
pub const prototype = *HTMLImageElement;
|
||||||
|
|
||||||
@@ -631,6 +749,10 @@ pub const HTMLInputElement = struct {
|
|||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_defaultValue(self: *parser.Input) ![]const u8 {
|
pub fn get_defaultValue(self: *parser.Input) ![]const u8 {
|
||||||
return try parser.inputGetDefaultValue(self);
|
return try parser.inputGetDefaultValue(self);
|
||||||
}
|
}
|
||||||
@@ -719,114 +841,190 @@ pub const HTMLLIElement = struct {
|
|||||||
pub const Self = parser.LI;
|
pub const Self = parser.LI;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLLabelElement = struct {
|
pub const HTMLLabelElement = struct {
|
||||||
pub const Self = parser.Label;
|
pub const Self = parser.Label;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLLegendElement = struct {
|
pub const HTMLLegendElement = struct {
|
||||||
pub const Self = parser.Legend;
|
pub const Self = parser.Legend;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLLinkElement = struct {
|
pub const HTMLLinkElement = struct {
|
||||||
pub const Self = parser.Link;
|
pub const Self = parser.Link;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLMapElement = struct {
|
pub const HTMLMapElement = struct {
|
||||||
pub const Self = parser.Map;
|
pub const Self = parser.Map;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLMetaElement = struct {
|
pub const HTMLMetaElement = struct {
|
||||||
pub const Self = parser.Meta;
|
pub const Self = parser.Meta;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLMeterElement = struct {
|
pub const HTMLMeterElement = struct {
|
||||||
pub const Self = parser.Meter;
|
pub const Self = parser.Meter;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLModElement = struct {
|
pub const HTMLModElement = struct {
|
||||||
pub const Self = parser.Mod;
|
pub const Self = parser.Mod;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLOListElement = struct {
|
pub const HTMLOListElement = struct {
|
||||||
pub const Self = parser.OList;
|
pub const Self = parser.OList;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLObjectElement = struct {
|
pub const HTMLObjectElement = struct {
|
||||||
pub const Self = parser.Object;
|
pub const Self = parser.Object;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLOptGroupElement = struct {
|
pub const HTMLOptGroupElement = struct {
|
||||||
pub const Self = parser.OptGroup;
|
pub const Self = parser.OptGroup;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLOptionElement = struct {
|
pub const HTMLOptionElement = struct {
|
||||||
pub const Self = parser.Option;
|
pub const Self = parser.Option;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLOutputElement = struct {
|
pub const HTMLOutputElement = struct {
|
||||||
pub const Self = parser.Output;
|
pub const Self = parser.Output;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLParagraphElement = struct {
|
pub const HTMLParagraphElement = struct {
|
||||||
pub const Self = parser.Paragraph;
|
pub const Self = parser.Paragraph;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLParamElement = struct {
|
pub const HTMLParamElement = struct {
|
||||||
pub const Self = parser.Param;
|
pub const Self = parser.Param;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLPictureElement = struct {
|
pub const HTMLPictureElement = struct {
|
||||||
pub const Self = parser.Picture;
|
pub const Self = parser.Picture;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLPreElement = struct {
|
pub const HTMLPreElement = struct {
|
||||||
pub const Self = parser.Pre;
|
pub const Self = parser.Pre;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLProgressElement = struct {
|
pub const HTMLProgressElement = struct {
|
||||||
pub const Self = parser.Progress;
|
pub const Self = parser.Progress;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLQuoteElement = struct {
|
pub const HTMLQuoteElement = struct {
|
||||||
pub const Self = parser.Quote;
|
pub const Self = parser.Quote;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/#the-script-element
|
// https://html.spec.whatwg.org/#the-script-element
|
||||||
@@ -835,6 +1033,10 @@ pub const HTMLScriptElement = struct {
|
|||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_src(self: *parser.Script) !?[]const u8 {
|
pub fn get_src(self: *parser.Script) !?[]const u8 {
|
||||||
return try parser.elementGetAttribute(
|
return try parser.elementGetAttribute(
|
||||||
parser.scriptToElt(self),
|
parser.scriptToElt(self),
|
||||||
@@ -969,101 +1171,166 @@ pub const HTMLSourceElement = struct {
|
|||||||
pub const Self = parser.Source;
|
pub const Self = parser.Source;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLSpanElement = struct {
|
pub const HTMLSpanElement = struct {
|
||||||
pub const Self = parser.Span;
|
pub const Self = parser.Span;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLStyleElement = struct {
|
pub const HTMLStyleElement = struct {
|
||||||
pub const Self = parser.Style;
|
pub const Self = parser.Style;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLTableElement = struct {
|
pub const HTMLTableElement = struct {
|
||||||
pub const Self = parser.Table;
|
pub const Self = parser.Table;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLTableCaptionElement = struct {
|
pub const HTMLTableCaptionElement = struct {
|
||||||
pub const Self = parser.TableCaption;
|
pub const Self = parser.TableCaption;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLTableCellElement = struct {
|
pub const HTMLTableCellElement = struct {
|
||||||
pub const Self = parser.TableCell;
|
pub const Self = parser.TableCell;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLTableColElement = struct {
|
pub const HTMLTableColElement = struct {
|
||||||
pub const Self = parser.TableCol;
|
pub const Self = parser.TableCol;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLTableRowElement = struct {
|
pub const HTMLTableRowElement = struct {
|
||||||
pub const Self = parser.TableRow;
|
pub const Self = parser.TableRow;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLTableSectionElement = struct {
|
pub const HTMLTableSectionElement = struct {
|
||||||
pub const Self = parser.TableSection;
|
pub const Self = parser.TableSection;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLTemplateElement = struct {
|
pub const HTMLTemplateElement = struct {
|
||||||
pub const Self = parser.Template;
|
pub const Self = parser.Template;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLTextAreaElement = struct {
|
pub const HTMLTextAreaElement = struct {
|
||||||
pub const Self = parser.TextArea;
|
pub const Self = parser.TextArea;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLTimeElement = struct {
|
pub const HTMLTimeElement = struct {
|
||||||
pub const Self = parser.Time;
|
pub const Self = parser.Time;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLTitleElement = struct {
|
pub const HTMLTitleElement = struct {
|
||||||
pub const Self = parser.Title;
|
pub const Self = parser.Title;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLTrackElement = struct {
|
pub const HTMLTrackElement = struct {
|
||||||
pub const Self = parser.Track;
|
pub const Self = parser.Track;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLUListElement = struct {
|
pub const HTMLUListElement = struct {
|
||||||
pub const Self = parser.UList;
|
pub const Self = parser.UList;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const HTMLVideoElement = struct {
|
pub const HTMLVideoElement = struct {
|
||||||
pub const Self = parser.Video;
|
pub const Self = parser.Video;
|
||||||
pub const prototype = *HTMLElement;
|
pub const prototype = *HTMLElement;
|
||||||
pub const subtype = .node;
|
pub const subtype = .node;
|
||||||
|
|
||||||
|
pub fn constructor(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
return constructHtmlElement(page, js_this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn toInterface(comptime T: type, e: *parser.Element) !T {
|
pub fn toInterface(comptime T: type, e: *parser.Element) !T {
|
||||||
const elem: *align(@alignOf(*parser.Element)) parser.Element = @alignCast(e);
|
const elem: *align(@alignOf(*parser.Element)) parser.Element = @alignCast(e);
|
||||||
const tag = try parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(elem)));
|
const tag = try parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(elem)));
|
||||||
|
|
||||||
return switch (tag) {
|
return switch (tag) {
|
||||||
.abbr, .acronym, .address, .article, .aside, .b, .basefont, .bdi, .bdo, .bgsound, .big, .center, .cite, .code, .dd, .details, .dfn, .dt, .em, .figcaption, .figure, .footer, .header, .hgroup, .i, .isindex, .keygen, .kbd, .main, .mark, .marquee, .menu, .menuitem, .nav, .nobr, .noframes, .noscript, .rp, .rt, .ruby, .s, .samp, .section, .small, .spacer, .strike, .strong, .sub, .summary, .sup, .tt, .u, .wbr, ._var => .{ .HTMLElement = @as(*parser.ElementHTML, @ptrCast(elem)) },
|
.abbr, .acronym, .address, .article, .aside, .b, .basefont, .bdi, .bdo, .bgsound, .big, .center, .cite, .code, .dd, .details, .dfn, .dt, .em, .figcaption, .figure, .footer, .header, .hgroup, .i, .isindex, .keygen, .kbd, .main, .mark, .marquee, .menu, .menuitem, .nav, .nobr, .noframes, .noscript, .rp, .rt, .ruby, .s, .samp, .section, .small, .spacer, .strike, .strong, .sub, .summary, .sup, .tt, .u, .wbr, ._var => .{ .HTMLElement = @as(*parser.ElementHTML, @ptrCast(elem)) },
|
||||||
.a => .{ .HTMLAnchorElement = @as(*parser.Anchor, @ptrCast(elem)) },
|
.a => .{ .HTMLAnchorElement = @as(*parser.Anchor, @ptrCast(elem)) },
|
||||||
@@ -1135,6 +1402,16 @@ pub fn toInterface(comptime T: type, e: *parser.Element) !T {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn constructHtmlElement(page: *Page, js_this: Env.JsThis) !*parser.Element {
|
||||||
|
const constructor_name = try js_this.constructorName(page.call_arena);
|
||||||
|
if (!page.window.custom_elements.lookup.contains(constructor_name)) {
|
||||||
|
return error.IllegalContructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const el = try parser.documentCreateElement(@ptrCast(page.window.document), constructor_name);
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
const testing = @import("../../testing.zig");
|
const testing = @import("../../testing.zig");
|
||||||
test "Browser.HTML.Element" {
|
test "Browser.HTML.Element" {
|
||||||
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
|
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ const EventTarget = @import("../dom/event_target.zig").EventTarget;
|
|||||||
const MediaQueryList = @import("media_query_list.zig").MediaQueryList;
|
const MediaQueryList = @import("media_query_list.zig").MediaQueryList;
|
||||||
const Performance = @import("performance.zig").Performance;
|
const Performance = @import("performance.zig").Performance;
|
||||||
const CSSStyleDeclaration = @import("../cssom/css_style_declaration.zig").CSSStyleDeclaration;
|
const CSSStyleDeclaration = @import("../cssom/css_style_declaration.zig").CSSStyleDeclaration;
|
||||||
|
const CustomElementRegistry = @import("../webcomponents/custom_element_registry.zig").CustomElementRegistry;
|
||||||
|
|
||||||
const storage = @import("../storage/storage.zig");
|
const storage = @import("../storage/storage.zig");
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ pub const Window = struct {
|
|||||||
console: Console = .{},
|
console: Console = .{},
|
||||||
navigator: Navigator = .{},
|
navigator: Navigator = .{},
|
||||||
performance: Performance,
|
performance: Performance,
|
||||||
|
custom_elements: CustomElementRegistry = .{},
|
||||||
|
|
||||||
pub fn create(target: ?[]const u8, navigator: ?Navigator) !Window {
|
pub fn create(target: ?[]const u8, navigator: ?Navigator) !Window {
|
||||||
var fbs = std.io.fixedBufferStream("");
|
var fbs = std.io.fixedBufferStream("");
|
||||||
@@ -163,6 +165,10 @@ pub const Window = struct {
|
|||||||
return &self.performance;
|
return &self.performance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_customElements(self: *Window) *CustomElementRegistry {
|
||||||
|
return &self.custom_elements;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn _requestAnimationFrame(self: *Window, cbk: Function, page: *Page) !u32 {
|
pub fn _requestAnimationFrame(self: *Window, cbk: Function, page: *Page) !u32 {
|
||||||
return self.createTimeout(cbk, 5, page, .{ .animation_frame = true });
|
return self.createTimeout(cbk, 5, page, .{ .animation_frame = true });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -352,8 +352,23 @@ pub const Page = struct {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const e = parser.nodeToElement(next.?);
|
const current = next.?;
|
||||||
|
|
||||||
|
const e = parser.nodeToElement(current);
|
||||||
const tag = try parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(e)));
|
const tag = try parser.elementHTMLGetTagType(@as(*parser.ElementHTML, @ptrCast(e)));
|
||||||
|
|
||||||
|
// if (tag == .undef) {
|
||||||
|
// const tag_name = try parser.nodeLocalName(@ptrCast(e));
|
||||||
|
// const custom_elements = &self.window.custom_elements;
|
||||||
|
// if (custom_elements._get(tag_name)) |construct| {
|
||||||
|
// try construct.printFunc();
|
||||||
|
// // This is just here for testing for now.
|
||||||
|
// // var result: Env.Function.Result = undefined;
|
||||||
|
// // _ = try construct.newInstance(*parser.Element, &result);
|
||||||
|
// log.info(.browser, "Registered WebComponent Found", .{ .element_name = tag_name });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
if (tag != .script) {
|
if (tag != .script) {
|
||||||
// ignore non-js script.
|
// ignore non-js script.
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
91
src/browser/webcomponents/custom_element_registry.zig
Normal file
91
src/browser/webcomponents/custom_element_registry.zig
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
// Copyright (C) 2023-2024 Lightpanda (Selecy SAS)
|
||||||
|
//
|
||||||
|
// Francis Bouvier <francis@lightpanda.io>
|
||||||
|
// Pierre Tachoire <pierre@lightpanda.io>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const log = @import("../../log.zig");
|
||||||
|
const v8 = @import("v8");
|
||||||
|
|
||||||
|
const Env = @import("../env.zig").Env;
|
||||||
|
const Page = @import("../page.zig").Page;
|
||||||
|
|
||||||
|
const Element = @import("../dom/element.zig").Element;
|
||||||
|
|
||||||
|
pub const CustomElementRegistry = struct {
|
||||||
|
// tag_name -> Function
|
||||||
|
lookup: std.StringHashMapUnmanaged(Env.Function) = .empty,
|
||||||
|
|
||||||
|
pub fn _define(self: *CustomElementRegistry, tag_name: []const u8, fun: Env.Function, page: *Page) !void {
|
||||||
|
log.info(.browser, "define custom element", .{ .name = tag_name });
|
||||||
|
|
||||||
|
const arena = page.arena;
|
||||||
|
const gop = try self.lookup.getOrPut(arena, tag_name);
|
||||||
|
if (!gop.found_existing) {
|
||||||
|
errdefer _ = self.lookup.remove(tag_name);
|
||||||
|
const owned_tag_name = try arena.dupe(u8, tag_name);
|
||||||
|
gop.key_ptr.* = owned_tag_name;
|
||||||
|
}
|
||||||
|
gop.value_ptr.* = fun;
|
||||||
|
fun.setName(tag_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _get(self: *CustomElementRegistry, name: []const u8) ?Env.Function {
|
||||||
|
return self.lookup.get(name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const testing = @import("../../testing.zig");
|
||||||
|
|
||||||
|
test "Browser.CustomElementRegistry" {
|
||||||
|
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
|
||||||
|
defer runner.deinit();
|
||||||
|
try runner.testCases(&.{
|
||||||
|
// Basic registry access
|
||||||
|
.{ "typeof customElements", "object" },
|
||||||
|
.{ "customElements instanceof CustomElementRegistry", "true" },
|
||||||
|
|
||||||
|
// Define a simple custom element
|
||||||
|
.{
|
||||||
|
\\ class MyElement extends HTMLElement {
|
||||||
|
\\ constructor() {
|
||||||
|
\\ super();
|
||||||
|
\\ this.textContent = 'Hello World';
|
||||||
|
\\ }
|
||||||
|
\\ }
|
||||||
|
,
|
||||||
|
null,
|
||||||
|
},
|
||||||
|
.{ "customElements.define('my-element', MyElement)", "undefined" },
|
||||||
|
|
||||||
|
// Check if element is defined
|
||||||
|
.{ "customElements.get('my-element') === MyElement", "true" },
|
||||||
|
// .{ "customElements.get('non-existent')", "null" },
|
||||||
|
|
||||||
|
// Create element via document.createElement
|
||||||
|
.{ "let el = document.createElement('my-element')", "undefined" },
|
||||||
|
.{ "el instanceof MyElement", "true" },
|
||||||
|
.{ "el instanceof HTMLElement", "true" },
|
||||||
|
.{ "el.tagName", "MY-ELEMENT" },
|
||||||
|
.{ "el.textContent", "Hello World" },
|
||||||
|
|
||||||
|
// Create element via HTML parsing
|
||||||
|
// .{ "document.body.innerHTML = '<my-element></my-element>'", "undefined" },
|
||||||
|
// .{ "let parsed = document.querySelector('my-element')", "undefined" },
|
||||||
|
// .{ "parsed instanceof MyElement", "true" },
|
||||||
|
// .{ "parsed.textContent", "Hello World" },
|
||||||
|
}, .{});
|
||||||
|
}
|
||||||
23
src/browser/webcomponents/webcomponents.zig
Normal file
23
src/browser/webcomponents/webcomponents.zig
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (C) 2023-2024 Lightpanda (Selecy SAS)
|
||||||
|
//
|
||||||
|
// Francis Bouvier <francis@lightpanda.io>
|
||||||
|
// Pierre Tachoire <pierre@lightpanda.io>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
const CustomElementRegistry = @import("custom_element_registry.zig").CustomElementRegistry;
|
||||||
|
|
||||||
|
pub const Interfaces = .{
|
||||||
|
CustomElementRegistry,
|
||||||
|
};
|
||||||
@@ -1257,6 +1257,16 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
|||||||
exception: []const u8,
|
exception: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn getName(self: *const Function, allocator: Allocator) ![]const u8 {
|
||||||
|
const name = self.func.castToFunction().getName();
|
||||||
|
return valueToString(allocator, name, self.js_context.isolate, self.js_context.v8_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setName(self: *const Function, name: []const u8) void {
|
||||||
|
const v8_name = v8.String.initUtf8(self.js_context.isolate, name);
|
||||||
|
self.func.castToFunction().setName(v8_name);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn withThis(self: *const Function, value: anytype) !Function {
|
pub fn withThis(self: *const Function, value: anytype) !Function {
|
||||||
const this_obj = if (@TypeOf(value) == JsObject)
|
const this_obj = if (@TypeOf(value) == JsObject)
|
||||||
value.js_obj
|
value.js_obj
|
||||||
@@ -1271,6 +1281,33 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn newInstance(self: *const Function, result: *Result) !JsObject {
|
||||||
|
const context = self.js_context;
|
||||||
|
|
||||||
|
var try_catch: TryCatch = undefined;
|
||||||
|
try_catch.init(context);
|
||||||
|
defer try_catch.deinit();
|
||||||
|
|
||||||
|
// This creates a new instance using this Function as a constructor.
|
||||||
|
// This returns a generic Object
|
||||||
|
const js_obj = self.func.castToFunction().initInstance(context.v8_context, &.{}) orelse {
|
||||||
|
if (try_catch.hasCaught()) {
|
||||||
|
const allocator = context.call_arena;
|
||||||
|
result.stack = try_catch.stack(allocator) catch null;
|
||||||
|
result.exception = (try_catch.exception(allocator) catch "???") orelse "???";
|
||||||
|
} else {
|
||||||
|
result.stack = null;
|
||||||
|
result.exception = "???";
|
||||||
|
}
|
||||||
|
return error.JsConstructorFailed;
|
||||||
|
};
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.js_context = context,
|
||||||
|
.js_obj = js_obj,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub fn call(self: *const Function, comptime T: type, args: anytype) !T {
|
pub fn call(self: *const Function, comptime T: type, args: anytype) !T {
|
||||||
return self.callWithThis(T, self.getThis(), args);
|
return self.callWithThis(T, self.getThis(), args);
|
||||||
}
|
}
|
||||||
@@ -1450,6 +1487,11 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
|||||||
.js_obj = array.castTo(v8.Object),
|
.js_obj = array.castTo(v8.Object),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn constructorName(self: JsObject, allocator: Allocator) ![]const u8 {
|
||||||
|
const str = try self.js_obj.getConstructorName();
|
||||||
|
return jsStringToZig(allocator, str, self.js_context.isolate);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This only exists so that we know whether a function wants the opaque
|
// This only exists so that we know whether a function wants the opaque
|
||||||
@@ -1472,6 +1514,10 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
|||||||
pub fn set(self: JsThis, key: []const u8, value: anytype, opts: JsObject.SetOpts) !void {
|
pub fn set(self: JsThis, key: []const u8, value: anytype, opts: JsObject.SetOpts) !void {
|
||||||
return self.obj.set(key, value, opts);
|
return self.obj.set(key, value, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn constructorName(self: JsThis, allocator: Allocator) ![]const u8 {
|
||||||
|
return try self.obj.constructorName(allocator);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const TryCatch = struct {
|
pub const TryCatch = struct {
|
||||||
@@ -1784,7 +1830,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
|||||||
// a constructor function, we'll return an error.
|
// a constructor function, we'll return an error.
|
||||||
if (@hasDecl(Struct, "constructor") == false) {
|
if (@hasDecl(Struct, "constructor") == false) {
|
||||||
const iso = caller.isolate;
|
const iso = caller.isolate;
|
||||||
const js_exception = iso.throwException(createException(iso, "illegal constructor"));
|
const js_exception = iso.throwException(createException(iso, "Illegal Constructor"));
|
||||||
info.getReturnValue().set(js_exception);
|
info.getReturnValue().set(js_exception);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2543,6 +2589,7 @@ fn Caller(comptime E: type, comptime State: type) type {
|
|||||||
var js_err: ?v8.Value = switch (err) {
|
var js_err: ?v8.Value = switch (err) {
|
||||||
error.InvalidArgument => createTypeException(isolate, "invalid argument"),
|
error.InvalidArgument => createTypeException(isolate, "invalid argument"),
|
||||||
error.OutOfMemory => createException(isolate, "out of memory"),
|
error.OutOfMemory => createException(isolate, "out of memory"),
|
||||||
|
error.IllegalConstructor => createException(isolate, "Illegal Contructor"),
|
||||||
else => blk: {
|
else => blk: {
|
||||||
const func = @field(Struct, named_function.name);
|
const func = @field(Struct, named_function.name);
|
||||||
const return_type = @typeInfo(@TypeOf(func)).@"fn".return_type orelse {
|
const return_type = @typeInfo(@TypeOf(func)).@"fn".return_type orelse {
|
||||||
@@ -2656,8 +2703,8 @@ fn Caller(comptime E: type, comptime State: type) type {
|
|||||||
// a JS argument
|
// a JS argument
|
||||||
if (comptime isJsThis(params[params.len - 1].type.?)) {
|
if (comptime isJsThis(params[params.len - 1].type.?)) {
|
||||||
@field(args, std.fmt.comptimePrint("{d}", .{params.len - 1 + offset})) = .{ .obj = .{
|
@field(args, std.fmt.comptimePrint("{d}", .{params.len - 1 + offset})) = .{ .obj = .{
|
||||||
|
.js_context = js_context,
|
||||||
.js_obj = info.getThis(),
|
.js_obj = info.getThis(),
|
||||||
.executor = self.executor,
|
|
||||||
} };
|
} };
|
||||||
|
|
||||||
// AND the 2nd last parameter is state
|
// AND the 2nd last parameter is state
|
||||||
|
|||||||
Reference in New Issue
Block a user