mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-16 16:28:58 +00:00
add add_attrs_if_missing callback
This commit is contained in:
@@ -64,6 +64,8 @@ const Error = struct {
|
|||||||
append,
|
append,
|
||||||
create_element,
|
create_element,
|
||||||
create_comment,
|
create_comment,
|
||||||
|
append_doctype_to_document,
|
||||||
|
add_attrs_if_missing,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -80,6 +82,7 @@ pub fn parse(self: *Parser, html: []const u8) void {
|
|||||||
popCallback,
|
popCallback,
|
||||||
createCommentCallback,
|
createCommentCallback,
|
||||||
appendDoctypeToDocument,
|
appendDoctypeToDocument,
|
||||||
|
addAttrsIfMissingCallback,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,6 +99,7 @@ pub fn parseFragment(self: *Parser, html: []const u8) void {
|
|||||||
popCallback,
|
popCallback,
|
||||||
createCommentCallback,
|
createCommentCallback,
|
||||||
appendDoctypeToDocument,
|
appendDoctypeToDocument,
|
||||||
|
addAttrsIfMissingCallback,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +133,7 @@ pub const Streaming = struct {
|
|||||||
popCallback,
|
popCallback,
|
||||||
createCommentCallback,
|
createCommentCallback,
|
||||||
appendDoctypeToDocument,
|
appendDoctypeToDocument,
|
||||||
|
addAttrsIfMissingCallback,
|
||||||
) orelse return error.ParserCreationFailed;
|
) orelse return error.ParserCreationFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,6 +220,31 @@ fn _appendDoctypeToDocument(self: *Parser, name: []const u8) !void {
|
|||||||
_ = name;
|
_ = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn addAttrsIfMissingCallback(ctx: *anyopaque, target_ref: *anyopaque, attributes: h5e.AttributeIterator) callconv(.c) void {
|
||||||
|
const self: *Parser = @ptrCast(@alignCast(ctx));
|
||||||
|
self._addAttrsIfMissingCallback(getNode(target_ref), attributes) catch |err| {
|
||||||
|
self.err = .{ .err = err, .source = .add_attrs_if_missing };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
fn _addAttrsIfMissingCallback(self: *Parser, node: *Node, attributes: h5e.AttributeIterator) !void {
|
||||||
|
const element = node.as(Element);
|
||||||
|
const page = self.page;
|
||||||
|
|
||||||
|
const attr_list = element._attributes orelse blk: {
|
||||||
|
const a = try page.arena.create(@import("../webapi/element/Attribute.zig").List);
|
||||||
|
a.* = .{};
|
||||||
|
element._attributes = a;
|
||||||
|
break :blk a;
|
||||||
|
};
|
||||||
|
|
||||||
|
while (attributes.next()) |attr| {
|
||||||
|
const name = attr.name.local.slice();
|
||||||
|
const value = attr.value.slice();
|
||||||
|
// putNew only adds if the attribute doesn't already exist
|
||||||
|
try attr_list.putNew(name, value, page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn getDataCallback(ctx: *anyopaque) callconv(.c) *anyopaque {
|
fn getDataCallback(ctx: *anyopaque) callconv(.c) *anyopaque {
|
||||||
const pn: *ParsedNode = @ptrCast(@alignCast(ctx));
|
const pn: *ParsedNode = @ptrCast(@alignCast(ctx));
|
||||||
// For non-elements, data is null. But, we expect this to only ever
|
// For non-elements, data is null. But, we expect this to only ever
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ pub extern "c" fn html5ever_parse_document(
|
|||||||
popCallback: *const fn (ctx: *anyopaque, node_ref: *anyopaque) callconv(.c) void,
|
popCallback: *const fn (ctx: *anyopaque, node_ref: *anyopaque) callconv(.c) void,
|
||||||
createCommentCallback: *const fn (ctx: *anyopaque, StringSlice) callconv(.c) ?*anyopaque,
|
createCommentCallback: *const fn (ctx: *anyopaque, StringSlice) callconv(.c) ?*anyopaque,
|
||||||
appendDoctypeToDocument: *const fn (ctx: *anyopaque, StringSlice, StringSlice, StringSlice) callconv(.c) void,
|
appendDoctypeToDocument: *const fn (ctx: *anyopaque, StringSlice, StringSlice, StringSlice) callconv(.c) void,
|
||||||
|
addAttrsIfMissingCallback: *const fn (ctx: *anyopaque, target_ref: *anyopaque, AttributeIterator) callconv(.c) void,
|
||||||
) void;
|
) void;
|
||||||
|
|
||||||
pub extern "c" fn html5ever_parse_fragment(
|
pub extern "c" fn html5ever_parse_fragment(
|
||||||
@@ -44,6 +45,7 @@ pub extern "c" fn html5ever_parse_fragment(
|
|||||||
popCallback: *const fn (ctx: *anyopaque, node_ref: *anyopaque) callconv(.c) void,
|
popCallback: *const fn (ctx: *anyopaque, node_ref: *anyopaque) callconv(.c) void,
|
||||||
createCommentCallback: *const fn (ctx: *anyopaque, StringSlice) callconv(.c) ?*anyopaque,
|
createCommentCallback: *const fn (ctx: *anyopaque, StringSlice) callconv(.c) ?*anyopaque,
|
||||||
appendDoctypeToDocument: *const fn (ctx: *anyopaque, StringSlice, StringSlice, StringSlice) callconv(.c) void,
|
appendDoctypeToDocument: *const fn (ctx: *anyopaque, StringSlice, StringSlice, StringSlice) callconv(.c) void,
|
||||||
|
addAttrsIfMissingCallback: *const fn (ctx: *anyopaque, target_ref: *anyopaque, AttributeIterator) callconv(.c) void,
|
||||||
) void;
|
) void;
|
||||||
|
|
||||||
pub extern "c" fn html5ever_attribute_iterator_next(ctx: *anyopaque) Nullable(Attribute);
|
pub extern "c" fn html5ever_attribute_iterator_next(ctx: *anyopaque) Nullable(Attribute);
|
||||||
@@ -67,6 +69,7 @@ pub extern "c" fn html5ever_streaming_parser_create(
|
|||||||
popCallback: *const fn (ctx: *anyopaque, node_ref: *anyopaque) callconv(.c) void,
|
popCallback: *const fn (ctx: *anyopaque, node_ref: *anyopaque) callconv(.c) void,
|
||||||
createCommentCallback: *const fn (ctx: *anyopaque, StringSlice) callconv(.c) ?*anyopaque,
|
createCommentCallback: *const fn (ctx: *anyopaque, StringSlice) callconv(.c) ?*anyopaque,
|
||||||
appendDoctypeToDocument: *const fn (ctx: *anyopaque, StringSlice, StringSlice, StringSlice) callconv(.c) void,
|
appendDoctypeToDocument: *const fn (ctx: *anyopaque, StringSlice, StringSlice, StringSlice) callconv(.c) void,
|
||||||
|
addAttrsIfMissingCallback: *const fn (ctx: *anyopaque, target_ref: *anyopaque, AttributeIterator) callconv(.c) void,
|
||||||
) ?*anyopaque;
|
) ?*anyopaque;
|
||||||
|
|
||||||
pub extern "c" fn html5ever_streaming_parser_feed(
|
pub extern "c" fn html5ever_streaming_parser_feed(
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ pub extern "C" fn html5ever_parse_document(
|
|||||||
pop_callback: PopCallback,
|
pop_callback: PopCallback,
|
||||||
create_comment_callback: CreateCommentCallback,
|
create_comment_callback: CreateCommentCallback,
|
||||||
append_doctype_to_document: AppendDoctypeToDocumentCallback,
|
append_doctype_to_document: AppendDoctypeToDocumentCallback,
|
||||||
|
add_attrs_if_missing_callback: AddAttrsIfMissingCallback,
|
||||||
) -> () {
|
) -> () {
|
||||||
if html.is_null() || len == 0 {
|
if html.is_null() || len == 0 {
|
||||||
return ();
|
return ();
|
||||||
@@ -63,6 +64,7 @@ pub extern "C" fn html5ever_parse_document(
|
|||||||
create_element_callback: create_element_callback,
|
create_element_callback: create_element_callback,
|
||||||
create_comment_callback: create_comment_callback,
|
create_comment_callback: create_comment_callback,
|
||||||
append_doctype_to_document: append_doctype_to_document,
|
append_doctype_to_document: append_doctype_to_document,
|
||||||
|
add_attrs_if_missing_callback: add_attrs_if_missing_callback,
|
||||||
};
|
};
|
||||||
|
|
||||||
let bytes = unsafe { std::slice::from_raw_parts(html, len) };
|
let bytes = unsafe { std::slice::from_raw_parts(html, len) };
|
||||||
@@ -84,6 +86,7 @@ pub extern "C" fn html5ever_parse_fragment(
|
|||||||
pop_callback: PopCallback,
|
pop_callback: PopCallback,
|
||||||
create_comment_callback: CreateCommentCallback,
|
create_comment_callback: CreateCommentCallback,
|
||||||
append_doctype_to_document: AppendDoctypeToDocumentCallback,
|
append_doctype_to_document: AppendDoctypeToDocumentCallback,
|
||||||
|
add_attrs_if_missing_callback: AddAttrsIfMissingCallback,
|
||||||
) -> () {
|
) -> () {
|
||||||
if html.is_null() || len == 0 {
|
if html.is_null() || len == 0 {
|
||||||
return ();
|
return ();
|
||||||
@@ -103,6 +106,7 @@ pub extern "C" fn html5ever_parse_fragment(
|
|||||||
create_element_callback: create_element_callback,
|
create_element_callback: create_element_callback,
|
||||||
create_comment_callback: create_comment_callback,
|
create_comment_callback: create_comment_callback,
|
||||||
append_doctype_to_document: append_doctype_to_document,
|
append_doctype_to_document: append_doctype_to_document,
|
||||||
|
add_attrs_if_missing_callback: add_attrs_if_missing_callback,
|
||||||
};
|
};
|
||||||
|
|
||||||
let bytes = unsafe { std::slice::from_raw_parts(html, len) };
|
let bytes = unsafe { std::slice::from_raw_parts(html, len) };
|
||||||
@@ -183,6 +187,7 @@ pub extern "C" fn html5ever_streaming_parser_create(
|
|||||||
pop_callback: PopCallback,
|
pop_callback: PopCallback,
|
||||||
create_comment_callback: CreateCommentCallback,
|
create_comment_callback: CreateCommentCallback,
|
||||||
append_doctype_to_document: AppendDoctypeToDocumentCallback,
|
append_doctype_to_document: AppendDoctypeToDocumentCallback,
|
||||||
|
add_attrs_if_missing_callback: AddAttrsIfMissingCallback,
|
||||||
) -> *mut c_void {
|
) -> *mut c_void {
|
||||||
let arena = Box::new(typed_arena::Arena::new());
|
let arena = Box::new(typed_arena::Arena::new());
|
||||||
|
|
||||||
@@ -205,6 +210,7 @@ pub extern "C" fn html5ever_streaming_parser_create(
|
|||||||
create_element_callback: create_element_callback,
|
create_element_callback: create_element_callback,
|
||||||
create_comment_callback: create_comment_callback,
|
create_comment_callback: create_comment_callback,
|
||||||
append_doctype_to_document: append_doctype_to_document,
|
append_doctype_to_document: append_doctype_to_document,
|
||||||
|
add_attrs_if_missing_callback: add_attrs_if_missing_callback,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a parser which implements TendrilSink for streaming parsing
|
// Create a parser which implements TendrilSink for streaming parsing
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ pub struct Sink<'arena> {
|
|||||||
pub create_element_callback: CreateElementCallback,
|
pub create_element_callback: CreateElementCallback,
|
||||||
pub create_comment_callback: CreateCommentCallback,
|
pub create_comment_callback: CreateCommentCallback,
|
||||||
pub append_doctype_to_document: AppendDoctypeToDocumentCallback,
|
pub append_doctype_to_document: AppendDoctypeToDocumentCallback,
|
||||||
|
pub add_attrs_if_missing_callback: AddAttrsIfMissingCallback,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'arena> TreeSink for Sink<'arena> {
|
impl<'arena> TreeSink for Sink<'arena> {
|
||||||
@@ -120,19 +121,6 @@ impl<'arena> TreeSink for Sink<'arena> {
|
|||||||
let data = self.arena.alloc(ElementData::new(name.clone(), flags));
|
let data = self.arena.alloc(ElementData::new(name.clone(), flags));
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut c_attrs: Vec<CAttribute> = Vec::with_capacity(attrs.len());
|
|
||||||
|
|
||||||
for attr in attrs.iter() {
|
|
||||||
let v: &str = &attr.value;
|
|
||||||
c_attrs.push(CAttribute {
|
|
||||||
name: CQualName::create(&attr.name),
|
|
||||||
value: StringSlice {
|
|
||||||
ptr: v.as_ptr(),
|
|
||||||
len: attr.value.len(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut attribute_iterator = CAttributeIterator { vec: attrs, pos: 0 };
|
let mut attribute_iterator = CAttributeIterator { vec: attrs, pos: 0 };
|
||||||
|
|
||||||
return (self.create_element_callback)(
|
return (self.create_element_callback)(
|
||||||
@@ -226,9 +214,15 @@ impl<'arena> TreeSink for Sink<'arena> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_attrs_if_missing(&self, target: &Ref, attrs: Vec<Attribute>) {
|
fn add_attrs_if_missing(&self, target: &Ref, attrs: Vec<Attribute>) {
|
||||||
_ = target;
|
unsafe {
|
||||||
_ = attrs;
|
let mut attribute_iterator = CAttributeIterator { vec: attrs, pos: 0 };
|
||||||
panic!("add_attrs_if_missing");
|
|
||||||
|
(self.add_attrs_if_missing_callback)(
|
||||||
|
self.ctx,
|
||||||
|
*target,
|
||||||
|
&mut attribute_iterator as *mut _ as *mut c_void,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_from_parent(&self, target: &Ref) {
|
fn remove_from_parent(&self, target: &Ref) {
|
||||||
|
|||||||
@@ -51,6 +51,12 @@ pub type ParseErrorCallback = unsafe extern "C" fn(ctx: Ref, str: StringSlice) -
|
|||||||
|
|
||||||
pub type PopCallback = unsafe extern "C" fn(ctx: Ref, node: Ref) -> ();
|
pub type PopCallback = unsafe extern "C" fn(ctx: Ref, node: Ref) -> ();
|
||||||
|
|
||||||
|
pub type AddAttrsIfMissingCallback = unsafe extern "C" fn(
|
||||||
|
ctx: Ref,
|
||||||
|
target: Ref,
|
||||||
|
attributes: *mut c_void,
|
||||||
|
) -> ();
|
||||||
|
|
||||||
pub type Ref = *const c_void;
|
pub type Ref = *const c_void;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|||||||
Reference in New Issue
Block a user