1use html5ever::LocalName;
6use js::context::JSContext;
7use script_bindings::root::DomRoot;
8use style::attr::AttrValue;
9
10use crate::dom::bindings::inheritance::{
11 Castable, DocumentFragmentTypeId, ElementTypeId, HTMLElementTypeId, HTMLMediaElementTypeId,
12 NodeTypeId, SVGElementTypeId, SVGGeometryElementTypeId, SVGGradientElementTypeId,
13 SVGGraphicsElementTypeId, SVGTextContentElementTypeId, SVGTextPositioningElementTypeId,
14};
15use crate::dom::bindings::str::DOMString;
16use crate::dom::document::Document;
17use crate::dom::documentfragment::DocumentFragment;
18use crate::dom::element::attributes::storage::AttrRef;
19use crate::dom::element::{AttributeMutation, Element};
20use crate::dom::event::Event;
21use crate::dom::html::form_controls::htmlinputelement::HTMLInputElement;
22use crate::dom::html::htmlanchorelement::HTMLAnchorElement;
23use crate::dom::html::htmlareaelement::HTMLAreaElement;
24use crate::dom::html::htmlbaseelement::HTMLBaseElement;
25use crate::dom::html::htmlbodyelement::HTMLBodyElement;
26use crate::dom::html::htmlbuttonelement::HTMLButtonElement;
27use crate::dom::html::htmlcanvaselement::HTMLCanvasElement;
28use crate::dom::html::htmldetailselement::HTMLDetailsElement;
29use crate::dom::html::htmlelement::HTMLElement;
30use crate::dom::html::htmlfieldsetelement::HTMLFieldSetElement;
31use crate::dom::html::htmlfontelement::HTMLFontElement;
32use crate::dom::html::htmlformelement::HTMLFormElement;
33use crate::dom::html::htmlheadelement::HTMLHeadElement;
34use crate::dom::html::htmlhrelement::HTMLHRElement;
35use crate::dom::html::htmliframeelement::HTMLIFrameElement;
36use crate::dom::html::htmlimageelement::HTMLImageElement;
37use crate::dom::html::htmllabelelement::HTMLLabelElement;
38use crate::dom::html::htmllielement::HTMLLIElement;
39use crate::dom::html::htmllinkelement::HTMLLinkElement;
40use crate::dom::html::htmlmarqueeelement::HTMLMarqueeElement;
41use crate::dom::html::htmlmediaelement::HTMLMediaElement;
42use crate::dom::html::htmlmetaelement::HTMLMetaElement;
43use crate::dom::html::htmlmeterelement::HTMLMeterElement;
44use crate::dom::html::htmlobjectelement::HTMLObjectElement;
45use crate::dom::html::htmloptgroupelement::HTMLOptGroupElement;
46use crate::dom::html::htmloptionelement::HTMLOptionElement;
47use crate::dom::html::htmloutputelement::HTMLOutputElement;
48use crate::dom::html::htmlpreelement::HTMLPreElement;
49use crate::dom::html::htmlprogresselement::HTMLProgressElement;
50use crate::dom::html::htmlscriptelement::HTMLScriptElement;
51use crate::dom::html::htmlselectelement::HTMLSelectElement;
52use crate::dom::html::htmlslotelement::HTMLSlotElement;
53use crate::dom::html::htmlsourceelement::HTMLSourceElement;
54use crate::dom::html::htmlstyleelement::HTMLStyleElement;
55use crate::dom::html::htmltablecellelement::HTMLTableCellElement;
56use crate::dom::html::htmltablecolelement::HTMLTableColElement;
57use crate::dom::html::htmltableelement::HTMLTableElement;
58use crate::dom::html::htmltablerowelement::HTMLTableRowElement;
59use crate::dom::html::htmltablesectionelement::HTMLTableSectionElement;
60use crate::dom::html::htmltemplateelement::HTMLTemplateElement;
61use crate::dom::html::htmltextareaelement::HTMLTextAreaElement;
62use crate::dom::html::htmltitleelement::HTMLTitleElement;
63use crate::dom::html::htmltrackelement::HTMLTrackElement;
64use crate::dom::html::htmlvideoelement::HTMLVideoElement;
65use crate::dom::htmlbuttonelement::CommandState;
66use crate::dom::htmldialogelement::HTMLDialogElement;
67use crate::dom::node::{
68 BindContext, ChildrenMutation, CloneChildrenFlag, MoveContext, Node, UnbindContext,
69};
70use crate::dom::shadowroot::shadowroot::ShadowRoot;
71use crate::dom::svg::svgaelement::SVGAElement;
72use crate::dom::svg::svgcircleelement::SVGCircleElement;
73use crate::dom::svg::svgdefselement::SVGDefsElement;
74use crate::dom::svg::svgelement::SVGElement;
75use crate::dom::svg::svgellipseelement::SVGEllipseElement;
76use crate::dom::svg::svggelement::SVGGElement;
77use crate::dom::svg::svgimageelement::SVGImageElement;
78use crate::dom::svg::svglineargradientelement::SVGLinearGradientElement;
79use crate::dom::svg::svglineelement::SVGLineElement;
80use crate::dom::svg::svgpathelement::SVGPathElement;
81use crate::dom::svg::svgpatternelement::SVGPatternElement;
82use crate::dom::svg::svgpolygonelement::SVGPolygonElement;
83use crate::dom::svg::svgpolylineelement::SVGPolylineElement;
84use crate::dom::svg::svgradialgradientelement::SVGRadialGradientElement;
85use crate::dom::svg::svgrectelement::SVGRectElement;
86use crate::dom::svg::svgstopelement::SVGStopElement;
87use crate::dom::svg::svgsvgelement::SVGSVGElement;
88use crate::dom::svg::svgsymbolelement::SVGSymbolElement;
89use crate::dom::svg::svgtextelement::SVGTextElement;
90use crate::dom::svg::svgtspanelement::SVGTSpanElement;
91use crate::dom::svg::svguseelement::SVGUseElement;
92
93pub(crate) trait VirtualMethods {
96 fn super_type(&self) -> Option<&dyn VirtualMethods>;
99
100 fn attribute_mutated(
104 &self,
105 cx: &mut js::context::JSContext,
106 attr: AttrRef<'_>,
107 mutation: AttributeMutation,
108 ) {
109 if let Some(s) = self.super_type() {
110 s.attribute_mutated(cx, attr, mutation);
111 }
112 }
113
114 fn attribute_affects_presentational_hints(&self, attr: AttrRef<'_>) -> bool {
117 match self.super_type() {
118 Some(s) => s.attribute_affects_presentational_hints(attr),
119 None => false,
120 }
121 }
122
123 fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue {
126 match self.super_type() {
127 Some(s) => s.parse_plain_attribute(name, value),
128 _ => AttrValue::String(value.into()),
129 }
130 }
131
132 fn post_connection_steps(&self, cx: &mut JSContext) {
136 if let Some(s) = self.super_type() {
137 s.post_connection_steps(cx);
138 }
139 }
140
141 fn moving_steps(&self, cx: &mut JSContext, context: &MoveContext) {
143 if let Some(s) = self.super_type() {
144 s.moving_steps(cx, context);
145 }
146 }
147
148 fn bind_to_tree(&self, cx: &mut JSContext, context: &BindContext) {
150 if let Some(s) = self.super_type() {
151 s.bind_to_tree(cx, context);
152 }
153 }
154
155 fn unbind_from_tree(&self, cx: &mut js::context::JSContext, context: &UnbindContext) {
159 if let Some(s) = self.super_type() {
160 s.unbind_from_tree(cx, context);
161 }
162 }
163
164 fn children_changed(&self, cx: &mut JSContext, mutation: &ChildrenMutation) {
166 if let Some(s) = self.super_type() {
167 s.children_changed(cx, mutation);
168 }
169 }
170
171 fn handle_event(&self, cx: &mut js::context::JSContext, event: &Event) {
173 if let Some(s) = self.super_type() {
174 s.handle_event(cx, event);
175 }
176 }
177
178 fn is_valid_command_steps(&self, command: CommandState) -> bool {
180 self.super_type()
181 .is_some_and(|super_type| super_type.is_valid_command_steps(command))
182 }
183
184 fn command_steps(
186 &self,
187 cx: &mut js::context::JSContext,
188 button: DomRoot<HTMLButtonElement>,
189 command: CommandState,
190 ) -> bool {
191 self.super_type()
192 .is_some_and(|super_type| super_type.command_steps(cx, button, command))
193 }
194
195 fn adopting_steps(&self, cx: &mut JSContext, old_doc: &Document) {
197 if let Some(s) = self.super_type() {
198 s.adopting_steps(cx, old_doc);
199 }
200 }
201
202 fn cloning_steps(
204 &self,
205 cx: &mut JSContext,
206 copy: &Node,
207 maybe_doc: Option<&Document>,
208 clone_children: CloneChildrenFlag,
209 ) {
210 if let Some(s) = self.super_type() {
211 s.cloning_steps(cx, copy, maybe_doc, clone_children);
212 }
213 }
214
215 fn pop(&self, cx: &mut js::context::JSContext) {
218 if let Some(s) = self.super_type() {
219 s.pop(cx);
220 }
221 }
222}
223
224pub(crate) fn vtable_for(node: &Node) -> &dyn VirtualMethods {
229 match node.type_id() {
230 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) => {
231 node.downcast::<HTMLAnchorElement>().unwrap() as &dyn VirtualMethods
232 },
233 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) => {
234 node.downcast::<HTMLAreaElement>().unwrap() as &dyn VirtualMethods
235 },
236 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLBaseElement)) => {
237 node.downcast::<HTMLBaseElement>().unwrap() as &dyn VirtualMethods
238 },
239 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLBodyElement)) => {
240 node.downcast::<HTMLBodyElement>().unwrap() as &dyn VirtualMethods
241 },
242 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) => {
243 node.downcast::<HTMLButtonElement>().unwrap() as &dyn VirtualMethods
244 },
245 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLCanvasElement)) => {
246 node.downcast::<HTMLCanvasElement>().unwrap() as &dyn VirtualMethods
247 },
248 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLDetailsElement)) => {
249 node.downcast::<HTMLDetailsElement>().unwrap() as &dyn VirtualMethods
250 },
251 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLDialogElement)) => {
252 node.downcast::<HTMLDialogElement>().unwrap() as &dyn VirtualMethods
253 },
254 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFieldSetElement)) => {
255 node.downcast::<HTMLFieldSetElement>().unwrap() as &dyn VirtualMethods
256 },
257 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFontElement)) => {
258 node.downcast::<HTMLFontElement>().unwrap() as &dyn VirtualMethods
259 },
260 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFormElement)) => {
261 node.downcast::<HTMLFormElement>().unwrap() as &dyn VirtualMethods
262 },
263 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLHeadElement)) => {
264 node.downcast::<HTMLHeadElement>().unwrap() as &dyn VirtualMethods
265 },
266 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLHRElement)) => {
267 node.downcast::<HTMLHRElement>().unwrap() as &dyn VirtualMethods
268 },
269 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLImageElement)) => {
270 node.downcast::<HTMLImageElement>().unwrap() as &dyn VirtualMethods
271 },
272 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLIFrameElement)) => {
273 node.downcast::<HTMLIFrameElement>().unwrap() as &dyn VirtualMethods
274 },
275 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => {
276 node.downcast::<HTMLInputElement>().unwrap() as &dyn VirtualMethods
277 },
278 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLabelElement)) => {
279 node.downcast::<HTMLLabelElement>().unwrap() as &dyn VirtualMethods
280 },
281 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLIElement)) => {
282 node.downcast::<HTMLLIElement>().unwrap() as &dyn VirtualMethods
283 },
284 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => {
285 node.downcast::<HTMLLinkElement>().unwrap() as &dyn VirtualMethods
286 },
287 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLMarqueeElement)) => {
288 node.downcast::<HTMLMarqueeElement>().unwrap() as &dyn VirtualMethods
289 },
290 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLMediaElement(
291 media_el,
292 ))) => match media_el {
293 HTMLMediaElementTypeId::HTMLVideoElement => {
294 node.downcast::<HTMLVideoElement>().unwrap() as &dyn VirtualMethods
295 },
296 _ => node.downcast::<HTMLMediaElement>().unwrap() as &dyn VirtualMethods,
297 },
298 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLMetaElement)) => {
299 node.downcast::<HTMLMetaElement>().unwrap() as &dyn VirtualMethods
300 },
301 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLMeterElement)) => {
302 node.downcast::<HTMLMeterElement>().unwrap() as &dyn VirtualMethods
303 },
304 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement)) => {
305 node.downcast::<HTMLObjectElement>().unwrap() as &dyn VirtualMethods
306 },
307 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOptGroupElement)) => {
308 node.downcast::<HTMLOptGroupElement>().unwrap() as &dyn VirtualMethods
309 },
310 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOptionElement)) => {
311 node.downcast::<HTMLOptionElement>().unwrap() as &dyn VirtualMethods
312 },
313 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOutputElement)) => {
314 node.downcast::<HTMLOutputElement>().unwrap() as &dyn VirtualMethods
315 },
316 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLPreElement)) => {
317 node.downcast::<HTMLPreElement>().unwrap() as &dyn VirtualMethods
318 },
319 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLProgressElement)) => {
320 node.downcast::<HTMLProgressElement>().unwrap() as &dyn VirtualMethods
321 },
322 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLScriptElement)) => {
323 node.downcast::<HTMLScriptElement>().unwrap() as &dyn VirtualMethods
324 },
325 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) => {
326 node.downcast::<HTMLSelectElement>().unwrap() as &dyn VirtualMethods
327 },
328 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSourceElement)) => {
329 node.downcast::<HTMLSourceElement>().unwrap() as &dyn VirtualMethods
330 },
331 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSlotElement)) => {
332 node.downcast::<HTMLSlotElement>().unwrap() as &dyn VirtualMethods
333 },
334 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLStyleElement)) => {
335 node.downcast::<HTMLStyleElement>().unwrap() as &dyn VirtualMethods
336 },
337 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableElement)) => {
338 node.downcast::<HTMLTableElement>().unwrap() as &dyn VirtualMethods
339 },
340 NodeTypeId::Element(ElementTypeId::HTMLElement(
341 HTMLElementTypeId::HTMLTableCellElement,
342 )) => node.downcast::<HTMLTableCellElement>().unwrap() as &dyn VirtualMethods,
343 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableColElement)) => {
344 node.downcast::<HTMLTableColElement>().unwrap() as &dyn VirtualMethods
345 },
346 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableRowElement)) => {
347 node.downcast::<HTMLTableRowElement>().unwrap() as &dyn VirtualMethods
348 },
349 NodeTypeId::Element(ElementTypeId::HTMLElement(
350 HTMLElementTypeId::HTMLTableSectionElement,
351 )) => node.downcast::<HTMLTableSectionElement>().unwrap() as &dyn VirtualMethods,
352 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTemplateElement)) => {
353 node.downcast::<HTMLTemplateElement>().unwrap() as &dyn VirtualMethods
354 },
355 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) => {
356 node.downcast::<HTMLTextAreaElement>().unwrap() as &dyn VirtualMethods
357 },
358 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTitleElement)) => {
359 node.downcast::<HTMLTitleElement>().unwrap() as &dyn VirtualMethods
360 },
361 NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTrackElement)) => {
362 node.downcast::<HTMLTrackElement>().unwrap() as &dyn VirtualMethods
363 },
364 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
365 SVGGraphicsElementTypeId::SVGGeometryElement(
366 SVGGeometryElementTypeId::SVGCircleElement,
367 ),
368 ))) => node.downcast::<SVGCircleElement>().unwrap() as &dyn VirtualMethods,
369 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
370 SVGGraphicsElementTypeId::SVGGeometryElement(
371 SVGGeometryElementTypeId::SVGEllipseElement,
372 ),
373 ))) => node.downcast::<SVGEllipseElement>().unwrap() as &dyn VirtualMethods,
374 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
375 SVGGraphicsElementTypeId::SVGImageElement,
376 ))) => node.downcast::<SVGImageElement>().unwrap() as &dyn VirtualMethods,
377 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
378 SVGGraphicsElementTypeId::SVGTextContentElement(
379 SVGTextContentElementTypeId::SVGTextPositioningElement(
380 SVGTextPositioningElementTypeId::SVGTextElement,
381 ),
382 ),
383 ))) => node.downcast::<SVGTextElement>().unwrap() as &dyn VirtualMethods,
384 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
385 SVGGraphicsElementTypeId::SVGTextContentElement(
386 SVGTextContentElementTypeId::SVGTextPositioningElement(
387 SVGTextPositioningElementTypeId::SVGTSpanElement,
388 ),
389 ),
390 ))) => node.downcast::<SVGTSpanElement>().unwrap() as &dyn VirtualMethods,
391 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
392 SVGGraphicsElementTypeId::SVGGeometryElement(SVGGeometryElementTypeId::SVGRectElement),
393 ))) => node.downcast::<SVGRectElement>().unwrap() as &dyn VirtualMethods,
394 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
395 SVGGraphicsElementTypeId::SVGGeometryElement(SVGGeometryElementTypeId::SVGLineElement),
396 ))) => node.downcast::<SVGLineElement>().unwrap() as &dyn VirtualMethods,
397 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
398 SVGGraphicsElementTypeId::SVGGeometryElement(
399 SVGGeometryElementTypeId::SVGPolylineElement,
400 ),
401 ))) => node.downcast::<SVGPolylineElement>().unwrap() as &dyn VirtualMethods,
402 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
403 SVGGraphicsElementTypeId::SVGGeometryElement(
404 SVGGeometryElementTypeId::SVGPolygonElement,
405 ),
406 ))) => node.downcast::<SVGPolygonElement>().unwrap() as &dyn VirtualMethods,
407 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
408 SVGGraphicsElementTypeId::SVGGeometryElement(SVGGeometryElementTypeId::SVGPathElement),
409 ))) => node.downcast::<SVGPathElement>().unwrap() as &dyn VirtualMethods,
410 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
411 SVGGraphicsElementTypeId::SVGSVGElement,
412 ))) => node.downcast::<SVGSVGElement>().unwrap() as &dyn VirtualMethods,
413 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
414 SVGGraphicsElementTypeId::SVGGElement,
415 ))) => node.downcast::<SVGGElement>().unwrap() as &dyn VirtualMethods,
416 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
417 SVGGraphicsElementTypeId::SVGUseElement,
418 ))) => node.downcast::<SVGUseElement>().unwrap() as &dyn VirtualMethods,
419 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
420 SVGGraphicsElementTypeId::SVGSymbolElement,
421 ))) => node.downcast::<SVGSymbolElement>().unwrap() as &dyn VirtualMethods,
422 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
423 SVGGraphicsElementTypeId::SVGDefsElement,
424 ))) => node.downcast::<SVGDefsElement>().unwrap() as &dyn VirtualMethods,
425 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGradientElement(
426 SVGGradientElementTypeId::SVGLinearGradientElement,
427 ))) => node.downcast::<SVGLinearGradientElement>().unwrap() as &dyn VirtualMethods,
428 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGradientElement(
429 SVGGradientElementTypeId::SVGRadialGradientElement,
430 ))) => node.downcast::<SVGRadialGradientElement>().unwrap() as &dyn VirtualMethods,
431 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGStopElement)) => {
432 node.downcast::<SVGStopElement>().unwrap() as &dyn VirtualMethods
433 },
434 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGPatternElement)) => {
435 node.downcast::<SVGPatternElement>().unwrap() as &dyn VirtualMethods
436 },
437 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
438 SVGGraphicsElementTypeId::SVGAElement,
439 ))) => node.downcast::<SVGAElement>().unwrap() as &dyn VirtualMethods,
440 NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGElement)) => {
441 node.downcast::<SVGElement>().unwrap() as &dyn VirtualMethods
442 },
443 NodeTypeId::Element(ElementTypeId::Element) => {
444 node.downcast::<Element>().unwrap() as &dyn VirtualMethods
445 },
446 NodeTypeId::Element(_) => node.downcast::<HTMLElement>().unwrap() as &dyn VirtualMethods,
447 NodeTypeId::DocumentFragment(DocumentFragmentTypeId::ShadowRoot) => {
448 node.downcast::<ShadowRoot>().unwrap() as &dyn VirtualMethods
449 },
450 NodeTypeId::DocumentFragment(_) => {
451 node.downcast::<DocumentFragment>().unwrap() as &dyn VirtualMethods
452 },
453 _ => node as &dyn VirtualMethods,
454 }
455}