cangc fixes in node.rs (#33984)

Signed-off-by: L Ashwin B <lashwinib@gmail.com>
This commit is contained in:
chickenleaf 2024-10-24 04:14:50 +05:30 committed by GitHub
parent 3ed778150f
commit bb4932026c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
97 changed files with 1038 additions and 534 deletions

View file

@ -395,6 +395,7 @@ pub fn handle_modify_attribute(
pipeline: PipelineId, pipeline: PipelineId,
node_id: String, node_id: String,
modifications: Vec<AttrModification>, modifications: Vec<AttrModification>,
can_gc: CanGc,
) { ) {
let Some(document) = documents.find_document(pipeline) else { let Some(document) = documents.find_document(pipeline) else {
return warn!("document for pipeline id {} is not found", &pipeline); return warn!("document for pipeline id {} is not found", &pipeline);
@ -421,6 +422,7 @@ pub fn handle_modify_attribute(
let _ = elem.SetAttribute( let _ = elem.SetAttribute(
DOMString::from(modification.attribute_name), DOMString::from(modification.attribute_name),
DOMString::from(string), DOMString::from(string),
can_gc,
); );
}, },
None => elem.RemoveAttribute(DOMString::from(modification.attribute_name)), None => elem.RemoveAttribute(DOMString::from(modification.attribute_name)),

View file

@ -23,6 +23,7 @@ use crate::dom::element::{AttributeMutation, Element};
use crate::dom::mutationobserver::{Mutation, MutationObserver}; use crate::dom::mutationobserver::{Mutation, MutationObserver};
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::dom::virtualmethods::vtable_for; use crate::dom::virtualmethods::vtable_for;
use crate::script_runtime::CanGc;
use crate::script_thread::ScriptThread; use crate::script_thread::ScriptThread;
// https://dom.spec.whatwg.org/#interface-attr // https://dom.spec.whatwg.org/#interface-attr
@ -60,7 +61,7 @@ impl Attr {
owner: MutNullableDom::new(owner), owner: MutNullableDom::new(owner),
} }
} }
#[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
document: &Document, document: &Document,
local_name: LocalName, local_name: LocalName,
@ -69,12 +70,14 @@ impl Attr {
namespace: Namespace, namespace: Namespace,
prefix: Option<Prefix>, prefix: Option<Prefix>,
owner: Option<&Element>, owner: Option<&Element>,
can_gc: CanGc,
) -> DomRoot<Attr> { ) -> DomRoot<Attr> {
Node::reflect_node( Node::reflect_node(
Box::new(Attr::new_inherited( Box::new(Attr::new_inherited(
document, local_name, value, name, namespace, prefix, owner, document, local_name, value, name, namespace, prefix, owner,
)), )),
document, document,
can_gc,
) )
} }

View file

@ -66,6 +66,14 @@ DOMInterfaces = {
'canGc': ['GetTransform','GetImageData', 'CreateImageData', 'CreateImageData_', 'SetFont', 'FillText', 'MeasureText', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'], 'canGc': ['GetTransform','GetImageData', 'CreateImageData', 'CreateImageData_', 'SetFont', 'FillText', 'MeasureText', 'SetStrokeStyle', 'SetFillStyle', 'SetShadowColor'],
}, },
'CharacterData': {
'canGc': ['Before', 'After', 'ReplaceWith']
},
'CSSStyleDeclaration': {
'canGc': ['RemoveProperty', 'SetCssText']
},
'CanvasGradient': { 'CanvasGradient': {
'canGc': ['AddColorStop'], 'canGc': ['AddColorStop'],
}, },
@ -76,7 +84,7 @@ DOMInterfaces = {
}, },
'DOMImplementation': { 'DOMImplementation': {
'canGc': ['CreateDocument', 'CreateHTMLDocument'], 'canGc': ['CreateDocument', 'CreateHTMLDocument', 'CreateDocumentType'],
}, },
'DOMMatrix': { 'DOMMatrix': {
@ -104,15 +112,31 @@ DOMInterfaces = {
}, },
'Document': { 'Document': {
'canGc': ['Close', 'CreateElement', 'CreateElementNS', 'ImportNode', 'SetTitle', 'Write', 'Writeln', 'CreateEvent', 'CreateRange', 'Open', 'Open_', 'Fonts', 'ElementFromPoint', 'ElementsFromPoint', 'ExitFullscreen'], 'canGc': ['Close', 'CreateElement', 'CreateElementNS', 'ImportNode', 'SetTitle', 'Write', 'Writeln', 'CreateEvent', 'CreateRange', 'Open', 'Open_', 'CreateComment', 'CreateAttribute', 'CreateAttributeNS', 'CreateDocumentFragment', 'CreateTextNode', 'CreateCDATASection', 'CreateProcessingInstruction', 'Prepend', 'Append', 'ReplaceChildren', 'SetBgColor', 'SetFgColor', 'Fonts', 'ElementFromPoint', 'ElementsFromPoint', 'ExitFullscreen'],
}, },
'DynamicModuleOwner': { 'DynamicModuleOwner': {
'inRealms': ['PromiseAttribute'], 'inRealms': ['PromiseAttribute'],
}, },
'DocumentFragment': {
'canGc': ['Prepend', 'Append', 'ReplaceChildren']
},
'DocumentType': {
'canGc': ['Before', 'After', 'ReplaceWith']
},
'DOMStringMap': {
'canGc': ['NamedSetter']
},
"DOMTokenList": {
'canGc': ['SetValue', 'Add', 'Remove', 'Toggle', 'Replace']
},
'Element': { 'Element': {
'canGc': ['SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect', 'SetScrollTop', 'SetScrollLeft', 'Scroll', 'Scroll_', 'ScrollBy', 'ScrollBy_', 'ScrollWidth', 'ScrollHeight', 'ScrollTop', 'ScrollLeft', 'ClientTop', 'ClientLeft', 'ClientWidth', 'ClientHeight', 'RequestFullscreen'], 'canGc': ['SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect', 'InsertAdjacentText', 'ToggleAttribute', 'SetAttribute', 'SetAttributeNS', "SetId","SetClassName","Prepend","Append","ReplaceChildren","Before","After","ReplaceWith", 'SetRole', 'SetAriaAtomic', 'SetAriaAutoComplete', 'SetAriaBrailleLabel', 'SetAriaBrailleRoleDescription', 'SetAriaBusy', 'SetAriaChecked', 'SetAriaColCount', 'SetAriaColIndex', 'SetAriaColIndexText', 'SetAriaColSpan', 'SetAriaCurrent', 'SetAriaDescription', 'SetAriaDisabled', 'SetAriaExpanded', 'SetAriaHasPopup', 'SetAriaHidden', 'SetAriaInvalid', 'SetAriaKeyShortcuts', 'SetAriaLabel', 'SetAriaLevel', 'SetAriaLive', 'SetAriaModal', 'SetAriaMultiLine', 'SetAriaMultiSelectable', 'SetAriaOrientation', 'SetAriaPlaceholder', 'SetAriaPosInSet', 'SetAriaPressed','SetAriaReadOnly', 'SetAriaRelevant', 'SetAriaRequired', 'SetAriaRoleDescription', 'SetAriaRowCount', 'SetAriaRowIndex', 'SetAriaRowIndexText', 'SetAriaRowSpan', 'SetAriaSelected', 'SetAriaSetSize','SetAriaSort', 'SetAriaValueMax', 'SetAriaValueMin', 'SetAriaValueNow', 'SetAriaValueText', 'SetScrollTop', 'SetScrollLeft', 'Scroll', 'Scroll_', 'ScrollBy', 'ScrollBy_', 'ScrollWidth', 'ScrollHeight', 'ScrollTop', 'ScrollLeft', 'ClientTop', 'ClientLeft', 'ClientWidth', 'ClientHeight', 'RequestFullscreen'],
}, },
'ElementInternals': { 'ElementInternals': {
@ -184,31 +208,47 @@ DOMInterfaces = {
}, },
'HTMLButtonElement': { 'HTMLButtonElement': {
'canGc': ['CheckValidity', 'ReportValidity'], 'canGc': ['CheckValidity', 'ReportValidity','SetBackground'],
}, },
'HTMLElement': { 'HTMLElement': {
'canGc': ['GetOffsetParent', 'OffsetTop', 'OffsetLeft', 'OffsetWidth', 'OffsetHeight', 'InnerText', 'GetOuterText', 'Focus', 'Blur', 'Click'], 'canGc': ['Focus', 'Blur', 'Click', 'SetInnerText', 'SetOuterText', "SetTranslate", 'SetAutofocus', 'GetOffsetParent', 'OffsetTop', 'OffsetLeft', 'OffsetWidth', 'OffsetHeight', 'InnerText', 'GetOuterText'],
}, },
'HTMLFieldSetElement': { 'HTMLFieldSetElement': {
'canGc': ['CheckValidity', 'ReportValidity'], 'canGc': ['CheckValidity', 'ReportValidity'],
}, },
'HTMLDialogElement': {
'canGc': ['Show'],
},
'HTMLFormElement': { 'HTMLFormElement': {
'canGc': ['CheckValidity', 'RequestSubmit', 'ReportValidity', 'Submit'], 'canGc': ['CheckValidity', 'RequestSubmit', 'ReportValidity', 'Submit', 'Reset', 'SetRel'],
}, },
'HTMLImageElement': { 'HTMLImageElement': {
'canGc': ['Width', 'Height', 'Decode'], 'canGc': ['RequestSubmit', 'ReportValidity', 'Reset','SetRel', 'Width', 'Height', 'Decode', 'SetCrossOrigin', 'SetWidth', 'SetHeight', 'SetReferrerPolicy'],
},
'HTMLFontElement': {
'canGc': ['SetSize']
}, },
'HTMLInputElement': { 'HTMLInputElement': {
'canGc': ['CheckValidity', 'ReportValidity', 'SelectFiles'], 'canGc': ['ReportValidity', 'SetValue', 'SetValueAsNumber', 'SetValueAsDate', 'StepUp', 'StepDown', 'CheckValidity', 'ReportValidity', 'SelectFiles'],
},
"HTMLAreaElement": {
"canGc": ["SetRel"]
},
"HTMLBodyElement": {
"canGc": ["SetBackground"]
}, },
'HTMLMediaElement': { 'HTMLMediaElement': {
'canGc': ['Load', 'Pause', 'Play', 'SetSrcObject'], 'canGc': ['Load', 'Pause', 'Play', 'SetSrcObject', 'SetCrossOrigin'],
'inRealms': ['Play'], 'inRealms': ['Play'],
}, },
@ -217,7 +257,11 @@ DOMInterfaces = {
}, },
'HTMLOutputElement': { 'HTMLOutputElement': {
'canGc': ['CheckValidity', 'ReportValidity'], 'canGc': ['ReportValidity', 'SetDefaultValue', 'SetValue', 'CheckValidity'],
},
'HTMLMeterElement': {
'canGc': ['SetValue', 'SetMin', 'SetMax', 'SetLow', 'SetHigh', 'SetOptimum', 'CheckValidity', 'ReportValidity']
}, },
'HTMLCanvasElement': { 'HTMLCanvasElement': {
@ -225,15 +269,55 @@ DOMInterfaces = {
}, },
'HTMLSelectElement': { 'HTMLSelectElement': {
'canGc': ['CheckValidity', 'ReportValidity'], 'canGc': ['ReportValidity', 'SetLength', 'IndexedSetter', 'CheckValidity'],
}, },
'HTMLTemplateElement': { 'HTMLTemplateElement': {
'canGc': ['Content'], 'canGc': ['Content'],
}, },
'HTMLTitleElement': {
'canGc': ['SetText']
},
'HTMLTextAreaElement': { 'HTMLTextAreaElement': {
'canGc': ['CheckValidity', 'ReportValidity'], 'canGc': ['ReportValidity', 'SetDefaultValue', 'CheckValidity'],
},
'HTMLTableElement': {
'canGc': ['CreateCaption', 'CreateTBody', 'InsertRow', 'InsertCell', 'InsertRow', 'CreateTHead', 'CreateTFoot']
},
'HTMLTableRowElement': {
'canGc': ['InsertCell']
},
'HTMLTableSectionElement': {
'canGc': ['InsertRow']
},
'HTMLOptionsCollection': {
'canGc': ['IndexedSetter', 'SetLength']
},
'HTMLOptionElement': {
'canGc': ['SetText']
},
'HTMLProgressElement': {
'canGc': ['SetValue', 'SetMax']
},
'HTMLScriptElement': {
'canGc': ['SetAsync', 'SetCrossOrigin', 'SetText']
},
"HTMLAnchorElement": {
"canGc": ["SetText","SetRel","SetHref", 'SetHash', 'SetHost', 'SetHostname', 'SetPassword', 'SetPathname', 'SetPort', 'SetProtocol', 'SetSearch', 'SetUsername']
},
'HTMLLinkElement': {
'canGc': ['SetRel', 'SetCrossOrigin'],
}, },
'Location': { 'Location': {
@ -275,7 +359,7 @@ DOMInterfaces = {
}, },
'Node': { 'Node': {
'canGc': ['CloneNode'], 'canGc': ['CloneNode', 'SetTextContent'],
}, },
'OfflineAudioContext': { 'OfflineAudioContext': {
@ -313,7 +397,7 @@ DOMInterfaces = {
}, },
'Range': { 'Range': {
'canGc': ['CloneContents', 'CloneRange', 'CreateContextualFragment', 'ExtractContents', 'SurroundContents'], 'canGc': ['CloneContents', 'CloneRange', 'CreateContextualFragment', 'ExtractContents', 'SurroundContents', 'InsertNode'],
'weakReferenceable': True, 'weakReferenceable': True,
}, },
@ -348,6 +432,10 @@ DOMInterfaces = {
'canGc': ['Encrypt', 'Decrypt', 'GenerateKey', 'ImportKey', 'ExportKey'], 'canGc': ['Encrypt', 'Decrypt', 'GenerateKey', 'ImportKey', 'ExportKey'],
}, },
'SVGElement': {
'canGc': ['SetAutofocus']
},
#FIXME(jdm): This should be 'register': False, but then we don't generate enum types #FIXME(jdm): This should be 'register': False, but then we don't generate enum types
'TestBinding': { 'TestBinding': {
'inRealms': ['PromiseAttribute', 'PromiseNativeHandler'], 'inRealms': ['PromiseAttribute', 'PromiseNativeHandler'],
@ -359,6 +447,10 @@ DOMInterfaces = {
'canGc': ['AddModule'], 'canGc': ['AddModule'],
}, },
'Text': {
'canGc': ['SplitText']
},
'URL': { 'URL': {
'weakReferenceable': True, 'weakReferenceable': True,
'canGc': ['Parse', 'SearchParams'], 'canGc': ['Parse', 'SearchParams'],

View file

@ -6239,6 +6239,7 @@ let global = GlobalScope::from_object(JS_CALLEE(*cx, vp).to_object());
&global, &global,
PrototypeList::ID::{MakeNativeName(self.descriptor.name)}, PrototypeList::ID::{MakeNativeName(self.descriptor.name)},
CreateInterfaceObjects, CreateInterfaceObjects,
CanGc::note()
) )
""" """
else: else:

View file

@ -63,6 +63,7 @@ unsafe fn html_constructor(
check_type: fn(&Element) -> bool, check_type: fn(&Element) -> bool,
proto_id: PrototypeList::ID, proto_id: PrototypeList::ID,
creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray), creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
can_gc: CanGc,
) -> Result<(), ()> { ) -> Result<(), ()> {
let window = global.downcast::<Window>().unwrap(); let window = global.downcast::<Window>().unwrap();
let document = window.Document(); let document = window.Document();
@ -157,7 +158,7 @@ unsafe fn html_constructor(
// Any prototype used to create these elements will be overwritten before returning // Any prototype used to create these elements will be overwritten before returning
// from this function, so we don't bother overwriting the defaults here. // from this function, so we don't bother overwriting the defaults here.
let element = if definition.is_autonomous() { let element = if definition.is_autonomous() {
DomRoot::upcast(HTMLElement::new(name.local, None, &document, None)) DomRoot::upcast(HTMLElement::new(name.local, None, &document, None, can_gc))
} else { } else {
create_native_html_element( create_native_html_element(
name, name,
@ -384,6 +385,7 @@ pub unsafe fn call_html_constructor<T: DerivedFrom<Element> + DomObject>(
global: &GlobalScope, global: &GlobalScope,
proto_id: PrototypeList::ID, proto_id: PrototypeList::ID,
creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray), creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
can_gc: CanGc,
) -> bool { ) -> bool {
fn element_derives_interface<T: DerivedFrom<Element>>(element: &Element) -> bool { fn element_derives_interface<T: DerivedFrom<Element>>(element: &Element) -> bool {
element.is::<T>() element.is::<T>()
@ -396,6 +398,7 @@ pub unsafe fn call_html_constructor<T: DerivedFrom<Element> + DomObject>(
element_derives_interface::<T>, element_derives_interface::<T>,
proto_id, proto_id,
creator, creator,
can_gc,
) )
.is_ok() .is_ok()
} }

View file

@ -9,6 +9,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::dom::text::Text; use crate::dom::text::Text;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct CDATASection { pub struct CDATASection {
@ -22,10 +23,11 @@ impl CDATASection {
} }
} }
pub fn new(text: DOMString, document: &Document) -> DomRoot<CDATASection> { pub fn new(text: DOMString, document: &Document, can_gc: CanGc) -> DomRoot<CDATASection> {
Node::reflect_node( Node::reflect_node(
Box::new(CDATASection::new_inherited(text, document)), Box::new(CDATASection::new_inherited(text, document)),
document, document,
can_gc,
) )
} }
} }

View file

@ -25,6 +25,7 @@ use crate::dom::node::{ChildrenMutation, Node, NodeDamage};
use crate::dom::processinginstruction::ProcessingInstruction; use crate::dom::processinginstruction::ProcessingInstruction;
use crate::dom::text::Text; use crate::dom::text::Text;
use crate::dom::virtualmethods::vtable_for; use crate::dom::virtualmethods::vtable_for;
use crate::script_runtime::CanGc;
// https://dom.spec.whatwg.org/#characterdata // https://dom.spec.whatwg.org/#characterdata
#[dom_struct] #[dom_struct]
@ -41,20 +42,30 @@ impl CharacterData {
} }
} }
pub fn clone_with_data(&self, data: DOMString, document: &Document) -> DomRoot<Node> { pub fn clone_with_data(
&self,
data: DOMString,
document: &Document,
can_gc: CanGc,
) -> DomRoot<Node> {
match self.upcast::<Node>().type_id() { match self.upcast::<Node>().type_id() {
NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => { NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => {
DomRoot::upcast(Comment::new(data, document, None)) DomRoot::upcast(Comment::new(data, document, None, can_gc))
}, },
NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) => { NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) => {
let pi = self.downcast::<ProcessingInstruction>().unwrap(); let pi = self.downcast::<ProcessingInstruction>().unwrap();
DomRoot::upcast(ProcessingInstruction::new(pi.Target(), data, document)) DomRoot::upcast(ProcessingInstruction::new(
pi.Target(),
data,
document,
can_gc,
))
}, },
NodeTypeId::CharacterData(CharacterDataTypeId::Text(TextTypeId::CDATASection)) => { NodeTypeId::CharacterData(CharacterDataTypeId::Text(TextTypeId::CDATASection)) => {
DomRoot::upcast(CDATASection::new(data, document)) DomRoot::upcast(CDATASection::new(data, document, can_gc))
}, },
NodeTypeId::CharacterData(CharacterDataTypeId::Text(TextTypeId::Text)) => { NodeTypeId::CharacterData(CharacterDataTypeId::Text(TextTypeId::Text)) => {
DomRoot::upcast(Text::new(data, document)) DomRoot::upcast(Text::new(data, document, can_gc))
}, },
_ => unreachable!(), _ => unreachable!(),
} }
@ -243,18 +254,18 @@ impl CharacterDataMethods for CharacterData {
} }
// https://dom.spec.whatwg.org/#dom-childnode-before // https://dom.spec.whatwg.org/#dom-childnode-before
fn Before(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn Before(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().before(nodes) self.upcast::<Node>().before(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-childnode-after // https://dom.spec.whatwg.org/#dom-childnode-after
fn After(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn After(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().after(nodes) self.upcast::<Node>().after(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-childnode-replacewith // https://dom.spec.whatwg.org/#dom-childnode-replacewith
fn ReplaceWith(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn ReplaceWith(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().replace_with(nodes) self.upcast::<Node>().replace_with(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-childnode-remove // https://dom.spec.whatwg.org/#dom-childnode-remove

View file

@ -33,11 +33,13 @@ impl Comment {
text: DOMString, text: DOMString,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<Comment> { ) -> DomRoot<Comment> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(Comment::new_inherited(text, document)), Box::new(Comment::new_inherited(text, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }
@ -47,10 +49,10 @@ impl CommentMethods for Comment {
fn Constructor( fn Constructor(
window: &Window, window: &Window,
proto: Option<HandleObject>, proto: Option<HandleObject>,
_can_gc: CanGc, can_gc: CanGc,
data: DOMString, data: DOMString,
) -> Fallible<DomRoot<Comment>> { ) -> Fallible<DomRoot<Comment>> {
let document = window.Document(); let document = window.Document();
Ok(Comment::new(data, &document, proto)) Ok(Comment::new(data, &document, proto, can_gc))
} }
} }

View file

@ -99,17 +99,17 @@ fn create_svg_element(
macro_rules! make( macro_rules! make(
($ctor:ident) => ({ ($ctor:ident) => ({
let obj = $ctor::new(name.local, prefix, document, proto); let obj = $ctor::new(name.local, prefix, document, proto, CanGc::note());
DomRoot::upcast(obj) DomRoot::upcast(obj)
}); });
($ctor:ident, $($arg:expr),+) => ({ ($ctor:ident, $($arg:expr),+) => ({
let obj = $ctor::new(name.local, prefix, document, proto, $($arg),+); let obj = $ctor::new(name.local, prefix, document, proto, $($arg),+, CanGc::note());
DomRoot::upcast(obj) DomRoot::upcast(obj)
}) })
); );
if !pref!(dom.svg.enabled) { if !pref!(dom.svg.enabled) {
return Element::new(name.local, name.ns, prefix, document, proto); return Element::new(name.local, name.ns, prefix, document, proto, CanGc::note());
} }
match name.local { match name.local {
@ -145,6 +145,7 @@ fn create_html_element(
prefix.clone(), prefix.clone(),
document, document,
proto, proto,
can_gc,
)); ));
result.set_custom_element_state(CustomElementState::Undefined); result.set_custom_element_state(CustomElementState::Undefined);
ScriptThread::enqueue_upgrade_reaction(&result, definition); ScriptThread::enqueue_upgrade_reaction(&result, definition);
@ -173,7 +174,7 @@ fn create_html_element(
// Step 6.1.2 // Step 6.1.2
let element = DomRoot::upcast::<Element>(HTMLUnknownElement::new( let element = DomRoot::upcast::<Element>(HTMLUnknownElement::new(
local_name, prefix, document, proto, local_name, prefix, document, proto, can_gc,
)); ));
element.set_custom_element_state(CustomElementState::Failed); element.set_custom_element_state(CustomElementState::Failed);
element element
@ -231,11 +232,11 @@ pub fn create_native_html_element(
macro_rules! make( macro_rules! make(
($ctor:ident) => ({ ($ctor:ident) => ({
let obj = $ctor::new(name.local, prefix, document, proto); let obj = $ctor::new(name.local, prefix, document, proto, CanGc::note());
DomRoot::upcast(obj) DomRoot::upcast(obj)
}); });
($ctor:ident, $($arg:expr),+) => ({ ($ctor:ident, $($arg:expr),+) => ({
let obj = $ctor::new(name.local, prefix, document, proto, $($arg),+); let obj = $ctor::new(name.local, prefix, document, proto, $($arg),+, CanGc::note());
DomRoot::upcast(obj) DomRoot::upcast(obj)
}) })
); );
@ -406,6 +407,6 @@ pub fn create_element(
match name.ns { match name.ns {
ns!(html) => create_html_element(name, prefix, is, document, creator, mode, proto, can_gc), ns!(html) => create_html_element(name, prefix, is, document, creator, mode, proto, can_gc),
ns!(svg) => create_svg_element(name, prefix, document, proto), ns!(svg) => create_svg_element(name, prefix, document, proto),
_ => Element::new(name.local, name.ns, prefix, document, proto), _ => Element::new(name.local, name.ns, prefix, document, proto, can_gc),
} }
} }

View file

@ -57,7 +57,7 @@ pub enum CSSStyleOwner {
impl CSSStyleOwner { impl CSSStyleOwner {
// Mutate the declaration block associated to this style owner, and // Mutate the declaration block associated to this style owner, and
// optionally indicate if it has changed (assumed to be true). // optionally indicate if it has changed (assumed to be true).
fn mutate_associated_block<F, R>(&self, f: F) -> R fn mutate_associated_block<F, R>(&self, f: F, can_gc: CanGc) -> R
where where
F: FnOnce(&mut PropertyDeclarationBlock, &mut bool) -> R, F: FnOnce(&mut PropertyDeclarationBlock, &mut bool) -> R,
{ {
@ -103,6 +103,7 @@ impl CSSStyleOwner {
el.set_attribute( el.set_attribute(
&local_name!("style"), &local_name!("style"),
AttrValue::Declaration(serialization, pdb), AttrValue::Declaration(serialization, pdb),
can_gc,
); );
} }
} else { } else {
@ -287,61 +288,64 @@ impl CSSStyleDeclaration {
return Ok(()); return Ok(());
} }
self.owner.mutate_associated_block(|pdb, changed| { self.owner.mutate_associated_block(
if value.is_empty() { |pdb, changed| {
// Step 3 if value.is_empty() {
*changed = remove_property(pdb, &id); // Step 3
return Ok(()); *changed = remove_property(pdb, &id);
}
// Step 4
let importance = match &*priority {
"" => Importance::Normal,
p if p.eq_ignore_ascii_case("important") => Importance::Important,
_ => {
*changed = false;
return Ok(()); return Ok(());
}, }
};
// Step 5 // Step 4
let window = self.owner.window(); let importance = match &*priority {
let quirks_mode = window.Document().quirks_mode(); "" => Importance::Normal,
let mut declarations = SourcePropertyDeclaration::default(); p if p.eq_ignore_ascii_case("important") => Importance::Important,
let result = parse_one_declaration_into( _ => {
&mut declarations, *changed = false;
id, return Ok(());
&value, },
Origin::Author, };
&UrlExtraData(self.owner.base_url().get_arc()),
window.css_error_reporter(),
ParsingMode::DEFAULT,
quirks_mode,
CssRuleType::Style,
);
// Step 6 // Step 5
match result { let window = self.owner.window();
Ok(()) => {}, let quirks_mode = window.Document().quirks_mode();
Err(_) => { let mut declarations = SourcePropertyDeclaration::default();
*changed = false; let result = parse_one_declaration_into(
&mut declarations,
id,
&value,
Origin::Author,
&UrlExtraData(self.owner.base_url().get_arc()),
window.css_error_reporter(),
ParsingMode::DEFAULT,
quirks_mode,
CssRuleType::Style,
);
// Step 6
match result {
Ok(()) => {},
Err(_) => {
*changed = false;
return Ok(());
},
}
let mut updates = Default::default();
*changed = pdb.prepare_for_update(&declarations, importance, &mut updates);
if !*changed {
return Ok(()); return Ok(());
}, }
}
let mut updates = Default::default(); // Step 7
*changed = pdb.prepare_for_update(&declarations, importance, &mut updates); // Step 8
pdb.update(declarations.drain(), importance, &mut updates);
if !*changed { Ok(())
return Ok(()); },
} CanGc::note(),
)
// Step 7
// Step 8
pdb.update(declarations.drain(), importance, &mut updates);
Ok(())
})
} }
} }
@ -435,7 +439,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
} }
// https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-removeproperty // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-removeproperty
fn RemoveProperty(&self, property: DOMString) -> Fallible<DOMString> { fn RemoveProperty(&self, property: DOMString, can_gc: CanGc) -> Fallible<DOMString> {
// Step 1 // Step 1
if self.readonly { if self.readonly {
return Err(Error::NoModificationAllowed); return Err(Error::NoModificationAllowed);
@ -447,10 +451,13 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
}; };
let mut string = String::new(); let mut string = String::new();
self.owner.mutate_associated_block(|pdb, changed| { self.owner.mutate_associated_block(
pdb.property_value_to_css(&id, &mut string).unwrap(); |pdb, changed| {
*changed = remove_property(pdb, &id); pdb.property_value_to_css(&id, &mut string).unwrap();
}); *changed = remove_property(pdb, &id);
},
can_gc,
);
// Step 6 // Step 6
Ok(DOMString::from(string)) Ok(DOMString::from(string))
@ -498,7 +505,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
} }
// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext
fn SetCssText(&self, value: DOMString) -> ErrorResult { fn SetCssText(&self, value: DOMString, can_gc: CanGc) -> ErrorResult {
let window = self.owner.window(); let window = self.owner.window();
// Step 1 // Step 1
@ -507,16 +514,19 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
} }
let quirks_mode = window.Document().quirks_mode(); let quirks_mode = window.Document().quirks_mode();
self.owner.mutate_associated_block(|pdb, _changed| { self.owner.mutate_associated_block(
// Step 3 |pdb, _changed| {
*pdb = parse_style_attribute( // Step 3
&value, *pdb = parse_style_attribute(
&UrlExtraData(self.owner.base_url().get_arc()), &value,
window.css_error_reporter(), &UrlExtraData(self.owner.base_url().get_arc()),
quirks_mode, window.css_error_reporter(),
CssRuleType::Style, quirks_mode,
); CssRuleType::Style,
}); );
},
can_gc,
);
Ok(()) Ok(())
} }

View file

@ -1973,21 +1973,24 @@ impl Document {
pub fn node_from_nodes_and_strings( pub fn node_from_nodes_and_strings(
&self, &self,
mut nodes: Vec<NodeOrString>, mut nodes: Vec<NodeOrString>,
can_gc: CanGc,
) -> Fallible<DomRoot<Node>> { ) -> Fallible<DomRoot<Node>> {
if nodes.len() == 1 { if nodes.len() == 1 {
Ok(match nodes.pop().unwrap() { Ok(match nodes.pop().unwrap() {
NodeOrString::Node(node) => node, NodeOrString::Node(node) => node,
NodeOrString::String(string) => DomRoot::upcast(self.CreateTextNode(string)), NodeOrString::String(string) => {
DomRoot::upcast(self.CreateTextNode(string, can_gc))
},
}) })
} else { } else {
let fragment = DomRoot::upcast::<Node>(self.CreateDocumentFragment()); let fragment = DomRoot::upcast::<Node>(self.CreateDocumentFragment(can_gc));
for node in nodes { for node in nodes {
match node { match node {
NodeOrString::Node(node) => { NodeOrString::Node(node) => {
fragment.AppendChild(&node)?; fragment.AppendChild(&node)?;
}, },
NodeOrString::String(string) => { NodeOrString::String(string) => {
let node = DomRoot::upcast::<Node>(self.CreateTextNode(string)); let node = DomRoot::upcast::<Node>(self.CreateTextNode(string, can_gc));
// No try!() here because appending a text node // No try!() here because appending a text node
// should not fail. // should not fail.
fragment.AppendChild(&node).unwrap(); fragment.AppendChild(&node).unwrap();
@ -2008,14 +2011,14 @@ impl Document {
} }
} }
pub fn set_body_attribute(&self, local_name: &LocalName, value: DOMString) { pub fn set_body_attribute(&self, local_name: &LocalName, value: DOMString, can_gc: CanGc) {
if let Some(ref body) = self if let Some(ref body) = self
.GetBody() .GetBody()
.and_then(DomRoot::downcast::<HTMLBodyElement>) .and_then(DomRoot::downcast::<HTMLBodyElement>)
{ {
let body = body.upcast::<Element>(); let body = body.upcast::<Element>();
let value = body.parse_attribute(&ns!(), local_name, value); let value = body.parse_attribute(&ns!(), local_name, value);
body.set_attribute(local_name, value); body.set_attribute(local_name, value, can_gc);
} }
} }
@ -4565,7 +4568,7 @@ impl DocumentMethods for Document {
} }
// https://dom.spec.whatwg.org/#dom-document-createattribute // https://dom.spec.whatwg.org/#dom-document-createattribute
fn CreateAttribute(&self, mut local_name: DOMString) -> Fallible<DomRoot<Attr>> { fn CreateAttribute(&self, mut local_name: DOMString, can_gc: CanGc) -> Fallible<DomRoot<Attr>> {
if xml_name_type(&local_name) == Invalid { if xml_name_type(&local_name) == Invalid {
debug!("Not a valid element name"); debug!("Not a valid element name");
return Err(Error::InvalidCharacter); return Err(Error::InvalidCharacter);
@ -4584,6 +4587,7 @@ impl DocumentMethods for Document {
ns!(), ns!(),
None, None,
None, None,
can_gc,
)) ))
} }
@ -4592,6 +4596,7 @@ impl DocumentMethods for Document {
&self, &self,
namespace: Option<DOMString>, namespace: Option<DOMString>,
qualified_name: DOMString, qualified_name: DOMString,
can_gc: CanGc,
) -> Fallible<DomRoot<Attr>> { ) -> Fallible<DomRoot<Attr>> {
let (namespace, prefix, local_name) = validate_and_extract(namespace, &qualified_name)?; let (namespace, prefix, local_name) = validate_and_extract(namespace, &qualified_name)?;
let value = AttrValue::String("".to_owned()); let value = AttrValue::String("".to_owned());
@ -4604,21 +4609,26 @@ impl DocumentMethods for Document {
namespace, namespace,
prefix, prefix,
None, None,
can_gc,
)) ))
} }
// https://dom.spec.whatwg.org/#dom-document-createdocumentfragment // https://dom.spec.whatwg.org/#dom-document-createdocumentfragment
fn CreateDocumentFragment(&self) -> DomRoot<DocumentFragment> { fn CreateDocumentFragment(&self, can_gc: CanGc) -> DomRoot<DocumentFragment> {
DocumentFragment::new(self) DocumentFragment::new(self, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-document-createtextnode // https://dom.spec.whatwg.org/#dom-document-createtextnode
fn CreateTextNode(&self, data: DOMString) -> DomRoot<Text> { fn CreateTextNode(&self, data: DOMString, can_gc: CanGc) -> DomRoot<Text> {
Text::new(data, self) Text::new(data, self, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-document-createcdatasection // https://dom.spec.whatwg.org/#dom-document-createcdatasection
fn CreateCDATASection(&self, data: DOMString) -> Fallible<DomRoot<CDATASection>> { fn CreateCDATASection(
&self,
data: DOMString,
can_gc: CanGc,
) -> Fallible<DomRoot<CDATASection>> {
// Step 1 // Step 1
if self.is_html_document { if self.is_html_document {
return Err(Error::NotSupported); return Err(Error::NotSupported);
@ -4630,12 +4640,12 @@ impl DocumentMethods for Document {
} }
// Step 3 // Step 3
Ok(CDATASection::new(data, self)) Ok(CDATASection::new(data, self, can_gc))
} }
// https://dom.spec.whatwg.org/#dom-document-createcomment // https://dom.spec.whatwg.org/#dom-document-createcomment
fn CreateComment(&self, data: DOMString) -> DomRoot<Comment> { fn CreateComment(&self, data: DOMString, can_gc: CanGc) -> DomRoot<Comment> {
Comment::new(data, self, None) Comment::new(data, self, None, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction // https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction
@ -4643,6 +4653,7 @@ impl DocumentMethods for Document {
&self, &self,
target: DOMString, target: DOMString,
data: DOMString, data: DOMString,
can_gc: CanGc,
) -> Fallible<DomRoot<ProcessingInstruction>> { ) -> Fallible<DomRoot<ProcessingInstruction>> {
// Step 1. // Step 1.
if xml_name_type(&target) == Invalid { if xml_name_type(&target) == Invalid {
@ -4655,7 +4666,7 @@ impl DocumentMethods for Document {
} }
// Step 3. // Step 3.
Ok(ProcessingInstruction::new(target, data, self)) Ok(ProcessingInstruction::new(target, data, self, can_gc))
} }
// https://dom.spec.whatwg.org/#dom-document-importnode // https://dom.spec.whatwg.org/#dom-document-importnode
@ -4853,7 +4864,7 @@ impl DocumentMethods for Document {
return; return;
}; };
elem.SetTextContent(Some(title)); elem.SetTextContent(Some(title), can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-document-head // https://html.spec.whatwg.org/multipage/#dom-document-head
@ -5030,18 +5041,18 @@ impl DocumentMethods for Document {
} }
// https://dom.spec.whatwg.org/#dom-parentnode-prepend // https://dom.spec.whatwg.org/#dom-parentnode-prepend
fn Prepend(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn Prepend(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().prepend(nodes) self.upcast::<Node>().prepend(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-parentnode-append // https://dom.spec.whatwg.org/#dom-parentnode-append
fn Append(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn Append(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().append(nodes) self.upcast::<Node>().append(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-parentnode-replacechildren // https://dom.spec.whatwg.org/#dom-parentnode-replacechildren
fn ReplaceChildren(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn ReplaceChildren(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().replace_children(nodes) self.upcast::<Node>().replace_children(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-parentnode-queryselector // https://dom.spec.whatwg.org/#dom-parentnode-queryselector
@ -5121,8 +5132,8 @@ impl DocumentMethods for Document {
} }
// https://html.spec.whatwg.org/multipage/#dom-document-bgcolor // https://html.spec.whatwg.org/multipage/#dom-document-bgcolor
fn SetBgColor(&self, value: DOMString) { fn SetBgColor(&self, value: DOMString, can_gc: CanGc) {
self.set_body_attribute(&local_name!("bgcolor"), value) self.set_body_attribute(&local_name!("bgcolor"), value, can_gc)
} }
// https://html.spec.whatwg.org/multipage/#dom-document-fgcolor // https://html.spec.whatwg.org/multipage/#dom-document-fgcolor
@ -5131,8 +5142,8 @@ impl DocumentMethods for Document {
} }
// https://html.spec.whatwg.org/multipage/#dom-document-fgcolor // https://html.spec.whatwg.org/multipage/#dom-document-fgcolor
fn SetFgColor(&self, value: DOMString) { fn SetFgColor(&self, value: DOMString, can_gc: CanGc) {
self.set_body_attribute(&local_name!("text"), value) self.set_body_attribute(&local_name!("text"), value, can_gc)
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]

View file

@ -40,18 +40,20 @@ impl DocumentFragment {
} }
} }
pub fn new(document: &Document) -> DomRoot<DocumentFragment> { pub fn new(document: &Document, can_gc: CanGc) -> DomRoot<DocumentFragment> {
Self::new_with_proto(document, None) Self::new_with_proto(document, None, can_gc)
} }
fn new_with_proto( fn new_with_proto(
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<DocumentFragment> { ) -> DomRoot<DocumentFragment> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(DocumentFragment::new_inherited(document)), Box::new(DocumentFragment::new_inherited(document)),
document, document,
proto, proto,
can_gc,
) )
} }
@ -65,11 +67,11 @@ impl DocumentFragmentMethods for DocumentFragment {
fn Constructor( fn Constructor(
window: &Window, window: &Window,
proto: Option<HandleObject>, proto: Option<HandleObject>,
_can_gc: CanGc, can_gc: CanGc,
) -> Fallible<DomRoot<DocumentFragment>> { ) -> Fallible<DomRoot<DocumentFragment>> {
let document = window.Document(); let document = window.Document();
Ok(DocumentFragment::new_with_proto(&document, proto)) Ok(DocumentFragment::new_with_proto(&document, proto, can_gc))
} }
// https://dom.spec.whatwg.org/#dom-parentnode-children // https://dom.spec.whatwg.org/#dom-parentnode-children
@ -106,18 +108,18 @@ impl DocumentFragmentMethods for DocumentFragment {
} }
// https://dom.spec.whatwg.org/#dom-parentnode-prepend // https://dom.spec.whatwg.org/#dom-parentnode-prepend
fn Prepend(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn Prepend(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().prepend(nodes) self.upcast::<Node>().prepend(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-parentnode-append // https://dom.spec.whatwg.org/#dom-parentnode-append
fn Append(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn Append(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().append(nodes) self.upcast::<Node>().append(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-parentnode-replacechildren // https://dom.spec.whatwg.org/#dom-parentnode-replacechildren
fn ReplaceChildren(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn ReplaceChildren(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().replace_children(nodes) self.upcast::<Node>().replace_children(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-parentnode-queryselector // https://dom.spec.whatwg.org/#dom-parentnode-queryselector

View file

@ -12,6 +12,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString; use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
// https://dom.spec.whatwg.org/#documenttype // https://dom.spec.whatwg.org/#documenttype
/// The `DOCTYPE` tag. /// The `DOCTYPE` tag.
@ -43,12 +44,14 @@ impl DocumentType {
public_id: Option<DOMString>, public_id: Option<DOMString>,
system_id: Option<DOMString>, system_id: Option<DOMString>,
document: &Document, document: &Document,
can_gc: CanGc,
) -> DomRoot<DocumentType> { ) -> DomRoot<DocumentType> {
Node::reflect_node( Node::reflect_node(
Box::new(DocumentType::new_inherited( Box::new(DocumentType::new_inherited(
name, public_id, system_id, document, name, public_id, system_id, document,
)), )),
document, document,
can_gc,
) )
} }
@ -85,18 +88,18 @@ impl DocumentTypeMethods for DocumentType {
} }
// https://dom.spec.whatwg.org/#dom-childnode-before // https://dom.spec.whatwg.org/#dom-childnode-before
fn Before(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn Before(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().before(nodes) self.upcast::<Node>().before(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-childnode-after // https://dom.spec.whatwg.org/#dom-childnode-after
fn After(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn After(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().after(nodes) self.upcast::<Node>().after(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-childnode-replacewith // https://dom.spec.whatwg.org/#dom-childnode-replacewith
fn ReplaceWith(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn ReplaceWith(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().replace_with(nodes) self.upcast::<Node>().replace_with(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-childnode-remove // https://dom.spec.whatwg.org/#dom-childnode-remove

View file

@ -59,6 +59,7 @@ impl DOMImplementationMethods for DOMImplementation {
qualified_name: DOMString, qualified_name: DOMString,
pubid: DOMString, pubid: DOMString,
sysid: DOMString, sysid: DOMString,
can_gc: CanGc,
) -> Fallible<DomRoot<DocumentType>> { ) -> Fallible<DomRoot<DocumentType>> {
validate_qualified_name(&qualified_name)?; validate_qualified_name(&qualified_name)?;
Ok(DocumentType::new( Ok(DocumentType::new(
@ -66,6 +67,7 @@ impl DOMImplementationMethods for DOMImplementation {
Some(pubid), Some(pubid),
Some(sysid), Some(sysid),
&self.document, &self.document,
can_gc,
)) ))
} }
@ -165,7 +167,7 @@ impl DOMImplementationMethods for DOMImplementation {
{ {
// Step 3. // Step 3.
let doc_node = doc.upcast::<Node>(); let doc_node = doc.upcast::<Node>();
let doc_type = DocumentType::new(DOMString::from("html"), None, None, &doc); let doc_type = DocumentType::new(DOMString::from("html"), None, None, &doc, can_gc);
doc_node.AppendChild(doc_type.upcast()).unwrap(); doc_node.AppendChild(doc_type.upcast()).unwrap();
} }
@ -177,6 +179,7 @@ impl DOMImplementationMethods for DOMImplementation {
None, None,
&doc, &doc,
None, None,
can_gc,
)); ));
doc_node.AppendChild(&doc_html).expect("Appending failed"); doc_node.AppendChild(&doc_html).expect("Appending failed");
@ -187,6 +190,7 @@ impl DOMImplementationMethods for DOMImplementation {
None, None,
&doc, &doc,
None, None,
can_gc,
)); ));
doc_html.AppendChild(&doc_head).unwrap(); doc_html.AppendChild(&doc_head).unwrap();
@ -198,17 +202,18 @@ impl DOMImplementationMethods for DOMImplementation {
None, None,
&doc, &doc,
None, None,
can_gc,
)); ));
doc_head.AppendChild(&doc_title).unwrap(); doc_head.AppendChild(&doc_title).unwrap();
// Step 6.2. // Step 6.2.
let title_text = Text::new(title_str, &doc); let title_text = Text::new(title_str, &doc, can_gc);
doc_title.AppendChild(title_text.upcast()).unwrap(); doc_title.AppendChild(title_text.upcast()).unwrap();
} }
} }
// Step 7. // Step 7.
let doc_body = HTMLBodyElement::new(local_name!("body"), None, &doc, None); let doc_body = HTMLBodyElement::new(local_name!("body"), None, &doc, None, can_gc);
doc_html.AppendChild(doc_body.upcast()).unwrap(); doc_html.AppendChild(doc_body.upcast()).unwrap();
} }

View file

@ -11,6 +11,7 @@ use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString; use crate::dom::bindings::str::DOMString;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::window_from_node; use crate::dom::node::window_from_node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct DOMStringMap { pub struct DOMStringMap {
@ -40,8 +41,8 @@ impl DOMStringMapMethods for DOMStringMap {
} }
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-setitem // https://html.spec.whatwg.org/multipage/#dom-domstringmap-setitem
fn NamedSetter(&self, name: DOMString, value: DOMString) -> ErrorResult { fn NamedSetter(&self, name: DOMString, value: DOMString, can_gc: CanGc) -> ErrorResult {
self.element.set_custom_attr(name, value) self.element.set_custom_attr(name, value, can_gc)
} }
// https://html.spec.whatwg.org/multipage/#dom-domstringmap-nameditem // https://html.spec.whatwg.org/multipage/#dom-domstringmap-nameditem

View file

@ -15,6 +15,7 @@ use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString; use crate::dom::bindings::str::DOMString;
use crate::dom::element::Element; use crate::dom::element::Element;
use crate::dom::node::window_from_node; use crate::dom::node::window_from_node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct DOMTokenList { pub struct DOMTokenList {
@ -69,14 +70,14 @@ impl DOMTokenList {
} }
/// <https://dom.spec.whatwg.org/#concept-dtl-update> /// <https://dom.spec.whatwg.org/#concept-dtl-update>
fn perform_update_steps(&self, atoms: Vec<Atom>) { fn perform_update_steps(&self, atoms: Vec<Atom>, can_gc: CanGc) {
// Step 1 // Step 1
if !self.element.has_attribute(&self.local_name) && atoms.is_empty() { if !self.element.has_attribute(&self.local_name) && atoms.is_empty() {
return; return;
} }
// step 2 // step 2
self.element self.element
.set_atomic_tokenlist_attribute(&self.local_name, atoms) .set_atomic_tokenlist_attribute(&self.local_name, atoms, can_gc)
} }
/// <https://dom.spec.whatwg.org/#concept-domtokenlist-validation> /// <https://dom.spec.whatwg.org/#concept-domtokenlist-validation>
@ -130,7 +131,7 @@ impl DOMTokenListMethods for DOMTokenList {
} }
/// <https://dom.spec.whatwg.org/#dom-domtokenlist-add> /// <https://dom.spec.whatwg.org/#dom-domtokenlist-add>
fn Add(&self, tokens: Vec<DOMString>) -> ErrorResult { fn Add(&self, tokens: Vec<DOMString>, can_gc: CanGc) -> ErrorResult {
let mut atoms = self.element.get_tokenlist_attribute(&self.local_name); let mut atoms = self.element.get_tokenlist_attribute(&self.local_name);
for token in &tokens { for token in &tokens {
let token = self.check_token_exceptions(token)?; let token = self.check_token_exceptions(token)?;
@ -138,12 +139,12 @@ impl DOMTokenListMethods for DOMTokenList {
atoms.push(token); atoms.push(token);
} }
} }
self.perform_update_steps(atoms); self.perform_update_steps(atoms, can_gc);
Ok(()) Ok(())
} }
/// <https://dom.spec.whatwg.org/#dom-domtokenlist-remove> /// <https://dom.spec.whatwg.org/#dom-domtokenlist-remove>
fn Remove(&self, tokens: Vec<DOMString>) -> ErrorResult { fn Remove(&self, tokens: Vec<DOMString>, can_gc: CanGc) -> ErrorResult {
let mut atoms = self.element.get_tokenlist_attribute(&self.local_name); let mut atoms = self.element.get_tokenlist_attribute(&self.local_name);
for token in &tokens { for token in &tokens {
let token = self.check_token_exceptions(token)?; let token = self.check_token_exceptions(token)?;
@ -152,12 +153,12 @@ impl DOMTokenListMethods for DOMTokenList {
.position(|atom| *atom == token) .position(|atom| *atom == token)
.map(|index| atoms.remove(index)); .map(|index| atoms.remove(index));
} }
self.perform_update_steps(atoms); self.perform_update_steps(atoms, can_gc);
Ok(()) Ok(())
} }
/// <https://dom.spec.whatwg.org/#dom-domtokenlist-toggle> /// <https://dom.spec.whatwg.org/#dom-domtokenlist-toggle>
fn Toggle(&self, token: DOMString, force: Option<bool>) -> Fallible<bool> { fn Toggle(&self, token: DOMString, force: Option<bool>, can_gc: CanGc) -> Fallible<bool> {
let mut atoms = self.element.get_tokenlist_attribute(&self.local_name); let mut atoms = self.element.get_tokenlist_attribute(&self.local_name);
let token = self.check_token_exceptions(&token)?; let token = self.check_token_exceptions(&token)?;
match atoms.iter().position(|atom| *atom == token) { match atoms.iter().position(|atom| *atom == token) {
@ -165,7 +166,7 @@ impl DOMTokenListMethods for DOMTokenList {
Some(true) => Ok(true), Some(true) => Ok(true),
_ => { _ => {
atoms.remove(index); atoms.remove(index);
self.perform_update_steps(atoms); self.perform_update_steps(atoms, can_gc);
Ok(false) Ok(false)
}, },
}, },
@ -173,7 +174,7 @@ impl DOMTokenListMethods for DOMTokenList {
Some(false) => Ok(false), Some(false) => Ok(false),
_ => { _ => {
atoms.push(token); atoms.push(token);
self.perform_update_steps(atoms); self.perform_update_steps(atoms, can_gc);
Ok(true) Ok(true)
}, },
}, },
@ -186,13 +187,13 @@ impl DOMTokenListMethods for DOMTokenList {
} }
/// <https://dom.spec.whatwg.org/#dom-domtokenlist-value> /// <https://dom.spec.whatwg.org/#dom-domtokenlist-value>
fn SetValue(&self, value: DOMString) { fn SetValue(&self, value: DOMString, can_gc: CanGc) {
self.element self.element
.set_tokenlist_attribute(&self.local_name, value); .set_tokenlist_attribute(&self.local_name, value, can_gc);
} }
/// <https://dom.spec.whatwg.org/#dom-domtokenlist-replace> /// <https://dom.spec.whatwg.org/#dom-domtokenlist-replace>
fn Replace(&self, token: DOMString, new_token: DOMString) -> Fallible<bool> { fn Replace(&self, token: DOMString, new_token: DOMString, can_gc: CanGc) -> Fallible<bool> {
if token.is_empty() || new_token.is_empty() { if token.is_empty() || new_token.is_empty() {
// Step 1. // Step 1.
return Err(Error::Syntax); return Err(Error::Syntax);
@ -231,7 +232,7 @@ impl DOMTokenListMethods for DOMTokenList {
} }
// Step 5. // Step 5.
self.perform_update_steps(atoms); self.perform_update_steps(atoms, can_gc);
result = true; result = true;
} }
Ok(result) Ok(result)

View file

@ -314,6 +314,7 @@ impl Element {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<Element> { ) -> DomRoot<Element> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(Element::new_inherited( Box::new(Element::new_inherited(
@ -321,6 +322,7 @@ impl Element {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
@ -1441,6 +1443,7 @@ impl Element {
name: LocalName, name: LocalName,
namespace: Namespace, namespace: Namespace,
prefix: Option<Prefix>, prefix: Option<Prefix>,
can_gc: CanGc,
) { ) {
let attr = Attr::new( let attr = Attr::new(
&self.node.owner_doc(), &self.node.owner_doc(),
@ -1450,6 +1453,7 @@ impl Element {
namespace, namespace,
prefix, prefix,
Some(self), Some(self),
can_gc,
); );
self.push_attribute(&attr); self.push_attribute(&attr);
} }
@ -1519,6 +1523,7 @@ impl Element {
qname: QualName, qname: QualName,
value: DOMString, value: DOMString,
prefix: Option<Prefix>, prefix: Option<Prefix>,
can_gc: CanGc,
) { ) {
// Don't set if the attribute already exists, so we can handle add_attrs_if_missing // Don't set if the attribute already exists, so we can handle add_attrs_if_missing
if self if self
@ -1538,20 +1543,31 @@ impl Element {
}, },
}; };
let value = self.parse_attribute(&qname.ns, &qname.local, value); let value = self.parse_attribute(&qname.ns, &qname.local, value);
self.push_new_attribute(qname.local, value, name, qname.ns, prefix); self.push_new_attribute(qname.local, value, name, qname.ns, prefix, can_gc);
} }
pub fn set_attribute(&self, name: &LocalName, value: AttrValue) { pub fn set_attribute(&self, name: &LocalName, value: AttrValue, can_gc: CanGc) {
assert!(name == &name.to_ascii_lowercase()); assert!(name == &name.to_ascii_lowercase());
assert!(!name.contains(':')); assert!(!name.contains(':'));
self.set_first_matching_attribute(name.clone(), value, name.clone(), ns!(), None, |attr| { self.set_first_matching_attribute(
attr.local_name() == name name.clone(),
}); value,
name.clone(),
ns!(),
None,
|attr| attr.local_name() == name,
can_gc,
);
} }
// https://html.spec.whatwg.org/multipage/#attr-data-* // https://html.spec.whatwg.org/multipage/#attr-data-*
pub fn set_custom_attribute(&self, name: DOMString, value: DOMString) -> ErrorResult { pub fn set_custom_attribute(
&self,
name: DOMString,
value: DOMString,
can_gc: CanGc,
) -> ErrorResult {
// Step 1. // Step 1.
if let Invalid = xml_name_type(&name) { if let Invalid = xml_name_type(&name) {
return Err(Error::InvalidCharacter); return Err(Error::InvalidCharacter);
@ -1560,12 +1576,19 @@ impl Element {
// Steps 2-5. // Steps 2-5.
let name = LocalName::from(name); let name = LocalName::from(name);
let value = self.parse_attribute(&ns!(), &name, value); let value = self.parse_attribute(&ns!(), &name, value);
self.set_first_matching_attribute(name.clone(), value, name.clone(), ns!(), None, |attr| { self.set_first_matching_attribute(
*attr.name() == name && *attr.namespace() == ns!() name.clone(),
}); value,
name.clone(),
ns!(),
None,
|attr| *attr.name() == name && *attr.namespace() == ns!(),
can_gc,
);
Ok(()) Ok(())
} }
#[allow(clippy::too_many_arguments)]
fn set_first_matching_attribute<F>( fn set_first_matching_attribute<F>(
&self, &self,
local_name: LocalName, local_name: LocalName,
@ -1574,6 +1597,7 @@ impl Element {
namespace: Namespace, namespace: Namespace,
prefix: Option<Prefix>, prefix: Option<Prefix>,
find: F, find: F,
can_gc: CanGc,
) where ) where
F: Fn(&Attr) -> bool, F: Fn(&Attr) -> bool,
{ {
@ -1586,7 +1610,7 @@ impl Element {
if let Some(attr) = attr { if let Some(attr) = attr {
attr.set_value(value, self); attr.set_value(value, self);
} else { } else {
self.push_new_attribute(local_name, value, name, namespace, prefix); self.push_new_attribute(local_name, value, name, namespace, prefix, can_gc);
}; };
} }
@ -1660,10 +1684,10 @@ impl Element {
}) })
} }
pub fn set_atomic_attribute(&self, local_name: &LocalName, value: DOMString) { pub fn set_atomic_attribute(&self, local_name: &LocalName, value: DOMString, can_gc: CanGc) {
assert!(*local_name == local_name.to_ascii_lowercase()); assert!(*local_name == local_name.to_ascii_lowercase());
let value = AttrValue::from_atomic(value.into()); let value = AttrValue::from_atomic(value.into());
self.set_attribute(local_name, value); self.set_attribute(local_name, value, can_gc);
} }
pub fn has_attribute(&self, local_name: &LocalName) -> bool { pub fn has_attribute(&self, local_name: &LocalName) -> bool {
@ -1674,12 +1698,12 @@ impl Element {
.any(|attr| attr.local_name() == local_name && attr.namespace() == &ns!()) .any(|attr| attr.local_name() == local_name && attr.namespace() == &ns!())
} }
pub fn set_bool_attribute(&self, local_name: &LocalName, value: bool) { pub fn set_bool_attribute(&self, local_name: &LocalName, value: bool, can_gc: CanGc) {
if self.has_attribute(local_name) == value { if self.has_attribute(local_name) == value {
return; return;
} }
if value { if value {
self.set_string_attribute(local_name, DOMString::new()); self.set_string_attribute(local_name, DOMString::new(), can_gc);
} else { } else {
self.remove_attribute(&ns!(), local_name); self.remove_attribute(&ns!(), local_name);
} }
@ -1700,9 +1724,9 @@ impl Element {
.unwrap_or_else(|_| USVString(value.to_owned())) .unwrap_or_else(|_| USVString(value.to_owned()))
} }
pub fn set_url_attribute(&self, local_name: &LocalName, value: USVString) { pub fn set_url_attribute(&self, local_name: &LocalName, value: USVString, can_gc: CanGc) {
assert!(*local_name == local_name.to_ascii_lowercase()); assert!(*local_name == local_name.to_ascii_lowercase());
self.set_attribute(local_name, AttrValue::String(value.to_string())); self.set_attribute(local_name, AttrValue::String(value.to_string()), can_gc);
} }
pub fn get_string_attribute(&self, local_name: &LocalName) -> DOMString { pub fn get_string_attribute(&self, local_name: &LocalName) -> DOMString {
@ -1712,9 +1736,9 @@ impl Element {
} }
} }
pub fn set_string_attribute(&self, local_name: &LocalName, value: DOMString) { pub fn set_string_attribute(&self, local_name: &LocalName, value: DOMString, can_gc: CanGc) {
assert!(*local_name == local_name.to_ascii_lowercase()); assert!(*local_name == local_name.to_ascii_lowercase());
self.set_attribute(local_name, AttrValue::String(value.into())); self.set_attribute(local_name, AttrValue::String(value.into()), can_gc);
} }
/// Used for string attribute reflections where absence of the attribute returns `null`, /// Used for string attribute reflections where absence of the attribute returns `null`,
@ -1729,10 +1753,15 @@ impl Element {
/// Used for string attribute reflections where setting `null`/`undefined` removes the /// Used for string attribute reflections where setting `null`/`undefined` removes the
/// attribute, e.g. `element.ariaLabel = null` removing the `aria-label` attribute. /// attribute, e.g. `element.ariaLabel = null` removing the `aria-label` attribute.
fn set_nullable_string_attribute(&self, local_name: &LocalName, value: Option<DOMString>) { fn set_nullable_string_attribute(
&self,
local_name: &LocalName,
value: Option<DOMString>,
can_gc: CanGc,
) {
match value { match value {
Some(val) => { Some(val) => {
self.set_string_attribute(local_name, val); self.set_string_attribute(local_name, val, can_gc);
}, },
None => { None => {
self.remove_attribute(&ns!(), local_name); self.remove_attribute(&ns!(), local_name);
@ -1746,17 +1775,23 @@ impl Element {
.unwrap_or_default() .unwrap_or_default()
} }
pub fn set_tokenlist_attribute(&self, local_name: &LocalName, value: DOMString) { pub fn set_tokenlist_attribute(&self, local_name: &LocalName, value: DOMString, can_gc: CanGc) {
assert!(*local_name == local_name.to_ascii_lowercase()); assert!(*local_name == local_name.to_ascii_lowercase());
self.set_attribute( self.set_attribute(
local_name, local_name,
AttrValue::from_serialized_tokenlist(value.into()), AttrValue::from_serialized_tokenlist(value.into()),
can_gc,
); );
} }
pub fn set_atomic_tokenlist_attribute(&self, local_name: &LocalName, tokens: Vec<Atom>) { pub fn set_atomic_tokenlist_attribute(
&self,
local_name: &LocalName,
tokens: Vec<Atom>,
can_gc: CanGc,
) {
assert!(*local_name == local_name.to_ascii_lowercase()); assert!(*local_name == local_name.to_ascii_lowercase());
self.set_attribute(local_name, AttrValue::from_atomic_tokens(tokens)); self.set_attribute(local_name, AttrValue::from_atomic_tokens(tokens), can_gc);
} }
pub fn get_int_attribute(&self, local_name: &LocalName, default: i32) -> i32 { pub fn get_int_attribute(&self, local_name: &LocalName, default: i32) -> i32 {
@ -1778,9 +1813,9 @@ impl Element {
} }
} }
pub fn set_int_attribute(&self, local_name: &LocalName, value: i32) { pub fn set_int_attribute(&self, local_name: &LocalName, value: i32, can_gc: CanGc) {
assert!(*local_name == local_name.to_ascii_lowercase()); assert!(*local_name == local_name.to_ascii_lowercase());
self.set_attribute(local_name, AttrValue::Int(value.to_string(), value)); self.set_attribute(local_name, AttrValue::Int(value.to_string(), value), can_gc);
} }
pub fn get_uint_attribute(&self, local_name: &LocalName, default: u32) -> u32 { pub fn get_uint_attribute(&self, local_name: &LocalName, default: u32) -> u32 {
@ -1796,9 +1831,13 @@ impl Element {
None => default, None => default,
} }
} }
pub fn set_uint_attribute(&self, local_name: &LocalName, value: u32) { pub fn set_uint_attribute(&self, local_name: &LocalName, value: u32, can_gc: CanGc) {
assert!(*local_name == local_name.to_ascii_lowercase()); assert!(*local_name == local_name.to_ascii_lowercase());
self.set_attribute(local_name, AttrValue::UInt(value.to_string(), value)); self.set_attribute(
local_name,
AttrValue::UInt(value.to_string(), value),
can_gc,
);
} }
pub fn will_mutate_attr(&self, attr: &Attr) { pub fn will_mutate_attr(&self, attr: &Attr) {
@ -1905,7 +1944,7 @@ impl Element {
document_from_node(self) document_from_node(self)
} }
}; };
let fragment = DocumentFragment::new(&context_document); let fragment = DocumentFragment::new(&context_document, can_gc);
// Step 4. // Step 4.
for child in new_children { for child in new_children {
fragment.upcast::<Node>().AppendChild(&child).unwrap(); fragment.upcast::<Node>().AppendChild(&child).unwrap();
@ -1914,7 +1953,11 @@ impl Element {
Ok(fragment) Ok(fragment)
} }
pub fn fragment_parsing_context(owner_doc: &Document, element: Option<&Self>) -> DomRoot<Self> { pub fn fragment_parsing_context(
owner_doc: &Document,
element: Option<&Self>,
can_gc: CanGc,
) -> DomRoot<Self> {
match element { match element {
Some(elem) Some(elem)
if elem.local_name() != &local_name!("html") || if elem.local_name() != &local_name!("html") ||
@ -1927,6 +1970,7 @@ impl Element {
None, None,
owner_doc, owner_doc,
None, None,
can_gc,
)), )),
} }
} }
@ -2078,8 +2122,8 @@ impl ElementMethods for Element {
} }
// https://dom.spec.whatwg.org/#dom-element-id // https://dom.spec.whatwg.org/#dom-element-id
fn SetId(&self, id: DOMString) { fn SetId(&self, id: DOMString, can_gc: CanGc) {
self.set_atomic_attribute(&local_name!("id"), id); self.set_atomic_attribute(&local_name!("id"), id, can_gc);
} }
// https://dom.spec.whatwg.org/#dom-element-classname // https://dom.spec.whatwg.org/#dom-element-classname
@ -2088,8 +2132,8 @@ impl ElementMethods for Element {
} }
// https://dom.spec.whatwg.org/#dom-element-classname // https://dom.spec.whatwg.org/#dom-element-classname
fn SetClassName(&self, class: DOMString) { fn SetClassName(&self, class: DOMString, can_gc: CanGc) {
self.set_tokenlist_attribute(&local_name!("class"), class); self.set_tokenlist_attribute(&local_name!("class"), class, can_gc);
} }
// https://dom.spec.whatwg.org/#dom-element-classlist // https://dom.spec.whatwg.org/#dom-element-classlist
@ -2145,7 +2189,12 @@ impl ElementMethods for Element {
} }
// https://dom.spec.whatwg.org/#dom-element-toggleattribute // https://dom.spec.whatwg.org/#dom-element-toggleattribute
fn ToggleAttribute(&self, name: DOMString, force: Option<bool>) -> Fallible<bool> { fn ToggleAttribute(
&self,
name: DOMString,
force: Option<bool>,
can_gc: CanGc,
) -> Fallible<bool> {
// Step 1. // Step 1.
if xml_name_type(&name) == Invalid { if xml_name_type(&name) == Invalid {
return Err(Error::InvalidCharacter); return Err(Error::InvalidCharacter);
@ -2168,6 +2217,7 @@ impl ElementMethods for Element {
ns!(), ns!(),
None, None,
|attr| *attr.name() == name, |attr| *attr.name() == name,
can_gc,
); );
Ok(true) Ok(true)
}, },
@ -2187,7 +2237,7 @@ impl ElementMethods for Element {
} }
// https://dom.spec.whatwg.org/#dom-element-setattribute // https://dom.spec.whatwg.org/#dom-element-setattribute
fn SetAttribute(&self, name: DOMString, value: DOMString) -> ErrorResult { fn SetAttribute(&self, name: DOMString, value: DOMString, can_gc: CanGc) -> ErrorResult {
// Step 1. // Step 1.
if xml_name_type(&name) == Invalid { if xml_name_type(&name) == Invalid {
return Err(Error::InvalidCharacter); return Err(Error::InvalidCharacter);
@ -2198,9 +2248,15 @@ impl ElementMethods for Element {
// Step 3-5. // Step 3-5.
let value = self.parse_attribute(&ns!(), &name, value); let value = self.parse_attribute(&ns!(), &name, value);
self.set_first_matching_attribute(name.clone(), value, name.clone(), ns!(), None, |attr| { self.set_first_matching_attribute(
*attr.name() == name name.clone(),
}); value,
name.clone(),
ns!(),
None,
|attr| *attr.name() == name,
can_gc,
);
Ok(()) Ok(())
} }
@ -2210,6 +2266,7 @@ impl ElementMethods for Element {
namespace: Option<DOMString>, namespace: Option<DOMString>,
qualified_name: DOMString, qualified_name: DOMString,
value: DOMString, value: DOMString,
can_gc: CanGc,
) -> ErrorResult { ) -> ErrorResult {
let (namespace, prefix, local_name) = validate_and_extract(namespace, &qualified_name)?; let (namespace, prefix, local_name) = validate_and_extract(namespace, &qualified_name)?;
let qualified_name = LocalName::from(qualified_name); let qualified_name = LocalName::from(qualified_name);
@ -2221,6 +2278,7 @@ impl ElementMethods for Element {
namespace.clone(), namespace.clone(),
prefix, prefix,
|attr| *attr.local_name() == local_name && *attr.namespace() == namespace, |attr| *attr.local_name() == local_name && *attr.namespace() == namespace,
can_gc,
); );
Ok(()) Ok(())
} }
@ -2684,7 +2742,7 @@ impl ElementMethods for Element {
.iter() .iter()
.any(|c| matches!(*c, b'&' | b'\0' | b'<' | b'\r')) .any(|c| matches!(*c, b'&' | b'\0' | b'<' | b'\r'))
{ {
Node::SetTextContent(&target, Some(value)); Node::SetTextContent(&target, Some(value), can_gc);
return Ok(()); return Ok(());
} }
@ -2785,18 +2843,18 @@ impl ElementMethods for Element {
} }
// https://dom.spec.whatwg.org/#dom-parentnode-prepend // https://dom.spec.whatwg.org/#dom-parentnode-prepend
fn Prepend(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn Prepend(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().prepend(nodes) self.upcast::<Node>().prepend(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-parentnode-append // https://dom.spec.whatwg.org/#dom-parentnode-append
fn Append(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn Append(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().append(nodes) self.upcast::<Node>().append(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-parentnode-replacechildren // https://dom.spec.whatwg.org/#dom-parentnode-replacechildren
fn ReplaceChildren(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn ReplaceChildren(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().replace_children(nodes) self.upcast::<Node>().replace_children(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-parentnode-queryselector // https://dom.spec.whatwg.org/#dom-parentnode-queryselector
@ -2812,18 +2870,18 @@ impl ElementMethods for Element {
} }
// https://dom.spec.whatwg.org/#dom-childnode-before // https://dom.spec.whatwg.org/#dom-childnode-before
fn Before(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn Before(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().before(nodes) self.upcast::<Node>().before(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-childnode-after // https://dom.spec.whatwg.org/#dom-childnode-after
fn After(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn After(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().after(nodes) self.upcast::<Node>().after(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-childnode-replacewith // https://dom.spec.whatwg.org/#dom-childnode-replacewith
fn ReplaceWith(&self, nodes: Vec<NodeOrString>) -> ErrorResult { fn ReplaceWith(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
self.upcast::<Node>().replace_with(nodes) self.upcast::<Node>().replace_with(nodes, can_gc)
} }
// https://dom.spec.whatwg.org/#dom-childnode-remove // https://dom.spec.whatwg.org/#dom-childnode-remove
@ -2886,9 +2944,9 @@ impl ElementMethods for Element {
} }
// https://dom.spec.whatwg.org/#dom-element-insertadjacenttext // https://dom.spec.whatwg.org/#dom-element-insertadjacenttext
fn InsertAdjacentText(&self, where_: DOMString, data: DOMString) -> ErrorResult { fn InsertAdjacentText(&self, where_: DOMString, data: DOMString, can_gc: CanGc) -> ErrorResult {
// Step 1. // Step 1.
let text = Text::new(data, &document_from_node(self)); let text = Text::new(data, &document_from_node(self), can_gc);
// Step 2. // Step 2.
let where_ = where_.parse::<AdjacentPosition>()?; let where_ = where_.parse::<AdjacentPosition>()?;
@ -2921,8 +2979,11 @@ impl ElementMethods for Element {
}; };
// Step 2. // Step 2.
let context = let context = Element::fragment_parsing_context(
Element::fragment_parsing_context(&context.owner_doc(), context.downcast::<Element>()); &context.owner_doc(),
context.downcast::<Element>(),
can_gc,
);
// Step 3. // Step 3.
let fragment = context.parse_fragment(text, can_gc)?; let fragment = context.parse_fragment(text, can_gc)?;
@ -2970,352 +3031,356 @@ impl ElementMethods for Element {
self.get_nullable_string_attribute(&local_name!("role")) self.get_nullable_string_attribute(&local_name!("role"))
} }
fn SetRole(&self, value: Option<DOMString>) { fn SetRole(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("role"), value); self.set_nullable_string_attribute(&local_name!("role"), value, can_gc);
} }
fn GetAriaAtomic(&self) -> Option<DOMString> { fn GetAriaAtomic(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-atomic")) self.get_nullable_string_attribute(&local_name!("aria-atomic"))
} }
fn SetAriaAtomic(&self, value: Option<DOMString>) { fn SetAriaAtomic(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-atomic"), value); self.set_nullable_string_attribute(&local_name!("aria-atomic"), value, can_gc);
} }
fn GetAriaAutoComplete(&self) -> Option<DOMString> { fn GetAriaAutoComplete(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-autocomplete")) self.get_nullable_string_attribute(&local_name!("aria-autocomplete"))
} }
fn SetAriaAutoComplete(&self, value: Option<DOMString>) { fn SetAriaAutoComplete(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-autocomplete"), value); self.set_nullable_string_attribute(&local_name!("aria-autocomplete"), value, can_gc);
} }
fn GetAriaBrailleLabel(&self) -> Option<DOMString> { fn GetAriaBrailleLabel(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-braillelabel")) self.get_nullable_string_attribute(&local_name!("aria-braillelabel"))
} }
fn SetAriaBrailleLabel(&self, value: Option<DOMString>) { fn SetAriaBrailleLabel(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-braillelabel"), value); self.set_nullable_string_attribute(&local_name!("aria-braillelabel"), value, can_gc);
} }
fn GetAriaBrailleRoleDescription(&self) -> Option<DOMString> { fn GetAriaBrailleRoleDescription(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-brailleroledescription")) self.get_nullable_string_attribute(&local_name!("aria-brailleroledescription"))
} }
fn SetAriaBrailleRoleDescription(&self, value: Option<DOMString>) { fn SetAriaBrailleRoleDescription(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-brailleroledescription"), value); self.set_nullable_string_attribute(
&local_name!("aria-brailleroledescription"),
value,
can_gc,
);
} }
fn GetAriaBusy(&self) -> Option<DOMString> { fn GetAriaBusy(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-busy")) self.get_nullable_string_attribute(&local_name!("aria-busy"))
} }
fn SetAriaBusy(&self, value: Option<DOMString>) { fn SetAriaBusy(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-busy"), value); self.set_nullable_string_attribute(&local_name!("aria-busy"), value, can_gc);
} }
fn GetAriaChecked(&self) -> Option<DOMString> { fn GetAriaChecked(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-checked")) self.get_nullable_string_attribute(&local_name!("aria-checked"))
} }
fn SetAriaChecked(&self, value: Option<DOMString>) { fn SetAriaChecked(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-checked"), value); self.set_nullable_string_attribute(&local_name!("aria-checked"), value, can_gc);
} }
fn GetAriaColCount(&self) -> Option<DOMString> { fn GetAriaColCount(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-colcount")) self.get_nullable_string_attribute(&local_name!("aria-colcount"))
} }
fn SetAriaColCount(&self, value: Option<DOMString>) { fn SetAriaColCount(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-colcount"), value); self.set_nullable_string_attribute(&local_name!("aria-colcount"), value, can_gc);
} }
fn GetAriaColIndex(&self) -> Option<DOMString> { fn GetAriaColIndex(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-colindex")) self.get_nullable_string_attribute(&local_name!("aria-colindex"))
} }
fn SetAriaColIndex(&self, value: Option<DOMString>) { fn SetAriaColIndex(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-colindex"), value); self.set_nullable_string_attribute(&local_name!("aria-colindex"), value, can_gc);
} }
fn GetAriaColIndexText(&self) -> Option<DOMString> { fn GetAriaColIndexText(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-colindextext")) self.get_nullable_string_attribute(&local_name!("aria-colindextext"))
} }
fn SetAriaColIndexText(&self, value: Option<DOMString>) { fn SetAriaColIndexText(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-colindextext"), value); self.set_nullable_string_attribute(&local_name!("aria-colindextext"), value, can_gc);
} }
fn GetAriaColSpan(&self) -> Option<DOMString> { fn GetAriaColSpan(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-colspan")) self.get_nullable_string_attribute(&local_name!("aria-colspan"))
} }
fn SetAriaColSpan(&self, value: Option<DOMString>) { fn SetAriaColSpan(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-colspan"), value); self.set_nullable_string_attribute(&local_name!("aria-colspan"), value, can_gc);
} }
fn GetAriaCurrent(&self) -> Option<DOMString> { fn GetAriaCurrent(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-current")) self.get_nullable_string_attribute(&local_name!("aria-current"))
} }
fn SetAriaCurrent(&self, value: Option<DOMString>) { fn SetAriaCurrent(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-current"), value); self.set_nullable_string_attribute(&local_name!("aria-current"), value, can_gc);
} }
fn GetAriaDescription(&self) -> Option<DOMString> { fn GetAriaDescription(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-description")) self.get_nullable_string_attribute(&local_name!("aria-description"))
} }
fn SetAriaDescription(&self, value: Option<DOMString>) { fn SetAriaDescription(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-description"), value); self.set_nullable_string_attribute(&local_name!("aria-description"), value, can_gc);
} }
fn GetAriaDisabled(&self) -> Option<DOMString> { fn GetAriaDisabled(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-disabled")) self.get_nullable_string_attribute(&local_name!("aria-disabled"))
} }
fn SetAriaDisabled(&self, value: Option<DOMString>) { fn SetAriaDisabled(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-disabled"), value); self.set_nullable_string_attribute(&local_name!("aria-disabled"), value, can_gc);
} }
fn GetAriaExpanded(&self) -> Option<DOMString> { fn GetAriaExpanded(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-expanded")) self.get_nullable_string_attribute(&local_name!("aria-expanded"))
} }
fn SetAriaExpanded(&self, value: Option<DOMString>) { fn SetAriaExpanded(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-expanded"), value); self.set_nullable_string_attribute(&local_name!("aria-expanded"), value, can_gc);
} }
fn GetAriaHasPopup(&self) -> Option<DOMString> { fn GetAriaHasPopup(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-haspopup")) self.get_nullable_string_attribute(&local_name!("aria-haspopup"))
} }
fn SetAriaHasPopup(&self, value: Option<DOMString>) { fn SetAriaHasPopup(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-haspopup"), value); self.set_nullable_string_attribute(&local_name!("aria-haspopup"), value, can_gc);
} }
fn GetAriaHidden(&self) -> Option<DOMString> { fn GetAriaHidden(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-hidden")) self.get_nullable_string_attribute(&local_name!("aria-hidden"))
} }
fn SetAriaHidden(&self, value: Option<DOMString>) { fn SetAriaHidden(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-hidden"), value); self.set_nullable_string_attribute(&local_name!("aria-hidden"), value, can_gc);
} }
fn GetAriaInvalid(&self) -> Option<DOMString> { fn GetAriaInvalid(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-invalid")) self.get_nullable_string_attribute(&local_name!("aria-invalid"))
} }
fn SetAriaInvalid(&self, value: Option<DOMString>) { fn SetAriaInvalid(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-invalid"), value); self.set_nullable_string_attribute(&local_name!("aria-invalid"), value, can_gc);
} }
fn GetAriaKeyShortcuts(&self) -> Option<DOMString> { fn GetAriaKeyShortcuts(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-keyshortcuts")) self.get_nullable_string_attribute(&local_name!("aria-keyshortcuts"))
} }
fn SetAriaKeyShortcuts(&self, value: Option<DOMString>) { fn SetAriaKeyShortcuts(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-keyshortcuts"), value); self.set_nullable_string_attribute(&local_name!("aria-keyshortcuts"), value, can_gc);
} }
fn GetAriaLabel(&self) -> Option<DOMString> { fn GetAriaLabel(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-label")) self.get_nullable_string_attribute(&local_name!("aria-label"))
} }
fn SetAriaLabel(&self, value: Option<DOMString>) { fn SetAriaLabel(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-label"), value); self.set_nullable_string_attribute(&local_name!("aria-label"), value, can_gc);
} }
fn GetAriaLevel(&self) -> Option<DOMString> { fn GetAriaLevel(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-level")) self.get_nullable_string_attribute(&local_name!("aria-level"))
} }
fn SetAriaLevel(&self, value: Option<DOMString>) { fn SetAriaLevel(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-level"), value); self.set_nullable_string_attribute(&local_name!("aria-level"), value, can_gc);
} }
fn GetAriaLive(&self) -> Option<DOMString> { fn GetAriaLive(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-live")) self.get_nullable_string_attribute(&local_name!("aria-live"))
} }
fn SetAriaLive(&self, value: Option<DOMString>) { fn SetAriaLive(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-live"), value); self.set_nullable_string_attribute(&local_name!("aria-live"), value, can_gc);
} }
fn GetAriaModal(&self) -> Option<DOMString> { fn GetAriaModal(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-modal")) self.get_nullable_string_attribute(&local_name!("aria-modal"))
} }
fn SetAriaModal(&self, value: Option<DOMString>) { fn SetAriaModal(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-modal"), value); self.set_nullable_string_attribute(&local_name!("aria-modal"), value, can_gc);
} }
fn GetAriaMultiLine(&self) -> Option<DOMString> { fn GetAriaMultiLine(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-multiline")) self.get_nullable_string_attribute(&local_name!("aria-multiline"))
} }
fn SetAriaMultiLine(&self, value: Option<DOMString>) { fn SetAriaMultiLine(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-multiline"), value); self.set_nullable_string_attribute(&local_name!("aria-multiline"), value, can_gc);
} }
fn GetAriaMultiSelectable(&self) -> Option<DOMString> { fn GetAriaMultiSelectable(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-multiselectable")) self.get_nullable_string_attribute(&local_name!("aria-multiselectable"))
} }
fn SetAriaMultiSelectable(&self, value: Option<DOMString>) { fn SetAriaMultiSelectable(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-multiselectable"), value); self.set_nullable_string_attribute(&local_name!("aria-multiselectable"), value, can_gc);
} }
fn GetAriaOrientation(&self) -> Option<DOMString> { fn GetAriaOrientation(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-orientation")) self.get_nullable_string_attribute(&local_name!("aria-orientation"))
} }
fn SetAriaOrientation(&self, value: Option<DOMString>) { fn SetAriaOrientation(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-orientation"), value); self.set_nullable_string_attribute(&local_name!("aria-orientation"), value, can_gc);
} }
fn GetAriaPlaceholder(&self) -> Option<DOMString> { fn GetAriaPlaceholder(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-placeholder")) self.get_nullable_string_attribute(&local_name!("aria-placeholder"))
} }
fn SetAriaPlaceholder(&self, value: Option<DOMString>) { fn SetAriaPlaceholder(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-placeholder"), value); self.set_nullable_string_attribute(&local_name!("aria-placeholder"), value, can_gc);
} }
fn GetAriaPosInSet(&self) -> Option<DOMString> { fn GetAriaPosInSet(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-posinset")) self.get_nullable_string_attribute(&local_name!("aria-posinset"))
} }
fn SetAriaPosInSet(&self, value: Option<DOMString>) { fn SetAriaPosInSet(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-posinset"), value); self.set_nullable_string_attribute(&local_name!("aria-posinset"), value, can_gc);
} }
fn GetAriaPressed(&self) -> Option<DOMString> { fn GetAriaPressed(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-pressed")) self.get_nullable_string_attribute(&local_name!("aria-pressed"))
} }
fn SetAriaPressed(&self, value: Option<DOMString>) { fn SetAriaPressed(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-pressed"), value); self.set_nullable_string_attribute(&local_name!("aria-pressed"), value, can_gc);
} }
fn GetAriaReadOnly(&self) -> Option<DOMString> { fn GetAriaReadOnly(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-readonly")) self.get_nullable_string_attribute(&local_name!("aria-readonly"))
} }
fn SetAriaReadOnly(&self, value: Option<DOMString>) { fn SetAriaReadOnly(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-readonly"), value); self.set_nullable_string_attribute(&local_name!("aria-readonly"), value, can_gc);
} }
fn GetAriaRelevant(&self) -> Option<DOMString> { fn GetAriaRelevant(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-relevant")) self.get_nullable_string_attribute(&local_name!("aria-relevant"))
} }
fn SetAriaRelevant(&self, value: Option<DOMString>) { fn SetAriaRelevant(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-relevant"), value); self.set_nullable_string_attribute(&local_name!("aria-relevant"), value, can_gc);
} }
fn GetAriaRequired(&self) -> Option<DOMString> { fn GetAriaRequired(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-required")) self.get_nullable_string_attribute(&local_name!("aria-required"))
} }
fn SetAriaRequired(&self, value: Option<DOMString>) { fn SetAriaRequired(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-required"), value); self.set_nullable_string_attribute(&local_name!("aria-required"), value, can_gc);
} }
fn GetAriaRoleDescription(&self) -> Option<DOMString> { fn GetAriaRoleDescription(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-roledescription")) self.get_nullable_string_attribute(&local_name!("aria-roledescription"))
} }
fn SetAriaRoleDescription(&self, value: Option<DOMString>) { fn SetAriaRoleDescription(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-roledescription"), value); self.set_nullable_string_attribute(&local_name!("aria-roledescription"), value, can_gc);
} }
fn GetAriaRowCount(&self) -> Option<DOMString> { fn GetAriaRowCount(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-rowcount")) self.get_nullable_string_attribute(&local_name!("aria-rowcount"))
} }
fn SetAriaRowCount(&self, value: Option<DOMString>) { fn SetAriaRowCount(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-rowcount"), value); self.set_nullable_string_attribute(&local_name!("aria-rowcount"), value, can_gc);
} }
fn GetAriaRowIndex(&self) -> Option<DOMString> { fn GetAriaRowIndex(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-rowindex")) self.get_nullable_string_attribute(&local_name!("aria-rowindex"))
} }
fn SetAriaRowIndex(&self, value: Option<DOMString>) { fn SetAriaRowIndex(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-rowindex"), value); self.set_nullable_string_attribute(&local_name!("aria-rowindex"), value, can_gc);
} }
fn GetAriaRowIndexText(&self) -> Option<DOMString> { fn GetAriaRowIndexText(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-rowindextext")) self.get_nullable_string_attribute(&local_name!("aria-rowindextext"))
} }
fn SetAriaRowIndexText(&self, value: Option<DOMString>) { fn SetAriaRowIndexText(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-rowindextext"), value); self.set_nullable_string_attribute(&local_name!("aria-rowindextext"), value, can_gc);
} }
fn GetAriaRowSpan(&self) -> Option<DOMString> { fn GetAriaRowSpan(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-rowspan")) self.get_nullable_string_attribute(&local_name!("aria-rowspan"))
} }
fn SetAriaRowSpan(&self, value: Option<DOMString>) { fn SetAriaRowSpan(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-rowspan"), value); self.set_nullable_string_attribute(&local_name!("aria-rowspan"), value, can_gc);
} }
fn GetAriaSelected(&self) -> Option<DOMString> { fn GetAriaSelected(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-selected")) self.get_nullable_string_attribute(&local_name!("aria-selected"))
} }
fn SetAriaSelected(&self, value: Option<DOMString>) { fn SetAriaSelected(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-selected"), value); self.set_nullable_string_attribute(&local_name!("aria-selected"), value, can_gc);
} }
fn GetAriaSetSize(&self) -> Option<DOMString> { fn GetAriaSetSize(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-setsize")) self.get_nullable_string_attribute(&local_name!("aria-setsize"))
} }
fn SetAriaSetSize(&self, value: Option<DOMString>) { fn SetAriaSetSize(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-setsize"), value); self.set_nullable_string_attribute(&local_name!("aria-setsize"), value, can_gc);
} }
fn GetAriaSort(&self) -> Option<DOMString> { fn GetAriaSort(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-sort")) self.get_nullable_string_attribute(&local_name!("aria-sort"))
} }
fn SetAriaSort(&self, value: Option<DOMString>) { fn SetAriaSort(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-sort"), value); self.set_nullable_string_attribute(&local_name!("aria-sort"), value, can_gc);
} }
fn GetAriaValueMax(&self) -> Option<DOMString> { fn GetAriaValueMax(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-valuemax")) self.get_nullable_string_attribute(&local_name!("aria-valuemax"))
} }
fn SetAriaValueMax(&self, value: Option<DOMString>) { fn SetAriaValueMax(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-valuemax"), value); self.set_nullable_string_attribute(&local_name!("aria-valuemax"), value, can_gc);
} }
fn GetAriaValueMin(&self) -> Option<DOMString> { fn GetAriaValueMin(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-valuemin")) self.get_nullable_string_attribute(&local_name!("aria-valuemin"))
} }
fn SetAriaValueMin(&self, value: Option<DOMString>) { fn SetAriaValueMin(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-valuemin"), value); self.set_nullable_string_attribute(&local_name!("aria-valuemin"), value, can_gc);
} }
fn GetAriaValueNow(&self) -> Option<DOMString> { fn GetAriaValueNow(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-valuenow")) self.get_nullable_string_attribute(&local_name!("aria-valuenow"))
} }
fn SetAriaValueNow(&self, value: Option<DOMString>) { fn SetAriaValueNow(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-valuenow"), value); self.set_nullable_string_attribute(&local_name!("aria-valuenow"), value, can_gc);
} }
fn GetAriaValueText(&self) -> Option<DOMString> { fn GetAriaValueText(&self) -> Option<DOMString> {
self.get_nullable_string_attribute(&local_name!("aria-valuetext")) self.get_nullable_string_attribute(&local_name!("aria-valuetext"))
} }
fn SetAriaValueText(&self, value: Option<DOMString>) { fn SetAriaValueText(&self, value: Option<DOMString>, can_gc: CanGc) {
self.set_nullable_string_attribute(&local_name!("aria-valuetext"), value); self.set_nullable_string_attribute(&local_name!("aria-valuetext"), value, can_gc);
} }
} }
@ -4414,9 +4479,9 @@ pub fn reflect_cross_origin_attribute(element: &Element) -> Option<DOMString> {
None None
} }
pub fn set_cross_origin_attribute(element: &Element, value: Option<DOMString>) { pub fn set_cross_origin_attribute(element: &Element, value: Option<DOMString>, can_gc: CanGc) {
match value { match value {
Some(val) => element.set_string_attribute(&local_name!("crossorigin"), val), Some(val) => element.set_string_attribute(&local_name!("crossorigin"), val, can_gc),
None => { None => {
element.remove_attribute(&ns!(), &local_name!("crossorigin")); element.remove_attribute(&ns!(), &local_name!("crossorigin"));
}, },

View file

@ -67,6 +67,7 @@ impl HTMLAnchorElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLAnchorElement> { ) -> DomRoot<HTMLAnchorElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLAnchorElement::new_inherited( Box::new(HTMLAnchorElement::new_inherited(
@ -74,6 +75,7 @@ impl HTMLAnchorElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
@ -115,9 +117,9 @@ impl HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#update-href // https://html.spec.whatwg.org/multipage/#update-href
fn update_href(&self, url: DOMString) { fn update_href(&self, url: DOMString, can_gc: CanGc) {
self.upcast::<Element>() self.upcast::<Element>()
.set_string_attribute(&local_name!("href"), url); .set_string_attribute(&local_name!("href"), url, can_gc);
} }
} }
@ -165,17 +167,17 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-a-text // https://html.spec.whatwg.org/multipage/#dom-a-text
fn SetText(&self, value: DOMString) { fn SetText(&self, value: DOMString, can_gc: CanGc) {
self.upcast::<Node>().SetTextContent(Some(value)) self.upcast::<Node>().SetTextContent(Some(value), can_gc)
} }
// https://html.spec.whatwg.org/multipage/#dom-a-rel // https://html.spec.whatwg.org/multipage/#dom-a-rel
make_getter!(Rel, "rel"); make_getter!(Rel, "rel");
// https://html.spec.whatwg.org/multipage/#dom-a-rel // https://html.spec.whatwg.org/multipage/#dom-a-rel
fn SetRel(&self, rel: DOMString) { fn SetRel(&self, rel: DOMString, can_gc: CanGc) {
self.upcast::<Element>() self.upcast::<Element>()
.set_tokenlist_attribute(&local_name!("rel"), rel); .set_tokenlist_attribute(&local_name!("rel"), rel, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-a-rellist // https://html.spec.whatwg.org/multipage/#dom-a-rellist
@ -239,7 +241,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-hash // https://html.spec.whatwg.org/multipage/#dom-hyperlink-hash
fn SetHash(&self, value: USVString) { fn SetHash(&self, value: USVString, can_gc: CanGc) {
// Step 1. // Step 1.
self.reinitialize_url(); self.reinitialize_url();
@ -255,7 +257,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
}, },
}; };
// Step 6. // Step 6.
self.update_href(url); self.update_href(url, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-host // https://html.spec.whatwg.org/multipage/#dom-hyperlink-host
@ -278,7 +280,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-host // https://html.spec.whatwg.org/multipage/#dom-hyperlink-host
fn SetHost(&self, value: USVString) { fn SetHost(&self, value: USVString, can_gc: CanGc) {
// Step 1. // Step 1.
self.reinitialize_url(); self.reinitialize_url();
@ -294,7 +296,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
}, },
}; };
// Step 5. // Step 5.
self.update_href(url); self.update_href(url, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-hostname // https://html.spec.whatwg.org/multipage/#dom-hyperlink-hostname
@ -313,7 +315,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-hostname // https://html.spec.whatwg.org/multipage/#dom-hyperlink-hostname
fn SetHostname(&self, value: USVString) { fn SetHostname(&self, value: USVString, can_gc: CanGc) {
// Step 1. // Step 1.
self.reinitialize_url(); self.reinitialize_url();
@ -329,7 +331,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
}, },
}; };
// Step 5. // Step 5.
self.update_href(url); self.update_href(url, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-href // https://html.spec.whatwg.org/multipage/#dom-hyperlink-href
@ -355,9 +357,12 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-href // https://html.spec.whatwg.org/multipage/#dom-hyperlink-href
fn SetHref(&self, value: USVString) { fn SetHref(&self, value: USVString, can_gc: CanGc) {
self.upcast::<Element>() self.upcast::<Element>().set_string_attribute(
.set_string_attribute(&local_name!("href"), DOMString::from_string(value.0)); &local_name!("href"),
DOMString::from_string(value.0),
can_gc,
);
self.set_url(); self.set_url();
} }
@ -392,7 +397,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-password // https://html.spec.whatwg.org/multipage/#dom-hyperlink-password
fn SetPassword(&self, value: USVString) { fn SetPassword(&self, value: USVString, can_gc: CanGc) {
// Step 1. // Step 1.
self.reinitialize_url(); self.reinitialize_url();
@ -408,7 +413,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
}, },
}; };
// Step 5. // Step 5.
self.update_href(url); self.update_href(url, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-pathname // https://html.spec.whatwg.org/multipage/#dom-hyperlink-pathname
@ -425,7 +430,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-pathname // https://html.spec.whatwg.org/multipage/#dom-hyperlink-pathname
fn SetPathname(&self, value: USVString) { fn SetPathname(&self, value: USVString, can_gc: CanGc) {
// Step 1. // Step 1.
self.reinitialize_url(); self.reinitialize_url();
@ -441,7 +446,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
}, },
}; };
// Step 6. // Step 6.
self.update_href(url); self.update_href(url, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-port // https://html.spec.whatwg.org/multipage/#dom-hyperlink-port
@ -458,7 +463,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-port // https://html.spec.whatwg.org/multipage/#dom-hyperlink-port
fn SetPort(&self, value: USVString) { fn SetPort(&self, value: USVString, can_gc: CanGc) {
// Step 1. // Step 1.
self.reinitialize_url(); self.reinitialize_url();
@ -477,7 +482,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
}, },
}; };
// Step 5. // Step 5.
self.update_href(url); self.update_href(url, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-protocol // https://html.spec.whatwg.org/multipage/#dom-hyperlink-protocol
@ -494,7 +499,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-protocol // https://html.spec.whatwg.org/multipage/#dom-hyperlink-protocol
fn SetProtocol(&self, value: USVString) { fn SetProtocol(&self, value: USVString, can_gc: CanGc) {
// Step 1. // Step 1.
self.reinitialize_url(); self.reinitialize_url();
@ -508,7 +513,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
}, },
}; };
// Step 4. // Step 4.
self.update_href(url); self.update_href(url, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-search // https://html.spec.whatwg.org/multipage/#dom-hyperlink-search
@ -525,7 +530,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-search // https://html.spec.whatwg.org/multipage/#dom-hyperlink-search
fn SetSearch(&self, value: USVString) { fn SetSearch(&self, value: USVString, can_gc: CanGc) {
// Step 1. // Step 1.
self.reinitialize_url(); self.reinitialize_url();
@ -542,7 +547,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
}, },
}; };
// Step 6. // Step 6.
self.update_href(url); self.update_href(url, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-username // https://html.spec.whatwg.org/multipage/#dom-hyperlink-username
@ -559,7 +564,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-hyperlink-username // https://html.spec.whatwg.org/multipage/#dom-hyperlink-username
fn SetUsername(&self, value: USVString) { fn SetUsername(&self, value: USVString, can_gc: CanGc) {
// Step 1. // Step 1.
self.reinitialize_url(); self.reinitialize_url();
@ -575,7 +580,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement {
}, },
}; };
// Step 5. // Step 5.
self.update_href(url); self.update_href(url, can_gc);
} }
} }

View file

@ -264,11 +264,13 @@ impl HTMLAreaElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLAreaElement> { ) -> DomRoot<HTMLAreaElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLAreaElement::new_inherited(local_name, prefix, document)), Box::new(HTMLAreaElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
@ -341,9 +343,9 @@ impl HTMLAreaElementMethods for HTMLAreaElement {
make_getter!(Rel, "rel"); make_getter!(Rel, "rel");
// https://html.spec.whatwg.org/multipage/#dom-a-rel // https://html.spec.whatwg.org/multipage/#dom-a-rel
fn SetRel(&self, rel: DOMString) { fn SetRel(&self, rel: DOMString, can_gc: CanGc) {
self.upcast::<Element>() self.upcast::<Element>()
.set_tokenlist_attribute(&local_name!("rel"), rel); .set_tokenlist_attribute(&local_name!("rel"), rel, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-area-rellist // https://html.spec.whatwg.org/multipage/#dom-area-rellist

View file

@ -42,6 +42,7 @@ impl HTMLAudioElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLAudioElement> { ) -> DomRoot<HTMLAudioElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLAudioElement::new_inherited( Box::new(HTMLAudioElement::new_inherited(
@ -49,6 +50,7 @@ impl HTMLAudioElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }
@ -75,12 +77,12 @@ impl HTMLAudioElementMethods for HTMLAudioElement {
audio audio
.upcast::<Element>() .upcast::<Element>()
.SetAttribute(DOMString::from("preload"), DOMString::from("auto")) .SetAttribute(DOMString::from("preload"), DOMString::from("auto"), can_gc)
.expect("should be infallible"); .expect("should be infallible");
if let Some(s) = src { if let Some(s) = src {
audio audio
.upcast::<Element>() .upcast::<Element>()
.SetAttribute(DOMString::from("src"), s) .SetAttribute(DOMString::from("src"), s, can_gc)
.expect("should be infallible"); .expect("should be infallible");
} }

View file

@ -17,6 +17,7 @@ use crate::dom::element::{AttributeMutation, Element};
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{document_from_node, BindContext, Node, UnbindContext}; use crate::dom::node::{document_from_node, BindContext, Node, UnbindContext};
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLBaseElement { pub struct HTMLBaseElement {
@ -40,11 +41,13 @@ impl HTMLBaseElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLBaseElement> { ) -> DomRoot<HTMLBaseElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLBaseElement::new_inherited(local_name, prefix, document)), Box::new(HTMLBaseElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }

View file

@ -24,6 +24,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{document_from_node, window_from_node, BindContext, Node}; use crate::dom::node::{document_from_node, window_from_node, BindContext, Node};
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
/// How long we should wait before performing the initial reflow after `<body>` is parsed. /// How long we should wait before performing the initial reflow after `<body>` is parsed.
const INITIAL_REFLOW_DELAY: Duration = Duration::from_millis(200); const INITIAL_REFLOW_DELAY: Duration = Duration::from_millis(200);
@ -50,11 +51,13 @@ impl HTMLBodyElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLBodyElement> { ) -> DomRoot<HTMLBodyElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLBodyElement::new_inherited(local_name, prefix, document)), Box::new(HTMLBodyElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
@ -87,13 +90,13 @@ impl HTMLBodyElementMethods for HTMLBodyElement {
make_getter!(Background, "background"); make_getter!(Background, "background");
// https://html.spec.whatwg.org/multipage/#dom-body-background // https://html.spec.whatwg.org/multipage/#dom-body-background
fn SetBackground(&self, input: DOMString) { fn SetBackground(&self, input: DOMString, can_gc: CanGc) {
let value = AttrValue::from_resolved_url( let value = AttrValue::from_resolved_url(
&document_from_node(self).base_url().get_arc(), &document_from_node(self).base_url().get_arc(),
input.into(), input.into(),
); );
self.upcast::<Element>() self.upcast::<Element>()
.set_attribute(&local_name!("background"), value); .set_attribute(&local_name!("background"), value, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#windoweventhandlers // https://html.spec.whatwg.org/multipage/#windoweventhandlers

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLBRElement { pub struct HTMLBRElement {
@ -33,11 +34,13 @@ impl HTMLBRElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLBRElement> { ) -> DomRoot<HTMLBRElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLBRElement::new_inherited(local_name, prefix, document)), Box::new(HTMLBRElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -75,6 +75,7 @@ impl HTMLButtonElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLButtonElement> { ) -> DomRoot<HTMLButtonElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLButtonElement::new_inherited( Box::new(HTMLButtonElement::new_inherited(
@ -82,6 +83,7 @@ impl HTMLButtonElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
@ -360,7 +362,7 @@ impl Activatable for HTMLButtonElement {
ButtonType::Reset => { ButtonType::Reset => {
// TODO: is document owner fully active? // TODO: is document owner fully active?
if let Some(owner) = self.form_owner() { if let Some(owner) = self.form_owner() {
owner.reset(ResetFrom::NotFromForm); owner.reset(ResetFrom::NotFromForm, CanGc::note());
} }
}, },
_ => (), _ => (),

View file

@ -86,6 +86,7 @@ impl HTMLCanvasElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLCanvasElement> { ) -> DomRoot<HTMLCanvasElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLCanvasElement::new_inherited( Box::new(HTMLCanvasElement::new_inherited(
@ -93,6 +94,7 @@ impl HTMLCanvasElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }

View file

@ -12,6 +12,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLDataElement { pub struct HTMLDataElement {
@ -35,11 +36,13 @@ impl HTMLDataElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLDataElement> { ) -> DomRoot<HTMLDataElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLDataElement::new_inherited(local_name, prefix, document)), Box::new(HTMLDataElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -15,6 +15,7 @@ use crate::dom::htmlcollection::{CollectionFilter, HTMLCollection};
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::htmloptionelement::HTMLOptionElement; use crate::dom::htmloptionelement::HTMLOptionElement;
use crate::dom::node::{window_from_node, Node}; use crate::dom::node::{window_from_node, Node};
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLDataListElement { pub struct HTMLDataListElement {
@ -38,6 +39,7 @@ impl HTMLDataListElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLDataListElement> { ) -> DomRoot<HTMLDataListElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLDataListElement::new_inherited( Box::new(HTMLDataListElement::new_inherited(
@ -45,6 +47,7 @@ impl HTMLDataListElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -19,6 +19,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{window_from_node, Node, NodeDamage}; use crate::dom::node::{window_from_node, Node, NodeDamage};
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
use crate::task_source::TaskSource; use crate::task_source::TaskSource;
#[dom_struct] #[dom_struct]
@ -45,6 +46,7 @@ impl HTMLDetailsElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLDetailsElement> { ) -> DomRoot<HTMLDetailsElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLDetailsElement::new_inherited( Box::new(HTMLDetailsElement::new_inherited(
@ -52,6 +54,7 @@ impl HTMLDetailsElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }

View file

@ -16,6 +16,7 @@ use crate::dom::element::Element;
use crate::dom::eventtarget::EventTarget; use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{window_from_node, Node}; use crate::dom::node::{window_from_node, Node};
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLDialogElement { pub struct HTMLDialogElement {
@ -41,6 +42,7 @@ impl HTMLDialogElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLDialogElement> { ) -> DomRoot<HTMLDialogElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLDialogElement::new_inherited( Box::new(HTMLDialogElement::new_inherited(
@ -48,6 +50,7 @@ impl HTMLDialogElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }
@ -71,7 +74,7 @@ impl HTMLDialogElementMethods for HTMLDialogElement {
} }
/// <https://html.spec.whatwg.org/multipage/#dom-dialog-show> /// <https://html.spec.whatwg.org/multipage/#dom-dialog-show>
fn Show(&self) { fn Show(&self, can_gc: CanGc) {
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
// Step 1 TODO: Check is modal flag is false // Step 1 TODO: Check is modal flag is false
@ -82,7 +85,7 @@ impl HTMLDialogElementMethods for HTMLDialogElement {
// TODO: Step 2 If this has an open attribute, then throw an "InvalidStateError" DOMException. // TODO: Step 2 If this has an open attribute, then throw an "InvalidStateError" DOMException.
// Step 3 // Step 3
element.set_bool_attribute(&local_name!("open"), true); element.set_bool_attribute(&local_name!("open"), true, can_gc);
// TODO: Step 4 Set this's previously focused element to the focused element. // TODO: Step 4 Set this's previously focused element to the focused element.

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLDirectoryElement { pub struct HTMLDirectoryElement {
@ -33,6 +34,7 @@ impl HTMLDirectoryElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLDirectoryElement> { ) -> DomRoot<HTMLDirectoryElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLDirectoryElement::new_inherited( Box::new(HTMLDirectoryElement::new_inherited(
@ -40,6 +42,7 @@ impl HTMLDirectoryElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -12,6 +12,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLDivElement { pub struct HTMLDivElement {
@ -35,11 +36,13 @@ impl HTMLDivElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLDivElement> { ) -> DomRoot<HTMLDivElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLDivElement::new_inherited(local_name, prefix, document)), Box::new(HTMLDivElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLDListElement { pub struct HTMLDListElement {
@ -33,6 +34,7 @@ impl HTMLDListElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLDListElement> { ) -> DomRoot<HTMLDListElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLDListElement::new_inherited( Box::new(HTMLDListElement::new_inherited(
@ -40,6 +42,7 @@ impl HTMLDListElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -95,11 +95,13 @@ impl HTMLElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLElement> { ) -> DomRoot<HTMLElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLElement::new_inherited(local_name, prefix, document)), Box::new(HTMLElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
@ -481,10 +483,10 @@ impl HTMLElementMethods for HTMLElement {
} }
/// <https://html.spec.whatwg.org/multipage/#set-the-inner-text-steps> /// <https://html.spec.whatwg.org/multipage/#set-the-inner-text-steps>
fn SetInnerText(&self, input: DOMString) { fn SetInnerText(&self, input: DOMString, can_gc: CanGc) {
// Step 1: Let fragment be the rendered text fragment for value given element's node // Step 1: Let fragment be the rendered text fragment for value given element's node
// document. // document.
let fragment = self.rendered_text_fragment(input); let fragment = self.rendered_text_fragment(input, can_gc);
// Step 2: Replace all with fragment within element. // Step 2: Replace all with fragment within element.
Node::replace_all(Some(fragment.upcast()), self.upcast::<Node>()); Node::replace_all(Some(fragment.upcast()), self.upcast::<Node>());
@ -496,7 +498,7 @@ impl HTMLElementMethods for HTMLElement {
} }
/// <https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute:dom-outertext-2> /// <https://html.spec.whatwg.org/multipage/#the-innertext-idl-attribute:dom-outertext-2>
fn SetOuterText(&self, input: DOMString) -> Fallible<()> { fn SetOuterText(&self, input: DOMString, can_gc: CanGc) -> Fallible<()> {
// Step 1: If this's parent is null, then throw a "NoModificationAllowedError" DOMException. // Step 1: If this's parent is null, then throw a "NoModificationAllowedError" DOMException.
let Some(parent) = self.upcast::<Node>().GetParentNode() else { let Some(parent) = self.upcast::<Node>().GetParentNode() else {
return Err(Error::NoModificationAllowed); return Err(Error::NoModificationAllowed);
@ -513,12 +515,12 @@ impl HTMLElementMethods for HTMLElement {
// Step 4: Let fragment be the rendered text fragment for the given value given this's node // Step 4: Let fragment be the rendered text fragment for the given value given this's node
// document. // document.
let fragment = self.rendered_text_fragment(input); let fragment = self.rendered_text_fragment(input, can_gc);
// Step 5: If fragment has no children, then append a new Text node whose data is the empty // Step 5: If fragment has no children, then append a new Text node whose data is the empty
// string and node document is this's node document to fragment. // string and node document is this's node document to fragment.
if fragment.upcast::<Node>().children_count() == 0 { if fragment.upcast::<Node>().children_count() == 0 {
let text_node = Text::new(DOMString::from("".to_owned()), &document); let text_node = Text::new(DOMString::from("".to_owned()), &document, can_gc);
fragment.upcast::<Node>().AppendChild(text_node.upcast())?; fragment.upcast::<Node>().AppendChild(text_node.upcast())?;
} }
@ -548,13 +550,14 @@ impl HTMLElementMethods for HTMLElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-translate // https://html.spec.whatwg.org/multipage/#dom-translate
fn SetTranslate(&self, yesno: bool) { fn SetTranslate(&self, yesno: bool, can_gc: CanGc) {
self.as_element().set_string_attribute( self.as_element().set_string_attribute(
&html5ever::local_name!("translate"), &html5ever::local_name!("translate"),
match yesno { match yesno {
true => DOMString::from("yes"), true => DOMString::from("yes"),
false => DOMString::from("no"), false => DOMString::from("no"),
}, },
can_gc,
); );
} }
@ -625,14 +628,19 @@ impl HTMLElementMethods for HTMLElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-fe-autofocus // https://html.spec.whatwg.org/multipage/#dom-fe-autofocus
fn SetAutofocus(&self, autofocus: bool) { fn SetAutofocus(&self, autofocus: bool, can_gc: CanGc) {
self.element self.element
.set_bool_attribute(&local_name!("autofocus"), autofocus); .set_bool_attribute(&local_name!("autofocus"), autofocus, can_gc);
} }
} }
fn append_text_node_to_fragment(document: &Document, fragment: &DocumentFragment, text: String) { fn append_text_node_to_fragment(
let text = Text::new(DOMString::from(text), document); document: &Document,
fragment: &DocumentFragment,
text: String,
can_gc: CanGc,
) {
let text = Text::new(DOMString::from(text), document, can_gc);
fragment fragment
.upcast::<Node>() .upcast::<Node>()
.AppendChild(text.upcast()) .AppendChild(text.upcast())
@ -695,7 +703,7 @@ fn to_camel_case(name: &str) -> Option<DOMString> {
} }
impl HTMLElement { impl HTMLElement {
pub fn set_custom_attr(&self, name: DOMString, value: DOMString) -> ErrorResult { pub fn set_custom_attr(&self, name: DOMString, value: DOMString, can_gc: CanGc) -> ErrorResult {
if name if name
.chars() .chars()
.skip_while(|&ch| ch != '\u{2d}') .skip_while(|&ch| ch != '\u{2d}')
@ -705,7 +713,7 @@ impl HTMLElement {
return Err(Error::Syntax); return Err(Error::Syntax);
} }
self.as_element() self.as_element()
.set_custom_attribute(to_snake_case(name), value) .set_custom_attribute(to_snake_case(name), value, can_gc)
} }
pub fn get_custom_attr(&self, local_name: DOMString) -> Option<DOMString> { pub fn get_custom_attr(&self, local_name: DOMString) -> Option<DOMString> {
@ -926,10 +934,10 @@ impl HTMLElement {
} }
/// <https://html.spec.whatwg.org/multipage/#rendered-text-fragment> /// <https://html.spec.whatwg.org/multipage/#rendered-text-fragment>
fn rendered_text_fragment(&self, input: DOMString) -> DomRoot<DocumentFragment> { fn rendered_text_fragment(&self, input: DOMString, can_gc: CanGc) -> DomRoot<DocumentFragment> {
// Step 1: Let fragment be a new DocumentFragment whose node document is document. // Step 1: Let fragment be a new DocumentFragment whose node document is document.
let document = document_from_node(self); let document = document_from_node(self);
let fragment = DocumentFragment::new(&document); let fragment = DocumentFragment::new(&document, can_gc);
// Step 2: Let position be a position variable for input, initially pointing at the start // Step 2: Let position be a position variable for input, initially pointing at the start
// of input. // of input.
@ -951,11 +959,11 @@ impl HTMLElement {
} }
if !text.is_empty() { if !text.is_empty() {
append_text_node_to_fragment(&document, &fragment, text); append_text_node_to_fragment(&document, &fragment, text, can_gc);
text = String::new(); text = String::new();
} }
let br = HTMLBRElement::new(local_name!("br"), None, &document, None); let br = HTMLBRElement::new(local_name!("br"), None, &document, None, can_gc);
fragment.upcast::<Node>().AppendChild(br.upcast()).unwrap(); fragment.upcast::<Node>().AppendChild(br.upcast()).unwrap();
}, },
_ => { _ => {
@ -969,7 +977,7 @@ impl HTMLElement {
// If text is not the empty string, then append a new Text node whose data is text and node // If text is not the empty string, then append a new Text node whose data is text and node
// document is document to fragment. // document is document to fragment.
if !text.is_empty() { if !text.is_empty() {
append_text_node_to_fragment(&document, &fragment, text); append_text_node_to_fragment(&document, &fragment, text, can_gc);
} }
fragment fragment

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLEmbedElement { pub struct HTMLEmbedElement {
@ -33,6 +34,7 @@ impl HTMLEmbedElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLEmbedElement> { ) -> DomRoot<HTMLEmbedElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLEmbedElement::new_inherited( Box::new(HTMLEmbedElement::new_inherited(
@ -40,6 +42,7 @@ impl HTMLEmbedElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -59,6 +59,7 @@ impl HTMLFieldSetElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLFieldSetElement> { ) -> DomRoot<HTMLFieldSetElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLFieldSetElement::new_inherited( Box::new(HTMLFieldSetElement::new_inherited(
@ -66,6 +67,7 @@ impl HTMLFieldSetElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }

View file

@ -24,6 +24,7 @@ use crate::dom::element::{Element, LayoutElementHelpers};
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLFontElement { pub struct HTMLFontElement {
@ -47,11 +48,13 @@ impl HTMLFontElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLFontElement> { ) -> DomRoot<HTMLFontElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLFontElement::new_inherited(local_name, prefix, document)), Box::new(HTMLFontElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
@ -104,9 +107,9 @@ impl HTMLFontElementMethods for HTMLFontElement {
make_getter!(Size, "size"); make_getter!(Size, "size");
// https://html.spec.whatwg.org/multipage/#dom-font-size // https://html.spec.whatwg.org/multipage/#dom-font-size
fn SetSize(&self, value: DOMString) { fn SetSize(&self, value: DOMString, can_gc: CanGc) {
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
element.set_attribute(&local_name!("size"), parse_size(&value)); element.set_attribute(&local_name!("size"), parse_size(&value), can_gc);
} }
} }

View file

@ -140,11 +140,13 @@ impl HTMLFormElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLFormElement> { ) -> DomRoot<HTMLFormElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLFormElement::new_inherited(local_name, prefix, document)), Box::new(HTMLFormElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
@ -339,8 +341,8 @@ impl HTMLFormElementMethods for HTMLFormElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-form-reset // https://html.spec.whatwg.org/multipage/#dom-form-reset
fn Reset(&self) { fn Reset(&self, can_gc: CanGc) {
self.reset(ResetFrom::FromForm); self.reset(ResetFrom::FromForm, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-form-elements // https://html.spec.whatwg.org/multipage/#dom-form-elements
@ -474,9 +476,9 @@ impl HTMLFormElementMethods for HTMLFormElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-a-rel // https://html.spec.whatwg.org/multipage/#dom-a-rel
fn SetRel(&self, rel: DOMString) { fn SetRel(&self, rel: DOMString, can_gc: CanGc) {
self.upcast::<Element>() self.upcast::<Element>()
.set_tokenlist_attribute(&local_name!("rel"), rel); .set_tokenlist_attribute(&local_name!("rel"), rel, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-a-rellist // https://html.spec.whatwg.org/multipage/#dom-a-rellist
@ -1230,7 +1232,7 @@ impl HTMLFormElement {
Some(form_data.datums()) Some(form_data.datums())
} }
pub fn reset(&self, _reset_method_flag: ResetFrom) { pub fn reset(&self, _reset_method_flag: ResetFrom, can_gc: CanGc) {
// https://html.spec.whatwg.org/multipage/#locked-for-reset // https://html.spec.whatwg.org/multipage/#locked-for-reset
if self.marked_for_reset.get() { if self.marked_for_reset.get() {
return; return;
@ -1268,7 +1270,7 @@ impl HTMLFormElement {
NodeTypeId::Element(ElementTypeId::HTMLElement( NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLOutputElement, HTMLElementTypeId::HTMLOutputElement,
)) => { )) => {
child.downcast::<HTMLOutputElement>().unwrap().reset(); child.downcast::<HTMLOutputElement>().unwrap().reset(can_gc);
}, },
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLElement)) => { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLElement)) => {
let html_element = child.downcast::<HTMLElement>().unwrap(); let html_element = child.downcast::<HTMLElement>().unwrap();

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLFrameElement { pub struct HTMLFrameElement {
@ -33,6 +34,7 @@ impl HTMLFrameElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLFrameElement> { ) -> DomRoot<HTMLFrameElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLFrameElement::new_inherited( Box::new(HTMLFrameElement::new_inherited(
@ -40,6 +42,7 @@ impl HTMLFrameElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -13,6 +13,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{document_from_node, Node}; use crate::dom::node::{document_from_node, Node};
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLFrameSetElement { pub struct HTMLFrameSetElement {
@ -36,6 +37,7 @@ impl HTMLFrameSetElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLFrameSetElement> { ) -> DomRoot<HTMLFrameSetElement> {
let n = Node::reflect_node_with_proto( let n = Node::reflect_node_with_proto(
Box::new(HTMLFrameSetElement::new_inherited( Box::new(HTMLFrameSetElement::new_inherited(
@ -43,6 +45,7 @@ impl HTMLFrameSetElement {
)), )),
document, document,
proto, proto,
can_gc,
); );
n.upcast::<Node>().set_weird_parser_insertion_mode(); n.upcast::<Node>().set_weird_parser_insertion_mode();
n n

View file

@ -17,6 +17,7 @@ use crate::dom::htmlmetaelement::HTMLMetaElement;
use crate::dom::node::{document_from_node, BindContext, Node, ShadowIncluding}; use crate::dom::node::{document_from_node, BindContext, Node, ShadowIncluding};
use crate::dom::userscripts::load_script; use crate::dom::userscripts::load_script;
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLHeadElement { pub struct HTMLHeadElement {
@ -40,11 +41,13 @@ impl HTMLHeadElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLHeadElement> { ) -> DomRoot<HTMLHeadElement> {
let n = Node::reflect_node_with_proto( let n = Node::reflect_node_with_proto(
Box::new(HTMLHeadElement::new_inherited(local_name, prefix, document)), Box::new(HTMLHeadElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
); );
n.upcast::<Node>().set_weird_parser_insertion_mode(); n.upcast::<Node>().set_weird_parser_insertion_mode();

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
pub enum HeadingLevel { pub enum HeadingLevel {
@ -47,6 +48,7 @@ impl HTMLHeadingElement {
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
level: HeadingLevel, level: HeadingLevel,
can_gc: CanGc,
) -> DomRoot<HTMLHeadingElement> { ) -> DomRoot<HTMLHeadingElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLHeadingElement::new_inherited( Box::new(HTMLHeadingElement::new_inherited(
@ -54,6 +56,7 @@ impl HTMLHeadingElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -17,6 +17,7 @@ use crate::dom::element::{Element, LayoutElementHelpers};
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLHRElement { pub struct HTMLHRElement {
@ -40,11 +41,13 @@ impl HTMLHRElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLHRElement> { ) -> DomRoot<HTMLHRElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLHRElement::new_inherited(local_name, prefix, document)), Box::new(HTMLHRElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -11,6 +11,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLHtmlElement { pub struct HTMLHtmlElement {
@ -35,11 +36,13 @@ impl HTMLHtmlElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLHtmlElement> { ) -> DomRoot<HTMLHtmlElement> {
let n = Node::reflect_node_with_proto( let n = Node::reflect_node_with_proto(
Box::new(HTMLHtmlElement::new_inherited(localName, prefix, document)), Box::new(HTMLHtmlElement::new_inherited(localName, prefix, document)),
document, document,
proto, proto,
can_gc,
); );
n.upcast::<Node>().set_weird_parser_insertion_mode(); n.upcast::<Node>().set_weird_parser_insertion_mode();

View file

@ -456,6 +456,7 @@ impl HTMLIFrameElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLIFrameElement> { ) -> DomRoot<HTMLIFrameElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLIFrameElement::new_inherited( Box::new(HTMLIFrameElement::new_inherited(
@ -463,6 +464,7 @@ impl HTMLIFrameElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }

View file

@ -1335,6 +1335,7 @@ impl HTMLImageElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLImageElement> { ) -> DomRoot<HTMLImageElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLImageElement::new_inherited( Box::new(HTMLImageElement::new_inherited(
@ -1342,6 +1343,7 @@ impl HTMLImageElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
@ -1546,10 +1548,10 @@ impl HTMLImageElementMethods for HTMLImageElement {
let image = DomRoot::downcast::<HTMLImageElement>(element).unwrap(); let image = DomRoot::downcast::<HTMLImageElement>(element).unwrap();
if let Some(w) = width { if let Some(w) = width {
image.SetWidth(w); image.SetWidth(w, can_gc);
} }
if let Some(h) = height { if let Some(h) = height {
image.SetHeight(h); image.SetHeight(h, can_gc);
} }
// run update_the_image_data when the element is created. // run update_the_image_data when the element is created.
@ -1581,8 +1583,8 @@ impl HTMLImageElementMethods for HTMLImageElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-img-crossOrigin // https://html.spec.whatwg.org/multipage/#dom-img-crossOrigin
fn SetCrossOrigin(&self, value: Option<DOMString>) { fn SetCrossOrigin(&self, value: Option<DOMString>, can_gc: CanGc) {
set_cross_origin_attribute(self.upcast::<Element>(), value); set_cross_origin_attribute(self.upcast::<Element>(), value, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-img-usemap // https://html.spec.whatwg.org/multipage/#dom-img-usemap
@ -1605,8 +1607,8 @@ impl HTMLImageElementMethods for HTMLImageElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-img-width // https://html.spec.whatwg.org/multipage/#dom-img-width
fn SetWidth(&self, value: u32) { fn SetWidth(&self, value: u32, can_gc: CanGc) {
image_dimension_setter(self.upcast(), local_name!("width"), value); image_dimension_setter(self.upcast(), local_name!("width"), value, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-img-height // https://html.spec.whatwg.org/multipage/#dom-img-height
@ -1619,8 +1621,8 @@ impl HTMLImageElementMethods for HTMLImageElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-img-height // https://html.spec.whatwg.org/multipage/#dom-img-height
fn SetHeight(&self, value: u32) { fn SetHeight(&self, value: u32, can_gc: CanGc) {
image_dimension_setter(self.upcast(), local_name!("height"), value); image_dimension_setter(self.upcast(), local_name!("height"), value, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-img-naturalwidth // https://html.spec.whatwg.org/multipage/#dom-img-naturalwidth
@ -1688,7 +1690,7 @@ impl HTMLImageElementMethods for HTMLImageElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-img-referrerpolicy // https://html.spec.whatwg.org/multipage/#dom-img-referrerpolicy
fn SetReferrerPolicy(&self, value: DOMString) { fn SetReferrerPolicy(&self, value: DOMString, can_gc: CanGc) {
let referrerpolicy_attr_name = local_name!("referrerpolicy"); let referrerpolicy_attr_name = local_name!("referrerpolicy");
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
let previous_correct_attribute_value = get_correct_referrerpolicy_from_raw_token( let previous_correct_attribute_value = get_correct_referrerpolicy_from_raw_token(
@ -1698,7 +1700,11 @@ impl HTMLImageElementMethods for HTMLImageElement {
if previous_correct_attribute_value != correct_value_or_empty_string { if previous_correct_attribute_value != correct_value_or_empty_string {
// Setting the attribute to the same value will update the image. // Setting the attribute to the same value will update the image.
// We don't want to start an update if referrerpolicy is set to the same value. // We don't want to start an update if referrerpolicy is set to the same value.
element.set_string_attribute(&referrerpolicy_attr_name, correct_value_or_empty_string); element.set_string_attribute(
&referrerpolicy_attr_name,
correct_value_or_empty_string,
can_gc,
);
} }
} }
@ -1890,7 +1896,7 @@ impl ImageCacheListener for HTMLImageElement {
} }
} }
fn image_dimension_setter(element: &Element, attr: LocalName, value: u32) { fn image_dimension_setter(element: &Element, attr: LocalName, value: u32, can_gc: CanGc) {
// This setter is a bit weird: the IDL type is unsigned long, but it's parsed as // This setter is a bit weird: the IDL type is unsigned long, but it's parsed as
// a dimension for rendering. // a dimension for rendering.
let value = if value > UNSIGNED_LONG_MAX { 0 } else { value }; let value = if value > UNSIGNED_LONG_MAX { 0 } else { value };
@ -1908,7 +1914,7 @@ fn image_dimension_setter(element: &Element, attr: LocalName, value: u32) {
let dim = LengthOrPercentageOrAuto::Length(Au::from_px(pixel_value as i32)); let dim = LengthOrPercentageOrAuto::Length(Au::from_px(pixel_value as i32));
let value = AttrValue::Dimension(value.to_string(), dim); let value = AttrValue::Dimension(value.to_string(), dim);
element.set_attribute(&attr, value); element.set_attribute(&attr, value, can_gc);
} }
/// Collect sequence of code points /// Collect sequence of code points

View file

@ -326,6 +326,7 @@ impl HTMLInputElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLInputElement> { ) -> DomRoot<HTMLInputElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLInputElement::new_inherited( Box::new(HTMLInputElement::new_inherited(
@ -333,6 +334,7 @@ impl HTMLInputElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
@ -655,7 +657,7 @@ impl HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#dom-input-stepdown // https://html.spec.whatwg.org/multipage/#dom-input-stepdown
// https://html.spec.whatwg.org/multipage/#dom-input-stepup // https://html.spec.whatwg.org/multipage/#dom-input-stepup
fn step_up_or_down(&self, n: i32, dir: StepDirection) -> ErrorResult { fn step_up_or_down(&self, n: i32, dir: StepDirection, can_gc: CanGc) -> ErrorResult {
// Step 1 // Step 1
if !self.does_value_as_number_apply() { if !self.does_value_as_number_apply() {
return Err(Error::InvalidState); return Err(Error::InvalidState);
@ -738,7 +740,7 @@ impl HTMLInputElement {
} }
// Step 11 // Step 11
self.SetValueAsNumber(value) self.SetValueAsNumber(value, can_gc)
} }
// https://html.spec.whatwg.org/multipage/#concept-input-list // https://html.spec.whatwg.org/multipage/#concept-input-list
@ -1242,7 +1244,7 @@ impl HTMLInputElementMethods for HTMLInputElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-input-value // https://html.spec.whatwg.org/multipage/#dom-input-value
fn SetValue(&self, mut value: DOMString) -> ErrorResult { fn SetValue(&self, mut value: DOMString, can_gc: CanGc) -> ErrorResult {
match self.value_mode() { match self.value_mode() {
ValueMode::Value => { ValueMode::Value => {
// Step 3. // Step 3.
@ -1264,7 +1266,7 @@ impl HTMLInputElementMethods for HTMLInputElement {
}, },
ValueMode::Default | ValueMode::DefaultOn => { ValueMode::Default | ValueMode::DefaultOn => {
self.upcast::<Element>() self.upcast::<Element>()
.set_string_attribute(&local_name!("value"), value); .set_string_attribute(&local_name!("value"), value, can_gc);
}, },
ValueMode::Filename => { ValueMode::Filename => {
if value.is_empty() { if value.is_empty() {
@ -1314,13 +1316,18 @@ impl HTMLInputElementMethods for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#dom-input-valueasdate // https://html.spec.whatwg.org/multipage/#dom-input-valueasdate
#[allow(unsafe_code, non_snake_case)] #[allow(unsafe_code, non_snake_case)]
fn SetValueAsDate(&self, cx: SafeJSContext, value: *mut JSObject) -> ErrorResult { fn SetValueAsDate(
&self,
cx: SafeJSContext,
value: *mut JSObject,
can_gc: CanGc,
) -> ErrorResult {
rooted!(in(*cx) let value = value); rooted!(in(*cx) let value = value);
if !self.does_value_as_date_apply() { if !self.does_value_as_date_apply() {
return Err(Error::InvalidState); return Err(Error::InvalidState);
} }
if value.is_null() { if value.is_null() {
return self.SetValue(DOMString::from("")); return self.SetValue(DOMString::from(""), can_gc);
} }
let mut msecs: f64 = 0.0; let mut msecs: f64 = 0.0;
// We need to go through unsafe code to interrogate jsapi about a Date. // We need to go through unsafe code to interrogate jsapi about a Date.
@ -1338,14 +1345,14 @@ impl HTMLInputElementMethods for HTMLInputElement {
return Err(Error::JSFailed); return Err(Error::JSFailed);
} }
if !msecs.is_finite() { if !msecs.is_finite() {
return self.SetValue(DOMString::from("")); return self.SetValue(DOMString::from(""), can_gc);
} }
} }
let Ok(date_time) = OffsetDateTime::from_unix_timestamp_nanos((msecs * 1e6) as i128) else { let Ok(date_time) = OffsetDateTime::from_unix_timestamp_nanos((msecs * 1e6) as i128) else {
return self.SetValue(DOMString::from("")); return self.SetValue(DOMString::from(""), can_gc);
}; };
self.SetValue(self.convert_datetime_to_dom_string(date_time)) self.SetValue(self.convert_datetime_to_dom_string(date_time), can_gc)
} }
// https://html.spec.whatwg.org/multipage/#dom-input-valueasnumber // https://html.spec.whatwg.org/multipage/#dom-input-valueasnumber
@ -1355,21 +1362,21 @@ impl HTMLInputElementMethods for HTMLInputElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-input-valueasnumber // https://html.spec.whatwg.org/multipage/#dom-input-valueasnumber
fn SetValueAsNumber(&self, value: f64) -> ErrorResult { fn SetValueAsNumber(&self, value: f64, can_gc: CanGc) -> ErrorResult {
if value.is_infinite() { if value.is_infinite() {
Err(Error::Type("value is not finite".to_string())) Err(Error::Type("value is not finite".to_string()))
} else if !self.does_value_as_number_apply() { } else if !self.does_value_as_number_apply() {
Err(Error::InvalidState) Err(Error::InvalidState)
} else if value.is_nan() { } else if value.is_nan() {
self.SetValue(DOMString::from("")) self.SetValue(DOMString::from(""), can_gc)
} else if let Some(converted) = self.convert_number_to_string(value) { } else if let Some(converted) = self.convert_number_to_string(value) {
self.SetValue(converted) self.SetValue(converted, can_gc)
} else { } else {
// The most literal spec-compliant implementation would use bignum types so // The most literal spec-compliant implementation would use bignum types so
// overflow is impossible, but just setting an overflow to the empty string // overflow is impossible, but just setting an overflow to the empty string
// matches Firefox's behavior. For example, try input.valueAsNumber=1e30 on // matches Firefox's behavior. For example, try input.valueAsNumber=1e30 on
// a type="date" input. // a type="date" input.
self.SetValue(DOMString::from("")) self.SetValue(DOMString::from(""), can_gc)
} }
} }
@ -1566,13 +1573,13 @@ impl HTMLInputElementMethods for HTMLInputElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-input-stepup // https://html.spec.whatwg.org/multipage/#dom-input-stepup
fn StepUp(&self, n: i32) -> ErrorResult { fn StepUp(&self, n: i32, can_gc: CanGc) -> ErrorResult {
self.step_up_or_down(n, StepDirection::Up) self.step_up_or_down(n, StepDirection::Up, can_gc)
} }
// https://html.spec.whatwg.org/multipage/#dom-input-stepdown // https://html.spec.whatwg.org/multipage/#dom-input-stepdown
fn StepDown(&self, n: i32) -> ErrorResult { fn StepDown(&self, n: i32, can_gc: CanGc) -> ErrorResult {
self.step_up_or_down(n, StepDirection::Down) self.step_up_or_down(n, StepDirection::Down, can_gc)
} }
// https://html.spec.whatwg.org/multipage/#dom-cva-willvalidate // https://html.spec.whatwg.org/multipage/#dom-cva-willvalidate
@ -2314,7 +2321,7 @@ impl VirtualMethods for HTMLInputElement {
// Step 1 // Step 1
(&ValueMode::Value, false, ValueMode::Default) | (&ValueMode::Value, false, ValueMode::Default) |
(&ValueMode::Value, false, ValueMode::DefaultOn) => { (&ValueMode::Value, false, ValueMode::DefaultOn) => {
self.SetValue(old_idl_value) self.SetValue(old_idl_value, CanGc::note())
.expect("Failed to set input value on type change to a default ValueMode."); .expect("Failed to set input value on type change to a default ValueMode.");
}, },
@ -2326,6 +2333,7 @@ impl VirtualMethods for HTMLInputElement {
.map_or(DOMString::from(""), |a| { .map_or(DOMString::from(""), |a| {
DOMString::from(a.summarize().value) DOMString::from(a.summarize().value)
}), }),
CanGc::note(),
) )
.expect( .expect(
"Failed to set input value on type change to ValueMode::Value.", "Failed to set input value on type change to ValueMode::Value.",
@ -2337,7 +2345,7 @@ impl VirtualMethods for HTMLInputElement {
(_, _, ValueMode::Filename) (_, _, ValueMode::Filename)
if old_value_mode != ValueMode::Filename => if old_value_mode != ValueMode::Filename =>
{ {
self.SetValue(DOMString::from("")) self.SetValue(DOMString::from(""), CanGc::note())
.expect("Failed to set input value on type change to ValueMode::Filename."); .expect("Failed to set input value on type change to ValueMode::Filename.");
}, },
_ => {}, _ => {},
@ -2825,7 +2833,7 @@ impl Activatable for HTMLInputElement {
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context) // FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
// Check if document owner is fully active // Check if document owner is fully active
if let Some(o) = self.form_owner() { if let Some(o) = self.form_owner() {
o.reset(ResetFrom::NotFromForm) o.reset(ResetFrom::NotFromForm, CanGc::note())
} }
}, },
InputType::Checkbox | InputType::Radio => { InputType::Checkbox | InputType::Radio => {

View file

@ -49,6 +49,7 @@ impl HTMLLabelElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLLabelElement> { ) -> DomRoot<HTMLLabelElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLLabelElement::new_inherited( Box::new(HTMLLabelElement::new_inherited(
@ -56,6 +57,7 @@ impl HTMLLabelElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -17,6 +17,7 @@ use crate::dom::htmlfieldsetelement::HTMLFieldSetElement;
use crate::dom::htmlformelement::{FormControl, HTMLFormElement}; use crate::dom::htmlformelement::{FormControl, HTMLFormElement};
use crate::dom::node::{BindContext, Node, UnbindContext}; use crate::dom::node::{BindContext, Node, UnbindContext};
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLLegendElement { pub struct HTMLLegendElement {
@ -42,6 +43,7 @@ impl HTMLLegendElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLLegendElement> { ) -> DomRoot<HTMLLegendElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLLegendElement::new_inherited( Box::new(HTMLLegendElement::new_inherited(
@ -49,6 +51,7 @@ impl HTMLLegendElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -15,6 +15,7 @@ use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLLIElement { pub struct HTMLLIElement {
@ -38,11 +39,13 @@ impl HTMLLIElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLLIElement> { ) -> DomRoot<HTMLLIElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLLIElement::new_inherited(local_name, prefix, document)), Box::new(HTMLLIElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -56,6 +56,7 @@ use crate::dom::virtualmethods::VirtualMethods;
use crate::fetch::create_a_potential_cors_request; use crate::fetch::create_a_potential_cors_request;
use crate::links::LinkRelations; use crate::links::LinkRelations;
use crate::network_listener::{submit_timing, PreInvoke, ResourceTimingListener}; use crate::network_listener::{submit_timing, PreInvoke, ResourceTimingListener};
use crate::script_runtime::CanGc;
use crate::stylesheet_loader::{StylesheetContextSource, StylesheetLoader, StylesheetOwner}; use crate::stylesheet_loader::{StylesheetContextSource, StylesheetLoader, StylesheetOwner};
#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)] #[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
@ -137,6 +138,7 @@ impl HTMLLinkElement {
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
creator: ElementCreator, creator: ElementCreator,
can_gc: CanGc,
) -> DomRoot<HTMLLinkElement> { ) -> DomRoot<HTMLLinkElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLLinkElement::new_inherited( Box::new(HTMLLinkElement::new_inherited(
@ -144,6 +146,7 @@ impl HTMLLinkElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
@ -522,9 +525,9 @@ impl HTMLLinkElementMethods for HTMLLinkElement {
make_getter!(Rel, "rel"); make_getter!(Rel, "rel");
// https://html.spec.whatwg.org/multipage/#dom-link-rel // https://html.spec.whatwg.org/multipage/#dom-link-rel
fn SetRel(&self, rel: DOMString) { fn SetRel(&self, rel: DOMString, can_gc: CanGc) {
self.upcast::<Element>() self.upcast::<Element>()
.set_tokenlist_attribute(&local_name!("rel"), rel); .set_tokenlist_attribute(&local_name!("rel"), rel, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-link-media // https://html.spec.whatwg.org/multipage/#dom-link-media
@ -602,8 +605,8 @@ impl HTMLLinkElementMethods for HTMLLinkElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-link-crossorigin // https://html.spec.whatwg.org/multipage/#dom-link-crossorigin
fn SetCrossOrigin(&self, value: Option<DOMString>) { fn SetCrossOrigin(&self, value: Option<DOMString>, can_gc: CanGc) {
set_cross_origin_attribute(self.upcast::<Element>(), value); set_cross_origin_attribute(self.upcast::<Element>(), value, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-link-referrerpolicy // https://html.spec.whatwg.org/multipage/#dom-link-referrerpolicy

View file

@ -12,6 +12,7 @@ use crate::dom::document::Document;
use crate::dom::htmlareaelement::HTMLAreaElement; use crate::dom::htmlareaelement::HTMLAreaElement;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{Node, ShadowIncluding}; use crate::dom::node::{Node, ShadowIncluding};
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLMapElement { pub struct HTMLMapElement {
@ -35,11 +36,13 @@ impl HTMLMapElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLMapElement> { ) -> DomRoot<HTMLMapElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLMapElement::new_inherited(local_name, prefix, document)), Box::new(HTMLMapElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }

View file

@ -1767,7 +1767,7 @@ impl HTMLMediaElement {
// We wait until we have metadata to render the controls, so we render them // We wait until we have metadata to render the controls, so we render them
// with the appropriate size. // with the appropriate size.
if self.Controls() { if self.Controls() {
self.render_controls(); self.render_controls(can_gc);
} }
let global = self.global(); let global = self.global();
@ -1887,7 +1887,7 @@ impl HTMLMediaElement {
.unwrap_or_else(|_| self.playback_position.get()) .unwrap_or_else(|_| self.playback_position.get())
} }
fn render_controls(&self) { fn render_controls(&self, can_gc: CanGc) {
let element = self.htmlelement.upcast::<Element>(); let element = self.htmlelement.upcast::<Element>();
if self.ready_state.get() < ReadyState::HaveMetadata || element.is_shadow_host() { if self.ready_state.get() < ReadyState::HaveMetadata || element.is_shadow_host() {
// Bail out if we have no metadata yet or // Bail out if we have no metadata yet or
@ -1902,6 +1902,7 @@ impl HTMLMediaElement {
&document, &document,
None, None,
ElementCreator::ScriptCreated, ElementCreator::ScriptCreated,
can_gc,
); );
let mut media_controls_script = resources::read_string(EmbedderResource::MediaControlsJS); let mut media_controls_script = resources::read_string(EmbedderResource::MediaControlsJS);
// This is our hacky way to temporarily workaround the lack of a privileged // This is our hacky way to temporarily workaround the lack of a privileged
@ -1914,7 +1915,7 @@ impl HTMLMediaElement {
*self.media_controls_id.borrow_mut() = Some(id); *self.media_controls_id.borrow_mut() = Some(id);
script script
.upcast::<Node>() .upcast::<Node>()
.SetTextContent(Some(DOMString::from(media_controls_script))); .SetTextContent(Some(DOMString::from(media_controls_script)), can_gc);
if let Err(e) = shadow_root if let Err(e) = shadow_root
.upcast::<Node>() .upcast::<Node>()
.AppendChild(script.upcast::<Node>()) .AppendChild(script.upcast::<Node>())
@ -1930,10 +1931,11 @@ impl HTMLMediaElement {
&document, &document,
None, None,
ElementCreator::ScriptCreated, ElementCreator::ScriptCreated,
can_gc,
); );
style style
.upcast::<Node>() .upcast::<Node>()
.SetTextContent(Some(DOMString::from(media_controls_style))); .SetTextContent(Some(DOMString::from(media_controls_style)), can_gc);
if let Err(e) = shadow_root if let Err(e) = shadow_root
.upcast::<Node>() .upcast::<Node>()
@ -2078,8 +2080,8 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
reflect_cross_origin_attribute(self.upcast::<Element>()) reflect_cross_origin_attribute(self.upcast::<Element>())
} }
// https://html.spec.whatwg.org/multipage/#dom-media-crossOrigin // https://html.spec.whatwg.org/multipage/#dom-media-crossOrigin
fn SetCrossOrigin(&self, value: Option<DOMString>) { fn SetCrossOrigin(&self, value: Option<DOMString>, can_gc: CanGc) {
set_cross_origin_attribute(self.upcast::<Element>(), value); set_cross_origin_attribute(self.upcast::<Element>(), value, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-media-muted // https://html.spec.whatwg.org/multipage/#dom-media-muted
@ -2473,7 +2475,7 @@ impl VirtualMethods for HTMLMediaElement {
}, },
local_name!("controls") => { local_name!("controls") => {
if mutation.new_value(attr).is_some() { if mutation.new_value(attr).is_some() {
self.render_controls(); self.render_controls(CanGc::note());
} else { } else {
self.remove_controls(); self.remove_controls();
} }

View file

@ -11,6 +11,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLMenuElement { pub struct HTMLMenuElement {
@ -34,11 +35,13 @@ impl HTMLMenuElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLMenuElement> { ) -> DomRoot<HTMLMenuElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLMenuElement::new_inherited(local_name, prefix, document)), Box::new(HTMLMenuElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -73,11 +73,13 @@ impl HTMLMetaElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLMetaElement> { ) -> DomRoot<HTMLMetaElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLMetaElement::new_inherited(local_name, prefix, document)), Box::new(HTMLMetaElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }

View file

@ -18,6 +18,7 @@ use crate::dom::element::Element;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::dom::nodelist::NodeList; use crate::dom::nodelist::NodeList;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLMeterElement { pub struct HTMLMeterElement {
@ -44,6 +45,7 @@ impl HTMLMeterElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLMeterElement> { ) -> DomRoot<HTMLMeterElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLMeterElement::new_inherited( Box::new(HTMLMeterElement::new_inherited(
@ -51,6 +53,7 @@ impl HTMLMeterElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }
@ -75,13 +78,13 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
} }
/// <https://html.spec.whatwg.org/multipage/#dom-meter-value> /// <https://html.spec.whatwg.org/multipage/#dom-meter-value>
fn SetValue(&self, value: Finite<f64>) { fn SetValue(&self, value: Finite<f64>, can_gc: CanGc) {
let mut string_value = DOMString::from_string((*value).to_string()); let mut string_value = DOMString::from_string((*value).to_string());
string_value.set_best_representation_of_the_floating_point_number(); string_value.set_best_representation_of_the_floating_point_number();
self.upcast::<Element>() self.upcast::<Element>()
.set_string_attribute(&local_name!("value"), string_value); .set_string_attribute(&local_name!("value"), string_value, can_gc);
} }
/// <https://html.spec.whatwg.org/multipage/#concept-meter-minimum> /// <https://html.spec.whatwg.org/multipage/#concept-meter-minimum>
@ -95,13 +98,13 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
} }
/// <https://html.spec.whatwg.org/multipage/#dom-meter-min> /// <https://html.spec.whatwg.org/multipage/#dom-meter-min>
fn SetMin(&self, value: Finite<f64>) { fn SetMin(&self, value: Finite<f64>, can_gc: CanGc) {
let mut string_value = DOMString::from_string((*value).to_string()); let mut string_value = DOMString::from_string((*value).to_string());
string_value.set_best_representation_of_the_floating_point_number(); string_value.set_best_representation_of_the_floating_point_number();
self.upcast::<Element>() self.upcast::<Element>()
.set_string_attribute(&local_name!("min"), string_value); .set_string_attribute(&local_name!("min"), string_value, can_gc);
} }
/// <https://html.spec.whatwg.org/multipage/#concept-meter-maximum> /// <https://html.spec.whatwg.org/multipage/#concept-meter-maximum>
@ -116,13 +119,13 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
} }
/// <https://html.spec.whatwg.org/multipage/#concept-meter-maximum> /// <https://html.spec.whatwg.org/multipage/#concept-meter-maximum>
fn SetMax(&self, value: Finite<f64>) { fn SetMax(&self, value: Finite<f64>, can_gc: CanGc) {
let mut string_value = DOMString::from_string((*value).to_string()); let mut string_value = DOMString::from_string((*value).to_string());
string_value.set_best_representation_of_the_floating_point_number(); string_value.set_best_representation_of_the_floating_point_number();
self.upcast::<Element>() self.upcast::<Element>()
.set_string_attribute(&local_name!("max"), string_value); .set_string_attribute(&local_name!("max"), string_value, can_gc);
} }
/// <https://html.spec.whatwg.org/multipage/#concept-meter-low> /// <https://html.spec.whatwg.org/multipage/#concept-meter-low>
@ -141,13 +144,13 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
} }
/// <https://html.spec.whatwg.org/multipage/#dom-meter-low> /// <https://html.spec.whatwg.org/multipage/#dom-meter-low>
fn SetLow(&self, value: Finite<f64>) { fn SetLow(&self, value: Finite<f64>, can_gc: CanGc) {
let mut string_value = DOMString::from_string((*value).to_string()); let mut string_value = DOMString::from_string((*value).to_string());
string_value.set_best_representation_of_the_floating_point_number(); string_value.set_best_representation_of_the_floating_point_number();
self.upcast::<Element>() self.upcast::<Element>()
.set_string_attribute(&local_name!("low"), string_value); .set_string_attribute(&local_name!("low"), string_value, can_gc);
} }
/// <https://html.spec.whatwg.org/multipage/#concept-meter-high> /// <https://html.spec.whatwg.org/multipage/#concept-meter-high>
@ -170,13 +173,13 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
} }
/// <https://html.spec.whatwg.org/multipage/#dom-meter-high> /// <https://html.spec.whatwg.org/multipage/#dom-meter-high>
fn SetHigh(&self, value: Finite<f64>) { fn SetHigh(&self, value: Finite<f64>, can_gc: CanGc) {
let mut string_value = DOMString::from_string((*value).to_string()); let mut string_value = DOMString::from_string((*value).to_string());
string_value.set_best_representation_of_the_floating_point_number(); string_value.set_best_representation_of_the_floating_point_number();
self.upcast::<Element>() self.upcast::<Element>()
.set_string_attribute(&local_name!("high"), string_value); .set_string_attribute(&local_name!("high"), string_value, can_gc);
} }
/// <https://html.spec.whatwg.org/multipage/#concept-meter-optimum> /// <https://html.spec.whatwg.org/multipage/#concept-meter-optimum>
@ -195,12 +198,15 @@ impl HTMLMeterElementMethods for HTMLMeterElement {
} }
/// <https://html.spec.whatwg.org/multipage/#dom-meter-optimum> /// <https://html.spec.whatwg.org/multipage/#dom-meter-optimum>
fn SetOptimum(&self, value: Finite<f64>) { fn SetOptimum(&self, value: Finite<f64>, can_gc: CanGc) {
let mut string_value = DOMString::from_string((*value).to_string()); let mut string_value = DOMString::from_string((*value).to_string());
string_value.set_best_representation_of_the_floating_point_number(); string_value.set_best_representation_of_the_floating_point_number();
self.upcast::<Element>() self.upcast::<Element>().set_string_attribute(
.set_string_attribute(&local_name!("optimum"), string_value); &local_name!("optimum"),
string_value,
can_gc,
);
} }
} }

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLModElement { pub struct HTMLModElement {
@ -33,11 +34,13 @@ impl HTMLModElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLModElement> { ) -> DomRoot<HTMLModElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLModElement::new_inherited(local_name, prefix, document)), Box::new(HTMLModElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -56,6 +56,7 @@ impl HTMLObjectElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLObjectElement> { ) -> DomRoot<HTMLObjectElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLObjectElement::new_inherited( Box::new(HTMLObjectElement::new_inherited(
@ -63,6 +64,7 @@ impl HTMLObjectElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLOListElement { pub struct HTMLOListElement {
@ -33,6 +34,7 @@ impl HTMLOListElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLOListElement> { ) -> DomRoot<HTMLOListElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLOListElement::new_inherited( Box::new(HTMLOListElement::new_inherited(
@ -40,6 +42,7 @@ impl HTMLOListElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -20,6 +20,7 @@ use crate::dom::node::{BindContext, Node, ShadowIncluding, UnbindContext};
use crate::dom::validation::Validatable; use crate::dom::validation::Validatable;
use crate::dom::validitystate::ValidationFlags; use crate::dom::validitystate::ValidationFlags;
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLOptGroupElement { pub struct HTMLOptGroupElement {
@ -48,6 +49,7 @@ impl HTMLOptGroupElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLOptGroupElement> { ) -> DomRoot<HTMLOptGroupElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLOptGroupElement::new_inherited( Box::new(HTMLOptGroupElement::new_inherited(
@ -55,6 +57,7 @@ impl HTMLOptGroupElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }

View file

@ -72,6 +72,7 @@ impl HTMLOptionElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLOptionElement> { ) -> DomRoot<HTMLOptionElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLOptionElement::new_inherited( Box::new(HTMLOptionElement::new_inherited(
@ -79,6 +80,7 @@ impl HTMLOptionElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
@ -196,7 +198,7 @@ impl HTMLOptionElementMethods for HTMLOptionElement {
let option = DomRoot::downcast::<HTMLOptionElement>(element).unwrap(); let option = DomRoot::downcast::<HTMLOptionElement>(element).unwrap();
if !text.is_empty() { if !text.is_empty() {
option.upcast::<Node>().SetTextContent(Some(text)) option.upcast::<Node>().SetTextContent(Some(text), can_gc)
} }
if let Some(val) = value { if let Some(val) = value {
@ -223,8 +225,8 @@ impl HTMLOptionElementMethods for HTMLOptionElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-option-text // https://html.spec.whatwg.org/multipage/#dom-option-text
fn SetText(&self, value: DOMString) { fn SetText(&self, value: DOMString, can_gc: CanGc) {
self.upcast::<Node>().SetTextContent(Some(value)) self.upcast::<Node>().SetTextContent(Some(value), can_gc)
} }
// https://html.spec.whatwg.org/multipage/#dom-option-form // https://html.spec.whatwg.org/multipage/#dom-option-form

View file

@ -26,6 +26,7 @@ use crate::dom::htmloptionelement::HTMLOptionElement;
use crate::dom::htmlselectelement::HTMLSelectElement; use crate::dom::htmlselectelement::HTMLSelectElement;
use crate::dom::node::{document_from_node, Node}; use crate::dom::node::{document_from_node, Node};
use crate::dom::window::Window; use crate::dom::window::Window;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLOptionsCollection { pub struct HTMLOptionsCollection {
@ -53,12 +54,13 @@ impl HTMLOptionsCollection {
) )
} }
fn add_new_elements(&self, count: u32) -> ErrorResult { fn add_new_elements(&self, count: u32, can_gc: CanGc) -> ErrorResult {
let root = self.upcast().root_node(); let root = self.upcast().root_node();
let document = document_from_node(&*root); let document = document_from_node(&*root);
for _ in 0..count { for _ in 0..count {
let element = HTMLOptionElement::new(local_name!("option"), None, &document, None); let element =
HTMLOptionElement::new(local_name!("option"), None, &document, None, can_gc);
let node = element.upcast::<Node>(); let node = element.upcast::<Node>();
root.AppendChild(node)?; root.AppendChild(node)?;
} }
@ -91,7 +93,12 @@ impl HTMLOptionsCollectionMethods for HTMLOptionsCollection {
} }
// https://html.spec.whatwg.org/multipage/#dom-htmloptionscollection-setter // https://html.spec.whatwg.org/multipage/#dom-htmloptionscollection-setter
fn IndexedSetter(&self, index: u32, value: Option<&HTMLOptionElement>) -> ErrorResult { fn IndexedSetter(
&self,
index: u32,
value: Option<&HTMLOptionElement>,
can_gc: CanGc,
) -> ErrorResult {
if let Some(value) = value { if let Some(value) = value {
// Step 2 // Step 2
let length = self.upcast().Length(); let length = self.upcast().Length();
@ -101,7 +108,7 @@ impl HTMLOptionsCollectionMethods for HTMLOptionsCollection {
// Step 4 // Step 4
if n > 0 { if n > 0 {
self.add_new_elements(n as u32)?; self.add_new_elements(n as u32, can_gc)?;
} }
// Step 5 // Step 5
@ -128,7 +135,7 @@ impl HTMLOptionsCollectionMethods for HTMLOptionsCollection {
} }
/// <https://html.spec.whatwg.org/multipage/#dom-htmloptionscollection-length> /// <https://html.spec.whatwg.org/multipage/#dom-htmloptionscollection-length>
fn SetLength(&self, length: u32) { fn SetLength(&self, length: u32, can_gc: CanGc) {
let current_length = self.upcast().Length(); let current_length = self.upcast().Length();
let delta = length as i32 - current_length as i32; let delta = length as i32 - current_length as i32;
match delta.cmp(&0) { match delta.cmp(&0) {
@ -140,7 +147,7 @@ impl HTMLOptionsCollectionMethods for HTMLOptionsCollection {
}, },
Ordering::Greater => { Ordering::Greater => {
// new length is higher - adding new option elements // new length is higher - adding new option elements
self.add_new_elements(delta as u32).unwrap(); self.add_new_elements(delta as u32, can_gc).unwrap();
}, },
_ => {}, _ => {},
} }

View file

@ -53,6 +53,7 @@ impl HTMLOutputElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLOutputElement> { ) -> DomRoot<HTMLOutputElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLOutputElement::new_inherited( Box::new(HTMLOutputElement::new_inherited(
@ -60,11 +61,12 @@ impl HTMLOutputElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
pub fn reset(&self) { pub fn reset(&self, can_gc: CanGc) {
Node::string_replace_all(self.DefaultValue(), self.upcast::<Node>()); Node::string_replace_all(self.DefaultValue(), self.upcast::<Node>(), can_gc);
*self.default_value_override.borrow_mut() = None; *self.default_value_override.borrow_mut() = None;
} }
} }
@ -89,10 +91,10 @@ impl HTMLOutputElementMethods for HTMLOutputElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-output-defaultvalue // https://html.spec.whatwg.org/multipage/#dom-output-defaultvalue
fn SetDefaultValue(&self, value: DOMString) { fn SetDefaultValue(&self, value: DOMString, can_gc: CanGc) {
if self.default_value_override.borrow().is_none() { if self.default_value_override.borrow().is_none() {
// Step 1 ("and return") // Step 1 ("and return")
Node::string_replace_all(value.clone(), self.upcast::<Node>()); Node::string_replace_all(value.clone(), self.upcast::<Node>(), can_gc);
} else { } else {
// Step 2, if not returned from step 1 // Step 2, if not returned from step 1
*self.default_value_override.borrow_mut() = Some(value); *self.default_value_override.borrow_mut() = Some(value);
@ -105,9 +107,9 @@ impl HTMLOutputElementMethods for HTMLOutputElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-output-value // https://html.spec.whatwg.org/multipage/#dom-output-value
fn SetValue(&self, value: DOMString) { fn SetValue(&self, value: DOMString, can_gc: CanGc) {
*self.default_value_override.borrow_mut() = Some(self.DefaultValue()); *self.default_value_override.borrow_mut() = Some(self.DefaultValue());
Node::string_replace_all(value, self.upcast::<Node>()); Node::string_replace_all(value, self.upcast::<Node>(), can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-output-type // https://html.spec.whatwg.org/multipage/#dom-output-type

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLParagraphElement { pub struct HTMLParagraphElement {
@ -33,6 +34,7 @@ impl HTMLParagraphElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLParagraphElement> { ) -> DomRoot<HTMLParagraphElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLParagraphElement::new_inherited( Box::new(HTMLParagraphElement::new_inherited(
@ -40,6 +42,7 @@ impl HTMLParagraphElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLParamElement { pub struct HTMLParamElement {
@ -33,6 +34,7 @@ impl HTMLParamElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLParamElement> { ) -> DomRoot<HTMLParamElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLParamElement::new_inherited( Box::new(HTMLParamElement::new_inherited(
@ -40,6 +42,7 @@ impl HTMLParamElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLPictureElement { pub struct HTMLPictureElement {
@ -33,6 +34,7 @@ impl HTMLPictureElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLPictureElement> { ) -> DomRoot<HTMLPictureElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLPictureElement::new_inherited( Box::new(HTMLPictureElement::new_inherited(
@ -40,6 +42,7 @@ impl HTMLPictureElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -15,6 +15,7 @@ use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLPreElement { pub struct HTMLPreElement {
@ -38,11 +39,13 @@ impl HTMLPreElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLPreElement> { ) -> DomRoot<HTMLPreElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLPreElement::new_inherited(local_name, prefix, document)), Box::new(HTMLPreElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -16,6 +16,7 @@ use crate::dom::element::Element;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::dom::nodelist::NodeList; use crate::dom::nodelist::NodeList;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLProgressElement { pub struct HTMLProgressElement {
@ -41,6 +42,7 @@ impl HTMLProgressElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLProgressElement> { ) -> DomRoot<HTMLProgressElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLProgressElement::new_inherited( Box::new(HTMLProgressElement::new_inherited(
@ -48,6 +50,7 @@ impl HTMLProgressElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }
@ -77,14 +80,17 @@ impl HTMLProgressElementMethods for HTMLProgressElement {
} }
/// <https://html.spec.whatwg.org/multipage/#dom-progress-value> /// <https://html.spec.whatwg.org/multipage/#dom-progress-value>
fn SetValue(&self, new_val: Finite<f64>) { fn SetValue(&self, new_val: Finite<f64>, can_gc: CanGc) {
if *new_val >= 0.0 { if *new_val >= 0.0 {
let mut string_value = DOMString::from_string((*new_val).to_string()); let mut string_value = DOMString::from_string((*new_val).to_string());
string_value.set_best_representation_of_the_floating_point_number(); string_value.set_best_representation_of_the_floating_point_number();
self.upcast::<Element>() self.upcast::<Element>().set_string_attribute(
.set_string_attribute(&local_name!("value"), string_value); &local_name!("value"),
string_value,
can_gc,
);
} }
} }
@ -106,14 +112,17 @@ impl HTMLProgressElementMethods for HTMLProgressElement {
} }
/// <https://html.spec.whatwg.org/multipage/#dom-progress-max> /// <https://html.spec.whatwg.org/multipage/#dom-progress-max>
fn SetMax(&self, new_val: Finite<f64>) { fn SetMax(&self, new_val: Finite<f64>, can_gc: CanGc) {
if *new_val > 0.0 { if *new_val > 0.0 {
let mut string_value = DOMString::from_string((*new_val).to_string()); let mut string_value = DOMString::from_string((*new_val).to_string());
string_value.set_best_representation_of_the_floating_point_number(); string_value.set_best_representation_of_the_floating_point_number();
self.upcast::<Element>() self.upcast::<Element>().set_string_attribute(
.set_string_attribute(&local_name!("max"), string_value); &local_name!("max"),
string_value,
can_gc,
);
} }
} }

View file

@ -12,6 +12,7 @@ use crate::dom::bindings::str::USVString;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLQuoteElement { pub struct HTMLQuoteElement {
@ -35,6 +36,7 @@ impl HTMLQuoteElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLQuoteElement> { ) -> DomRoot<HTMLQuoteElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLQuoteElement::new_inherited( Box::new(HTMLQuoteElement::new_inherited(
@ -42,6 +44,7 @@ impl HTMLQuoteElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -193,6 +193,7 @@ impl HTMLScriptElement {
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
creator: ElementCreator, creator: ElementCreator,
can_gc: CanGc,
) -> DomRoot<HTMLScriptElement> { ) -> DomRoot<HTMLScriptElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLScriptElement::new_inherited( Box::new(HTMLScriptElement::new_inherited(
@ -200,6 +201,7 @@ impl HTMLScriptElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
@ -1311,10 +1313,10 @@ impl HTMLScriptElementMethods for HTMLScriptElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-script-async // https://html.spec.whatwg.org/multipage/#dom-script-async
fn SetAsync(&self, value: bool) { fn SetAsync(&self, value: bool, can_gc: CanGc) {
self.non_blocking.set(false); self.non_blocking.set(false);
self.upcast::<Element>() self.upcast::<Element>()
.set_bool_attribute(&local_name!("async"), value); .set_bool_attribute(&local_name!("async"), value, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-script-defer // https://html.spec.whatwg.org/multipage/#dom-script-defer
@ -1348,8 +1350,8 @@ impl HTMLScriptElementMethods for HTMLScriptElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-script-crossorigin // https://html.spec.whatwg.org/multipage/#dom-script-crossorigin
fn SetCrossOrigin(&self, value: Option<DOMString>) { fn SetCrossOrigin(&self, value: Option<DOMString>, can_gc: CanGc) {
set_cross_origin_attribute(self.upcast::<Element>(), value); set_cross_origin_attribute(self.upcast::<Element>(), value, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#dom-script-referrerpolicy // https://html.spec.whatwg.org/multipage/#dom-script-referrerpolicy
@ -1366,8 +1368,8 @@ impl HTMLScriptElementMethods for HTMLScriptElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-script-text // https://html.spec.whatwg.org/multipage/#dom-script-text
fn SetText(&self, value: DOMString) { fn SetText(&self, value: DOMString, can_gc: CanGc) {
self.upcast::<Node>().SetTextContent(Some(value)) self.upcast::<Node>().SetTextContent(Some(value), can_gc)
} }
} }

View file

@ -98,6 +98,7 @@ impl HTMLSelectElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLSelectElement> { ) -> DomRoot<HTMLSelectElement> {
let n = Node::reflect_node_with_proto( let n = Node::reflect_node_with_proto(
Box::new(HTMLSelectElement::new_inherited( Box::new(HTMLSelectElement::new_inherited(
@ -105,6 +106,7 @@ impl HTMLSelectElement {
)), )),
document, document,
proto, proto,
can_gc,
); );
n.upcast::<Node>().set_weird_parser_insertion_mode(); n.upcast::<Node>().set_weird_parser_insertion_mode();
@ -288,8 +290,8 @@ impl HTMLSelectElementMethods for HTMLSelectElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-select-length // https://html.spec.whatwg.org/multipage/#dom-select-length
fn SetLength(&self, length: u32) { fn SetLength(&self, length: u32, can_gc: CanGc) {
self.Options().SetLength(length) self.Options().SetLength(length, can_gc)
} }
// https://html.spec.whatwg.org/multipage/#dom-select-item // https://html.spec.whatwg.org/multipage/#dom-select-item
@ -303,8 +305,13 @@ impl HTMLSelectElementMethods for HTMLSelectElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-select-setter // https://html.spec.whatwg.org/multipage/#dom-select-setter
fn IndexedSetter(&self, index: u32, value: Option<&HTMLOptionElement>) -> ErrorResult { fn IndexedSetter(
self.Options().IndexedSetter(index, value) &self,
index: u32,
value: Option<&HTMLOptionElement>,
can_gc: CanGc,
) -> ErrorResult {
self.Options().IndexedSetter(index, value, can_gc)
} }
// https://html.spec.whatwg.org/multipage/#dom-select-nameditem // https://html.spec.whatwg.org/multipage/#dom-select-nameditem

View file

@ -43,6 +43,7 @@ impl HTMLSourceElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLSourceElement> { ) -> DomRoot<HTMLSourceElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLSourceElement::new_inherited( Box::new(HTMLSourceElement::new_inherited(
@ -50,6 +51,7 @@ impl HTMLSourceElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLSpanElement { pub struct HTMLSpanElement {
@ -33,11 +34,13 @@ impl HTMLSpanElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLSpanElement> { ) -> DomRoot<HTMLSpanElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLSpanElement::new_inherited(local_name, prefix, document)), Box::new(HTMLSpanElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -30,6 +30,7 @@ use crate::dom::node::{
}; };
use crate::dom::stylesheet::StyleSheet as DOMStyleSheet; use crate::dom::stylesheet::StyleSheet as DOMStyleSheet;
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
use crate::stylesheet_loader::{StylesheetLoader, StylesheetOwner}; use crate::stylesheet_loader::{StylesheetLoader, StylesheetOwner};
#[dom_struct] #[dom_struct]
@ -73,6 +74,7 @@ impl HTMLStyleElement {
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
creator: ElementCreator, creator: ElementCreator,
can_gc: CanGc,
) -> DomRoot<HTMLStyleElement> { ) -> DomRoot<HTMLStyleElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLStyleElement::new_inherited( Box::new(HTMLStyleElement::new_inherited(
@ -80,6 +82,7 @@ impl HTMLStyleElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }

View file

@ -11,6 +11,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLTableCaptionElement { pub struct HTMLTableCaptionElement {
@ -34,6 +35,7 @@ impl HTMLTableCaptionElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableCaptionElement> { ) -> DomRoot<HTMLTableCaptionElement> {
let n = Node::reflect_node_with_proto( let n = Node::reflect_node_with_proto(
Box::new(HTMLTableCaptionElement::new_inherited( Box::new(HTMLTableCaptionElement::new_inherited(
@ -41,6 +43,7 @@ impl HTMLTableCaptionElement {
)), )),
document, document,
proto, proto,
can_gc,
); );
n.upcast::<Node>().set_weird_parser_insertion_mode(); n.upcast::<Node>().set_weird_parser_insertion_mode();

View file

@ -22,6 +22,7 @@ use crate::dom::htmltablerowelement::HTMLTableRowElement;
use crate::dom::htmltablesectionelement::HTMLTableSectionElement; use crate::dom::htmltablesectionelement::HTMLTableSectionElement;
use crate::dom::node::{LayoutNodeHelpers, Node}; use crate::dom::node::{LayoutNodeHelpers, Node};
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
const DEFAULT_COLSPAN: u32 = 1; const DEFAULT_COLSPAN: u32 = 1;
const DEFAULT_ROWSPAN: u32 = 1; const DEFAULT_ROWSPAN: u32 = 1;
@ -48,6 +49,7 @@ impl HTMLTableCellElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableCellElement> { ) -> DomRoot<HTMLTableCellElement> {
let n = Node::reflect_node_with_proto( let n = Node::reflect_node_with_proto(
Box::new(HTMLTableCellElement::new_inherited( Box::new(HTMLTableCellElement::new_inherited(
@ -55,6 +57,7 @@ impl HTMLTableCellElement {
)), )),
document, document,
proto, proto,
can_gc,
); );
n.upcast::<Node>().set_weird_parser_insertion_mode(); n.upcast::<Node>().set_weird_parser_insertion_mode();

View file

@ -18,6 +18,7 @@ use crate::dom::element::LayoutElementHelpers;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
const DEFAULT_SPAN: u32 = 1; const DEFAULT_SPAN: u32 = 1;
@ -43,6 +44,7 @@ impl HTMLTableColElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableColElement> { ) -> DomRoot<HTMLTableColElement> {
let n = Node::reflect_node_with_proto( let n = Node::reflect_node_with_proto(
Box::new(HTMLTableColElement::new_inherited( Box::new(HTMLTableColElement::new_inherited(
@ -50,6 +52,7 @@ impl HTMLTableColElement {
)), )),
document, document,
proto, proto,
can_gc,
); );
n.upcast::<Node>().set_weird_parser_insertion_mode(); n.upcast::<Node>().set_weird_parser_insertion_mode();

View file

@ -28,6 +28,7 @@ use crate::dom::htmltablerowelement::HTMLTableRowElement;
use crate::dom::htmltablesectionelement::HTMLTableSectionElement; use crate::dom::htmltablesectionelement::HTMLTableSectionElement;
use crate::dom::node::{document_from_node, window_from_node, Node}; use crate::dom::node::{document_from_node, window_from_node, Node};
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLTableElement { pub struct HTMLTableElement {
@ -75,6 +76,7 @@ impl HTMLTableElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableElement> { ) -> DomRoot<HTMLTableElement> {
let n = Node::reflect_node_with_proto( let n = Node::reflect_node_with_proto(
Box::new(HTMLTableElement::new_inherited( Box::new(HTMLTableElement::new_inherited(
@ -82,6 +84,7 @@ impl HTMLTableElement {
)), )),
document, document,
proto, proto,
can_gc,
); );
n.upcast::<Node>().set_weird_parser_insertion_mode(); n.upcast::<Node>().set_weird_parser_insertion_mode();
@ -137,13 +140,22 @@ impl HTMLTableElement {
// https://html.spec.whatwg.org/multipage/#dom-table-createthead // https://html.spec.whatwg.org/multipage/#dom-table-createthead
// https://html.spec.whatwg.org/multipage/#dom-table-createtfoot // https://html.spec.whatwg.org/multipage/#dom-table-createtfoot
fn create_section_of_type(&self, atom: &LocalName) -> DomRoot<HTMLTableSectionElement> { fn create_section_of_type(
&self,
atom: &LocalName,
can_gc: CanGc,
) -> DomRoot<HTMLTableSectionElement> {
if let Some(section) = self.get_first_section_of_type(atom) { if let Some(section) = self.get_first_section_of_type(atom) {
return section; return section;
} }
let section = let section = HTMLTableSectionElement::new(
HTMLTableSectionElement::new(atom.clone(), None, &document_from_node(self), None); atom.clone(),
None,
&document_from_node(self),
None,
can_gc,
);
match *atom { match *atom {
local_name!("thead") => self.SetTHead(Some(&section)), local_name!("thead") => self.SetTHead(Some(&section)),
local_name!("tfoot") => self.SetTFoot(Some(&section)), local_name!("tfoot") => self.SetTFoot(Some(&section)),
@ -206,7 +218,7 @@ impl HTMLTableElementMethods for HTMLTableElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-table-createcaption // https://html.spec.whatwg.org/multipage/#dom-table-createcaption
fn CreateCaption(&self) -> DomRoot<HTMLTableCaptionElement> { fn CreateCaption(&self, can_gc: CanGc) -> DomRoot<HTMLTableCaptionElement> {
match self.GetCaption() { match self.GetCaption() {
Some(caption) => caption, Some(caption) => caption,
None => { None => {
@ -215,6 +227,7 @@ impl HTMLTableElementMethods for HTMLTableElement {
None, None,
&document_from_node(self), &document_from_node(self),
None, None,
can_gc,
); );
self.SetCaption(Some(&caption)) self.SetCaption(Some(&caption))
.expect("Generated caption is invalid"); .expect("Generated caption is invalid");
@ -243,8 +256,8 @@ impl HTMLTableElementMethods for HTMLTableElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-table-createthead // https://html.spec.whatwg.org/multipage/#dom-table-createthead
fn CreateTHead(&self) -> DomRoot<HTMLTableSectionElement> { fn CreateTHead(&self, can_gc: CanGc) -> DomRoot<HTMLTableSectionElement> {
self.create_section_of_type(&local_name!("thead")) self.create_section_of_type(&local_name!("thead"), can_gc)
} }
// https://html.spec.whatwg.org/multipage/#dom-table-deletethead // https://html.spec.whatwg.org/multipage/#dom-table-deletethead
@ -276,8 +289,8 @@ impl HTMLTableElementMethods for HTMLTableElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-table-createtfoot // https://html.spec.whatwg.org/multipage/#dom-table-createtfoot
fn CreateTFoot(&self) -> DomRoot<HTMLTableSectionElement> { fn CreateTFoot(&self, can_gc: CanGc) -> DomRoot<HTMLTableSectionElement> {
self.create_section_of_type(&local_name!("tfoot")) self.create_section_of_type(&local_name!("tfoot"), can_gc)
} }
// https://html.spec.whatwg.org/multipage/#dom-table-deletetfoot // https://html.spec.whatwg.org/multipage/#dom-table-deletetfoot
@ -305,12 +318,13 @@ impl HTMLTableElementMethods for HTMLTableElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-table-createtbody // https://html.spec.whatwg.org/multipage/#dom-table-createtbody
fn CreateTBody(&self) -> DomRoot<HTMLTableSectionElement> { fn CreateTBody(&self, can_gc: CanGc) -> DomRoot<HTMLTableSectionElement> {
let tbody = HTMLTableSectionElement::new( let tbody = HTMLTableSectionElement::new(
local_name!("tbody"), local_name!("tbody"),
None, None,
&document_from_node(self), &document_from_node(self),
None, None,
can_gc,
); );
let node = self.upcast::<Node>(); let node = self.upcast::<Node>();
let last_tbody = node let last_tbody = node
@ -325,7 +339,7 @@ impl HTMLTableElementMethods for HTMLTableElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-table-insertrow // https://html.spec.whatwg.org/multipage/#dom-table-insertrow
fn InsertRow(&self, index: i32) -> Fallible<DomRoot<HTMLTableRowElement>> { fn InsertRow(&self, index: i32, can_gc: CanGc) -> Fallible<DomRoot<HTMLTableRowElement>> {
let rows = self.Rows(); let rows = self.Rows();
let number_of_row_elements = rows.Length(); let number_of_row_elements = rows.Length();
@ -333,8 +347,13 @@ impl HTMLTableElementMethods for HTMLTableElement {
return Err(Error::IndexSize); return Err(Error::IndexSize);
} }
let new_row = let new_row = HTMLTableRowElement::new(
HTMLTableRowElement::new(local_name!("tr"), None, &document_from_node(self), None); local_name!("tr"),
None,
&document_from_node(self),
None,
can_gc,
);
let node = self.upcast::<Node>(); let node = self.upcast::<Node>();
if number_of_row_elements == 0 { if number_of_row_elements == 0 {
@ -351,7 +370,7 @@ impl HTMLTableElementMethods for HTMLTableElement {
.AppendChild(new_row.upcast::<Node>()) .AppendChild(new_row.upcast::<Node>())
.expect("InsertRow failed to append first row."); .expect("InsertRow failed to append first row.");
} else { } else {
let tbody = self.CreateTBody(); let tbody = self.CreateTBody(can_gc);
node.AppendChild(tbody.upcast()) node.AppendChild(tbody.upcast())
.expect("InsertRow failed to append new tbody."); .expect("InsertRow failed to append new tbody.");

View file

@ -25,6 +25,7 @@ use crate::dom::htmltableelement::HTMLTableElement;
use crate::dom::htmltablesectionelement::HTMLTableSectionElement; use crate::dom::htmltablesectionelement::HTMLTableSectionElement;
use crate::dom::node::{window_from_node, Node}; use crate::dom::node::{window_from_node, Node};
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[derive(JSTraceable)] #[derive(JSTraceable)]
struct CellsFilter; struct CellsFilter;
@ -59,6 +60,7 @@ impl HTMLTableRowElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableRowElement> { ) -> DomRoot<HTMLTableRowElement> {
let n = Node::reflect_node_with_proto( let n = Node::reflect_node_with_proto(
Box::new(HTMLTableRowElement::new_inherited( Box::new(HTMLTableRowElement::new_inherited(
@ -66,6 +68,7 @@ impl HTMLTableRowElement {
)), )),
document, document,
proto, proto,
can_gc,
); );
n.upcast::<Node>().set_weird_parser_insertion_mode(); n.upcast::<Node>().set_weird_parser_insertion_mode();
@ -99,12 +102,12 @@ impl HTMLTableRowElementMethods for HTMLTableRowElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-tr-insertcell // https://html.spec.whatwg.org/multipage/#dom-tr-insertcell
fn InsertCell(&self, index: i32) -> Fallible<DomRoot<HTMLElement>> { fn InsertCell(&self, index: i32, can_gc: CanGc) -> Fallible<DomRoot<HTMLElement>> {
let node = self.upcast::<Node>(); let node = self.upcast::<Node>();
node.insert_cell_or_row( node.insert_cell_or_row(
index, index,
|| self.Cells(), || self.Cells(),
|| HTMLTableCellElement::new(local_name!("td"), None, &node.owner_doc(), None), || HTMLTableCellElement::new(local_name!("td"), None, &node.owner_doc(), None, can_gc),
) )
} }

View file

@ -21,6 +21,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::htmltablerowelement::HTMLTableRowElement; use crate::dom::htmltablerowelement::HTMLTableRowElement;
use crate::dom::node::{window_from_node, Node}; use crate::dom::node::{window_from_node, Node};
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLTableSectionElement { pub struct HTMLTableSectionElement {
@ -44,6 +45,7 @@ impl HTMLTableSectionElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTableSectionElement> { ) -> DomRoot<HTMLTableSectionElement> {
let n = Node::reflect_node_with_proto( let n = Node::reflect_node_with_proto(
Box::new(HTMLTableSectionElement::new_inherited( Box::new(HTMLTableSectionElement::new_inherited(
@ -51,6 +53,7 @@ impl HTMLTableSectionElement {
)), )),
document, document,
proto, proto,
can_gc,
); );
n.upcast::<Node>().set_weird_parser_insertion_mode(); n.upcast::<Node>().set_weird_parser_insertion_mode();
@ -74,12 +77,12 @@ impl HTMLTableSectionElementMethods for HTMLTableSectionElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-tbody-insertrow // https://html.spec.whatwg.org/multipage/#dom-tbody-insertrow
fn InsertRow(&self, index: i32) -> Fallible<DomRoot<HTMLElement>> { fn InsertRow(&self, index: i32, can_gc: CanGc) -> Fallible<DomRoot<HTMLElement>> {
let node = self.upcast::<Node>(); let node = self.upcast::<Node>();
node.insert_cell_or_row( node.insert_cell_or_row(
index, index,
|| self.Rows(), || self.Rows(),
|| HTMLTableRowElement::new(local_name!("tr"), None, &node.owner_doc(), None), || HTMLTableRowElement::new(local_name!("tr"), None, &node.owner_doc(), None, can_gc),
) )
} }

View file

@ -44,6 +44,7 @@ impl HTMLTemplateElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTemplateElement> { ) -> DomRoot<HTMLTemplateElement> {
let n = Node::reflect_node_with_proto( let n = Node::reflect_node_with_proto(
Box::new(HTMLTemplateElement::new_inherited( Box::new(HTMLTemplateElement::new_inherited(
@ -51,6 +52,7 @@ impl HTMLTemplateElement {
)), )),
document, document,
proto, proto,
can_gc,
); );
n.upcast::<Node>().set_weird_parser_insertion_mode(); n.upcast::<Node>().set_weird_parser_insertion_mode();
@ -64,7 +66,7 @@ impl HTMLTemplateElementMethods for HTMLTemplateElement {
self.contents.or_init(|| { self.contents.or_init(|| {
let doc = document_from_node(self); let doc = document_from_node(self);
doc.appropriate_template_contents_owner_document(can_gc) doc.appropriate_template_contents_owner_document(can_gc)
.CreateDocumentFragment() .CreateDocumentFragment(can_gc)
}) })
} }
} }

View file

@ -176,6 +176,7 @@ impl HTMLTextAreaElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTextAreaElement> { ) -> DomRoot<HTMLTextAreaElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLTextAreaElement::new_inherited( Box::new(HTMLTextAreaElement::new_inherited(
@ -183,6 +184,7 @@ impl HTMLTextAreaElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
@ -306,8 +308,8 @@ impl HTMLTextAreaElementMethods for HTMLTextAreaElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-textarea-defaultvalue // https://html.spec.whatwg.org/multipage/#dom-textarea-defaultvalue
fn SetDefaultValue(&self, value: DOMString) { fn SetDefaultValue(&self, value: DOMString, can_gc: CanGc) {
self.upcast::<Node>().SetTextContent(Some(value)); self.upcast::<Node>().SetTextContent(Some(value), can_gc);
// if the element's dirty value flag is false, then the element's // if the element's dirty value flag is false, then the element's
// raw value must be set to the value of the element's textContent IDL attribute // raw value must be set to the value of the element's textContent IDL attribute

View file

@ -12,6 +12,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLTimeElement { pub struct HTMLTimeElement {
@ -35,11 +36,13 @@ impl HTMLTimeElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTimeElement> { ) -> DomRoot<HTMLTimeElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLTimeElement::new_inherited(local_name, prefix, document)), Box::new(HTMLTimeElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -17,6 +17,7 @@ use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{BindContext, ChildrenMutation, Node}; use crate::dom::node::{BindContext, ChildrenMutation, Node};
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLTitleElement { pub struct HTMLTitleElement {
@ -42,6 +43,7 @@ impl HTMLTitleElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTitleElement> { ) -> DomRoot<HTMLTitleElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLTitleElement::new_inherited( Box::new(HTMLTitleElement::new_inherited(
@ -49,6 +51,7 @@ impl HTMLTitleElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
@ -67,8 +70,8 @@ impl HTMLTitleElementMethods for HTMLTitleElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-title-text // https://html.spec.whatwg.org/multipage/#dom-title-text
fn SetText(&self, value: DOMString) { fn SetText(&self, value: DOMString, can_gc: CanGc) {
self.upcast::<Node>().SetTextContent(Some(value)) self.upcast::<Node>().SetTextContent(Some(value), can_gc)
} }
} }

View file

@ -17,6 +17,7 @@ use crate::dom::element::Element;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::dom::texttrack::TextTrack; use crate::dom::texttrack::TextTrack;
use crate::script_runtime::CanGc;
#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)] #[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
#[repr(u16)] #[repr(u16)]
@ -54,6 +55,7 @@ impl HTMLTrackElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLTrackElement> { ) -> DomRoot<HTMLTrackElement> {
let track = TextTrack::new( let track = TextTrack::new(
document.window(), document.window(),
@ -70,6 +72,7 @@ impl HTMLTrackElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -12,6 +12,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLUListElement { pub struct HTMLUListElement {
@ -35,6 +36,7 @@ impl HTMLUListElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLUListElement> { ) -> DomRoot<HTMLUListElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLUListElement::new_inherited( Box::new(HTMLUListElement::new_inherited(
@ -42,6 +44,7 @@ impl HTMLUListElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct HTMLUnknownElement { pub struct HTMLUnknownElement {
@ -33,6 +34,7 @@ impl HTMLUnknownElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLUnknownElement> { ) -> DomRoot<HTMLUnknownElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLUnknownElement::new_inherited( Box::new(HTMLUnknownElement::new_inherited(
@ -40,6 +42,7 @@ impl HTMLUnknownElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -89,6 +89,7 @@ impl HTMLVideoElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<HTMLVideoElement> { ) -> DomRoot<HTMLVideoElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(HTMLVideoElement::new_inherited( Box::new(HTMLVideoElement::new_inherited(
@ -96,6 +97,7 @@ impl HTMLVideoElement {
)), )),
document, document,
proto, proto,
can_gc,
) )
} }

View file

@ -32,6 +32,7 @@ macro_rules! make_limited_int_setter(
fn $attr(&self, value: i32) -> $crate::dom::bindings::error::ErrorResult { fn $attr(&self, value: i32) -> $crate::dom::bindings::error::ErrorResult {
use $crate::dom::bindings::inheritance::Castable; use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element; use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let value = if value < 0 { let value = if value < 0 {
return Err($crate::dom::bindings::error::Error::IndexSize); return Err($crate::dom::bindings::error::Error::IndexSize);
@ -40,7 +41,7 @@ macro_rules! make_limited_int_setter(
}; };
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
element.set_int_attribute(&html5ever::local_name!($htmlname), value); element.set_int_attribute(&html5ever::local_name!($htmlname), value, CanGc::note());
Ok(()) Ok(())
} }
); );
@ -52,9 +53,10 @@ macro_rules! make_int_setter(
fn $attr(&self, value: i32) { fn $attr(&self, value: i32) {
use $crate::dom::bindings::inheritance::Castable; use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element; use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
element.set_int_attribute(&html5ever::local_name!($htmlname), value) element.set_int_attribute(&html5ever::local_name!($htmlname), value, CanGc::note())
} }
); );
($attr:ident, $htmlname:tt) => { ($attr:ident, $htmlname:tt) => {
@ -111,9 +113,10 @@ macro_rules! make_url_setter(
fn $attr(&self, value: USVString) { fn $attr(&self, value: USVString) {
use $crate::dom::bindings::inheritance::Castable; use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element; use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
element.set_url_attribute(&html5ever::local_name!($htmlname), element.set_url_attribute(&html5ever::local_name!($htmlname),
value); value, CanGc::note());
} }
); );
); );
@ -181,8 +184,9 @@ macro_rules! make_setter(
fn $attr(&self, value: DOMString) { fn $attr(&self, value: DOMString) {
use $crate::dom::bindings::inheritance::Castable; use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element; use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
element.set_string_attribute(&html5ever::local_name!($htmlname), value) element.set_string_attribute(&html5ever::local_name!($htmlname), value, CanGc::note())
} }
); );
); );
@ -193,8 +197,9 @@ macro_rules! make_bool_setter(
fn $attr(&self, value: bool) { fn $attr(&self, value: bool) {
use $crate::dom::bindings::inheritance::Castable; use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element; use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
element.set_bool_attribute(&html5ever::local_name!($htmlname), value) element.set_bool_attribute(&html5ever::local_name!($htmlname), value, CanGc::note())
} }
); );
); );
@ -206,13 +211,14 @@ macro_rules! make_uint_setter(
use $crate::dom::bindings::inheritance::Castable; use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element; use $crate::dom::element::Element;
use $crate::dom::values::UNSIGNED_LONG_MAX; use $crate::dom::values::UNSIGNED_LONG_MAX;
use $crate::script_runtime::CanGc;
let value = if value > UNSIGNED_LONG_MAX { let value = if value > UNSIGNED_LONG_MAX {
$default $default
} else { } else {
value value
}; };
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
element.set_uint_attribute(&html5ever::local_name!($htmlname), value) element.set_uint_attribute(&html5ever::local_name!($htmlname), value, CanGc::note())
} }
); );
($attr:ident, $htmlname:tt) => { ($attr:ident, $htmlname:tt) => {
@ -227,6 +233,7 @@ macro_rules! make_limited_uint_setter(
use $crate::dom::bindings::inheritance::Castable; use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element; use $crate::dom::element::Element;
use $crate::dom::values::UNSIGNED_LONG_MAX; use $crate::dom::values::UNSIGNED_LONG_MAX;
use $crate::script_runtime::CanGc;
let value = if value == 0 { let value = if value == 0 {
return Err($crate::dom::bindings::error::Error::IndexSize); return Err($crate::dom::bindings::error::Error::IndexSize);
} else if value > UNSIGNED_LONG_MAX { } else if value > UNSIGNED_LONG_MAX {
@ -235,7 +242,7 @@ macro_rules! make_limited_uint_setter(
value value
}; };
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
element.set_uint_attribute(&html5ever::local_name!($htmlname), value); element.set_uint_attribute(&html5ever::local_name!($htmlname), value, CanGc::note());
Ok(()) Ok(())
} }
); );
@ -250,8 +257,9 @@ macro_rules! make_atomic_setter(
fn $attr(&self, value: DOMString) { fn $attr(&self, value: DOMString) {
use $crate::dom::bindings::inheritance::Castable; use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element; use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
element.set_atomic_attribute(&html5ever::local_name!($htmlname), value) element.set_atomic_attribute(&html5ever::local_name!($htmlname), value, CanGc::note())
} }
); );
); );
@ -263,9 +271,10 @@ macro_rules! make_legacy_color_setter(
use $crate::dom::bindings::inheritance::Castable; use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element; use $crate::dom::element::Element;
use style::attr::AttrValue; use style::attr::AttrValue;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
let value = AttrValue::from_legacy_color(value.into()); let value = AttrValue::from_legacy_color(value.into());
element.set_attribute(&html5ever::local_name!($htmlname), value) element.set_attribute(&html5ever::local_name!($htmlname), value, CanGc::note())
} }
); );
); );
@ -276,9 +285,10 @@ macro_rules! make_dimension_setter(
fn $attr(&self, value: DOMString) { fn $attr(&self, value: DOMString) {
use $crate::dom::bindings::inheritance::Castable; use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element; use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
let value = AttrValue::from_dimension(value.into()); let value = AttrValue::from_dimension(value.into());
element.set_attribute(&html5ever::local_name!($htmlname), value) element.set_attribute(&html5ever::local_name!($htmlname), value, CanGc::note())
} }
); );
); );
@ -289,9 +299,10 @@ macro_rules! make_nonzero_dimension_setter(
fn $attr(&self, value: DOMString) { fn $attr(&self, value: DOMString) {
use $crate::dom::bindings::inheritance::Castable; use $crate::dom::bindings::inheritance::Castable;
use $crate::dom::element::Element; use $crate::dom::element::Element;
use $crate::script_runtime::CanGc;
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
let value = AttrValue::from_nonzero_dimension(value.into()); let value = AttrValue::from_nonzero_dimension(value.into());
element.set_attribute(&html5ever::local_name!($htmlname), value) element.set_attribute(&html5ever::local_name!($htmlname), value, CanGc::note())
} }
); );
); );

View file

@ -857,7 +857,7 @@ impl Node {
} }
/// <https://dom.spec.whatwg.org/#dom-childnode-before> /// <https://dom.spec.whatwg.org/#dom-childnode-before>
pub fn before(&self, nodes: Vec<NodeOrString>) -> ErrorResult { pub fn before(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
// Step 1. // Step 1.
let parent = &self.parent_node; let parent = &self.parent_node;
@ -871,7 +871,9 @@ impl Node {
let viable_previous_sibling = first_node_not_in(self.preceding_siblings(), &nodes); let viable_previous_sibling = first_node_not_in(self.preceding_siblings(), &nodes);
// Step 4. // Step 4.
let node = self.owner_doc().node_from_nodes_and_strings(nodes)?; let node = self
.owner_doc()
.node_from_nodes_and_strings(nodes, can_gc)?;
// Step 5. // Step 5.
let viable_previous_sibling = match viable_previous_sibling { let viable_previous_sibling = match viable_previous_sibling {
@ -886,7 +888,7 @@ impl Node {
} }
/// <https://dom.spec.whatwg.org/#dom-childnode-after> /// <https://dom.spec.whatwg.org/#dom-childnode-after>
pub fn after(&self, nodes: Vec<NodeOrString>) -> ErrorResult { pub fn after(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
// Step 1. // Step 1.
let parent = &self.parent_node; let parent = &self.parent_node;
@ -900,7 +902,9 @@ impl Node {
let viable_next_sibling = first_node_not_in(self.following_siblings(), &nodes); let viable_next_sibling = first_node_not_in(self.following_siblings(), &nodes);
// Step 4. // Step 4.
let node = self.owner_doc().node_from_nodes_and_strings(nodes)?; let node = self
.owner_doc()
.node_from_nodes_and_strings(nodes, can_gc)?;
// Step 5. // Step 5.
Node::pre_insert(&node, &parent, viable_next_sibling.as_deref())?; Node::pre_insert(&node, &parent, viable_next_sibling.as_deref())?;
@ -909,7 +913,7 @@ impl Node {
} }
/// <https://dom.spec.whatwg.org/#dom-childnode-replacewith> /// <https://dom.spec.whatwg.org/#dom-childnode-replacewith>
pub fn replace_with(&self, nodes: Vec<NodeOrString>) -> ErrorResult { pub fn replace_with(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
// Step 1. // Step 1.
let parent = if let Some(parent) = self.GetParentNode() { let parent = if let Some(parent) = self.GetParentNode() {
parent parent
@ -920,7 +924,9 @@ impl Node {
// Step 3. // Step 3.
let viable_next_sibling = first_node_not_in(self.following_siblings(), &nodes); let viable_next_sibling = first_node_not_in(self.following_siblings(), &nodes);
// Step 4. // Step 4.
let node = self.owner_doc().node_from_nodes_and_strings(nodes)?; let node = self
.owner_doc()
.node_from_nodes_and_strings(nodes, can_gc)?;
if self.parent_node == Some(&*parent) { if self.parent_node == Some(&*parent) {
// Step 5. // Step 5.
parent.ReplaceChild(&node, self)?; parent.ReplaceChild(&node, self)?;
@ -932,29 +938,29 @@ impl Node {
} }
/// <https://dom.spec.whatwg.org/#dom-parentnode-prepend> /// <https://dom.spec.whatwg.org/#dom-parentnode-prepend>
pub fn prepend(&self, nodes: Vec<NodeOrString>) -> ErrorResult { pub fn prepend(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
// Step 1. // Step 1.
let doc = self.owner_doc(); let doc = self.owner_doc();
let node = doc.node_from_nodes_and_strings(nodes)?; let node = doc.node_from_nodes_and_strings(nodes, can_gc)?;
// Step 2. // Step 2.
let first_child = self.first_child.get(); let first_child = self.first_child.get();
Node::pre_insert(&node, self, first_child.as_deref()).map(|_| ()) Node::pre_insert(&node, self, first_child.as_deref()).map(|_| ())
} }
/// <https://dom.spec.whatwg.org/#dom-parentnode-append> /// <https://dom.spec.whatwg.org/#dom-parentnode-append>
pub fn append(&self, nodes: Vec<NodeOrString>) -> ErrorResult { pub fn append(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
// Step 1. // Step 1.
let doc = self.owner_doc(); let doc = self.owner_doc();
let node = doc.node_from_nodes_and_strings(nodes)?; let node = doc.node_from_nodes_and_strings(nodes, can_gc)?;
// Step 2. // Step 2.
self.AppendChild(&node).map(|_| ()) self.AppendChild(&node).map(|_| ())
} }
/// <https://dom.spec.whatwg.org/#dom-parentnode-replacechildren> /// <https://dom.spec.whatwg.org/#dom-parentnode-replacechildren>
pub fn replace_children(&self, nodes: Vec<NodeOrString>) -> ErrorResult { pub fn replace_children(&self, nodes: Vec<NodeOrString>, can_gc: CanGc) -> ErrorResult {
// Step 1. // Step 1.
let doc = self.owner_doc(); let doc = self.owner_doc();
let node = doc.node_from_nodes_and_strings(nodes)?; let node = doc.node_from_nodes_and_strings(nodes, can_gc)?;
// Step 2. // Step 2.
Node::ensure_pre_insertion_validity(&node, self, None)?; Node::ensure_pre_insertion_validity(&node, self, None)?;
// Step 3. // Step 3.
@ -1767,23 +1773,24 @@ fn as_uintptr<T>(t: &T) -> uintptr_t {
} }
impl Node { impl Node {
pub fn reflect_node<N>(node: Box<N>, document: &Document) -> DomRoot<N> pub fn reflect_node<N>(node: Box<N>, document: &Document, can_gc: CanGc) -> DomRoot<N>
where where
N: DerivedFrom<Node> + DomObject + DomObjectWrap, N: DerivedFrom<Node> + DomObject + DomObjectWrap,
{ {
Self::reflect_node_with_proto(node, document, None) Self::reflect_node_with_proto(node, document, None, can_gc)
} }
pub fn reflect_node_with_proto<N>( pub fn reflect_node_with_proto<N>(
node: Box<N>, node: Box<N>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<N> ) -> DomRoot<N>
where where
N: DerivedFrom<Node> + DomObject + DomObjectWrap, N: DerivedFrom<Node> + DomObject + DomObjectWrap,
{ {
let window = document.window(); let window = document.window();
reflect_dom_object_with_proto(node, window, proto, CanGc::note()) reflect_dom_object_with_proto(node, window, proto, can_gc)
} }
pub fn new_inherited(doc: &Document) -> Node { pub fn new_inherited(doc: &Document) -> Node {
@ -2151,11 +2158,11 @@ impl Node {
} }
/// <https://dom.spec.whatwg.org/multipage/#string-replace-all> /// <https://dom.spec.whatwg.org/multipage/#string-replace-all>
pub fn string_replace_all(string: DOMString, parent: &Node) { pub fn string_replace_all(string: DOMString, parent: &Node, can_gc: CanGc) {
if string.len() == 0 { if string.len() == 0 {
Node::replace_all(None, parent); Node::replace_all(None, parent);
} else { } else {
let text = Text::new(string, &document_from_node(parent)); let text = Text::new(string, &document_from_node(parent), can_gc);
Node::replace_all(Some(text.upcast::<Node>()), parent); Node::replace_all(Some(text.upcast::<Node>()), parent);
}; };
} }
@ -2250,6 +2257,7 @@ impl Node {
Some(doctype.public_id().clone()), Some(doctype.public_id().clone()),
Some(doctype.system_id().clone()), Some(doctype.system_id().clone()),
&document, &document,
can_gc,
); );
DomRoot::upcast::<Node>(doctype) DomRoot::upcast::<Node>(doctype)
}, },
@ -2263,16 +2271,17 @@ impl Node {
attr.namespace().clone(), attr.namespace().clone(),
attr.prefix().cloned(), attr.prefix().cloned(),
None, None,
can_gc,
); );
DomRoot::upcast::<Node>(attr) DomRoot::upcast::<Node>(attr)
}, },
NodeTypeId::DocumentFragment(_) => { NodeTypeId::DocumentFragment(_) => {
let doc_fragment = DocumentFragment::new(&document); let doc_fragment = DocumentFragment::new(&document, can_gc);
DomRoot::upcast::<Node>(doc_fragment) DomRoot::upcast::<Node>(doc_fragment)
}, },
NodeTypeId::CharacterData(_) => { NodeTypeId::CharacterData(_) => {
let cdata = node.downcast::<CharacterData>().unwrap(); let cdata = node.downcast::<CharacterData>().unwrap();
cdata.clone_with_data(cdata.Data(), &document) cdata.clone_with_data(cdata.Data(), &document, can_gc)
}, },
NodeTypeId::Document(_) => { NodeTypeId::Document(_) => {
let document = node.downcast::<Document>().unwrap(); let document = node.downcast::<Document>().unwrap();
@ -2349,6 +2358,7 @@ impl Node {
attr.name().clone(), attr.name().clone(),
attr.namespace().clone(), attr.namespace().clone(),
attr.prefix().cloned(), attr.prefix().cloned(),
can_gc,
); );
} }
}, },
@ -2610,7 +2620,7 @@ impl NodeMethods for Node {
} }
/// <https://dom.spec.whatwg.org/#dom-node-textcontent> /// <https://dom.spec.whatwg.org/#dom-node-textcontent>
fn SetTextContent(&self, value: Option<DOMString>) { fn SetTextContent(&self, value: Option<DOMString>, can_gc: CanGc) {
let value = value.unwrap_or_default(); let value = value.unwrap_or_default();
match self.type_id() { match self.type_id() {
NodeTypeId::DocumentFragment(_) | NodeTypeId::Element(..) => { NodeTypeId::DocumentFragment(_) | NodeTypeId::Element(..) => {
@ -2618,7 +2628,9 @@ impl NodeMethods for Node {
let node = if value.is_empty() { let node = if value.is_empty() {
None None
} else { } else {
Some(DomRoot::upcast(self.owner_doc().CreateTextNode(value))) Some(DomRoot::upcast(
self.owner_doc().CreateTextNode(value, can_gc),
))
}; };
// Step 3. // Step 3.

View file

@ -10,6 +10,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::characterdata::CharacterData; use crate::dom::characterdata::CharacterData;
use crate::dom::document::Document; use crate::dom::document::Document;
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::script_runtime::CanGc;
/// An HTML processing instruction node. /// An HTML processing instruction node.
#[dom_struct] #[dom_struct]
@ -34,10 +35,12 @@ impl ProcessingInstruction {
target: DOMString, target: DOMString,
data: DOMString, data: DOMString,
document: &Document, document: &Document,
can_gc: CanGc,
) -> DomRoot<ProcessingInstruction> { ) -> DomRoot<ProcessingInstruction> {
Node::reflect_node( Node::reflect_node(
Box::new(ProcessingInstruction::new_inherited(target, data, document)), Box::new(ProcessingInstruction::new_inherited(target, data, document)),
document, document,
can_gc,
) )
} }
} }

View file

@ -561,7 +561,7 @@ impl RangeMethods for Range {
let end_offset = self.end_offset(); let end_offset = self.end_offset();
// Step 1. // Step 1.
let fragment = DocumentFragment::new(&start_node.owner_doc()); let fragment = DocumentFragment::new(&start_node.owner_doc(), can_gc);
// Step 2. // Step 2.
if self.start() == self.end() { if self.start() == self.end() {
@ -574,7 +574,7 @@ impl RangeMethods for Range {
let data = cdata let data = cdata
.SubstringData(start_offset, end_offset - start_offset) .SubstringData(start_offset, end_offset - start_offset)
.unwrap(); .unwrap();
let clone = cdata.clone_with_data(data, &start_node.owner_doc()); let clone = cdata.clone_with_data(data, &start_node.owner_doc(), can_gc);
// Step 4.3. // Step 4.3.
fragment.upcast::<Node>().AppendChild(&clone)?; fragment.upcast::<Node>().AppendChild(&clone)?;
// Step 4.4 // Step 4.4
@ -597,7 +597,7 @@ impl RangeMethods for Range {
let data = cdata let data = cdata
.SubstringData(start_offset, start_node.len() - start_offset) .SubstringData(start_offset, start_node.len() - start_offset)
.unwrap(); .unwrap();
let clone = cdata.clone_with_data(data, &start_node.owner_doc()); let clone = cdata.clone_with_data(data, &start_node.owner_doc(), can_gc);
// Step 13.3. // Step 13.3.
fragment.upcast::<Node>().AppendChild(&clone)?; fragment.upcast::<Node>().AppendChild(&clone)?;
} else { } else {
@ -635,7 +635,7 @@ impl RangeMethods for Range {
assert!(child == end_node); assert!(child == end_node);
// Steps 16.1-2. // Steps 16.1-2.
let data = cdata.SubstringData(0, end_offset).unwrap(); let data = cdata.SubstringData(0, end_offset).unwrap();
let clone = cdata.clone_with_data(data, &start_node.owner_doc()); let clone = cdata.clone_with_data(data, &start_node.owner_doc(), can_gc);
// Step 16.3. // Step 16.3.
fragment.upcast::<Node>().AppendChild(&clone)?; fragment.upcast::<Node>().AppendChild(&clone)?;
} else { } else {
@ -667,7 +667,7 @@ impl RangeMethods for Range {
let end_offset = self.end_offset(); let end_offset = self.end_offset();
// Step 1. // Step 1.
let fragment = DocumentFragment::new(&start_node.owner_doc()); let fragment = DocumentFragment::new(&start_node.owner_doc(), can_gc);
// Step 2. // Step 2.
if self.collapsed() { if self.collapsed() {
@ -807,7 +807,7 @@ impl RangeMethods for Range {
/// <https://dom.spec.whatwg.org/#dom-range-insertnode> /// <https://dom.spec.whatwg.org/#dom-range-insertnode>
/// <https://dom.spec.whatwg.org/#concept-range-insert> /// <https://dom.spec.whatwg.org/#concept-range-insert>
fn InsertNode(&self, node: &Node) -> ErrorResult { fn InsertNode(&self, node: &Node, can_gc: CanGc) -> ErrorResult {
let start_node = self.start_container(); let start_node = self.start_container();
let start_offset = self.start_offset(); let start_offset = self.start_offset();
@ -848,7 +848,7 @@ impl RangeMethods for Range {
let split_text; let split_text;
let reference_node = match start_node.downcast::<Text>() { let reference_node = match start_node.downcast::<Text>() {
Some(text) => { Some(text) => {
split_text = text.SplitText(start_offset)?; split_text = text.SplitText(start_offset, can_gc)?;
let new_reference = DomRoot::upcast::<Node>(split_text); let new_reference = DomRoot::upcast::<Node>(split_text);
assert!(new_reference.GetParentNode().as_deref() == Some(&parent)); assert!(new_reference.GetParentNode().as_deref() == Some(&parent));
Some(new_reference) Some(new_reference)
@ -1006,7 +1006,7 @@ impl RangeMethods for Range {
Node::replace_all(None, new_parent); Node::replace_all(None, new_parent);
// Step 5. // Step 5.
self.InsertNode(new_parent)?; self.InsertNode(new_parent, can_gc)?;
// Step 6. // Step 6.
new_parent.AppendChild(fragment.upcast())?; new_parent.AppendChild(fragment.upcast())?;
@ -1086,7 +1086,7 @@ impl RangeMethods for Range {
}; };
// Step 2. // Step 2.
let element = Element::fragment_parsing_context(&owner_doc, element.as_deref()); let element = Element::fragment_parsing_context(&owner_doc, element.as_deref(), can_gc);
// Step 3. // Step 3.
let fragment_node = element.parse_fragment(fragment, can_gc)?; let fragment_node = element.parse_fragment(fragment, can_gc)?;

View file

@ -447,7 +447,7 @@ impl Tokenizer {
self.insert_node(node, Dom::from_ref(element.upcast())); self.insert_node(node, Dom::from_ref(element.upcast()));
}, },
ParseOperation::CreateComment { text, node } => { ParseOperation::CreateComment { text, node } => {
let comment = Comment::new(DOMString::from(text), document, None); let comment = Comment::new(DOMString::from(text), document, None, can_gc);
self.insert_node(node, Dom::from_ref(comment.upcast())); self.insert_node(node, Dom::from_ref(comment.upcast()));
}, },
ParseOperation::AppendBeforeSibling { sibling, node } => { ParseOperation::AppendBeforeSibling { sibling, node } => {
@ -477,6 +477,7 @@ impl Tokenizer {
Some(DOMString::from(public_id)), Some(DOMString::from(public_id)),
Some(DOMString::from(system_id)), Some(DOMString::from(system_id)),
document, document,
can_gc,
); );
document document
@ -490,7 +491,12 @@ impl Tokenizer {
.downcast::<Element>() .downcast::<Element>()
.expect("tried to set attrs on non-Element in HTML parsing"); .expect("tried to set attrs on non-Element in HTML parsing");
for attr in attrs { for attr in attrs {
elem.set_attribute_from_parser(attr.name, DOMString::from(attr.value), None); elem.set_attribute_from_parser(
attr.name,
DOMString::from(attr.value),
None,
can_gc,
);
} }
}, },
ParseOperation::RemoveFromParent { target } => { ParseOperation::RemoveFromParent { target } => {
@ -549,6 +555,7 @@ impl Tokenizer {
DOMString::from(target), DOMString::from(target),
DOMString::from(data), DOMString::from(data),
document, document,
can_gc,
); );
self.insert_node(node, Dom::from_ref(pi.upcast())); self.insert_node(node, Dom::from_ref(pi.upcast()));
}, },

View file

@ -855,7 +855,7 @@ impl FetchResponseListener for ParserContext {
let doc = &parser.document; let doc = &parser.document;
let doc_body = DomRoot::upcast::<Node>(doc.GetBody().unwrap()); let doc_body = DomRoot::upcast::<Node>(doc.GetBody().unwrap());
let img = HTMLImageElement::new(local_name!("img"), None, doc, None); let img = HTMLImageElement::new(local_name!("img"), None, doc, None, CanGc::note());
img.SetSrc(USVString(self.url.to_string())); img.SetSrc(USVString(self.url.to_string()));
doc_body doc_body
.AppendChild(&DomRoot::upcast::<Node>(img)) .AppendChild(&DomRoot::upcast::<Node>(img))
@ -1053,7 +1053,7 @@ fn insert(
if let Some(text) = text { if let Some(text) = text {
text.upcast::<CharacterData>().append_data(&t); text.upcast::<CharacterData>().append_data(&t);
} else { } else {
let text = Text::new(String::from(t).into(), &parent.owner_doc()); let text = Text::new(String::from(t).into(), &parent.owner_doc(), can_gc);
parent.InsertBefore(text.upcast(), reference_child).unwrap(); parent.InsertBefore(text.upcast(), reference_child).unwrap();
} }
}, },
@ -1145,7 +1145,12 @@ impl TreeSink for Sink {
#[allow(crown::unrooted_must_root)] #[allow(crown::unrooted_must_root)]
fn create_comment(&self, text: StrTendril) -> Dom<Node> { fn create_comment(&self, text: StrTendril) -> Dom<Node> {
let comment = Comment::new(DOMString::from(String::from(text)), &self.document, None); let comment = Comment::new(
DOMString::from(String::from(text)),
&self.document,
None,
CanGc::note(),
);
Dom::from_ref(comment.upcast()) Dom::from_ref(comment.upcast())
} }
@ -1156,6 +1161,7 @@ impl TreeSink for Sink {
DOMString::from(String::from(target)), DOMString::from(String::from(target)),
DOMString::from(String::from(data)), DOMString::from(String::from(data)),
doc, doc,
CanGc::note(),
); );
Dom::from_ref(pi.upcast()) Dom::from_ref(pi.upcast())
} }
@ -1249,6 +1255,7 @@ impl TreeSink for Sink {
Some(DOMString::from(String::from(public_id))), Some(DOMString::from(String::from(public_id))),
Some(DOMString::from(String::from(system_id))), Some(DOMString::from(String::from(system_id))),
doc, doc,
CanGc::note(),
); );
doc.upcast::<Node>() doc.upcast::<Node>()
.AppendChild(doctype.upcast()) .AppendChild(doctype.upcast())
@ -1264,6 +1271,7 @@ impl TreeSink for Sink {
attr.name, attr.name,
DOMString::from(String::from(attr.value)), DOMString::from(String::from(attr.value)),
None, None,
CanGc::note(),
); );
} }
} }
@ -1377,7 +1385,7 @@ fn create_element_for_token(
// Step 8 // Step 8
for attr in attrs { for attr in attrs {
element.set_attribute_from_parser(attr.name, attr.value, None); element.set_attribute_from_parser(attr.name, attr.value, None, can_gc);
} }
// _now_ we can sanitize (and we sanitize now even if the "value" // _now_ we can sanitize (and we sanitize now even if the "value"

View file

@ -15,6 +15,7 @@ use crate::dom::document::Document;
use crate::dom::element::Element; use crate::dom::element::Element;
use crate::dom::node::{window_from_node, Node}; use crate::dom::node::{window_from_node, Node};
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub struct SVGElement { pub struct SVGElement {
@ -48,11 +49,13 @@ impl SVGElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<SVGElement> { ) -> DomRoot<SVGElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(SVGElement::new_inherited(tag_name, prefix, document)), Box::new(SVGElement::new_inherited(tag_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }
@ -83,8 +86,8 @@ impl SVGElementMethods for SVGElement {
} }
// https://html.spec.whatwg.org/multipage/#dom-fe-autofocus // https://html.spec.whatwg.org/multipage/#dom-fe-autofocus
fn SetAutofocus(&self, autofocus: bool) { fn SetAutofocus(&self, autofocus: bool, can_gc: CanGc) {
self.element self.element
.set_bool_attribute(&local_name!("autofocus"), autofocus); .set_bool_attribute(&local_name!("autofocus"), autofocus, can_gc);
} }
} }

View file

@ -17,6 +17,7 @@ use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
use crate::dom::node::Node; use crate::dom::node::Node;
use crate::dom::svggraphicselement::SVGGraphicsElement; use crate::dom::svggraphicselement::SVGGraphicsElement;
use crate::dom::virtualmethods::VirtualMethods; use crate::dom::virtualmethods::VirtualMethods;
use crate::script_runtime::CanGc;
const DEFAULT_WIDTH: u32 = 300; const DEFAULT_WIDTH: u32 = 300;
const DEFAULT_HEIGHT: u32 = 150; const DEFAULT_HEIGHT: u32 = 150;
@ -43,11 +44,13 @@ impl SVGSVGElement {
prefix: Option<Prefix>, prefix: Option<Prefix>,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<SVGSVGElement> { ) -> DomRoot<SVGSVGElement> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(SVGSVGElement::new_inherited(local_name, prefix, document)), Box::new(SVGSVGElement::new_inherited(local_name, prefix, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }

View file

@ -33,19 +33,21 @@ impl Text {
} }
} }
pub fn new(text: DOMString, document: &Document) -> DomRoot<Text> { pub fn new(text: DOMString, document: &Document, can_gc: CanGc) -> DomRoot<Text> {
Self::new_with_proto(text, document, None) Self::new_with_proto(text, document, None, can_gc)
} }
fn new_with_proto( fn new_with_proto(
text: DOMString, text: DOMString,
document: &Document, document: &Document,
proto: Option<HandleObject>, proto: Option<HandleObject>,
can_gc: CanGc,
) -> DomRoot<Text> { ) -> DomRoot<Text> {
Node::reflect_node_with_proto( Node::reflect_node_with_proto(
Box::new(Text::new_inherited(text, document)), Box::new(Text::new_inherited(text, document)),
document, document,
proto, proto,
can_gc,
) )
} }
} }
@ -55,16 +57,16 @@ impl TextMethods for Text {
fn Constructor( fn Constructor(
window: &Window, window: &Window,
proto: Option<HandleObject>, proto: Option<HandleObject>,
_can_gc: CanGc, can_gc: CanGc,
text: DOMString, text: DOMString,
) -> Fallible<DomRoot<Text>> { ) -> Fallible<DomRoot<Text>> {
let document = window.Document(); let document = window.Document();
Ok(Text::new_with_proto(text, &document, proto)) Ok(Text::new_with_proto(text, &document, proto, can_gc))
} }
// https://dom.spec.whatwg.org/#dom-text-splittext // https://dom.spec.whatwg.org/#dom-text-splittext
// https://dom.spec.whatwg.org/#concept-text-split // https://dom.spec.whatwg.org/#concept-text-split
fn SplitText(&self, offset: u32) -> Fallible<DomRoot<Text>> { fn SplitText(&self, offset: u32, can_gc: CanGc) -> Fallible<DomRoot<Text>> {
let cdata = self.upcast::<CharacterData>(); let cdata = self.upcast::<CharacterData>();
// Step 1. // Step 1.
let length = cdata.Length(); let length = cdata.Length();
@ -79,7 +81,7 @@ impl TextMethods for Text {
// Step 5. // Step 5.
let node = self.upcast::<Node>(); let node = self.upcast::<Node>();
let owner_doc = node.owner_doc(); let owner_doc = node.owner_doc();
let new_node = owner_doc.CreateTextNode(new_data); let new_node = owner_doc.CreateTextNode(new_data, can_gc);
// Step 6. // Step 6.
let parent = node.GetParentNode(); let parent = node.GetParentNode();
if let Some(ref parent) = parent { if let Some(ref parent) = parent {

View file

@ -2613,7 +2613,7 @@ impl ScriptThread {
devtools::handle_get_layout(&documents, id, node_id, reply, can_gc) devtools::handle_get_layout(&documents, id, node_id, reply, can_gc)
}, },
DevtoolScriptControlMsg::ModifyAttribute(id, node_id, modifications) => { DevtoolScriptControlMsg::ModifyAttribute(id, node_id, modifications) => {
devtools::handle_modify_attribute(&documents, id, node_id, modifications) devtools::handle_modify_attribute(&documents, id, node_id, modifications, can_gc)
}, },
DevtoolScriptControlMsg::ModifyRule(id, node_id, modifications) => { DevtoolScriptControlMsg::ModifyRule(id, node_id, modifications) => {
devtools::handle_modify_rule(&documents, id, node_id, modifications) devtools::handle_modify_rule(&documents, id, node_id, modifications)