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